WifiConfigManager: Prevent store writes before a read is triggered

Overwriting the store file before reading from it should not be allowed.
Usually the BOOT_COMPLETED notification is received pretty early on and
that would have triggered the store read before anything else happens.
But, looks like this is not the case in fugu/elfin. So, add checks in
place to reject such write requests.

Also, added a missing @Test annotation on one of the existing unit tests.

(cherry picked from commit 542e3414436e0441c1f3545a8fb905839b2d841d)

Bug: 71504864
Test: Unit tests
Test: Manually verified that the CL fixed the issue reported.
Merged-In: Ib0cf39fd0790c90287cc7219aba46f4e855815e0
Change-Id: Ib0cf39fd0790c90287cc7219aba46f4e855815e0
diff --git a/service/java/com/android/server/wifi/WifiConfigManager.java b/service/java/com/android/server/wifi/WifiConfigManager.java
index f256396..e7021a7 100644
--- a/service/java/com/android/server/wifi/WifiConfigManager.java
+++ b/service/java/com/android/server/wifi/WifiConfigManager.java
@@ -2776,6 +2776,10 @@
      * @return Whether the write was successful or not, this is applicable only for force writes.
      */
     public boolean saveToStore(boolean forceWrite) {
+        if (mPendingStoreRead) {
+            Log.e(TAG, "Cannot save to store before store is read!");
+            return false;
+        }
         ArrayList<WifiConfiguration> sharedConfigurations = new ArrayList<>();
         ArrayList<WifiConfiguration> userConfigurations = new ArrayList<>();
         // List of network IDs for legacy Passpoint configuration to be removed.
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java b/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java
index 0fa6600..b65e73c 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java
@@ -207,13 +207,29 @@
      * yet loaded data from store.
      */
     @Test
-    public void testAddNetworkBeforeLoadFromStore() {
+    public void testAddNetworkIsRejectedBeforeLoadFromStore() {
         WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
         assertFalse(
                 mWifiConfigManager.addOrUpdateNetwork(openNetwork, TEST_CREATOR_UID).isSuccess());
     }
 
     /**
+     * Verifies the {@link WifiConfigManager#saveToStore(boolean)} is rejected until the store has
+     * been read first using {@link WifiConfigManager#loadFromStore()}.
+     */
+    @Test
+    public void testSaveToStoreIsRejectedBeforeLoadFromStore() throws Exception {
+        assertFalse(mWifiConfigManager.saveToStore(true));
+        mContextConfigStoreMockOrder.verify(mWifiConfigStore, never()).write(anyBoolean());
+
+        assertTrue(mWifiConfigManager.loadFromStore());
+        mContextConfigStoreMockOrder.verify(mWifiConfigStore).read();
+
+        assertTrue(mWifiConfigManager.saveToStore(true));
+        mContextConfigStoreMockOrder.verify(mWifiConfigStore).write(anyBoolean());
+    }
+
+    /**
      * Verifies the addition of a single network using
      * {@link WifiConfigManager#addOrUpdateNetwork(WifiConfiguration, int)}
      */
@@ -2377,6 +2393,7 @@
      * and {@link WifiConfigManager#handleUserUnlock(int)} and ensures that the new store is not
      * read until the user is unlocked.
      */
+    @Test
     public void testHandleUserSwitchWhenLocked() throws Exception {
         int user1 = TEST_DEFAULT_USER;
         int user2 = TEST_DEFAULT_USER + 1;
@@ -2415,6 +2432,9 @@
         int user2 = TEST_DEFAULT_USER + 1;
         setupUserProfiles(user2);
 
+        // Set up the internal data first.
+        assertTrue(mWifiConfigManager.loadFromStore());
+
         // Try stopping background user2 first, this should not do anything.
         when(mUserManager.isUserUnlockingOrUnlocked(user2)).thenReturn(false);
         mWifiConfigManager.handleUserStop(user2);