From 89bec9c941dd1fe968e2a31d02baf306fa9927b5 Mon Sep 17 00:00:00 2001 From: Daniel Nishi Date: Thu, 30 Mar 2017 18:02:16 -0700 Subject: [PATCH] Fix storage settings crash. It may crash if opened during the uninstall of an app. By catching the exception which may occur, we can just skip the uninstalled app and avoid crashing. Change-Id: If556db7b5a299ba53a29baefbbe9709ba6d12190 Fixes: 36793223 Fixes: 36793372 Test: Settings unit test --- .../deviceinfo/StorageDashboardFragment.java | 2 +- .../deviceinfo/storage/StorageAsyncLoader.java | 10 ++++++++-- .../deviceinfo/storage/StorageAsyncLoaderTest.java | 14 ++++++++++++++ 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/com/android/settings/deviceinfo/StorageDashboardFragment.java b/src/com/android/settings/deviceinfo/StorageDashboardFragment.java index 602e65f802f..bc64ffa223c 100644 --- a/src/com/android/settings/deviceinfo/StorageDashboardFragment.java +++ b/src/com/android/settings/deviceinfo/StorageDashboardFragment.java @@ -117,7 +117,7 @@ public class StorageDashboardFragment extends DashboardFragment @Override public void onResume() { super.onResume(); - getLoaderManager().initLoader(STORAGE_JOB_ID, Bundle.EMPTY, this); + getLoaderManager().restartLoader(STORAGE_JOB_ID, Bundle.EMPTY, this); getLoaderManager().initLoader(ICON_JOB_ID, Bundle.EMPTY, new IconLoaderCallbacks()); } diff --git a/src/com/android/settings/deviceinfo/storage/StorageAsyncLoader.java b/src/com/android/settings/deviceinfo/storage/StorageAsyncLoader.java index e83c5d27ea9..86472f92f3f 100644 --- a/src/com/android/settings/deviceinfo/storage/StorageAsyncLoader.java +++ b/src/com/android/settings/deviceinfo/storage/StorageAsyncLoader.java @@ -79,8 +79,14 @@ public class StorageAsyncLoader UserHandle myUser = UserHandle.of(userId); for (int i = 0, size = applicationInfos.size(); i < size; i++) { ApplicationInfo app = applicationInfos.get(i); - StorageStatsSource.AppStorageStats stats = - mStatsManager.getStatsForPackage(mUuid, app.packageName, myUser); + + StorageStatsSource.AppStorageStats stats; + try { + stats = mStatsManager.getStatsForPackage(mUuid, app.packageName, myUser); + } catch (IllegalStateException e) { + // This may happen if the package was removed during our calculation. + continue; + } long attributedAppSizeInBytes = stats.getDataBytes(); // This matches how the package manager calculates sizes -- by zeroing out code sizes of diff --git a/tests/unit/src/com/android/settings/deviceinfo/storage/StorageAsyncLoaderTest.java b/tests/unit/src/com/android/settings/deviceinfo/storage/StorageAsyncLoaderTest.java index e82482ebe46..f7131b366bd 100644 --- a/tests/unit/src/com/android/settings/deviceinfo/storage/StorageAsyncLoaderTest.java +++ b/tests/unit/src/com/android/settings/deviceinfo/storage/StorageAsyncLoaderTest.java @@ -180,6 +180,20 @@ public class StorageAsyncLoaderTest { assertThat(result.get(PRIMARY_USER_ID).otherAppsSize).isEqualTo(0); } + @Test + public void testRemovedPackageDoesNotCrash() throws Exception { + ApplicationInfo info = new ApplicationInfo(); + info.packageName = PACKAGE_NAME_1; + info.category = ApplicationInfo.CATEGORY_UNDEFINED; + mInfo.add(info); + when(mSource.getStatsForPackage(anyString(), anyString(), any(UserHandle.class))) + .thenThrow(new IllegalStateException()); + + SparseArray result = mLoader.loadInBackground(); + + // Should not crash. + } + private ApplicationInfo addPackage( String packageName, long cacheSize, long codeSize, long dataSize, int category) { StorageStatsSource.AppStorageStats storageStats =