diff options
author | Roshan Pius <rpius@google.com> | 2019-04-12 11:47:26 -0700 |
---|---|---|
committer | Roshan Pius <rpius@google.com> | 2019-04-18 09:35:09 -0700 |
commit | 398087d8757bed09b520e54f62780fc389f316a3 (patch) | |
tree | 519f2c3c83367194681c38707cad6df64bf95920 | |
parent | f0b4ccd0d7aa67a71a16b02c91d6377c306c271c (diff) |
WifiConfigManager: Handle file creation errors gracefully
If the user's CE directory is not accessible for some reason, all of the
user store file creation/read will fail. Handle these errors more
gracefully by checking for nulls in that path.
Note: If there are errors accessing the CE directory, any existing data
within the user store files will be lost. This CL does not attempt to
fix that.
Bug: 130366402
Test: Existing ACTS tests for config store.
Change-Id: I4c51b224e35e0d1b352359cd3be1dbbe2e66936f
3 files changed, 39 insertions, 11 deletions
diff --git a/service/java/com/android/server/wifi/WifiConfigManager.java b/service/java/com/android/server/wifi/WifiConfigManager.java index 9332c5979..d649e6b10 100644 --- a/service/java/com/android/server/wifi/WifiConfigManager.java +++ b/service/java/com/android/server/wifi/WifiConfigManager.java @@ -3094,7 +3094,13 @@ public class WifiConfigManager { // configurations for the current user will also being loaded. if (mDeferredUserUnlockRead) { Log.i(TAG, "Handling user unlock before loading from store."); - mWifiConfigStore.setUserStores(WifiConfigStore.createUserFiles(mCurrentUserId)); + List<WifiConfigStore.StoreFile> userStoreFiles = + WifiConfigStore.createUserFiles(mCurrentUserId); + if (userStoreFiles == null) { + Log.wtf(TAG, "Failed to create user store files"); + return false; + } + mWifiConfigStore.setUserStores(userStoreFiles); mDeferredUserUnlockRead = false; } try { @@ -3125,9 +3131,15 @@ public class WifiConfigManager { * @param userId The identifier of the foreground user. * @return true on success, false otherwise. */ - public boolean loadFromUserStoreAfterUnlockOrSwitch(int userId) { + private boolean loadFromUserStoreAfterUnlockOrSwitch(int userId) { try { - mWifiConfigStore.switchUserStoresAndRead(WifiConfigStore.createUserFiles(userId)); + List<WifiConfigStore.StoreFile> userStoreFiles = + WifiConfigStore.createUserFiles(userId); + if (userStoreFiles == null) { + Log.e(TAG, "Failed to create user store files"); + return false; + } + mWifiConfigStore.switchUserStoresAndRead(userStoreFiles); } catch (IOException e) { Log.wtf(TAG, "Reading from new store failed. All saved private networks are lost!", e); return false; diff --git a/service/java/com/android/server/wifi/WifiConfigStore.java b/service/java/com/android/server/wifi/WifiConfigStore.java index ab7315f44..c7e75a5c4 100644 --- a/service/java/com/android/server/wifi/WifiConfigStore.java +++ b/service/java/com/android/server/wifi/WifiConfigStore.java @@ -55,6 +55,7 @@ import java.lang.annotation.RetentionPolicy; import java.nio.charset.StandardCharsets; import java.security.DigestException; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.HashSet; import java.util.List; @@ -267,7 +268,7 @@ public class WifiConfigStore { * @param fileId Identifier for the file. See {@link StoreFileId}. * @return new instance of the store file or null if the directory cannot be created. */ - private static StoreFile createFile(File storeBaseDir, @StoreFileId int fileId) { + private static @Nullable StoreFile createFile(File storeBaseDir, @StoreFileId int fileId) { File storeDir = new File(storeBaseDir, STORE_DIRECTORY_NAME); if (!storeDir.exists()) { if (!storeDir.mkdir()) { @@ -283,7 +284,7 @@ public class WifiConfigStore { * * @return new instance of the store file or null if the directory cannot be created. */ - public static StoreFile createSharedFile() { + public static @Nullable StoreFile createSharedFile() { return createFile(Environment.getDataMiscDirectory(), STORE_FILE_SHARED_GENERAL); } @@ -292,14 +293,19 @@ public class WifiConfigStore { * The user store file is inside the user's encrypted data directory. * * @param userId userId corresponding to the currently logged-in user. - * @return List of new instances of the store files created. + * @return List of new instances of the store files created or null if the directory cannot be + * created. */ - public static List<StoreFile> createUserFiles(int userId) { + public static @Nullable List<StoreFile> createUserFiles(int userId) { List<StoreFile> storeFiles = new ArrayList<>(); - storeFiles.add(createFile(Environment.getDataMiscCeDirectory(userId), - STORE_FILE_USER_GENERAL)); - storeFiles.add(createFile(Environment.getDataMiscCeDirectory(userId), - STORE_FILE_USER_NETWORK_SUGGESTIONS)); + for (int fileId : Arrays.asList( + STORE_FILE_USER_GENERAL, STORE_FILE_USER_NETWORK_SUGGESTIONS)) { + StoreFile storeFile = createFile(Environment.getDataMiscCeDirectory(userId), fileId); + if (storeFile == null) { + return null; + } + storeFiles.add(storeFile); + } return storeFiles; } @@ -500,6 +506,7 @@ public class WifiConfigStore { */ public void switchUserStoresAndRead(@NonNull List<StoreFile> userStores) throws XmlPullParserException, IOException { + Preconditions.checkNotNull(userStores); // Reset user store data. if (mUserStores != null) { for (StoreFile userStoreFile : mUserStores) { diff --git a/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java b/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java index d21808981..743ed6988 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java @@ -49,6 +49,7 @@ import android.util.Pair; import androidx.test.filters.SmallTest; +import com.android.dx.mockito.inline.extended.ExtendedMockito; import com.android.internal.R; import com.android.server.wifi.util.WifiPermissionsUtil; import com.android.server.wifi.util.WifiPermissionsWrapper; @@ -60,6 +61,7 @@ import org.mockito.ArgumentCaptor; import org.mockito.InOrder; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import org.mockito.MockitoSession; import java.io.FileDescriptor; import java.io.PrintWriter; @@ -137,6 +139,7 @@ public class WifiConfigManagerTest { private TestLooper mLooper = new TestLooper(); private ContentObserver mContentObserverPnoChannelCulling; private ContentObserver mContentObserverPnoRecencySorting; + private MockitoSession mSession; /** * Setup the mocks and an instance of WifiConfigManager before each test. @@ -219,6 +222,11 @@ public class WifiConfigManagerTest { Settings.Global.WIFI_PNO_RECENCY_SORTING_ENABLED)), eq(false), observerCaptor.capture()); mContentObserverPnoRecencySorting = observerCaptor.getValue(); + // static mocking + mSession = ExtendedMockito.mockitoSession() + .mockStatic(WifiConfigStore.class, withSettings().lenient()) + .startMocking(); + when(WifiConfigStore.createUserFiles(anyInt())).thenReturn(mock(List.class)); } /** @@ -227,6 +235,7 @@ public class WifiConfigManagerTest { @After public void cleanup() { validateMockitoUsage(); + mSession.finishMocking(); } /** |