diff options
Diffstat (limited to 'services/java/com/android/server/am/ActivityManagerService.java')
-rw-r--r-- | services/java/com/android/server/am/ActivityManagerService.java | 107 |
1 files changed, 101 insertions, 6 deletions
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index a6fbdd7..33250b8 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -62,10 +62,10 @@ import android.content.ContentProvider; import android.content.ContentResolver; import android.content.Context; import android.content.DialogInterface; -import android.content.Intent; -import android.content.IntentFilter; import android.content.IIntentReceiver; import android.content.IIntentSender; +import android.content.Intent; +import android.content.IntentFilter; import android.content.IntentSender; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; @@ -75,12 +75,12 @@ import android.content.pm.IPackageManager; import android.content.pm.InstrumentationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; +import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.PathPermission; import android.content.pm.ProviderInfo; import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; import android.content.pm.UserInfo; -import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.CompatibilityInfo; import android.content.res.Configuration; import android.graphics.Bitmap; @@ -113,10 +113,10 @@ import android.os.UserId; import android.provider.Settings; import android.text.format.Time; import android.util.EventLog; -import android.util.Pair; -import android.util.Slog; import android.util.Log; +import android.util.Pair; import android.util.PrintWriterPrinter; +import android.util.Slog; import android.util.SparseArray; import android.util.SparseIntArray; import android.util.TimeUtils; @@ -140,7 +140,6 @@ import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.io.StringWriter; -import java.lang.IllegalStateException; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Collection; @@ -13281,6 +13280,102 @@ public final class ActivityManagerService extends ActivityManagerNative } } + @Override + public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { + ActivityRecord srec = ActivityRecord.forToken(token); + return srec.task.affinity != null && srec.task.affinity.equals(destAffinity); + } + + public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, + Intent resultData) { + ComponentName dest = destIntent.getComponent(); + + synchronized (this) { + ActivityRecord srec = ActivityRecord.forToken(token); + ArrayList<ActivityRecord> history = srec.stack.mHistory; + final int start = history.indexOf(srec); + if (start < 0) { + // Current activity is not in history stack; do nothing. + return false; + } + int finishTo = start - 1; + ActivityRecord parent = null; + boolean foundParentInTask = false; + if (dest != null) { + TaskRecord tr = srec.task; + for (int i = start - 1; i >= 0; i--) { + ActivityRecord r = history.get(i); + if (tr != r.task) { + // Couldn't find parent in the same task; stop at the one above this. + // (Root of current task; in-app "home" behavior) + // Always at least finish the current activity. + finishTo = Math.min(start - 1, i + 1); + parent = history.get(finishTo); + break; + } else if (r.info.packageName.equals(dest.getPackageName()) && + r.info.name.equals(dest.getClassName())) { + finishTo = i; + parent = r; + foundParentInTask = true; + break; + } + } + } + + if (mController != null) { + ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); + if (next != null) { + // ask watcher if this is allowed + boolean resumeOK = true; + try { + resumeOK = mController.activityResuming(next.packageName); + } catch (RemoteException e) { + mController = null; + } + + if (!resumeOK) { + return false; + } + } + } + final long origId = Binder.clearCallingIdentity(); + for (int i = start; i > finishTo; i--) { + ActivityRecord r = history.get(i); + mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData, + "navigate-up"); + // Only return the supplied result for the first activity finished + resultCode = Activity.RESULT_CANCELED; + resultData = null; + } + + if (parent != null && foundParentInTask) { + final int parentLaunchMode = parent.info.launchMode; + final int destIntentFlags = destIntent.getFlags(); + if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE || + parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK || + parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP || + (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { + parent.deliverNewIntentLocked(srec.app.uid, destIntent); + } else { + try { + ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo( + destIntent.getComponent(), 0, UserId.getCallingUserId()); + int res = mMainStack.startActivityLocked(srec.app.thread, destIntent, + null, aInfo, parent.appToken, null, + 0, -1, parent.launchedFromUid, 0, null, true, null); + foundParentInTask = res == ActivityManager.START_SUCCESS; + } catch (RemoteException e) { + foundParentInTask = false; + } + mMainStack.requestFinishActivityLocked(parent.appToken, resultCode, + resultData, "navigate-up"); + } + } + Binder.restoreCallingIdentity(origId); + return foundParentInTask; + } + } + // ========================================================= // LIFETIME MANAGEMENT // ========================================================= |