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