[M87 merge] ambient: Close UI when unlock screen

When the secondary user logs in, the OnLockStateChanged() was returned
due to the Ambient mode is not allowed, therefore the ambient UI is not
closed. This patch moves the close ui logic before the ambient enabled
check.

[email protected]

(cherry picked from commit a2420700b5fe76027115950d18c0619d8951150c)

Bug: 1136302
Test: Added new unittest
Change-Id: I2d9c93087b8e8139936271db2a797f6322bb55ba
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2462246
Reviewed-by: Xiaohui Chen <[email protected]>
Commit-Queue: Tao Wu <[email protected]>
Cr-Original-Commit-Position: refs/heads/master@{#815463}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2462577
Reviewed-by: Tao Wu <[email protected]>
Cr-Commit-Position: refs/branch-heads/4280@{#222}
Cr-Branched-From: ea420fb963f9658c9969b6513c56b8f47efa1a2a-refs/heads/master@{#812852}
diff --git a/ash/ambient/ambient_controller.cc b/ash/ambient/ambient_controller.cc
index 9070fd4..f0ea88cf 100644
--- a/ash/ambient/ambient_controller.cc
+++ b/ash/ambient/ambient_controller.cc
@@ -285,41 +285,42 @@
 }
 
 void AmbientController::OnLockStateChanged(bool locked) {
+  if (!locked) {
+    // Ambient screen will be destroyed along with the lock screen when user
+    // logs in.
+    CloseUi();
+    return;
+  }
+
   if (!IsAmbientModeEnabled()) {
     VLOG(1) << "Ambient mode is not allowed.";
     return;
   }
 
-  if (locked) {
-    // We have 3 options to manage the token for lock screen. Here use option 1.
-    // 1. Request only one time after entering lock screen. We will use it once
-    //    to request all the image links and no more requests.
-    // 2. Request one time before entering lock screen. This will introduce
-    //    extra latency.
-    // 3. Request and refresh the token in the background (even the ambient mode
-    //    is not started) with extra buffer time to use. When entering
-    //    lock screen, it will be most likely to have the token already and
-    //    enough time to use. More specifically,
-    //    3a. We will leave enough buffer time (e.g. 10 mins before expire) to
-    //        start to refresh the token.
-    //    3b. When lock screen is triggered, most likely we will have >10 mins
-    //        of token which can be used on lock screen.
-    //    3c. There is a corner case that we may not have the token fetched when
-    //        locking screen, we probably can use PrepareForLock(callback) when
-    //        locking screen. We can add the refresh token into it. If the token
-    //        has already been fetched, then there is not additional time to
-    //        wait.
-    RequestAccessToken(base::DoNothing(), /*may_refresh_token_on_lock=*/true);
+  // We have 3 options to manage the token for lock screen. Here use option 1.
+  // 1. Request only one time after entering lock screen. We will use it once
+  //    to request all the image links and no more requests.
+  // 2. Request one time before entering lock screen. This will introduce
+  //    extra latency.
+  // 3. Request and refresh the token in the background (even the ambient mode
+  //    is not started) with extra buffer time to use. When entering
+  //    lock screen, it will be most likely to have the token already and
+  //    enough time to use. More specifically,
+  //    3a. We will leave enough buffer time (e.g. 10 mins before expire) to
+  //        start to refresh the token.
+  //    3b. When lock screen is triggered, most likely we will have >10 mins
+  //        of token which can be used on lock screen.
+  //    3c. There is a corner case that we may not have the token fetched when
+  //        locking screen, we probably can use PrepareForLock(callback) when
+  //        locking screen. We can add the refresh token into it. If the token
+  //        has already been fetched, then there is not additional time to
+  //        wait.
+  RequestAccessToken(base::DoNothing(), /*may_refresh_token_on_lock=*/true);
 
-    if (!IsShown()) {
-      // When lock screen starts, we don't immediately show the UI. The Ui is
-      // hidden and will show after a delay.
-      ShowHiddenUi();
-    }
-  } else {
-    // Ambient screen will be destroyed along with the lock screen when user
-    // logs in.
-    CloseUi();
+  if (!IsShown()) {
+    // When lock screen starts, we don't immediately show the UI. The Ui is
+    // hidden and will show after a delay.
+    ShowHiddenUi();
   }
 }
 
diff --git a/ash/ambient/ambient_controller_unittest.cc b/ash/ambient/ambient_controller_unittest.cc
index 56e9c72..df59f3ea 100644
--- a/ash/ambient/ambient_controller_unittest.cc
+++ b/ash/ambient/ambient_controller_unittest.cc
@@ -23,6 +23,9 @@
 
 namespace ash {
 
+constexpr char kUser1[] = "[email protected]";
+constexpr char kUser2[] = "[email protected]";
+
 class AmbientControllerTest : public AmbientAshTestBase {
  public:
   AmbientControllerTest() : AmbientAshTestBase() {}
@@ -117,6 +120,70 @@
   EXPECT_FALSE(container_view());
 }
 
+TEST_F(AmbientControllerTest, CloseAmbientScreenUponUnlockSecondaryUser) {
+  // Simulate the login screen.
+  ClearLogin();
+  SimulateUserLogin(kUser1);
+  SetAmbientModeEnabled(true);
+
+  LockScreen();
+  FastForwardToInactivity();
+  FastForwardTiny();
+
+  EXPECT_TRUE(container_view());
+  EXPECT_EQ(AmbientUiModel::Get()->ui_visibility(),
+            AmbientUiVisibility::kShown);
+  EXPECT_TRUE(ambient_controller()->IsShown());
+
+  SimulateUserLogin(kUser2);
+  EXPECT_EQ(AmbientUiModel::Get()->ui_visibility(),
+            AmbientUiVisibility::kClosed);
+  EXPECT_FALSE(ambient_controller()->IsShown());
+  // The view should be destroyed along the widget.
+  EXPECT_FALSE(container_view());
+
+  FastForwardToInactivity();
+  FastForwardTiny();
+  EXPECT_EQ(AmbientUiModel::Get()->ui_visibility(),
+            AmbientUiVisibility::kClosed);
+  EXPECT_FALSE(ambient_controller()->IsShown());
+  // The view should be destroyed along the widget.
+  EXPECT_FALSE(container_view());
+}
+
+TEST_F(AmbientControllerTest, NotShowAmbientWhenLockSecondaryUser) {
+  // Simulate the login screen.
+  ClearLogin();
+  SimulateUserLogin(kUser1);
+  SetAmbientModeEnabled(true);
+
+  LockScreen();
+  FastForwardToInactivity();
+  FastForwardTiny();
+
+  EXPECT_TRUE(container_view());
+  EXPECT_EQ(AmbientUiModel::Get()->ui_visibility(),
+            AmbientUiVisibility::kShown);
+  EXPECT_TRUE(ambient_controller()->IsShown());
+
+  SimulateUserLogin(kUser2);
+  EXPECT_EQ(AmbientUiModel::Get()->ui_visibility(),
+            AmbientUiVisibility::kClosed);
+  EXPECT_FALSE(ambient_controller()->IsShown());
+  // The view should be destroyed along the widget.
+  EXPECT_FALSE(container_view());
+
+  LockScreen();
+  FastForwardToInactivity();
+  FastForwardTiny();
+
+  EXPECT_EQ(AmbientUiModel::Get()->ui_visibility(),
+            AmbientUiVisibility::kClosed);
+  EXPECT_FALSE(ambient_controller()->IsShown());
+  // The view should be destroyed along the widget.
+  EXPECT_FALSE(container_view());
+}
+
 TEST_F(AmbientControllerTest, ShouldRequestAccessTokenWhenLockingScreen) {
   EXPECT_FALSE(IsAccessTokenRequestPending());