Merge "remove reference to skia vertical-text (never set/used)"
diff --git a/services/core/java/com/android/server/am/ActivityDisplay.java b/services/core/java/com/android/server/am/ActivityDisplay.java
index 9a47553..ede13ef 100644
--- a/services/core/java/com/android/server/am/ActivityDisplay.java
+++ b/services/core/java/com/android/server/am/ActivityDisplay.java
@@ -873,6 +873,52 @@
return null;
}
+ ActivityRecord topRunningActivity() {
+ return topRunningActivity(false /* considerKeyguardState */);
+ }
+
+ /**
+ * Returns the top running activity in the focused stack. In the case the focused stack has no
+ * such activity, the next focusable stack on this display is returned.
+ *
+ * @param considerKeyguardState Indicates whether the locked state should be considered. if
+ * {@code true} and the keyguard is locked, only activities that
+ * can be shown on top of the keyguard will be considered.
+ * @return The top running activity. {@code null} if none is available.
+ */
+ ActivityRecord topRunningActivity(boolean considerKeyguardState) {
+ ActivityRecord topRunning = null;
+ final ActivityStack focusedStack = getFocusedStack();
+ if (focusedStack != null) {
+ topRunning = focusedStack.topRunningActivityLocked();
+ }
+
+ // Look in other focusable stacks.
+ if (topRunning == null) {
+ for (int i = mStacks.size() - 1; i >= 0; --i) {
+ final ActivityStack stack = mStacks.get(i);
+ // Only consider focusable stacks other than the current focused one.
+ if (stack == focusedStack || !stack.isFocusable()) {
+ continue;
+ }
+ topRunning = stack.topRunningActivityLocked();
+ if (topRunning != null) {
+ break;
+ }
+ }
+ }
+
+ // This activity can be considered the top running activity if we are not considering
+ // the locked state, the keyguard isn't locked, or we can show when locked.
+ if (topRunning != null && considerKeyguardState
+ && mSupervisor.getKeyguardController().isKeyguardLocked()
+ && !topRunning.canShowWhenLocked()) {
+ return null;
+ }
+
+ return topRunning;
+ }
+
int getIndexOf(ActivityStack stack) {
return mStacks.indexOf(stack);
}
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 12ed726..026c5cc 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -3877,8 +3877,8 @@
// The activity that we are finishing may be over the lock screen. In this case, we do not
// want to consider activities that cannot be shown on the lock screen as running and should
// proceed with finishing the activity if there is no valid next top running activity.
- final ActivityRecord next = mStackSupervisor.topRunningActivityLocked(
- true /* considerKeyguardState */);
+ final ActivityDisplay display = getDisplay();
+ final ActivityRecord next = display.topRunningActivity(true /* considerKeyguardState */);
if (mode == FINISH_AFTER_VISIBLE && (r.visible || r.nowVisible)
&& next != null && !next.nowVisible) {
@@ -3902,23 +3902,25 @@
if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to FINISHING: " + r);
r.setState(FINISHING, "finishCurrentActivityLocked");
- final boolean finishingActivityInNonFocusedStack
- = r.getStack() != mStackSupervisor.getTopDisplayFocusedStack()
- && prevState == PAUSED && mode == FINISH_AFTER_VISIBLE;
+ final boolean finishingInNonFocusedStackOrNoRunning = mode == FINISH_AFTER_VISIBLE
+ && prevState == PAUSED && (r.getStack() != display.getFocusedStack()
+ || (next == null && display.topRunningActivity() == null));
if (mode == FINISH_IMMEDIATELY
|| (prevState == PAUSED
&& (mode == FINISH_AFTER_PAUSE || inPinnedWindowingMode()))
- || finishingActivityInNonFocusedStack
+ || finishingInNonFocusedStackOrNoRunning
|| prevState == STOPPING
|| prevState == STOPPED
|| prevState == ActivityState.INITIALIZING) {
r.makeFinishingLocked();
boolean activityRemoved = destroyActivityLocked(r, true, "finish-imm:" + reason);
- if (finishingActivityInNonFocusedStack) {
+ if (finishingInNonFocusedStackOrNoRunning) {
// Finishing activity that was in paused state and it was in not currently focused
- // stack, need to make something visible in its place.
+ // stack, need to make something visible in its place. Also if the display does not
+ // have running activity, the configuration may need to be updated for restoring
+ // original orientation of the display.
mStackSupervisor.ensureVisibilityAndConfig(next, mDisplayId,
false /* markFrozenIfConfigChanged */, true /* deferResume */);
}
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 90e2f5b..257a004 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -1214,75 +1214,15 @@
}
ActivityRecord topRunningActivityLocked() {
- return topRunningActivityLocked(false /* considerKeyguardState */);
- }
-
- /**
- * Returns the top running activity in the focused stack. In the case the focused stack has no
- * such activity, the next focusable stack on top of a display is returned.
- * @param considerKeyguardState Indicates whether the locked state should be considered. if
- * {@code true} and the keyguard is locked, only activities that
- * can be shown on top of the keyguard will be considered.
- * @return The top running activity. {@code null} if none is available.
- */
- ActivityRecord topRunningActivityLocked(boolean considerKeyguardState) {
- final ActivityStack focusedStack = getTopDisplayFocusedStack();
- ActivityRecord r = focusedStack.topRunningActivityLocked();
- if (r != null && isValidTopRunningActivity(r, considerKeyguardState)) {
- return r;
- }
-
- // Look in other non-focused and non-home stacks.
for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
- final ActivityDisplay display = mActivityDisplays.get(i);
-
- // TODO: We probably want to consider the top fullscreen stack as we could have a pinned
- // stack on top.
- final ActivityStack topStack = display.getTopStack();
-
- // Only consider focusable top stacks other than the current focused one.
- if (topStack == null || !topStack.isFocusable() || topStack == focusedStack) {
- continue;
- }
-
- final ActivityRecord topActivity = topStack.topRunningActivityLocked();
-
- // Skip if no top activity.
- if (topActivity == null) {
- continue;
- }
-
-
- // This activity can be considered the top running activity if we are not
- // considering the locked state, the keyguard isn't locked, or we can show when
- // locked.
- if (isValidTopRunningActivity(topActivity, considerKeyguardState)) {
+ final ActivityRecord topActivity = mActivityDisplays.get(i).topRunningActivity();
+ if (topActivity != null) {
return topActivity;
}
}
-
return null;
}
- /**
- * Verifies an {@link ActivityRecord} can be the top activity based on keyguard state and
- * whether we are considering it.
- */
- private boolean isValidTopRunningActivity(ActivityRecord record,
- boolean considerKeyguardState) {
- if (!considerKeyguardState) {
- return true;
- }
-
- final boolean keyguardLocked = getKeyguardController().isKeyguardLocked();
-
- if (!keyguardLocked) {
- return true;
- }
-
- return record.canShowWhenLocked();
- }
-
@VisibleForTesting
void getRunningTasks(int maxNum, List<RunningTaskInfo> list,
@ActivityType int ignoreActivityType, @WindowingMode int ignoreWindowingMode,
diff --git a/services/core/java/com/android/server/am/ActivityTaskManagerService.java b/services/core/java/com/android/server/am/ActivityTaskManagerService.java
index 8ae5495..f79d9aa 100644
--- a/services/core/java/com/android/server/am/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityTaskManagerService.java
@@ -5864,6 +5864,9 @@
@Override
public void finishHeavyWeightApp() {
synchronized (mGlobalLock) {
+ if (mHeavyWeightProcess != null) {
+ mHeavyWeightProcess.finishActivities();
+ }
ActivityTaskManagerService.this.clearHeavyWeightProcessIfEquals(
mHeavyWeightProcess);
}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 506cc44..348b8e6 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -719,8 +719,7 @@
return;
}
final long now = System.currentTimeMillis();
- MetricsLogger.action(r.getLogMaker(now)
- .setCategory(MetricsEvent.NOTIFICATION_ITEM)
+ MetricsLogger.action(r.getItemLogMaker()
.setType(MetricsEvent.TYPE_ACTION)
.addTaggedData(MetricsEvent.NOTIFICATION_SHADE_INDEX, nv.rank)
.addTaggedData(MetricsEvent.NOTIFICATION_SHADE_COUNT, nv.count));
@@ -865,8 +864,7 @@
r.stats.onExpansionChanged(userAction, expanded);
final long now = System.currentTimeMillis();
if (userAction) {
- MetricsLogger.action(r.getLogMaker(now)
- .setCategory(MetricsEvent.NOTIFICATION_ITEM)
+ MetricsLogger.action(r.getItemLogMaker()
.setType(expanded ? MetricsEvent.TYPE_DETAIL
: MetricsEvent.TYPE_COLLAPSE));
}
@@ -5842,8 +5840,7 @@
mArchive.record(r.sbn);
final long now = System.currentTimeMillis();
- final LogMaker logMaker = r.getLogMaker(now)
- .setCategory(MetricsEvent.NOTIFICATION_ITEM)
+ final LogMaker logMaker = r.getItemLogMaker()
.setType(MetricsEvent.TYPE_DISMISS)
.setSubtype(reason);
if (rank != -1 && count != -1) {
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index 65ec580..19a62d9 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -611,6 +611,7 @@
}
public void applyAdjustments() {
+ long now = System.currentTimeMillis();
synchronized (mAdjustments) {
for (Adjustment adjustment: mAdjustments) {
Bundle signals = adjustment.getSignals();
@@ -618,17 +619,25 @@
final ArrayList<String> people =
adjustment.getSignals().getStringArrayList(Adjustment.KEY_PEOPLE);
setPeopleOverride(people);
+ MetricsLogger.action(getAdjustmentLogMaker()
+ .addTaggedData(MetricsEvent.ADJUSTMENT_KEY_PEOPLE, people.size()));
}
if (signals.containsKey(Adjustment.KEY_SNOOZE_CRITERIA)) {
final ArrayList<SnoozeCriterion> snoozeCriterionList =
adjustment.getSignals().getParcelableArrayList(
Adjustment.KEY_SNOOZE_CRITERIA);
setSnoozeCriteria(snoozeCriterionList);
+ MetricsLogger.action(getAdjustmentLogMaker()
+ .addTaggedData(MetricsEvent.ADJUSTMENT_KEY_SNOOZE_CRITERIA,
+ snoozeCriterionList.size()));
}
if (signals.containsKey(Adjustment.KEY_GROUP_KEY)) {
final String groupOverrideKey =
adjustment.getSignals().getString(Adjustment.KEY_GROUP_KEY);
setOverrideGroupKey(groupOverrideKey);
+ MetricsLogger.action(getAdjustmentLogMaker()
+ .addTaggedData(MetricsEvent.ADJUSTMENT_KEY_GROUP_KEY,
+ groupOverrideKey));
}
if (signals.containsKey(Adjustment.KEY_USER_SENTIMENT)) {
// Only allow user sentiment update from assistant if user hasn't already
@@ -637,19 +646,31 @@
&& (getChannel().getUserLockedFields() & USER_LOCKED_IMPORTANCE) == 0) {
setUserSentiment(adjustment.getSignals().getInt(
Adjustment.KEY_USER_SENTIMENT, USER_SENTIMENT_NEUTRAL));
+ MetricsLogger.action(getAdjustmentLogMaker()
+ .addTaggedData(MetricsEvent.ADJUSTMENT_KEY_USER_SENTIMENT,
+ getUserSentiment()));
}
}
if (signals.containsKey(Adjustment.KEY_SMART_ACTIONS)) {
setSmartActions(signals.getParcelableArrayList(Adjustment.KEY_SMART_ACTIONS));
+ MetricsLogger.action(getAdjustmentLogMaker()
+ .addTaggedData(MetricsEvent.ADJUSTMENT_KEY_SMART_ACTIONS,
+ getSmartActions().size()));
}
if (signals.containsKey(Adjustment.KEY_SMART_REPLIES)) {
setSmartReplies(signals.getCharSequenceArrayList(Adjustment.KEY_SMART_REPLIES));
+ MetricsLogger.action(getAdjustmentLogMaker()
+ .addTaggedData(MetricsEvent.ADJUSTMENT_KEY_SMART_REPLIES,
+ getSmartReplies().size()));
}
if (signals.containsKey(Adjustment.KEY_IMPORTANCE)) {
int importance = signals.getInt(Adjustment.KEY_IMPORTANCE);
importance = Math.max(IMPORTANCE_UNSPECIFIED, importance);
importance = Math.min(IMPORTANCE_HIGH, importance);
setAssistantImportance(importance);
+ MetricsLogger.action(getAdjustmentLogMaker()
+ .addTaggedData(MetricsEvent.ADJUSTMENT_KEY_IMPORTANCE,
+ importance));
}
}
}
@@ -1203,6 +1224,16 @@
return getLogMaker(System.currentTimeMillis());
}
+ public LogMaker getItemLogMaker() {
+ return getLogMaker().setCategory(MetricsEvent.NOTIFICATION_ITEM);
+ }
+
+ public LogMaker getAdjustmentLogMaker() {
+ return getLogMaker()
+ .setCategory(MetricsEvent.NOTIFICATION_ITEM)
+ .setType(MetricsEvent.NOTIFICATION_ASSISTANT_ADJUSTMENT);
+ }
+
@VisibleForTesting
static final class Light {
public final int color;
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index 760f155..44b80c1 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -1212,27 +1212,89 @@
}
private final class Metrics extends Callback {
- private static final String COUNTER_PREFIX = "dnd_mode_";
+ private static final String COUNTER_MODE_PREFIX = "dnd_mode_";
+ private static final String COUNTER_TYPE_PREFIX = "dnd_type_";
+ private static final int DND_OFF = 0;
+ private static final int DND_ON_MANUAL = 1;
+ private static final int DND_ON_AUTOMATIC = 2;
+ private static final String COUNTER_RULE = "dnd_rule_count";
private static final long MINIMUM_LOG_PERIOD_MS = 60 * 1000;
+ // Total silence, alarms only, priority only
private int mPreviousZenMode = -1;
- private long mBeginningMs = 0L;
+ private long mModeLogTimeMs = 0L;
+
+ private int mNumZenRules = -1;
+ private long mRuleCountLogTime = 0L;
+
+ // automatic (1) vs manual (0) vs dnd off (2)
+ private int mPreviousZenType = -1;
+ private long mTypeLogTimeMs = 0L;
@Override
void onZenModeChanged() {
emit();
}
+ @Override
+ void onConfigChanged() {
+ emit();
+ }
+
private void emit() {
mHandler.postMetricsTimer();
+ emitZenMode();
+ emitRules();
+ emitDndType();
+ }
+
+ private void emitZenMode() {
final long now = SystemClock.elapsedRealtime();
- final long since = (now - mBeginningMs);
+ final long since = (now - mModeLogTimeMs);
if (mPreviousZenMode != mZenMode || since > MINIMUM_LOG_PERIOD_MS) {
if (mPreviousZenMode != -1) {
- MetricsLogger.count(mContext, COUNTER_PREFIX + mPreviousZenMode, (int) since);
+ MetricsLogger.count(
+ mContext, COUNTER_MODE_PREFIX + mPreviousZenMode, (int) since);
}
mPreviousZenMode = mZenMode;
- mBeginningMs = now;
+ mModeLogTimeMs = now;
+ }
+ }
+
+ private void emitRules() {
+ final long now = SystemClock.elapsedRealtime();
+ final long since = (now - mRuleCountLogTime);
+ synchronized (mConfig) {
+ int numZenRules = mConfig.automaticRules.size();
+ if (mNumZenRules != numZenRules
+ || since > MINIMUM_LOG_PERIOD_MS) {
+ if (mNumZenRules != -1) {
+ MetricsLogger.count(mContext, COUNTER_RULE,
+ numZenRules - mNumZenRules);
+ }
+ mNumZenRules = numZenRules;
+
+ mRuleCountLogTime = since;
+ }
+ }
+ }
+
+ private void emitDndType() {
+ final long now = SystemClock.elapsedRealtime();
+ final long since = (now - mTypeLogTimeMs);
+ synchronized (mConfig) {
+ boolean dndOn = mZenMode != Global.ZEN_MODE_OFF;
+ int zenType = !dndOn ? DND_OFF
+ : (mConfig.manualRule != null) ? DND_ON_MANUAL : DND_ON_AUTOMATIC;
+ if (zenType != mPreviousZenType
+ || since > MINIMUM_LOG_PERIOD_MS) {
+ if (mPreviousZenType != -1) {
+ MetricsLogger.count(
+ mContext, COUNTER_TYPE_PREFIX + mPreviousZenType, (int) since);
+ }
+ mTypeLogTimeMs = now;
+ mPreviousZenType = zenType;
+ }
}
}
}
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityDisplayTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityDisplayTests.java
index ea90ffd..0da5742 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityDisplayTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityDisplayTests.java
@@ -20,11 +20,14 @@
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.content.pm.ActivityInfo.FLAG_ALWAYS_FOCUSABLE;
+import static android.content.pm.ActivityInfo.FLAG_SHOW_WHEN_LOCKED;
import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.doReturn;
import android.platform.test.annotations.Presubmit;
@@ -131,4 +134,57 @@
new ActivityBuilder(mService).setTask(fullscreenTask).build();
return fullscreenStack;
}
+
+ /**
+ * Verifies the correct activity is returned when querying the top running activity.
+ */
+ @Test
+ public void testTopRunningActivity() {
+ // Create stack to hold focus.
+ final ActivityDisplay display = mSupervisor.getDefaultDisplay();
+ final ActivityStack emptyStack = display.createStack(WINDOWING_MODE_FULLSCREEN,
+ ACTIVITY_TYPE_STANDARD, true /* onTop */);
+
+ final KeyguardController keyguard = mSupervisor.getKeyguardController();
+ final ActivityStack stack = mSupervisor.getDefaultDisplay().createStack(
+ WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+ final ActivityRecord activity = new ActivityBuilder(mService).setCreateTask(true)
+ .setStack(stack).build();
+
+ // Make sure the top running activity is not affected when keyguard is not locked.
+ assertTopRunningActivity(activity, display);
+
+ // Check to make sure activity not reported when it cannot show on lock and lock is on.
+ doReturn(true).when(keyguard).isKeyguardLocked();
+ assertEquals(activity, display.topRunningActivity());
+ assertNull(display.topRunningActivity(true /* considerKeyguardState */));
+
+ // Change focus to stack with activity.
+ stack.moveToFront("focusChangeToTestStack");
+ assertEquals(stack, display.getFocusedStack());
+ assertEquals(activity, display.topRunningActivity());
+ assertNull(display.topRunningActivity(true /* considerKeyguardState */));
+
+ // Add activity that should be shown on the keyguard.
+ final ActivityRecord showWhenLockedActivity = new ActivityBuilder(mService)
+ .setCreateTask(true)
+ .setStack(stack)
+ .setActivityFlags(FLAG_SHOW_WHEN_LOCKED)
+ .build();
+
+ // Ensure the show when locked activity is returned.
+ assertTopRunningActivity(showWhenLockedActivity, display);
+
+ // Change focus back to empty stack.
+ emptyStack.moveToFront("focusChangeToEmptyStack");
+ assertEquals(emptyStack, display.getFocusedStack());
+ // If there is no running activity in focused stack, the running activity in next focusable
+ // stack should be returned.
+ assertTopRunningActivity(showWhenLockedActivity, display);
+ }
+
+ private static void assertTopRunningActivity(ActivityRecord top, ActivityDisplay display) {
+ assertEquals(top, display.topRunningActivity());
+ assertEquals(top, display.topRunningActivity(true /* considerKeyguardState */));
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java
index cc7a24d..2c993d3 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java
@@ -25,7 +25,6 @@
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
import static android.content.pm.ActivityInfo.FLAG_ALWAYS_FOCUSABLE;
-import static android.content.pm.ActivityInfo.FLAG_SHOW_WHEN_LOCKED;
import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE;
@@ -307,62 +306,6 @@
}
/**
- * Verifies the correct activity is returned when querying the top running activity.
- */
- @Test
- public void testTopRunningActivity() throws Exception {
- // Create stack to hold focus
- final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay();
- final ActivityStack emptyStack = display.createStack(WINDOWING_MODE_FULLSCREEN,
- ACTIVITY_TYPE_STANDARD, true /* onTop */);
-
- final KeyguardController keyguard = mSupervisor.getKeyguardController();
- final ActivityStack stack = mService.mStackSupervisor.getDefaultDisplay().createStack(
- WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
- final ActivityRecord activity = new ActivityBuilder(mService).setCreateTask(true)
- .setStack(stack).build();
-
- // Make sure the top running activity is not affected when keyguard is not locked
- assertEquals(activity, mService.mStackSupervisor.topRunningActivityLocked());
- assertEquals(activity, mService.mStackSupervisor.topRunningActivityLocked(
- true /* considerKeyguardState */));
-
- // Check to make sure activity not reported when it cannot show on lock and lock is on.
- doReturn(true).when(keyguard).isKeyguardLocked();
- assertEquals(activity, mService.mStackSupervisor.topRunningActivityLocked());
- assertEquals(null, mService.mStackSupervisor.topRunningActivityLocked(
- true /* considerKeyguardState */));
-
- // Change focus to stack with activity.
- stack.moveToFront("focusChangeToTestStack");
- assertEquals(stack, display.getFocusedStack());
- assertEquals(activity, mService.mStackSupervisor.topRunningActivityLocked());
- assertEquals(null, mService.mStackSupervisor.topRunningActivityLocked(
- true /* considerKeyguardState */));
-
- // Add activity that should be shown on the keyguard.
- final ActivityRecord showWhenLockedActivity = new ActivityBuilder(mService)
- .setCreateTask(true)
- .setStack(stack)
- .setActivityFlags(FLAG_SHOW_WHEN_LOCKED)
- .build();
-
- // Ensure the show when locked activity is returned.
- assertEquals(showWhenLockedActivity, mService.mStackSupervisor.topRunningActivityLocked());
- assertEquals(showWhenLockedActivity, mService.mStackSupervisor.topRunningActivityLocked(
- true /* considerKeyguardState */));
-
- // Change focus back to empty stack
- emptyStack.moveToFront("focusChangeToEmptyStack");
- assertEquals(emptyStack, display.getFocusedStack());
- // Looking for running activity only in top and focused stack, so nothing should be returned
- // from empty stack.
- assertEquals(null, mService.mStackSupervisor.topRunningActivityLocked());
- assertEquals(null, mService.mStackSupervisor.topRunningActivityLocked(
- true /* considerKeyguardState */));
- }
-
- /**
* Verify that split-screen primary stack will be chosen if activity is launched that targets
* split-screen secondary, but a matching existing instance is found on top of split-screen
* primary stack.
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java
index 5fcd2aa..53f67af 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java
@@ -26,6 +26,9 @@
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+import static com.android.server.am.ActivityStack.ActivityState.DESTROYING;
+import static com.android.server.am.ActivityStack.ActivityState.FINISHING;
+import static com.android.server.am.ActivityStack.ActivityState.PAUSED;
import static com.android.server.am.ActivityStack.ActivityState.PAUSING;
import static com.android.server.am.ActivityStack.ActivityState.RESUMED;
import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
@@ -35,10 +38,14 @@
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.anyInt;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
import android.content.pm.ActivityInfo;
import android.os.UserHandle;
@@ -655,6 +662,39 @@
}
@Test
+ public void testFinishCurrentActivity() {
+ // Create 2 activities on a new display.
+ final ActivityDisplay display = addNewActivityDisplayAt(ActivityDisplay.POSITION_TOP);
+ final ActivityStack stack1 = createStackForShouldBeVisibleTest(display,
+ WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+ final ActivityStack stack2 = createStackForShouldBeVisibleTest(display,
+ WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+
+ // There is still an activity1 in stack1 so the activity2 should be added to finishing list
+ // that will be destroyed until idle.
+ final ActivityRecord activity2 = finishCurrentActivity(stack2);
+ assertEquals(FINISHING, activity2.getState());
+ assertTrue(mSupervisor.mFinishingActivities.contains(activity2));
+
+ // The display becomes empty. Since there is no next activity to be idle, the activity
+ // should be destroyed immediately with updating configuration to restore original state.
+ final ActivityRecord activity1 = finishCurrentActivity(stack1);
+ assertEquals(DESTROYING, activity1.getState());
+ verify(mSupervisor).ensureVisibilityAndConfig(eq(null) /* starting */,
+ eq(display.mDisplayId), anyBoolean(), anyBoolean());
+ }
+
+ private ActivityRecord finishCurrentActivity(ActivityStack stack) {
+ final ActivityRecord activity = stack.topRunningActivityLocked();
+ assertNotNull(activity);
+ activity.setState(PAUSED, "finishCurrentActivity");
+ activity.makeFinishingLocked();
+ stack.finishCurrentActivityLocked(activity, ActivityStack.FINISH_AFTER_VISIBLE,
+ false /* oomAdj */, "finishCurrentActivity");
+ return activity;
+ }
+
+ @Test
public void testShouldSleepActivities() throws Exception {
// When focused activity and keyguard is going away, we should not sleep regardless
// of the display state