Loading services/core/java/com/android/server/wm/ActivityRecord.java +7 −3 Original line number Diff line number Diff line Loading @@ -4479,6 +4479,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A getDisplayContent().mOpeningApps.remove(this); getDisplayContent().mUnknownAppVisibilityController.appRemovedOrHidden(this); mWmService.mSnapshotController.onAppRemoved(this); mAtmService.mStartingProcessActivities.remove(this); mTaskSupervisor.getActivityMetricsLogger().notifyActivityRemoved(this); mTaskSupervisor.mStoppingActivities.remove(this); Loading Loading @@ -6221,6 +6222,10 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } boolean shouldBeVisible() { return shouldBeVisible(false /* ignoringKeyguard */); } boolean shouldBeVisible(boolean ignoringKeyguard) { final Task task = getTask(); if (task == null) { return false; Loading @@ -6228,7 +6233,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A final boolean behindOccludedContainer = !task.shouldBeVisible(null /* starting */) || task.getOccludingActivityAbove(this) != null; return shouldBeVisible(behindOccludedContainer, false /* ignoringKeyguard */); return shouldBeVisible(behindOccludedContainer, ignoringKeyguard); } void makeVisibleIfNeeded(ActivityRecord starting, boolean reportToClient) { Loading Loading @@ -10510,8 +10515,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A if (!getTurnScreenOnFlag()) { return false; } final Task rootTask = getRootTask(); return mCurrentLaunchCanTurnScreenOn && rootTask != null return mCurrentLaunchCanTurnScreenOn && mTaskSupervisor.getKeyguardController().checkKeyguardVisibility(this); } Loading services/core/java/com/android/server/wm/ActivityTaskManagerService.java +27 −1 Original line number Diff line number Diff line Loading @@ -390,6 +390,9 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { final VisibleActivityProcessTracker mVisibleActivityProcessTracker; /** The starting activities which are waiting for their processes to attach. */ final ArrayList<ActivityRecord> mStartingProcessActivities = new ArrayList<>(); /* Global service lock used by the package the owns this service. */ final WindowManagerGlobalLock mGlobalLock = new WindowManagerGlobalLock(); /** Loading Loading @@ -4331,6 +4334,9 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { if (mDemoteTopAppReasons != 0) { pw.println(" mDemoteTopAppReasons=" + mDemoteTopAppReasons); } if (!mStartingProcessActivities.isEmpty()) { pw.println(" mStartingProcessActivities=" + mStartingProcessActivities); } } if (!printedAnything) { Loading Loading @@ -5178,6 +5184,13 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { void startProcessAsync(ActivityRecord activity, boolean knownToBeDead, boolean isTop, String hostingType) { if (!mStartingProcessActivities.contains(activity)) { mStartingProcessActivities.add(activity); } else if (mProcessNames.get( activity.processName, activity.info.applicationInfo.uid) != null) { // The process is already starting. Wait for it to attach. return; } try { if (Trace.isTagEnabled(TRACE_TAG_WINDOW_MANAGER)) { Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "dispatchingStartProcess:" Loading Loading @@ -6174,7 +6187,20 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public void onProcessRemoved(String name, int uid) { synchronized (mGlobalLockWithoutBoost) { mProcessNames.remove(name, uid); final WindowProcessController proc = mProcessNames.remove(name, uid); if (proc != null && !mStartingProcessActivities.isEmpty()) { for (int i = mStartingProcessActivities.size() - 1; i >= 0; i--) { final ActivityRecord r = mStartingProcessActivities.get(i); if (uid == r.info.applicationInfo.uid && name.equals(r.processName)) { Slog.w(TAG, proc + " is removed with pending start " + r); mStartingProcessActivities.remove(i); // If visible, finish it to avoid getting stuck on screen. if (r.isVisibleRequested()) { r.finishIfPossible("starting-proc-removed", false /* oomAdj */); } } } } } } Loading services/core/java/com/android/server/wm/RootWindowContainer.java +32 −70 Original line number Diff line number Diff line Loading @@ -72,7 +72,6 @@ import static com.android.server.wm.RootWindowContainerProto.KEYGUARD_CONTROLLER import static com.android.server.wm.RootWindowContainerProto.WINDOW_CONTAINER; import static com.android.server.wm.Task.REPARENT_LEAVE_ROOT_TASK_IN_PLACE; import static com.android.server.wm.Task.REPARENT_MOVE_ROOT_TASK_TO_FRONT; import static com.android.server.wm.TaskFragment.TASK_FRAGMENT_VISIBILITY_INVISIBLE; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_TRACE; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; Loading Loading @@ -270,8 +269,6 @@ class RootWindowContainer extends WindowContainer<DisplayContent> private int mTmpTaskLayerRank; private final RankTaskLayersRunnable mRankTaskLayersRunnable = new RankTaskLayersRunnable(); private final AttachApplicationHelper mAttachApplicationHelper = new AttachApplicationHelper(); private String mDestroyAllActivitiesReason; private final Runnable mDestroyAllActivitiesRunnable = new Runnable() { @Override Loading Loading @@ -1838,11 +1835,39 @@ class RootWindowContainer extends WindowContainer<DisplayContent> } boolean attachApplication(WindowProcessController app) throws RemoteException { final ArrayList<ActivityRecord> activities = mService.mStartingProcessActivities; RemoteException remoteException = null; boolean hasActivityStarted = false; for (int i = activities.size() - 1; i >= 0; i--) { final ActivityRecord r = activities.get(i); if (app.mUid != r.info.applicationInfo.uid || !app.mName.equals(r.processName)) { // The attaching process does not match the starting activity. continue; } // Consume the pending record. activities.remove(i); final TaskFragment tf = r.getTaskFragment(); if (tf == null || r.finishing || r.app != null // Ignore keyguard because the app may use show-when-locked when creating. || !r.shouldBeVisible(true /* ignoringKeyguard */) || !r.showToCurrentUser()) { continue; } try { return mAttachApplicationHelper.process(app); } finally { mAttachApplicationHelper.reset(); final boolean canResume = r.isFocusable() && r == tf.topRunningActivity(); if (mTaskSupervisor.realStartActivityLocked(r, app, canResume, true /* checkConfig */)) { hasActivityStarted = true; } } catch (RemoteException e) { Slog.w(TAG, "Exception in new process when starting " + r, e); remoteException = e; } } if (remoteException != null) { throw remoteException; } return hasActivityStarted; } /** Loading Loading @@ -3748,67 +3773,4 @@ class RootWindowContainer extends WindowContainer<DisplayContent> } } } private class AttachApplicationHelper implements Consumer<Task>, Predicate<ActivityRecord> { private boolean mHasActivityStarted; private RemoteException mRemoteException; private WindowProcessController mApp; private ActivityRecord mTop; void reset() { mHasActivityStarted = false; mRemoteException = null; mApp = null; mTop = null; } boolean process(WindowProcessController app) throws RemoteException { mApp = app; for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) { getChildAt(displayNdx).forAllRootTasks(this); if (mRemoteException != null) { throw mRemoteException; } } if (!mHasActivityStarted) { ensureActivitiesVisible(); } return mHasActivityStarted; } @Override public void accept(Task rootTask) { if (mRemoteException != null) { return; } if (rootTask.getVisibility(null /* starting */) == TASK_FRAGMENT_VISIBILITY_INVISIBLE) { return; } mTop = rootTask.topRunningActivity(); rootTask.forAllActivities(this); } @Override public boolean test(ActivityRecord r) { if (r.finishing || !r.showToCurrentUser() || !r.visibleIgnoringKeyguard || r.app != null || mApp.mUid != r.info.applicationInfo.uid || !mApp.mName.equals(r.processName)) { return false; } try { if (mTaskSupervisor.realStartActivityLocked(r, mApp, mTop == r && r.getTask().canBeResumed(r) /* andResume */, true /* checkConfig */)) { mHasActivityStarted = true; } } catch (RemoteException e) { Slog.w(TAG, "Exception in new application when starting activity " + mTop, e); mRemoteException = e; return true; } return false; } } } services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java +19 −0 Original line number Diff line number Diff line Loading @@ -74,6 +74,7 @@ import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Rect; import android.os.PowerManager; import android.os.RemoteException; import android.os.UserHandle; import android.platform.test.annotations.Presubmit; import android.util.Pair; Loading Loading @@ -237,6 +238,24 @@ public class RootWindowContainerTests extends WindowTestsBase { assertFalse(wpc.hasActivities()); } @Test public void testAttachApplication() { final ActivityRecord activity = new ActivityBuilder(mAtm).setCreateTask(true).build(); activity.detachFromProcess(); mAtm.startProcessAsync(activity, false /* knownToBeDead */, true /* isTop */, "test" /* hostingType */); final WindowProcessController proc = mSystemServicesTestRule.addProcess( activity.packageName, activity.processName, 6789 /* pid */, activity.info.applicationInfo.uid); try { mRootWindowContainer.attachApplication(proc); verify(mSupervisor).realStartActivityLocked(eq(activity), eq(proc), anyBoolean(), anyBoolean()); } catch (RemoteException e) { e.rethrowAsRuntimeException(); } } /** * This test ensures that we do not try to restore a task based off an invalid task id. We * should expect {@code null} to be returned in this case. Loading Loading
services/core/java/com/android/server/wm/ActivityRecord.java +7 −3 Original line number Diff line number Diff line Loading @@ -4479,6 +4479,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A getDisplayContent().mOpeningApps.remove(this); getDisplayContent().mUnknownAppVisibilityController.appRemovedOrHidden(this); mWmService.mSnapshotController.onAppRemoved(this); mAtmService.mStartingProcessActivities.remove(this); mTaskSupervisor.getActivityMetricsLogger().notifyActivityRemoved(this); mTaskSupervisor.mStoppingActivities.remove(this); Loading Loading @@ -6221,6 +6222,10 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } boolean shouldBeVisible() { return shouldBeVisible(false /* ignoringKeyguard */); } boolean shouldBeVisible(boolean ignoringKeyguard) { final Task task = getTask(); if (task == null) { return false; Loading @@ -6228,7 +6233,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A final boolean behindOccludedContainer = !task.shouldBeVisible(null /* starting */) || task.getOccludingActivityAbove(this) != null; return shouldBeVisible(behindOccludedContainer, false /* ignoringKeyguard */); return shouldBeVisible(behindOccludedContainer, ignoringKeyguard); } void makeVisibleIfNeeded(ActivityRecord starting, boolean reportToClient) { Loading Loading @@ -10510,8 +10515,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A if (!getTurnScreenOnFlag()) { return false; } final Task rootTask = getRootTask(); return mCurrentLaunchCanTurnScreenOn && rootTask != null return mCurrentLaunchCanTurnScreenOn && mTaskSupervisor.getKeyguardController().checkKeyguardVisibility(this); } Loading
services/core/java/com/android/server/wm/ActivityTaskManagerService.java +27 −1 Original line number Diff line number Diff line Loading @@ -390,6 +390,9 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { final VisibleActivityProcessTracker mVisibleActivityProcessTracker; /** The starting activities which are waiting for their processes to attach. */ final ArrayList<ActivityRecord> mStartingProcessActivities = new ArrayList<>(); /* Global service lock used by the package the owns this service. */ final WindowManagerGlobalLock mGlobalLock = new WindowManagerGlobalLock(); /** Loading Loading @@ -4331,6 +4334,9 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { if (mDemoteTopAppReasons != 0) { pw.println(" mDemoteTopAppReasons=" + mDemoteTopAppReasons); } if (!mStartingProcessActivities.isEmpty()) { pw.println(" mStartingProcessActivities=" + mStartingProcessActivities); } } if (!printedAnything) { Loading Loading @@ -5178,6 +5184,13 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { void startProcessAsync(ActivityRecord activity, boolean knownToBeDead, boolean isTop, String hostingType) { if (!mStartingProcessActivities.contains(activity)) { mStartingProcessActivities.add(activity); } else if (mProcessNames.get( activity.processName, activity.info.applicationInfo.uid) != null) { // The process is already starting. Wait for it to attach. return; } try { if (Trace.isTagEnabled(TRACE_TAG_WINDOW_MANAGER)) { Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "dispatchingStartProcess:" Loading Loading @@ -6174,7 +6187,20 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public void onProcessRemoved(String name, int uid) { synchronized (mGlobalLockWithoutBoost) { mProcessNames.remove(name, uid); final WindowProcessController proc = mProcessNames.remove(name, uid); if (proc != null && !mStartingProcessActivities.isEmpty()) { for (int i = mStartingProcessActivities.size() - 1; i >= 0; i--) { final ActivityRecord r = mStartingProcessActivities.get(i); if (uid == r.info.applicationInfo.uid && name.equals(r.processName)) { Slog.w(TAG, proc + " is removed with pending start " + r); mStartingProcessActivities.remove(i); // If visible, finish it to avoid getting stuck on screen. if (r.isVisibleRequested()) { r.finishIfPossible("starting-proc-removed", false /* oomAdj */); } } } } } } Loading
services/core/java/com/android/server/wm/RootWindowContainer.java +32 −70 Original line number Diff line number Diff line Loading @@ -72,7 +72,6 @@ import static com.android.server.wm.RootWindowContainerProto.KEYGUARD_CONTROLLER import static com.android.server.wm.RootWindowContainerProto.WINDOW_CONTAINER; import static com.android.server.wm.Task.REPARENT_LEAVE_ROOT_TASK_IN_PLACE; import static com.android.server.wm.Task.REPARENT_MOVE_ROOT_TASK_TO_FRONT; import static com.android.server.wm.TaskFragment.TASK_FRAGMENT_VISIBILITY_INVISIBLE; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_TRACE; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; Loading Loading @@ -270,8 +269,6 @@ class RootWindowContainer extends WindowContainer<DisplayContent> private int mTmpTaskLayerRank; private final RankTaskLayersRunnable mRankTaskLayersRunnable = new RankTaskLayersRunnable(); private final AttachApplicationHelper mAttachApplicationHelper = new AttachApplicationHelper(); private String mDestroyAllActivitiesReason; private final Runnable mDestroyAllActivitiesRunnable = new Runnable() { @Override Loading Loading @@ -1838,11 +1835,39 @@ class RootWindowContainer extends WindowContainer<DisplayContent> } boolean attachApplication(WindowProcessController app) throws RemoteException { final ArrayList<ActivityRecord> activities = mService.mStartingProcessActivities; RemoteException remoteException = null; boolean hasActivityStarted = false; for (int i = activities.size() - 1; i >= 0; i--) { final ActivityRecord r = activities.get(i); if (app.mUid != r.info.applicationInfo.uid || !app.mName.equals(r.processName)) { // The attaching process does not match the starting activity. continue; } // Consume the pending record. activities.remove(i); final TaskFragment tf = r.getTaskFragment(); if (tf == null || r.finishing || r.app != null // Ignore keyguard because the app may use show-when-locked when creating. || !r.shouldBeVisible(true /* ignoringKeyguard */) || !r.showToCurrentUser()) { continue; } try { return mAttachApplicationHelper.process(app); } finally { mAttachApplicationHelper.reset(); final boolean canResume = r.isFocusable() && r == tf.topRunningActivity(); if (mTaskSupervisor.realStartActivityLocked(r, app, canResume, true /* checkConfig */)) { hasActivityStarted = true; } } catch (RemoteException e) { Slog.w(TAG, "Exception in new process when starting " + r, e); remoteException = e; } } if (remoteException != null) { throw remoteException; } return hasActivityStarted; } /** Loading Loading @@ -3748,67 +3773,4 @@ class RootWindowContainer extends WindowContainer<DisplayContent> } } } private class AttachApplicationHelper implements Consumer<Task>, Predicate<ActivityRecord> { private boolean mHasActivityStarted; private RemoteException mRemoteException; private WindowProcessController mApp; private ActivityRecord mTop; void reset() { mHasActivityStarted = false; mRemoteException = null; mApp = null; mTop = null; } boolean process(WindowProcessController app) throws RemoteException { mApp = app; for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) { getChildAt(displayNdx).forAllRootTasks(this); if (mRemoteException != null) { throw mRemoteException; } } if (!mHasActivityStarted) { ensureActivitiesVisible(); } return mHasActivityStarted; } @Override public void accept(Task rootTask) { if (mRemoteException != null) { return; } if (rootTask.getVisibility(null /* starting */) == TASK_FRAGMENT_VISIBILITY_INVISIBLE) { return; } mTop = rootTask.topRunningActivity(); rootTask.forAllActivities(this); } @Override public boolean test(ActivityRecord r) { if (r.finishing || !r.showToCurrentUser() || !r.visibleIgnoringKeyguard || r.app != null || mApp.mUid != r.info.applicationInfo.uid || !mApp.mName.equals(r.processName)) { return false; } try { if (mTaskSupervisor.realStartActivityLocked(r, mApp, mTop == r && r.getTask().canBeResumed(r) /* andResume */, true /* checkConfig */)) { mHasActivityStarted = true; } } catch (RemoteException e) { Slog.w(TAG, "Exception in new application when starting activity " + mTop, e); mRemoteException = e; return true; } return false; } } }
services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java +19 −0 Original line number Diff line number Diff line Loading @@ -74,6 +74,7 @@ import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Rect; import android.os.PowerManager; import android.os.RemoteException; import android.os.UserHandle; import android.platform.test.annotations.Presubmit; import android.util.Pair; Loading Loading @@ -237,6 +238,24 @@ public class RootWindowContainerTests extends WindowTestsBase { assertFalse(wpc.hasActivities()); } @Test public void testAttachApplication() { final ActivityRecord activity = new ActivityBuilder(mAtm).setCreateTask(true).build(); activity.detachFromProcess(); mAtm.startProcessAsync(activity, false /* knownToBeDead */, true /* isTop */, "test" /* hostingType */); final WindowProcessController proc = mSystemServicesTestRule.addProcess( activity.packageName, activity.processName, 6789 /* pid */, activity.info.applicationInfo.uid); try { mRootWindowContainer.attachApplication(proc); verify(mSupervisor).realStartActivityLocked(eq(activity), eq(proc), anyBoolean(), anyBoolean()); } catch (RemoteException e) { e.rethrowAsRuntimeException(); } } /** * This test ensures that we do not try to restore a task based off an invalid task id. We * should expect {@code null} to be returned in this case. Loading