From 6422e8fb4429936477f2cac82c472e5e4684f26d Mon Sep 17 00:00:00 2001 From: Daniel Nishi Date: Tue, 21 Feb 2017 16:04:20 -0800 Subject: [PATCH] Don't crash when primary volume is null in AppCollector. getPrimaryStorageCurrentVolume() may return a null value. I did not plan for this case in the AppCollector. This case occurs when the primary storage is not mounted when the function is called. By adding in a null check after getPrimaryStorageCurrentVolume() and adding in preconditions to verify the non-nullness of the volume as it propagates through the AppCollector, we ensure that there should be no more NPE crashes for this reason. Bug: 35636901 Test: FrameworkServicesTests Change-Id: I4009e55502f71b8f14dd917ddd00caef3551aafd (cherry picked from commit d54f3a487bba1dc5008e2e1482ef451a59500752) --- .../core/java/com/android/server/storage/AppCollector.java | 8 ++++++-- .../com/android/server/storage/DiskStatsLoggingService.java | 11 +++++++++-- .../src/com/android/server/storage/AppCollectorTest.java | 6 +++++- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/services/core/java/com/android/server/storage/AppCollector.java b/services/core/java/com/android/server/storage/AppCollector.java index cf05e9f73d19..ee9c5bf2775d 100644 --- a/services/core/java/com/android/server/storage/AppCollector.java +++ b/services/core/java/com/android/server/storage/AppCollector.java @@ -16,6 +16,7 @@ package com.android.server.storage; +import android.annotation.NonNull; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.IPackageStatsObserver; @@ -32,6 +33,7 @@ import android.os.UserManager; import android.os.storage.VolumeInfo; import android.util.Log; import com.android.internal.os.BackgroundThread; +import com.android.internal.util.Preconditions; import java.util.ArrayList; import java.util.List; @@ -56,7 +58,9 @@ public class AppCollector { * @param context Android context used to get * @param volume Volume to check for apps. */ - public AppCollector(Context context, VolumeInfo volume) { + public AppCollector(Context context, @NonNull VolumeInfo volume) { + Preconditions.checkNotNull(volume); + mBackgroundHandler = new BackgroundHandler(BackgroundThread.get().getLooper(), volume, context.getPackageManager(), @@ -117,7 +121,7 @@ public class AppCollector { private final PackageManager mPm; private final UserManager mUm; - BackgroundHandler(Looper looper, VolumeInfo volume, PackageManager pm, UserManager um) { + BackgroundHandler(Looper looper, @NonNull VolumeInfo volume, PackageManager pm, UserManager um) { super(looper); mVolume = volume; mPm = pm; diff --git a/services/core/java/com/android/server/storage/DiskStatsLoggingService.java b/services/core/java/com/android/server/storage/DiskStatsLoggingService.java index 7c43162ec692..4035adedafe1 100644 --- a/services/core/java/com/android/server/storage/DiskStatsLoggingService.java +++ b/services/core/java/com/android/server/storage/DiskStatsLoggingService.java @@ -29,6 +29,7 @@ import android.os.BatteryManager; import android.os.Environment; import android.os.Environment.UserEnvironment; import android.os.UserHandle; +import android.os.storage.VolumeInfo; import android.provider.Settings; import android.util.Log; @@ -61,10 +62,16 @@ public class DiskStatsLoggingService extends JobService { return false; } + + VolumeInfo volume = getPackageManager().getPrimaryStorageCurrentVolume(); + // volume is null if the primary storage is not yet mounted. + if (volume == null) { + return false; + } + AppCollector collector = new AppCollector(this, volume); + final int userId = UserHandle.myUserId(); UserEnvironment environment = new UserEnvironment(userId); - AppCollector collector = new AppCollector(this, - getPackageManager().getPrimaryStorageCurrentVolume()); LogRunnable task = new LogRunnable(); task.setRootDirectory(environment.getExternalStorageDirectory()); task.setDownloadsDirectory( diff --git a/services/tests/servicestests/src/com/android/server/storage/AppCollectorTest.java b/services/tests/servicestests/src/com/android/server/storage/AppCollectorTest.java index da22e77956a1..29185e92d5ed 100644 --- a/services/tests/servicestests/src/com/android/server/storage/AppCollectorTest.java +++ b/services/tests/servicestests/src/com/android/server/storage/AppCollectorTest.java @@ -187,10 +187,14 @@ public class AppCollectorTest extends AndroidTestCase { }).start(); latch.await(); - // This should assertThat(myStats).containsAllOf(stats, otherStats); } + @Test(expected=NullPointerException.class) + public void testNullVolumeShouldCauseNPE() throws Exception { + AppCollector collector = new AppCollector(mContext, null); + } + private void addApplication(String packageName, String uuid) { ApplicationInfo info = new ApplicationInfo(); info.packageName = packageName; -- 2.11.0