WifiConfigManager: Handle user switch before store load

On most devices, user 0 (system user) is fully started before allowing
a user switch. For the typical use case, the order of events expected:
BOOT_COMPLETED, USER_UNLOCK(ID=0), USER_SWITCH(ID=user_x),
USER_UNLOCK(ID=user_x).

On Android auto, another user (ID=10) is first started. So, the order of
events there: USER_SWITCH(ID=10), BOOT_COMPLETED, USER_UNLOCK(ID=10).

Make changes in WifiConfigManager to handle this sequence.

Bug: 112432082
Test: Unit tests
Test: Verified that wifi connection works on Android auto after the
change.
Change-Id: I5770790582dd9485a7b74bb5d3836820b512f3fa
diff --git a/service/java/com/android/server/wifi/WifiConfigManager.java b/service/java/com/android/server/wifi/WifiConfigManager.java
index 558a1f3..40f4874 100644
--- a/service/java/com/android/server/wifi/WifiConfigManager.java
+++ b/service/java/com/android/server/wifi/WifiConfigManager.java
@@ -2555,7 +2555,11 @@
             return new HashSet<>();
         }
         if (mPendingStoreRead) {
-            Log.wtf(TAG, "Unexpected user switch before store is read!");
+            Log.w(TAG, "User switch before store is read!");
+            mConfiguredNetworks.setNewUser(userId);
+            mCurrentUserId = userId;
+            // Cannot read data from new user's CE store file before they log-in.
+            mPendingUnlockStoreRead = true;
             return new HashSet<>();
         }
         if (mUserManager.isUserUnlockingOrUnlocked(mCurrentUserId)) {
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java
index a4bc61a..0971dbc 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java
@@ -2630,6 +2630,36 @@
     }
 
     /**
+     * Verifies that the store read after bootup received after
+     * a user switch via {@link WifiConfigManager#handleUserSwitch(int)}
+     * results in a user store read.
+     */
+    @Test
+    public void testHandleBootupAfterUserSwitch() throws Exception {
+        int user1 = TEST_DEFAULT_USER;
+        int user2 = TEST_DEFAULT_USER + 1;
+        setupUserProfiles(user2);
+
+        // Switch from user1 to user2 and ensure that we don't read or write any data
+        // (need to wait for loadFromStore invocation).
+        mWifiConfigManager.handleUserSwitch(user2);
+        mContextConfigStoreMockOrder.verify(mWifiConfigStore, never()).read();
+        mContextConfigStoreMockOrder.verify(mWifiConfigStore, never()).write(anyBoolean());
+        mContextConfigStoreMockOrder.verify(mWifiConfigStore, never())
+                .switchUserStoreAndRead(any(WifiConfigStore.StoreFile.class));
+
+        // Now load from the store.
+        assertTrue(mWifiConfigManager.loadFromStore());
+        mContextConfigStoreMockOrder.verify(mWifiConfigStore).read();
+
+        // Unlock the user2 and ensure that we read from the user store.
+        setupStoreDataForUserRead(new ArrayList<>(), new HashSet<>());
+        mWifiConfigManager.handleUserUnlock(user2);
+        mContextConfigStoreMockOrder.verify(mWifiConfigStore)
+                .switchUserStoreAndRead(any(WifiConfigStore.StoreFile.class));
+    }
+
+    /**
      * Verifies the foreground user unlock via {@link WifiConfigManager#handleUserUnlock(int)} does
      * not always result in a store read unless the user had switched or just booted up.
      */