Skip to content

Commit 493f74e

Browse files
Dianne HackbornAndroid (Google) Code Review
authored andcommitted
Merge "Add new Activity.finishAffinity() method." into jb-dev
2 parents e6eb929 + ecc5a9c commit 493f74e

6 files changed

Lines changed: 109 additions & 18 deletions

File tree

api/current.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2601,6 +2601,7 @@ package android.app {
26012601
method public void finish();
26022602
method public void finishActivity(int);
26032603
method public void finishActivityFromChild(android.app.Activity, int);
2604+
method public void finishAffinity();
26042605
method public void finishFromChild(android.app.Activity);
26052606
method public android.app.ActionBar getActionBar();
26062607
method public final android.app.Application getApplication();

core/java/android/app/Activity.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4092,6 +4092,36 @@ public void finish() {
40924092
}
40934093
}
40944094

4095+
/**
4096+
* Finish this activity as well as all activities immediately below it
4097+
* in the current task that have the same affinity. This is typically
4098+
* used when an application can be launched on to another task (such as
4099+
* from an ACTION_VIEW of a content type it understands) and the user
4100+
* has used the up navigation to switch out of the current task and in
4101+
* to its own task. In this case, if the user has navigated down into
4102+
* any other activities of the second application, all of those should
4103+
* be removed from the original task as part of the task switch.
4104+
*
4105+
* <p>Note that this finish does <em>not</em> allow you to deliver results
4106+
* to the previous activity, and an exception will be thrown if you are trying
4107+
* to do so.</p>
4108+
*/
4109+
public void finishAffinity() {
4110+
if (mParent != null) {
4111+
throw new IllegalStateException("Can not be called from an embedded activity");
4112+
}
4113+
if (mResultCode != RESULT_CANCELED || mResultData != null) {
4114+
throw new IllegalStateException("Can not be called to deliver a result");
4115+
}
4116+
try {
4117+
if (ActivityManagerNative.getDefault().finishActivityAffinity(mToken)) {
4118+
mFinished = true;
4119+
}
4120+
} catch (RemoteException e) {
4121+
// Empty
4122+
}
4123+
}
4124+
40954125
/**
40964126
* This is called when a child activity of this one calls its
40974127
* {@link #finish} method. The default implementation simply calls

core/java/android/app/ActivityManagerNative.java

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
218218
reply.writeInt(result ? 1 : 0);
219219
return true;
220220
}
221-
221+
222222
case FINISH_ACTIVITY_TRANSACTION: {
223223
data.enforceInterface(IActivityManager.descriptor);
224224
IBinder token = data.readStrongBinder();
@@ -243,6 +243,15 @@ public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
243243
return true;
244244
}
245245

246+
case FINISH_ACTIVITY_AFFINITY_TRANSACTION: {
247+
data.enforceInterface(IActivityManager.descriptor);
248+
IBinder token = data.readStrongBinder();
249+
boolean res = finishActivityAffinity(token);
250+
reply.writeNoException();
251+
reply.writeInt(res ? 1 : 0);
252+
return true;
253+
}
254+
246255
case WILL_ACTIVITY_BE_VISIBLE_TRANSACTION: {
247256
data.enforceInterface(IActivityManager.descriptor);
248257
IBinder token = data.readStrongBinder();
@@ -1866,6 +1875,18 @@ public void finishSubActivity(IBinder token, String resultWho, int requestCode)
18661875
data.recycle();
18671876
reply.recycle();
18681877
}
1878+
public boolean finishActivityAffinity(IBinder token) throws RemoteException {
1879+
Parcel data = Parcel.obtain();
1880+
Parcel reply = Parcel.obtain();
1881+
data.writeInterfaceToken(IActivityManager.descriptor);
1882+
data.writeStrongBinder(token);
1883+
mRemote.transact(FINISH_ACTIVITY_AFFINITY_TRANSACTION, data, reply, 0);
1884+
reply.readException();
1885+
boolean res = reply.readInt() != 0;
1886+
data.recycle();
1887+
reply.recycle();
1888+
return res;
1889+
}
18691890
public boolean willActivityBeVisible(IBinder token) throws RemoteException {
18701891
Parcel data = Parcel.obtain();
18711892
Parcel reply = Parcel.obtain();

core/java/android/app/IActivityManager.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ public boolean startNextMatchingActivity(IBinder callingActivity,
7272
public boolean finishActivity(IBinder token, int code, Intent data)
7373
throws RemoteException;
7474
public void finishSubActivity(IBinder token, String resultWho, int requestCode) throws RemoteException;
75+
public boolean finishActivityAffinity(IBinder token) throws RemoteException;
7576
public boolean willActivityBeVisible(IBinder token) throws RemoteException;
7677
public Intent registerReceiver(IApplicationThread caller, String callerPackage,
7778
IIntentReceiver receiver, IntentFilter filter,
@@ -590,4 +591,5 @@ private WaitResult(Parcel source) {
590591
int TARGET_TASK_AFFINITY_MATCHES_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+145;
591592
int NAVIGATE_UP_TO_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+146;
592593
int SET_LOCK_SCREEN_SHOWN_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+147;
594+
int FINISH_ACTIVITY_AFFINITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+148;
593595
}

services/java/com/android/server/am/ActivityManagerService.java

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2697,26 +2697,18 @@ public void crashApplication(int uid, int initialPid, String packageName,
26972697
public final void finishSubActivity(IBinder token, String resultWho,
26982698
int requestCode) {
26992699
synchronized(this) {
2700-
ActivityRecord self = mMainStack.isInStackLocked(token);
2701-
if (self == null) {
2702-
return;
2703-
}
2704-
27052700
final long origId = Binder.clearCallingIdentity();
2701+
mMainStack.finishSubActivityLocked(token, resultWho, requestCode);
2702+
Binder.restoreCallingIdentity(origId);
2703+
}
2704+
}
27062705

2707-
int i;
2708-
for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2709-
ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2710-
if (r.resultTo == self && r.requestCode == requestCode) {
2711-
if ((r.resultWho == null && resultWho == null) ||
2712-
(r.resultWho != null && r.resultWho.equals(resultWho))) {
2713-
mMainStack.finishActivityLocked(r, i,
2714-
Activity.RESULT_CANCELED, null, "request-sub");
2715-
}
2716-
}
2717-
}
2718-
2706+
public boolean finishActivityAffinity(IBinder token) {
2707+
synchronized(this) {
2708+
final long origId = Binder.clearCallingIdentity();
2709+
boolean res = mMainStack.finishActivityAffinityLocked(token);
27192710
Binder.restoreCallingIdentity(origId);
2711+
return res;
27202712
}
27212713
}
27222714

services/java/com/android/server/am/ActivityStack.java

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3497,6 +3497,51 @@ final boolean requestFinishActivityLocked(IBinder token, int resultCode,
34973497
return true;
34983498
}
34993499

3500+
final void finishSubActivityLocked(IBinder token, String resultWho, int requestCode) {
3501+
ActivityRecord self = isInStackLocked(token);
3502+
if (self == null) {
3503+
return;
3504+
}
3505+
3506+
int i;
3507+
for (i=mHistory.size()-1; i>=0; i--) {
3508+
ActivityRecord r = (ActivityRecord)mHistory.get(i);
3509+
if (r.resultTo == self && r.requestCode == requestCode) {
3510+
if ((r.resultWho == null && resultWho == null) ||
3511+
(r.resultWho != null && r.resultWho.equals(resultWho))) {
3512+
finishActivityLocked(r, i,
3513+
Activity.RESULT_CANCELED, null, "request-sub");
3514+
}
3515+
}
3516+
}
3517+
}
3518+
3519+
final boolean finishActivityAffinityLocked(IBinder token) {
3520+
int index = indexOfTokenLocked(token);
3521+
if (DEBUG_RESULTS) Slog.v(
3522+
TAG, "Finishing activity affinity @" + index + ": token=" + token);
3523+
if (index < 0) {
3524+
return false;
3525+
}
3526+
ActivityRecord r = mHistory.get(index);
3527+
3528+
while (index > 0) {
3529+
ActivityRecord cur = mHistory.get(index);
3530+
if (cur.task != r.task) {
3531+
break;
3532+
}
3533+
if (cur.taskAffinity == null && r.taskAffinity != null) {
3534+
break;
3535+
}
3536+
if (cur.taskAffinity != null && !cur.taskAffinity.equals(r.taskAffinity)) {
3537+
break;
3538+
}
3539+
finishActivityLocked(cur, index, Activity.RESULT_CANCELED, null, "request-affinity");
3540+
index--;
3541+
}
3542+
return true;
3543+
}
3544+
35003545
final void finishActivityResultsLocked(ActivityRecord r, int resultCode, Intent resultData) {
35013546
// send the result
35023547
ActivityRecord resultTo = r.resultTo;

0 commit comments

Comments
 (0)