Loading services/core/java/com/android/server/am/ActivityStack.java +155 −140 Original line number Diff line number Diff line Loading @@ -1418,19 +1418,9 @@ final class ActivityStack { if (top == null) { return; } if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "ensureActivitiesVisible behind " + top if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "ensureActivitiesVisible behind " + top + " configChanges=0x" + Integer.toHexString(configChanges)); if (mTranslucentActivityWaiting != top) { mUndrawnActivitiesBelowTopTranslucent.clear(); if (mTranslucentActivityWaiting != null) { // Call the callback with a timeout indication. notifyActivityDrawnLocked(null); mTranslucentActivityWaiting = null; } mHandler.removeMessages(TRANSLUCENT_TIMEOUT_MSG); } checkTranslucentActivityWaiting(top); // If the top activity is not fullscreen, then we need to // make sure any activities under it are now visible. Loading Loading @@ -1458,7 +1448,6 @@ final class ActivityStack { if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Make visible? " + r + " finishing=" + r.finishing + " state=" + r.state); // First: if this is not the current activity being started, make // sure it matches the current configuration. if (r != starting) { Loading @@ -1466,27 +1455,8 @@ final class ActivityStack { } if (r.app == null || r.app.thread == null) { // We need to make sure the app is running if it's the top, or it is // just made visible from invisible. // If the app is already visible, it must have died while it was visible. // In this case, we'll show the dead window but will not restart the app. // Otherwise we could end up thrashing. if (r == top || !r.visible) { // This activity needs to be visible, but isn't even running... // get it started and resume if no other stack in this stack is resumed. if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Start and freeze screen for " + r); if (r != starting) { r.startFreezingScreenLocked(r.app, configChanges); } if (!r.visible || r.mLaunchTaskBehind) { if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Starting and making visible: " + r); setVisible(r, true); } if (r != starting) { mStackSupervisor.startSpecificActivityLocked( r, noStackActivityResumed, false); if (makeVisibleAndRestartIfNeeded(starting, configChanges, top, noStackActivityResumed, r)) { if (activityNdx >= activities.size()) { // Record may be removed if its process needs to restart. activityNdx = activities.size() - 1; Loading @@ -1494,74 +1464,84 @@ final class ActivityStack { noStackActivityResumed = false; } } } } else if (r.visible) { // If this activity is already visible, then there is nothing // else to do here. if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Skipping: already visible at " + r); r.stopFreezingScreenLocked(false); try { if (r.returningOptions != null) { r.app.thread.scheduleOnNewActivityOptions(r.appToken, r.returningOptions); } } catch(RemoteException e) { } if (r.state == ActivityState.RESUMED) { if (alreadyVisible(r)) { noStackActivityResumed = false; } } else { // This activity is not currently visible, but is running. // Tell it to become visible. r.visible = true; if (r.state != ActivityState.RESUMED && r != starting) { // If this activity is paused, tell it // to now show its window. if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Making visible and scheduling visibility: " + r); try { becomeVisible(starting, r); } // Aggregate current change flags. configChanges |= r.configChangeFlags; behindFullscreenActivity = updateBehindFullscreen(stackInvisible, behindFullscreenActivity, task, r); } else { becomeInvisible(stackInvisible, behindFullscreenActivity, r); } } if (mStackId == FREEFORM_WORKSPACE_STACK_ID) { // The visibility of tasks and the activities they contain in freeform stack are // determined individually unlike other stacks where the visibility or fullscreen // status of an activity in a previous task affects other. behindFullscreenActivity = stackInvisible; } } if (mTranslucentActivityWaiting != null && mUndrawnActivitiesBelowTopTranslucent.isEmpty()) { // Nothing is getting drawn or everything was already visible, don't wait for timeout. notifyActivityDrawnLocked(null); } } private void checkTranslucentActivityWaiting(ActivityRecord top) { if (mTranslucentActivityWaiting != top) { mUndrawnActivitiesBelowTopTranslucent.clear(); if (mTranslucentActivityWaiting != null) { r.updateOptionsLocked(r.returningOptions); mUndrawnActivitiesBelowTopTranslucent.add(r); // Call the callback with a timeout indication. notifyActivityDrawnLocked(null); mTranslucentActivityWaiting = null; } mHandler.removeMessages(TRANSLUCENT_TIMEOUT_MSG); } } private boolean makeVisibleAndRestartIfNeeded(ActivityRecord starting, int configChanges, ActivityRecord top, boolean noStackActivityResumed, ActivityRecord r) { // We need to make sure the app is running if it's the top, or it is just made visible from // invisible. If the app is already visible, it must have died while it was visible. In this // case, we'll show the dead window but will not restart the app. Otherwise we could end up // thrashing. if (r == top || !r.visible) { // This activity needs to be visible, but isn't even running... // get it started and resume if no other stack in this stack is resumed. if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Start and freeze screen for " + r); if (r != starting) { r.startFreezingScreenLocked(r.app, configChanges); } if (!r.visible || r.mLaunchTaskBehind) { if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Starting and making visible: " + r); setVisible(r, true); r.sleeping = false; r.app.pendingUiClean = true; r.app.thread.scheduleWindowVisibility(r.appToken, true); r.stopFreezingScreenLocked(false); } catch (Exception e) { // Just skip on any failure; we'll make it // visible when it next restarts. Slog.w(TAG, "Exception thrown making visibile: " + r.intent.getComponent(), e); } if (r != starting) { mStackSupervisor.startSpecificActivityLocked(r, noStackActivityResumed, false); return true; } } return false; } // Aggregate current change flags. configChanges |= r.configChangeFlags; if (r.fullscreen) { // At this point, nothing else needs to be shown in this task. behindFullscreenActivity = true; if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Fullscreen: at " + r + " stackInvisible=" + stackInvisible + " behindFullscreenActivity=" + behindFullscreenActivity); } else if (!isHomeStack() && r.frontOfTask && task.isOverHomeStack()) { behindFullscreenActivity = true; if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Showing home: at " + r + " stackInvisible=" + stackInvisible private void becomeInvisible(boolean stackInvisible, boolean behindFullscreenActivity, ActivityRecord r) { if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Make invisible? " + r + " finishing=" + r.finishing + " state=" + r.state + " stackInvisible=" + stackInvisible + " behindFullscreenActivity=" + behindFullscreenActivity); if (!r.visible) { if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Already invisible: " + r); return; } } else { if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Make invisible? " + r + " finishing=" + r.finishing + " state=" + r.state + " stackInvisible=" + stackInvisible + " behindFullscreenActivity=" + behindFullscreenActivity); // Now for any activities that aren't visible to the user, make // sure they no longer are keeping the screen frozen. if (r.visible) { // Now for any activities that aren't visible to the user, make sure they no longer are // keeping the screen frozen. if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Making invisible: " + r); try { setVisible(r, false); Loading Loading @@ -1595,29 +1575,64 @@ final class ActivityStack { break; } } catch (Exception e) { // Just skip on any failure; we'll make it // visible when it next restarts. Slog.w(TAG, "Exception thrown making hidden: " + r.intent.getComponent(), e); // Just skip on any failure; we'll make it visible when it next restarts. Slog.w(TAG, "Exception thrown making hidden: " + r.intent.getComponent(), e); } } else { if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Already invisible: " + r); } private boolean updateBehindFullscreen(boolean stackInvisible, boolean behindFullscreenActivity, TaskRecord task, ActivityRecord r) { if (r.fullscreen) { // At this point, nothing else needs to be shown in this task. behindFullscreenActivity = true; if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Fullscreen: at " + r + " stackInvisible=" + stackInvisible + " behindFullscreenActivity=" + behindFullscreenActivity); } else if (!isHomeStack() && r.frontOfTask && task.isOverHomeStack()) { behindFullscreenActivity = true; if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Showing home: at " + r + " stackInvisible=" + stackInvisible + " behindFullscreenActivity=" + behindFullscreenActivity); } return behindFullscreenActivity; } private void becomeVisible(ActivityRecord starting, ActivityRecord r) { // This activity is not currently visible, but is running. Tell it to become visible. r.visible = true; if (r.state != ActivityState.RESUMED && r != starting) { // If this activity is paused, tell it to now show its window. if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Making visible and scheduling visibility: " + r); try { if (mTranslucentActivityWaiting != null) { r.updateOptionsLocked(r.returningOptions); mUndrawnActivitiesBelowTopTranslucent.add(r); } setVisible(r, true); r.sleeping = false; r.app.pendingUiClean = true; r.app.thread.scheduleWindowVisibility(r.appToken, true); r.stopFreezingScreenLocked(false); } catch (Exception e) { // Just skip on any failure; we'll make it // visible when it next restarts. Slog.w(TAG, "Exception thrown making visibile: " + r.intent.getComponent(), e); } if (mStackId == FREEFORM_WORKSPACE_STACK_ID) { // The visibility of tasks and the activities they contain in freeform stack are // determined individually unlike other stacks where the visibility or fullscreen // status of an activity in a previous task affects other. behindFullscreenActivity = stackInvisible; } } if (mTranslucentActivityWaiting != null && mUndrawnActivitiesBelowTopTranslucent.isEmpty()) { // Nothing is getting drawn or everything was already visible, don't wait for timeout. notifyActivityDrawnLocked(null); private boolean alreadyVisible(ActivityRecord r) { // If this activity is already visible, then there is nothing else to do here. if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Skipping: already visible at " + r); r.stopFreezingScreenLocked(false); try { if (r.returningOptions != null) { r.app.thread.scheduleOnNewActivityOptions(r.appToken, r.returningOptions); } } catch(RemoteException e) { } return r.state == ActivityState.RESUMED; } void convertActivityToTranslucent(ActivityRecord r) { Loading Loading
services/core/java/com/android/server/am/ActivityStack.java +155 −140 Original line number Diff line number Diff line Loading @@ -1418,19 +1418,9 @@ final class ActivityStack { if (top == null) { return; } if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "ensureActivitiesVisible behind " + top if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "ensureActivitiesVisible behind " + top + " configChanges=0x" + Integer.toHexString(configChanges)); if (mTranslucentActivityWaiting != top) { mUndrawnActivitiesBelowTopTranslucent.clear(); if (mTranslucentActivityWaiting != null) { // Call the callback with a timeout indication. notifyActivityDrawnLocked(null); mTranslucentActivityWaiting = null; } mHandler.removeMessages(TRANSLUCENT_TIMEOUT_MSG); } checkTranslucentActivityWaiting(top); // If the top activity is not fullscreen, then we need to // make sure any activities under it are now visible. Loading Loading @@ -1458,7 +1448,6 @@ final class ActivityStack { if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Make visible? " + r + " finishing=" + r.finishing + " state=" + r.state); // First: if this is not the current activity being started, make // sure it matches the current configuration. if (r != starting) { Loading @@ -1466,27 +1455,8 @@ final class ActivityStack { } if (r.app == null || r.app.thread == null) { // We need to make sure the app is running if it's the top, or it is // just made visible from invisible. // If the app is already visible, it must have died while it was visible. // In this case, we'll show the dead window but will not restart the app. // Otherwise we could end up thrashing. if (r == top || !r.visible) { // This activity needs to be visible, but isn't even running... // get it started and resume if no other stack in this stack is resumed. if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Start and freeze screen for " + r); if (r != starting) { r.startFreezingScreenLocked(r.app, configChanges); } if (!r.visible || r.mLaunchTaskBehind) { if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Starting and making visible: " + r); setVisible(r, true); } if (r != starting) { mStackSupervisor.startSpecificActivityLocked( r, noStackActivityResumed, false); if (makeVisibleAndRestartIfNeeded(starting, configChanges, top, noStackActivityResumed, r)) { if (activityNdx >= activities.size()) { // Record may be removed if its process needs to restart. activityNdx = activities.size() - 1; Loading @@ -1494,74 +1464,84 @@ final class ActivityStack { noStackActivityResumed = false; } } } } else if (r.visible) { // If this activity is already visible, then there is nothing // else to do here. if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Skipping: already visible at " + r); r.stopFreezingScreenLocked(false); try { if (r.returningOptions != null) { r.app.thread.scheduleOnNewActivityOptions(r.appToken, r.returningOptions); } } catch(RemoteException e) { } if (r.state == ActivityState.RESUMED) { if (alreadyVisible(r)) { noStackActivityResumed = false; } } else { // This activity is not currently visible, but is running. // Tell it to become visible. r.visible = true; if (r.state != ActivityState.RESUMED && r != starting) { // If this activity is paused, tell it // to now show its window. if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Making visible and scheduling visibility: " + r); try { becomeVisible(starting, r); } // Aggregate current change flags. configChanges |= r.configChangeFlags; behindFullscreenActivity = updateBehindFullscreen(stackInvisible, behindFullscreenActivity, task, r); } else { becomeInvisible(stackInvisible, behindFullscreenActivity, r); } } if (mStackId == FREEFORM_WORKSPACE_STACK_ID) { // The visibility of tasks and the activities they contain in freeform stack are // determined individually unlike other stacks where the visibility or fullscreen // status of an activity in a previous task affects other. behindFullscreenActivity = stackInvisible; } } if (mTranslucentActivityWaiting != null && mUndrawnActivitiesBelowTopTranslucent.isEmpty()) { // Nothing is getting drawn or everything was already visible, don't wait for timeout. notifyActivityDrawnLocked(null); } } private void checkTranslucentActivityWaiting(ActivityRecord top) { if (mTranslucentActivityWaiting != top) { mUndrawnActivitiesBelowTopTranslucent.clear(); if (mTranslucentActivityWaiting != null) { r.updateOptionsLocked(r.returningOptions); mUndrawnActivitiesBelowTopTranslucent.add(r); // Call the callback with a timeout indication. notifyActivityDrawnLocked(null); mTranslucentActivityWaiting = null; } mHandler.removeMessages(TRANSLUCENT_TIMEOUT_MSG); } } private boolean makeVisibleAndRestartIfNeeded(ActivityRecord starting, int configChanges, ActivityRecord top, boolean noStackActivityResumed, ActivityRecord r) { // We need to make sure the app is running if it's the top, or it is just made visible from // invisible. If the app is already visible, it must have died while it was visible. In this // case, we'll show the dead window but will not restart the app. Otherwise we could end up // thrashing. if (r == top || !r.visible) { // This activity needs to be visible, but isn't even running... // get it started and resume if no other stack in this stack is resumed. if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Start and freeze screen for " + r); if (r != starting) { r.startFreezingScreenLocked(r.app, configChanges); } if (!r.visible || r.mLaunchTaskBehind) { if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Starting and making visible: " + r); setVisible(r, true); r.sleeping = false; r.app.pendingUiClean = true; r.app.thread.scheduleWindowVisibility(r.appToken, true); r.stopFreezingScreenLocked(false); } catch (Exception e) { // Just skip on any failure; we'll make it // visible when it next restarts. Slog.w(TAG, "Exception thrown making visibile: " + r.intent.getComponent(), e); } if (r != starting) { mStackSupervisor.startSpecificActivityLocked(r, noStackActivityResumed, false); return true; } } return false; } // Aggregate current change flags. configChanges |= r.configChangeFlags; if (r.fullscreen) { // At this point, nothing else needs to be shown in this task. behindFullscreenActivity = true; if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Fullscreen: at " + r + " stackInvisible=" + stackInvisible + " behindFullscreenActivity=" + behindFullscreenActivity); } else if (!isHomeStack() && r.frontOfTask && task.isOverHomeStack()) { behindFullscreenActivity = true; if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Showing home: at " + r + " stackInvisible=" + stackInvisible private void becomeInvisible(boolean stackInvisible, boolean behindFullscreenActivity, ActivityRecord r) { if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Make invisible? " + r + " finishing=" + r.finishing + " state=" + r.state + " stackInvisible=" + stackInvisible + " behindFullscreenActivity=" + behindFullscreenActivity); if (!r.visible) { if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Already invisible: " + r); return; } } else { if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Make invisible? " + r + " finishing=" + r.finishing + " state=" + r.state + " stackInvisible=" + stackInvisible + " behindFullscreenActivity=" + behindFullscreenActivity); // Now for any activities that aren't visible to the user, make // sure they no longer are keeping the screen frozen. if (r.visible) { // Now for any activities that aren't visible to the user, make sure they no longer are // keeping the screen frozen. if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Making invisible: " + r); try { setVisible(r, false); Loading Loading @@ -1595,29 +1575,64 @@ final class ActivityStack { break; } } catch (Exception e) { // Just skip on any failure; we'll make it // visible when it next restarts. Slog.w(TAG, "Exception thrown making hidden: " + r.intent.getComponent(), e); // Just skip on any failure; we'll make it visible when it next restarts. Slog.w(TAG, "Exception thrown making hidden: " + r.intent.getComponent(), e); } } else { if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Already invisible: " + r); } private boolean updateBehindFullscreen(boolean stackInvisible, boolean behindFullscreenActivity, TaskRecord task, ActivityRecord r) { if (r.fullscreen) { // At this point, nothing else needs to be shown in this task. behindFullscreenActivity = true; if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Fullscreen: at " + r + " stackInvisible=" + stackInvisible + " behindFullscreenActivity=" + behindFullscreenActivity); } else if (!isHomeStack() && r.frontOfTask && task.isOverHomeStack()) { behindFullscreenActivity = true; if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Showing home: at " + r + " stackInvisible=" + stackInvisible + " behindFullscreenActivity=" + behindFullscreenActivity); } return behindFullscreenActivity; } private void becomeVisible(ActivityRecord starting, ActivityRecord r) { // This activity is not currently visible, but is running. Tell it to become visible. r.visible = true; if (r.state != ActivityState.RESUMED && r != starting) { // If this activity is paused, tell it to now show its window. if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Making visible and scheduling visibility: " + r); try { if (mTranslucentActivityWaiting != null) { r.updateOptionsLocked(r.returningOptions); mUndrawnActivitiesBelowTopTranslucent.add(r); } setVisible(r, true); r.sleeping = false; r.app.pendingUiClean = true; r.app.thread.scheduleWindowVisibility(r.appToken, true); r.stopFreezingScreenLocked(false); } catch (Exception e) { // Just skip on any failure; we'll make it // visible when it next restarts. Slog.w(TAG, "Exception thrown making visibile: " + r.intent.getComponent(), e); } if (mStackId == FREEFORM_WORKSPACE_STACK_ID) { // The visibility of tasks and the activities they contain in freeform stack are // determined individually unlike other stacks where the visibility or fullscreen // status of an activity in a previous task affects other. behindFullscreenActivity = stackInvisible; } } if (mTranslucentActivityWaiting != null && mUndrawnActivitiesBelowTopTranslucent.isEmpty()) { // Nothing is getting drawn or everything was already visible, don't wait for timeout. notifyActivityDrawnLocked(null); private boolean alreadyVisible(ActivityRecord r) { // If this activity is already visible, then there is nothing else to do here. if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Skipping: already visible at " + r); r.stopFreezingScreenLocked(false); try { if (r.returningOptions != null) { r.app.thread.scheduleOnNewActivityOptions(r.appToken, r.returningOptions); } } catch(RemoteException e) { } return r.state == ActivityState.RESUMED; } void convertActivityToTranslucent(ActivityRecord r) { Loading