Merge "Let fragment and indexProvider share prefControllers"
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index b58d1ee..a3365f7 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -2215,11 +2215,11 @@
                 <category android:name="android.intent.category.DEFAULT" />
                 <category android:name="com.android.settings.SHORTCUT" />
             </intent-filter>
-            <intent-filter android:priority="4">
+            <intent-filter android:priority="8">
                 <action android:name="com.android.settings.action.SETTINGS" />
             </intent-filter>
             <meta-data android:name="com.android.settings.category"
-                android:value="com.android.settings.category.device" />
+                android:value="com.android.settings.category.ia.homepage" />
             <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
                 android:value="com.android.settings.fuelgauge.PowerUsageSummary" />
         </activity>
@@ -3016,17 +3016,6 @@
                        android:value="@string/app_and_notification_dashboard_summary"/>
         </activity>
 
-        <activity-alias android:name="BatteryDashboardAlias"
-                        android:targetActivity="Settings$PowerUsageSummaryActivity">
-            <intent-filter android:priority="8">
-                <action android:name="com.android.settings.action.SETTINGS"/>
-            </intent-filter>
-            <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
-                       android:value="com.android.settings.fuelgauge.PowerUsageSummary"/>
-            <meta-data android:name="com.android.settings.category"
-                       android:value="com.android.settings.category.ia.homepage"/>
-        </activity-alias>
-
         <activity android:name=".Settings$StorageDashboardActivity"
                   android:label="@string/storage_settings"
                   android:icon="@drawable/ic_dashboard_storage">
diff --git a/src/com/android/settings/applications/AppStorageSettings.java b/src/com/android/settings/applications/AppStorageSettings.java
index e97a9ac..b4d7526 100644
--- a/src/com/android/settings/applications/AppStorageSettings.java
+++ b/src/com/android/settings/applications/AppStorageSettings.java
@@ -19,9 +19,11 @@
 import android.app.ActivityManager;
 import android.app.AlertDialog;
 import android.app.AppGlobals;
+import android.app.LoaderManager;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
+import android.content.Loader;
 import android.content.UriPermission;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.IPackageDataObserver;
@@ -52,8 +54,9 @@
 import com.android.settingslib.applications.ApplicationsState;
 import com.android.settingslib.applications.ApplicationsState.AppEntry;
 import com.android.settingslib.applications.ApplicationsState.Callbacks;
+import com.android.settingslib.applications.StorageStatsSource;
+import com.android.settingslib.applications.StorageStatsSource.AppStorageStats;
 
-import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
@@ -64,7 +67,8 @@
 import static android.content.pm.ApplicationInfo.FLAG_SYSTEM;
 
 public class AppStorageSettings extends AppInfoWithHeader
-        implements OnClickListener, Callbacks, DialogInterface.OnClickListener {
+        implements OnClickListener, Callbacks, DialogInterface.OnClickListener,
+        LoaderManager.LoaderCallbacks<AppStorageStats> {
     private static final String TAG = AppStorageSettings.class.getSimpleName();
 
     //internal constants used in Handler
@@ -123,6 +127,7 @@
     private boolean mCanClearData = true;
     private boolean mHaveSizes = false;
 
+    private AppStorageStats mLastResult;
     private long mLastCodeSize = -1;
     private long mLastDataSize = -1;
     private long mLastExternalCodeSize = -1;
@@ -139,6 +144,7 @@
 
     private VolumeInfo[] mCandidates;
     private AlertDialog.Builder mDialogBuilder;
+    private ApplicationInfo mInfo;
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
@@ -152,7 +158,7 @@
     @Override
     public void onResume() {
         super.onResume();
-        mState.requestSize(mPackageName, mUserId);
+        updateSize();
     }
 
     private void setupViews() {
@@ -266,79 +272,13 @@
         return Formatter.formatFileSize(getActivity(), size);
     }
 
-    private void refreshSizeInfo() {
-        if (mAppEntry.size == ApplicationsState.SIZE_INVALID
-                || mAppEntry.size == ApplicationsState.SIZE_UNKNOWN) {
-            mLastCodeSize = mLastDataSize = mLastCacheSize = mLastTotalSize = -1;
-            if (!mHaveSizes) {
-                mAppSize.setSummary(mComputingStr);
-                mDataSize.setSummary(mComputingStr);
-                mCacheSize.setSummary(mComputingStr);
-                mTotalSize.setSummary(mComputingStr);
-            }
-            mClearDataButton.setEnabled(false);
-            mClearCacheButton.setEnabled(false);
-        } else {
-            mHaveSizes = true;
-            long codeSize = mAppEntry.codeSize;
-            long dataSize = mAppEntry.dataSize;
-            if (Environment.isExternalStorageEmulated()) {
-                codeSize += mAppEntry.externalCodeSize;
-                dataSize +=  mAppEntry.externalDataSize;
-            } else {
-                if (mLastExternalCodeSize != mAppEntry.externalCodeSize) {
-                    mLastExternalCodeSize = mAppEntry.externalCodeSize;
-                    mExternalCodeSize.setSummary(getSizeStr(mAppEntry.externalCodeSize));
-                }
-                if (mLastExternalDataSize !=  mAppEntry.externalDataSize) {
-                    mLastExternalDataSize =  mAppEntry.externalDataSize;
-                    mExternalDataSize.setSummary(getSizeStr( mAppEntry.externalDataSize));
-                }
-            }
-            if (mLastCodeSize != codeSize) {
-                mLastCodeSize = codeSize;
-                mAppSize.setSummary(getSizeStr(codeSize));
-            }
-            if (mLastDataSize != dataSize) {
-                mLastDataSize = dataSize;
-                mDataSize.setSummary(getSizeStr(dataSize));
-            }
-            long cacheSize = mAppEntry.cacheSize + mAppEntry.externalCacheSize;
-            if (mLastCacheSize != cacheSize) {
-                mLastCacheSize = cacheSize;
-                mCacheSize.setSummary(getSizeStr(cacheSize));
-            }
-            if (mLastTotalSize != mAppEntry.size) {
-                mLastTotalSize = mAppEntry.size;
-                mTotalSize.setSummary(getSizeStr(mAppEntry.size));
-            }
-
-            if ((mAppEntry.dataSize+ mAppEntry.externalDataSize) <= 0 || !mCanClearData) {
-                mClearDataButton.setEnabled(false);
-            } else {
-                mClearDataButton.setEnabled(true);
-                mClearDataButton.setOnClickListener(this);
-            }
-            if (cacheSize <= 0) {
-                mClearCacheButton.setEnabled(false);
-            } else {
-                mClearCacheButton.setEnabled(true);
-                mClearCacheButton.setOnClickListener(this);
-            }
-        }
-        if (mAppsControlDisallowedBySystem) {
-            mClearCacheButton.setEnabled(false);
-            mClearDataButton.setEnabled(false);
-        }
-    }
-
     @Override
     protected boolean refreshUi() {
         retrieveAppEntry();
         if (mAppEntry == null) {
             return false;
         }
-        refreshSizeInfo();
+        updateUiWithSize(mLastResult);
         refreshGrantedUriPermissions();
 
         final VolumeInfo currentVol = getActivity().getPackageManager()
@@ -454,7 +394,7 @@
         mClearDataButton.setText(R.string.clear_user_data_text);
         if (result == OP_SUCCESSFUL) {
             Log.i(TAG, "Cleared user data for package : "+packageName);
-            mState.requestSize(mPackageName, mUserId);
+            updateSize();
         } else {
             mClearDataButton.setEnabled(true);
         }
@@ -570,8 +510,91 @@
 
     @Override
     public void onPackageSizeChanged(String packageName) {
-        if (packageName.equals(mAppEntry.info.packageName)) {
-            refreshSizeInfo();
+    }
+
+    @Override
+    public Loader<AppStorageStats> onCreateLoader(int id, Bundle args) {
+        Context context = getContext();
+        return new FetchPackageStorageAsyncLoader(
+                context, new StorageStatsSource(context), mInfo, UserHandle.of(mUserId));
+    }
+
+    @Override
+    public void onLoadFinished(Loader<AppStorageStats> loader, AppStorageStats result) {
+        mLastResult = result;
+        updateUiWithSize(result);
+    }
+
+    @Override
+    public void onLoaderReset(Loader<AppStorageStats> loader) {
+    }
+
+    private void updateSize() {
+        PackageManager packageManager = getPackageManager();
+        try {
+            mInfo = packageManager.getApplicationInfo(mPackageName, 0);
+        } catch (PackageManager.NameNotFoundException e) {
+            Log.e(TAG, "Could not find package", e);
+        }
+
+        if (mInfo == null) {
+            return;
+        }
+
+        getLoaderManager().restartLoader(1, Bundle.EMPTY, this);
+    }
+
+    private void updateUiWithSize(AppStorageStats result) {
+        if (result == null) {
+            mLastCodeSize = mLastDataSize = mLastCacheSize = mLastTotalSize = -1;
+            if (!mHaveSizes) {
+                mAppSize.setSummary(mComputingStr);
+                mDataSize.setSummary(mComputingStr);
+                mCacheSize.setSummary(mComputingStr);
+                mTotalSize.setSummary(mComputingStr);
+            }
+            mClearDataButton.setEnabled(false);
+            mClearCacheButton.setEnabled(false);
+        } else {
+            mHaveSizes = true;
+            long codeSize = result.getCodeBytes();
+            long dataSize = result.getDataBytes();
+            if (mLastCodeSize != codeSize) {
+                mLastCodeSize = codeSize;
+                mAppSize.setSummary(getSizeStr(codeSize));
+            }
+            if (mLastDataSize != dataSize) {
+                mLastDataSize = dataSize;
+                mDataSize.setSummary(getSizeStr(dataSize));
+            }
+            long cacheSize = result.getCacheBytes();
+            if (mLastCacheSize != cacheSize) {
+                mLastCacheSize = cacheSize;
+                mCacheSize.setSummary(getSizeStr(cacheSize));
+            }
+
+            long totalSize = codeSize + dataSize + cacheSize;
+            if (mLastTotalSize != totalSize) {
+                mLastTotalSize = totalSize;
+                mTotalSize.setSummary(getSizeStr(totalSize));
+            }
+
+            if (dataSize <= 0 || !mCanClearData) {
+                mClearDataButton.setEnabled(false);
+            } else {
+                mClearDataButton.setEnabled(true);
+                mClearDataButton.setOnClickListener(this);
+            }
+            if (cacheSize <= 0) {
+                mClearCacheButton.setEnabled(false);
+            } else {
+                mClearCacheButton.setEnabled(true);
+                mClearCacheButton.setOnClickListener(this);
+            }
+        }
+        if (mAppsControlDisallowedBySystem) {
+            mClearCacheButton.setEnabled(false);
+            mClearDataButton.setEnabled(false);
         }
     }
 
@@ -586,7 +609,7 @@
                     break;
                 case MSG_CLEAR_CACHE:
                     // Refresh size info
-                    mState.requestSize(mPackageName, mUserId);
+                    updateSize();
                     break;
             }
         }
diff --git a/src/com/android/settings/applications/FetchPackageStorageAsyncLoader.java b/src/com/android/settings/applications/FetchPackageStorageAsyncLoader.java
new file mode 100644
index 0000000..3477299
--- /dev/null
+++ b/src/com/android/settings/applications/FetchPackageStorageAsyncLoader.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.applications;
+
+import android.annotation.NonNull;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.os.UserHandle;
+
+import com.android.internal.util.Preconditions;
+import com.android.settings.utils.AsyncLoader;
+import com.android.settingslib.applications.StorageStatsSource;
+import com.android.settingslib.applications.StorageStatsSource.AppStorageStats;
+
+/**
+ * Fetches the storage stats using the StorageStatsManager for a given package and user tuple.
+ */
+public class FetchPackageStorageAsyncLoader extends AsyncLoader<AppStorageStats> {
+    private final StorageStatsSource mSource;
+    private final ApplicationInfo mInfo;
+    private final UserHandle mUser;
+
+    public FetchPackageStorageAsyncLoader(Context context, @NonNull StorageStatsSource source,
+            @NonNull ApplicationInfo info, @NonNull UserHandle user) {
+        super(context);
+        mSource = Preconditions.checkNotNull(source);
+        mInfo = info;
+        mUser = user;
+    }
+
+    @Override
+    public AppStorageStats loadInBackground() {
+        return mSource.getStatsForPackage(mInfo.volumeUuid, mInfo.packageName, mUser);
+    }
+
+    @Override
+    protected void onDiscardResult(AppStorageStats result) {
+    }
+}
diff --git a/src/com/android/settings/core/gateway/SettingsGateway.java b/src/com/android/settings/core/gateway/SettingsGateway.java
index 8cd0602..d6564fe 100644
--- a/src/com/android/settings/core/gateway/SettingsGateway.java
+++ b/src/com/android/settings/core/gateway/SettingsGateway.java
@@ -274,7 +274,6 @@
             Settings.NetworkDashboardActivity.class.getName(),
             Settings.ConnectedDeviceDashboardActivity.class.getName(),
             Settings.AppAndNotificationDashboardActivity.class.getName(),
-            "com.android.settings.BatteryDashboardAlias",
             "com.android.settings.SoundDashboardAlias",
             "com.android.settings.SecurityDashboardAlias",
             "com.android.settings.UsersDashboardAlias",
diff --git a/src/com/android/settings/deviceinfo/storage/StorageAsyncLoader.java b/src/com/android/settings/deviceinfo/storage/StorageAsyncLoader.java
index d5d96a5..f54c685 100644
--- a/src/com/android/settings/deviceinfo/storage/StorageAsyncLoader.java
+++ b/src/com/android/settings/deviceinfo/storage/StorageAsyncLoader.java
@@ -23,7 +23,6 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.UserInfo;
 import android.os.UserHandle;
-import android.util.ArraySet;
 import android.util.Log;
 import android.util.SparseArray;
 
@@ -75,27 +74,31 @@
         Log.d(TAG, "Loading apps");
         List<ApplicationInfo> applicationInfos =
                 mPackageManager.getInstalledApplicationsAsUser(0, userId);
-        ArraySet<Integer> seenUid = new ArraySet<>(); // some apps share a uid
         AppsStorageResult result = new AppsStorageResult();
+        UserHandle myUser = UserHandle.of(userId);
         for (int i = 0, size = applicationInfos.size(); i < size; i++) {
             ApplicationInfo app = applicationInfos.get(i);
-            if (seenUid.contains(app.uid)) {
-                continue;
-            }
-            seenUid.add(app.uid);
+            StorageStatsSource.AppStorageStats stats =
+                    mStatsManager.getStatsForPackage(mUuid, app.packageName, myUser);
 
-            StorageStatsSource.AppStorageStats stats = mStatsManager.getStatsForUid(mUuid, app.uid);
-            // Note: This omits cache intentionally -- we are not attributing it to the apps.
-            long appSize = stats.getCodeBytes() + stats.getDataBytes();
+            long attributedAppSizeInBytes = stats.getDataBytes();
+            // This matches how the package manager calculates sizes -- by zeroing out code sizes of
+            // system apps which are not updated. My initial tests suggest that this results in the
+            // original code size being counted for updated system apps when they shouldn't, but
+            // I am not sure how to avoid this problem without specifically going in to find that
+            // code size.
+            if (!app.isSystemApp() || app.isUpdatedSystemApp()) {
+                attributedAppSizeInBytes += stats.getCodeBytes();
+            }
             switch (app.category) {
                 case CATEGORY_GAME:
-                    result.gamesSize += appSize;
+                    result.gamesSize += attributedAppSizeInBytes;
                     break;
                 case CATEGORY_AUDIO:
-                    result.musicAppsSize += appSize;
+                    result.musicAppsSize += attributedAppSizeInBytes;
                     break;
                 default:
-                    result.otherAppsSize += appSize;
+                    result.otherAppsSize += attributedAppSizeInBytes;
                     break;
             }
         }
diff --git a/tests/robotests/src/com/android/settings/applications/FetchPackageStorageAsyncLoaderTest.java b/tests/robotests/src/com/android/settings/applications/FetchPackageStorageAsyncLoaderTest.java
new file mode 100644
index 0000000..0b1d1aa
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/applications/FetchPackageStorageAsyncLoaderTest.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.applications;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.os.UserHandle;
+
+import com.android.settings.SettingsRobolectricTestRunner;
+import com.android.settings.TestConfig;
+import com.android.settingslib.applications.StorageStatsSource;
+import com.android.settingslib.applications.StorageStatsSource.AppStorageStats;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class FetchPackageStorageAsyncLoaderTest {
+    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+    private Context mContext;
+    @Mock
+    private StorageStatsSource mSource;
+
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+    }
+
+    @Test
+    public void worksForValidPackageNameAndUid() {
+        AppStorageStats stats = mock(AppStorageStats.class);
+        when(stats.getCodeBytes()).thenReturn(1L);
+        when(stats.getDataBytes()).thenReturn(2L);
+        when(stats.getCacheBytes()).thenReturn(3L);
+        when(mSource.getStatsForPackage(anyString(), anyString(), any(UserHandle.class)))
+                .thenReturn(stats);
+        ApplicationInfo info = new ApplicationInfo();
+        info.packageName = "com.test.package";
+
+        FetchPackageStorageAsyncLoader task = new FetchPackageStorageAsyncLoader(
+                mContext, mSource, info, new UserHandle(0));
+        assertThat(task.loadInBackground()).isEqualTo(stats);
+    }
+}
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 70e05d6..10ba293 100644
--- a/tests/unit/src/com/android/settings/deviceinfo/storage/StorageAsyncLoaderTest.java
+++ b/tests/unit/src/com/android/settings/deviceinfo/storage/StorageAsyncLoaderTest.java
@@ -18,6 +18,7 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyInt;
 import static org.mockito.Matchers.anyString;
 import static org.mockito.Matchers.eq;
@@ -45,13 +46,14 @@
 
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Map;
 
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 public class StorageAsyncLoaderTest {
     private static final int PRIMARY_USER_ID = 0;
     private static final int SECONDARY_USER_ID = 10;
+    private static final String PACKAGE_NAME_1 = "com.blah.test";
+    private static final String PACKAGE_NAME_2 = "com.blah.test2";
 
     @Mock
     private StorageStatsSource mSource;
@@ -81,8 +83,8 @@
 
     @Test
     public void testLoadingApps() throws Exception {
-        addPackage(1001, 0, 1, 10, ApplicationInfo.CATEGORY_UNDEFINED);
-        addPackage(1002, 0, 100, 1000, ApplicationInfo.CATEGORY_UNDEFINED);
+        addPackage(PACKAGE_NAME_1, 0, 1, 10, ApplicationInfo.CATEGORY_UNDEFINED);
+        addPackage(PACKAGE_NAME_2, 0, 100, 1000, ApplicationInfo.CATEGORY_UNDEFINED);
 
         SparseArray<StorageAsyncLoader.AppsStorageResult> result = mLoader.loadInBackground();
 
@@ -93,7 +95,7 @@
 
     @Test
     public void testGamesAreFiltered() throws Exception {
-        addPackage(1001, 0, 1, 10, ApplicationInfo.CATEGORY_GAME);
+        addPackage(PACKAGE_NAME_1, 0, 1, 10, ApplicationInfo.CATEGORY_GAME);
 
         SparseArray<StorageAsyncLoader.AppsStorageResult> result = mLoader.loadInBackground();
 
@@ -103,19 +105,8 @@
     }
 
     @Test
-    public void testDuplicateUidsAreSkipped() throws Exception {
-        addPackage(1001, 0, 1, 10, ApplicationInfo.CATEGORY_UNDEFINED);
-        addPackage(1001, 0, 1, 10, ApplicationInfo.CATEGORY_UNDEFINED);
-
-        SparseArray<StorageAsyncLoader.AppsStorageResult> result = mLoader.loadInBackground();
-
-        assertThat(result.size()).isEqualTo(1);
-        assertThat(result.get(PRIMARY_USER_ID).otherAppsSize).isEqualTo(11L);
-    }
-
-    @Test
     public void testCacheIsIgnored() throws Exception {
-        addPackage(1001, 100, 1, 10, ApplicationInfo.CATEGORY_UNDEFINED);
+        addPackage(PACKAGE_NAME_1, 100, 1, 10, ApplicationInfo.CATEGORY_UNDEFINED);
 
         SparseArray<StorageAsyncLoader.AppsStorageResult> result = mLoader.loadInBackground();
 
@@ -140,16 +131,43 @@
         assertThat(result.get(SECONDARY_USER_ID).externalStats.totalBytes).isEqualTo(10L);
     }
 
-    private void addPackage(int uid, long cacheSize, long codeSize, long dataSize, int category) {
+    @Test
+    public void testSystemAppsBaseSizeIsIgnored() throws Exception {
+        ApplicationInfo systemApp =
+                addPackage(PACKAGE_NAME_1, 100, 1, 10, ApplicationInfo.CATEGORY_UNDEFINED);
+        systemApp.flags = ApplicationInfo.FLAG_SYSTEM;
+
+        SparseArray<StorageAsyncLoader.AppsStorageResult> result = mLoader.loadInBackground();
+
+        assertThat(result.size()).isEqualTo(1);
+        assertThat(result.get(PRIMARY_USER_ID).otherAppsSize).isEqualTo(10L);
+    }
+
+    @Test
+    public void testUpdatedSystemAppCodeSizeIsCounted() throws Exception {
+        ApplicationInfo systemApp =
+                addPackage(PACKAGE_NAME_1, 100, 1, 10, ApplicationInfo.CATEGORY_UNDEFINED);
+        systemApp.flags = ApplicationInfo.FLAG_SYSTEM & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
+
+        SparseArray<StorageAsyncLoader.AppsStorageResult> result = mLoader.loadInBackground();
+
+        assertThat(result.size()).isEqualTo(1);
+        assertThat(result.get(PRIMARY_USER_ID).otherAppsSize).isEqualTo(11L);
+    }
+
+    private ApplicationInfo addPackage(
+            String packageName, long cacheSize, long codeSize, long dataSize, int category) {
         StorageStatsSource.AppStorageStats storageStats =
                 mock(StorageStatsSource.AppStorageStats.class);
         when(storageStats.getCodeBytes()).thenReturn(codeSize);
         when(storageStats.getDataBytes()).thenReturn(dataSize);
-        when(mSource.getStatsForUid(anyString(), eq(uid))).thenReturn(storageStats);
+        when(mSource.getStatsForPackage(anyString(), eq(packageName), any(UserHandle.class)))
+                .thenReturn(storageStats);
 
         ApplicationInfo info = new ApplicationInfo();
-        info.uid = uid;
+        info.packageName = packageName;
         info.category = category;
         mInfo.add(info);
+        return info;
     }
 }