Merge "Ensure DashboardFragment shares pref controlls with search"
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index b58d1ee..4c8ba07 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -1945,11 +1945,11 @@
                 <category android:name="android.intent.category.DEFAULT" />
                 <category android:name="android.intent.category.VOICE_LAUNCH" />
             </intent-filter>
-            <intent-filter android:priority="3">
+            <intent-filter android:priority="2">
                 <action android:name="com.android.settings.action.SETTINGS" />
             </intent-filter>
             <meta-data android:name="com.android.settings.category"
-                android:value="com.android.settings.category.system" />
+                android:value="com.android.settings.category.ia.device" />
             <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
                 android:value="com.android.settings.print.PrintSettingsFragment" />
         </activity>
@@ -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">
@@ -3111,17 +3100,6 @@
                        android:value="com.android.settings.applications.ProcessStatsSummary" />
         </activity-alias>
 
-        <activity-alias android:name="PrintDashboardAlias"
-                        android:targetActivity="Settings$PrintSettingsActivity">
-            <intent-filter android:priority="2">
-                <action android:name="com.android.settings.action.SETTINGS"/>
-            </intent-filter>
-            <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
-                       android:value="com.android.settings.print.PrintSettingsFragment" />
-            <meta-data android:name="com.android.settings.category"
-                       android:value="com.android.settings.category.ia.device" />
-        </activity-alias>
-
         <activity-alias android:name="ManageApplicationsDashboardAlias"
                         android:targetActivity="Settings$ManageApplicationsActivity">
             <intent-filter android:priority="200">
diff --git a/src/com/android/settings/CreateShortcut.java b/src/com/android/settings/CreateShortcut.java
index 7d5a6d2..8bc801b 100644
--- a/src/com/android/settings/CreateShortcut.java
+++ b/src/com/android/settings/CreateShortcut.java
@@ -71,7 +71,7 @@
         ShortcutManager sm = getSystemService(ShortcutManager.class);
         ActivityInfo activityInfo = resolveInfo.activityInfo;
 
-        Icon maskableIcon = activityInfo.icon != 0 ? Icon.createWithMaskableBitmap(
+        Icon maskableIcon = activityInfo.icon != 0 ? Icon.createWithAdaptiveBitmap(
                 createIcon(activityInfo.icon,
                         R.layout.shortcut_badge_maskable,
                         getResources().getDimensionPixelSize(R.dimen.shortcut_size_maskable))) :
diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java
index b48174c..1b9b3b3 100644
--- a/src/com/android/settings/SettingsActivity.java
+++ b/src/com/android/settings/SettingsActivity.java
@@ -236,7 +236,6 @@
     private DashboardFeatureProvider mDashboardFeatureProvider;
     private Intent mResultIntentData;
     private ComponentName mCurrentSuggestion;
-    private final StringBuffer mDebugData = new StringBuffer();
 
     @VisibleForTesting
     String mSearchQuery;
@@ -433,34 +432,7 @@
             mDisplaySearch = savedState.getBoolean(SAVE_KEY_SHOW_SEARCH);
 
         } else {
-            if (!mIsShowingDashboard) {
-                if (initialFragmentName == null) {
-                    logFragmentData(intent, className, isSubSettings);
-                }
-                mDisplaySearch = false;
-                // UP will be shown only if it is a sub settings
-                if (mIsShortcut) {
-                    mDisplayHomeAsUpEnabled = isSubSettings;
-                } else if (isSubSettings) {
-                    mDisplayHomeAsUpEnabled = true;
-                } else {
-                    mDisplayHomeAsUpEnabled = false;
-                }
-                setTitleFromIntent(intent);
-
-                Bundle initialArguments = intent.getBundleExtra(EXTRA_SHOW_FRAGMENT_ARGUMENTS);
-                switchToFragment(initialFragmentName, initialArguments, true, false,
-                        mInitialTitleResId, mInitialTitle, false);
-            } else {
-                // No UP affordance if we are displaying the main Dashboard
-                mDisplayHomeAsUpEnabled = false;
-                // Show Search affordance
-                mDisplaySearch = true;
-                mInitialTitleResId = R.string.dashboard_title;
-
-                switchToFragment(DashboardSummary.class.getName(), null /* args */, false, false,
-                            mInitialTitleResId, mInitialTitle, false);
-            }
+            launchSettingFragment(initialFragmentName, isSubSettings, intent);
         }
 
         mActionBar = getActionBar();
@@ -532,6 +504,35 @@
         }
     }
 
+    @VisibleForTesting
+    void launchSettingFragment(String initialFragmentName, boolean isSubSettings, Intent intent) {
+        if (!mIsShowingDashboard && initialFragmentName != null) {
+            mDisplaySearch = false;
+            // UP will be shown only if it is a sub settings
+            if (mIsShortcut) {
+                mDisplayHomeAsUpEnabled = isSubSettings;
+            } else if (isSubSettings) {
+                mDisplayHomeAsUpEnabled = true;
+            } else {
+                mDisplayHomeAsUpEnabled = false;
+            }
+            setTitleFromIntent(intent);
+
+            Bundle initialArguments = intent.getBundleExtra(EXTRA_SHOW_FRAGMENT_ARGUMENTS);
+            switchToFragment(initialFragmentName, initialArguments, true, false,
+                mInitialTitleResId, mInitialTitle, false);
+        } else {
+            // No UP affordance if we are displaying the main Dashboard
+            mDisplayHomeAsUpEnabled = false;
+            // Show Search affordance
+            mDisplaySearch = true;
+            mInitialTitleResId = R.string.dashboard_title;
+
+            switchToFragment(DashboardSummary.class.getName(), null /* args */, false, false,
+                mInitialTitleResId, mInitialTitle, false);
+        }
+    }
+
     public void setDisplaySearchMenu(boolean displaySearch) {
         if (displaySearch != mDisplaySearch) {
             mDisplaySearch = displaySearch;
@@ -693,7 +694,6 @@
         String startingFragment = getStartingFragmentClass(superIntent);
         // This is called from super.onCreate, isMultiPane() is not yet reliable
         // Do not use onIsHidingHeaders either, which relies itself on this method
-        log("getIntent() startingFragment", startingFragment);
         if (startingFragment != null) {
             Intent modIntent = new Intent(superIntent);
             modIntent.putExtra(EXTRA_SHOW_FRAGMENT, startingFragment);
@@ -715,11 +715,9 @@
      * returns the class name to load as a fragment.
      */
     private String getStartingFragmentClass(Intent intent) {
-        log("getStartingFragmentClass() mFragmentClass", mFragmentClass);
         if (mFragmentClass != null) return mFragmentClass;
 
         String intentClass = intent.getComponent().getClassName();
-        log("getStartingFragmentClass() intentClass", intentClass);
         if (intentClass.equals(getClass().getName())) return null;
 
         if ("com.android.settings.ManageApplications".equals(intentClass)
@@ -1116,37 +1114,4 @@
         }
         super.onActivityResult(requestCode, resultCode, data);
     }
-
-    private void logFragmentData(Intent intent, String className, boolean isSubSettings) {
-        if (intent != null) {
-            logBundleData(intent.getExtras(), "Intent extra");
-            logBundleData(intent.getBundleExtra(EXTRA_SHOW_FRAGMENT_ARGUMENTS), "Fragment args");
-        } else {
-            log("Intent data", "NULL");
-        }
-        log("Fragment", mFragmentClass);
-        log("Shortcut", mIsShortcut);
-        log("Class Name", className);
-        log("Show dashboard", mIsShowingDashboard);
-        log("Sub setting", isSubSettings);
-        log("Title", mInitialTitle);
-        Log.d(LOG_TAG, mDebugData.toString());
-        mDebugData.delete(0, mDebugData.length());
-    }
-
-    private void logBundleData(Bundle data, String name) {
-        if (data != null) {
-            final Set<String> keys = data.keySet();
-            mDebugData.append(name).append(": ");
-            for (String key : keys) {
-                log(key, data.get(key));
-            }
-        } else {
-            log(name, "NULL");
-        }
-    }
-
-    private void log(String key, Object data) {
-        mDebugData.append(key).append("=").append(data).append(", ");
-    }
 }
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/applications/MusicViewHolderController.java b/src/com/android/settings/applications/MusicViewHolderController.java
index d7c142f..4599fcc 100644
--- a/src/com/android/settings/applications/MusicViewHolderController.java
+++ b/src/com/android/settings/applications/MusicViewHolderController.java
@@ -68,8 +68,10 @@
 
     @Override
     public void onClick(Fragment fragment) {
-        Intent intent = new Intent(DocumentsContract.ACTION_BROWSE);
-        intent.setData(DocumentsContract.buildRootUri(AUTHORITY_MEDIA, "audio_root"));
+        Intent intent = new Intent(Intent.ACTION_VIEW);
+        intent.setDataAndType(
+                DocumentsContract.buildRootUri(AUTHORITY_MEDIA, "audio_root"),
+                DocumentsContract.Root.MIME_TYPE_ITEM);
         intent.addCategory(Intent.CATEGORY_DEFAULT);
         intent.putExtra(Intent.EXTRA_USER_ID, mUser);
         Utils.launchIntent(fragment, intent);
diff --git a/src/com/android/settings/core/gateway/SettingsGateway.java b/src/com/android/settings/core/gateway/SettingsGateway.java
index 8cd0602..e0ed1eb 100644
--- a/src/com/android/settings/core/gateway/SettingsGateway.java
+++ b/src/com/android/settings/core/gateway/SettingsGateway.java
@@ -53,7 +53,6 @@
 import com.android.settings.applications.DrawOverlayDetails;
 import com.android.settings.applications.InstalledAppDetails;
 import com.android.settings.applications.ManageApplications;
-import com.android.settings.applications.assist.ManageAssist;
 import com.android.settings.applications.ManageDomainUrls;
 import com.android.settings.applications.NotificationApps;
 import com.android.settings.applications.PictureInPictureSettings;
@@ -62,6 +61,7 @@
 import com.android.settings.applications.UsageAccessDetails;
 import com.android.settings.applications.VrListenerSettings;
 import com.android.settings.applications.WriteSettingsDetails;
+import com.android.settings.applications.assist.ManageAssist;
 import com.android.settings.bluetooth.BluetoothSettings;
 import com.android.settings.connecteddevice.ConnectedDeviceDashboardFragment;
 import com.android.settings.dashboard.SupportFragment;
@@ -273,8 +273,9 @@
             // Home page
             Settings.NetworkDashboardActivity.class.getName(),
             Settings.ConnectedDeviceDashboardActivity.class.getName(),
+            Settings.WifiDisplaySettingsActivity.class.getName(),
             Settings.AppAndNotificationDashboardActivity.class.getName(),
-            "com.android.settings.BatteryDashboardAlias",
+            Settings.StorageDashboardActivity.class.getName(),
             "com.android.settings.SoundDashboardAlias",
             "com.android.settings.SecurityDashboardAlias",
             "com.android.settings.UsersDashboardAlias",
diff --git a/src/com/android/settings/deviceinfo/PrivateVolumeSettings.java b/src/com/android/settings/deviceinfo/PrivateVolumeSettings.java
index eb07a7f..076ec05 100644
--- a/src/com/android/settings/deviceinfo/PrivateVolumeSettings.java
+++ b/src/com/android/settings/deviceinfo/PrivateVolumeSettings.java
@@ -483,20 +483,26 @@
 
             } break;
             case R.string.storage_detail_images: {
-                intent = new Intent(DocumentsContract.ACTION_BROWSE);
-                intent.setData(DocumentsContract.buildRootUri(AUTHORITY_MEDIA, "images_root"));
+                intent = new Intent(Intent.ACTION_VIEW);
+                intent.setDataAndType(
+                        DocumentsContract.buildRootUri(AUTHORITY_MEDIA, "images_root"),
+                        DocumentsContract.Root.MIME_TYPE_ITEM);
                 intent.addCategory(Intent.CATEGORY_DEFAULT);
 
             } break;
             case R.string.storage_detail_videos: {
-                intent = new Intent(DocumentsContract.ACTION_BROWSE);
-                intent.setData(DocumentsContract.buildRootUri(AUTHORITY_MEDIA, "videos_root"));
+                intent = new Intent(Intent.ACTION_VIEW);
+                intent.setDataAndType(
+                        DocumentsContract.buildRootUri(AUTHORITY_MEDIA, "videos_root"),
+                        DocumentsContract.Root.MIME_TYPE_ITEM);
                 intent.addCategory(Intent.CATEGORY_DEFAULT);
 
             } break;
             case R.string.storage_detail_audio: {
-                intent = new Intent(DocumentsContract.ACTION_BROWSE);
-                intent.setData(DocumentsContract.buildRootUri(AUTHORITY_MEDIA, "audio_root"));
+                intent = new Intent(DocumentsContract.Root.MIME_TYPE_ITEM);
+                intent.setDataAndType(
+                        DocumentsContract.buildRootUri(AUTHORITY_MEDIA, "audio_root"),
+                        DocumentsContract.Root.MIME_TYPE_ITEM);
                 intent.addCategory(Intent.CATEGORY_DEFAULT);
 
             } break;
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/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImpl.java b/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImpl.java
index 011f417..b8c40fd 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImpl.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImpl.java
@@ -26,6 +26,9 @@
 public class PowerUsageFeatureProviderImpl implements PowerUsageFeatureProvider {
 
     private static final String PACKAGE_CALENDAR_PROVIDER = "com.android.providers.calendar";
+    private static final String PACKAGE_MEDIA_PROVIDER = "com.android.providers.media";
+    private static final String[] PACKAGES_SYSTEM = {PACKAGE_MEDIA_PROVIDER,
+            PACKAGE_CALENDAR_PROVIDER};
 
     protected PackageManager mPackageManager;
 
@@ -45,9 +48,15 @@
         // Classify all the sippers to type system if the range of uid is 0...FIRST_APPLICATION_UID
         if (uid >= Process.ROOT_UID && uid < Process.FIRST_APPLICATION_UID) {
             return true;
-        } else {
-            return ArrayUtils.contains(sipper.mPackages, PACKAGE_CALENDAR_PROVIDER);
+        } else if (sipper.mPackages != null) {
+            for (final String packageName : sipper.mPackages) {
+                if (ArrayUtils.contains(PACKAGES_SYSTEM, packageName)) {
+                    return true;
+                }
+            }
         }
+
+        return false;
     }
 
     @Override
diff --git a/src/com/android/settings/fuelgauge/PowerUsageSummary.java b/src/com/android/settings/fuelgauge/PowerUsageSummary.java
index 18ba1aa..50c3f06 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageSummary.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageSummary.java
@@ -581,7 +581,7 @@
         final DrainType drainType = sipper.drainType;
 
         return drainType == DrainType.IDLE || drainType == DrainType.CELL
-                || drainType == DrainType.SCREEN
+                || drainType == DrainType.SCREEN || drainType == DrainType.BLUETOOTH
                 || (sipper.totalPowerMah * SECONDS_IN_HOUR) < MIN_POWER_THRESHOLD_MILLI_AMP
                 || mPowerFeatureProvider.isTypeService(sipper)
                 || mPowerFeatureProvider.isTypeSystem(sipper);
diff --git a/src/com/android/settings/notification/AppNotificationSettings.java b/src/com/android/settings/notification/AppNotificationSettings.java
index 4c310e6..eecc77c 100644
--- a/src/com/android/settings/notification/AppNotificationSettings.java
+++ b/src/com/android/settings/notification/AppNotificationSettings.java
@@ -182,13 +182,13 @@
                             getPrefContext());
                     channelPref.setDisabledByAdmin(mSuspendedAppsAdmin);
                     channelPref.setKey(channel.getId());
-                    channelPref.setTitle(channel.getName());
+                    channelPref.setTitle(getNotificationChannelLabel(channel));
                     channelPref.setChecked(channel.getImportance() != IMPORTANCE_NONE);
                     channelPref.setMultiLine(true);
 
                     if (channel.isDeleted()) {
-                        channelPref.setTitle(
-                                getString(R.string.deleted_channel_name, channel.getName()));
+                        channelPref.setTitle(getString(R.string.deleted_channel_name,
+                                getNotificationChannelLabel(channel)));
                         channelPref.setEnabled(false);
                     } else {
                         channelPref.setSummary(getImportanceSummary(channel.getImportance()));
@@ -275,8 +275,10 @@
             if (left.isDeleted() != right.isDeleted()) {
                 return Boolean.compare(left.isDeleted(), right.isDeleted());
             }
-            if (!Objects.equals(left.getName(), right.getName())) {
-                return sCollator.compare(left.getName().toString(), right.getName().toString());
+            if (!Objects.equals(getNotificationChannelLabel(left),
+                    getNotificationChannelLabel(right))) {
+                return sCollator.compare(getNotificationChannelLabel(left).toString(),
+                        getNotificationChannelLabel(right).toString());
             }
             return left.getId().compareTo(right.getId());
         }
diff --git a/src/com/android/settings/notification/ChannelNotificationSettings.java b/src/com/android/settings/notification/ChannelNotificationSettings.java
index ea450f4..7be98c1 100644
--- a/src/com/android/settings/notification/ChannelNotificationSettings.java
+++ b/src/com/android/settings/notification/ChannelNotificationSettings.java
@@ -130,7 +130,7 @@
                     .getApplicationFeatureProvider(activity)
                     .newAppHeaderController(this /* fragment */, null /* appHeader */)
                     .setIcon(mAppRow.icon)
-                    .setLabel(mChannel.getName())
+                    .setLabel(getNotificationChannelLabel(mChannel))
                     .setSummary(mAppRow.label)
                     .setPackageName(mAppRow.pkg)
                     .setUid(mAppRow.uid)
diff --git a/src/com/android/settings/notification/NotificationBackend.java b/src/com/android/settings/notification/NotificationBackend.java
index 2a2185d..d201d60 100644
--- a/src/com/android/settings/notification/NotificationBackend.java
+++ b/src/com/android/settings/notification/NotificationBackend.java
@@ -155,8 +155,4 @@
         public boolean showBadge;
         public int userId;
     }
-
-    public static class ChannelRow extends AppRow {
-        public NotificationChannel channel;
-    }
 }
diff --git a/src/com/android/settings/notification/NotificationSettingsBase.java b/src/com/android/settings/notification/NotificationSettingsBase.java
index 80d249f..099b4f4 100644
--- a/src/com/android/settings/notification/NotificationSettingsBase.java
+++ b/src/com/android/settings/notification/NotificationSettingsBase.java
@@ -248,4 +248,17 @@
                 return getContext().getString(R.string.notification_importance_high);
         }
     }
+
+    protected CharSequence getNotificationChannelLabel(NotificationChannel channel) {
+        if (channel.getName() != null) {
+            return channel.getName();
+        }
+        try {
+            ApplicationInfo info = mPm.getApplicationInfoAsUser(mAppRow.pkg, 0, mAppRow.userId);
+            return mPm.getText(mAppRow.pkg, channel.getNameResId(), info);
+        } catch (NameNotFoundException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
 }
diff --git a/src/com/android/settings/wifi/WifiSettings.java b/src/com/android/settings/wifi/WifiSettings.java
index d97b461..d652efa 100644
--- a/src/com/android/settings/wifi/WifiSettings.java
+++ b/src/com/android/settings/wifi/WifiSettings.java
@@ -954,6 +954,8 @@
                 Log.e(TAG, "Failed to forget invalid network " + mSelectedAccessPoint.getConfig());
                 return;
             }
+        } else if (mSelectedAccessPoint.getConfig().isPasspoint()) {
+            mWifiManager.removePasspointConfiguration(mSelectedAccessPoint.getConfig().FQDN);
         } else {
             mWifiManager.forget(mSelectedAccessPoint.getConfig().networkId, mForgetListener);
         }
diff --git a/tests/robotests/src/com/android/settings/SettingsActivityTest.java b/tests/robotests/src/com/android/settings/SettingsActivityTest.java
index 1661947..df7a454 100644
--- a/tests/robotests/src/com/android/settings/SettingsActivityTest.java
+++ b/tests/robotests/src/com/android/settings/SettingsActivityTest.java
@@ -16,18 +16,47 @@
 
 package com.android.settings;
 
+import android.app.FragmentManager;
+import android.app.FragmentTransaction;
+import android.content.Context;
+import android.content.Intent;
+import com.android.settings.testutils.FakeFeatureFactory;
+
+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.RuntimeEnvironment;
 import org.robolectric.annotation.Config;
 
 import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
 
 @RunWith(SettingsRobolectricTestRunner.class)
 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
 public class SettingsActivityTest {
 
+    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+    private Context mContext;
+    @Mock
+    private FragmentManager mFragmentManager;
+
     private SettingsActivity mActivity;
 
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        FakeFeatureFactory.setupForTest(mContext);
+        final FakeFeatureFactory factory =
+            (FakeFeatureFactory) FakeFeatureFactory.getFactory(mContext);
+        when(factory.dashboardFeatureProvider.isEnabled()).thenReturn(true);
+    }
+
     @Test
     public void testQueryTextChange_shouldUpdate() {
         final String testQuery = "abc";
@@ -42,4 +71,16 @@
 
         assertThat(mActivity.mSearchQuery).isEqualTo(testQuery);
     }
+
+    @Test
+    public void launchSettingFragment_nullExtraShowFragment_shouldNotCrash()
+            throws ClassNotFoundException {
+        mActivity = spy(new SettingsActivity());
+        when(mActivity.getFragmentManager()).thenReturn(mFragmentManager);
+        when(mFragmentManager.beginTransaction()).thenReturn(mock(FragmentTransaction.class));
+
+        doReturn(RuntimeEnvironment.application.getClassLoader()).when(mActivity).getClassLoader();
+
+        mActivity.launchSettingFragment(null, true, mock(Intent.class));
+    }
 }
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/robotests/src/com/android/settings/applications/MusicViewHolderControllerTest.java b/tests/robotests/src/com/android/settings/applications/MusicViewHolderControllerTest.java
index 592293d..9bc7482 100644
--- a/tests/robotests/src/com/android/settings/applications/MusicViewHolderControllerTest.java
+++ b/tests/robotests/src/com/android/settings/applications/MusicViewHolderControllerTest.java
@@ -99,9 +99,10 @@
         verify(mFragment).startActivity(argumentCaptor.capture());
         Intent intent = argumentCaptor.getValue();
 
-        assertThat(intent.getAction()).isEqualTo(DocumentsContract.ACTION_BROWSE);
+        assertThat(intent.getAction()).isEqualTo(Intent.ACTION_VIEW);
         assertThat(intent.getData()).isEqualTo(DocumentsContract.buildRootUri(
                 "com.android.providers.media.documents",
                 "audio_root"));
+        assertThat(intent.getType()).isEqualTo(DocumentsContract.Root.MIME_TYPE_ITEM);
     }
 }
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImplTest.java b/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImplTest.java
index bfb4bc6..d467221 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImplTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImplTest.java
@@ -35,9 +35,11 @@
 @RunWith(SettingsRobolectricTestRunner.class)
 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
 public class PowerUsageFeatureProviderImplTest {
-    private static final int UID_CALENDAR = 1234;
     private static final int UID_OTHER = Process.FIRST_APPLICATION_UID + 2;
+    private static final int UID_CALENDAR = Process.FIRST_APPLICATION_UID + 3;
+    private static final int UID_MEDIA = Process.FIRST_APPLICATION_UID + 4;
     private static final String[] PACKAGES_CALENDAR = {"com.android.providers.calendar"};
+    private static final String[] PACKAGES_MEDIA = {"com.android.providers.media"};
     @Mock
     private Context mContext;
     @Mock
@@ -52,6 +54,7 @@
 
         mPowerFeatureProvider = new PowerUsageFeatureProviderImpl(mContext);
         when(mPackageManager.getPackagesForUid(UID_CALENDAR)).thenReturn(PACKAGES_CALENDAR);
+        when(mPackageManager.getPackagesForUid(UID_MEDIA)).thenReturn(PACKAGES_MEDIA);
         mPowerFeatureProvider.mPackageManager = mPackageManager;
         mBatterySipper.uidObj = new FakeUid(UID_OTHER);
     }
@@ -89,6 +92,14 @@
     }
 
     @Test
+    public void testIsTypeSystem_AppMedia_ReturnTrue() {
+        mBatterySipper.drainType = BatterySipper.DrainType.APP;
+        when(mBatterySipper.getUid()).thenReturn(UID_MEDIA);
+
+        assertThat(mPowerFeatureProvider.isTypeSystem(mBatterySipper)).isTrue();
+    }
+
+    @Test
     public void testIsTypeSystem_UidOther_ReturnFalse() {
         mBatterySipper.drainType = BatterySipper.DrainType.APP;
         when(mBatterySipper.getUid()).thenReturn(UID_OTHER);
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java b/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java
index 9513507..1a0f3fa 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java
@@ -292,6 +292,12 @@
     }
 
     @Test
+    public void testShouldHideSipper_TypeBluetooth_ReturnTrue() {
+        mNormalBatterySipper.drainType = BatterySipper.DrainType.BLUETOOTH;
+        assertThat(mFragment.shouldHideSipper(mNormalBatterySipper)).isTrue();
+    }
+
+    @Test
     public void testShouldHideSipper_TypeSystem_ReturnTrue() {
         mNormalBatterySipper.drainType = BatterySipper.DrainType.APP;
         when(mNormalBatterySipper.getUid()).thenReturn(Process.ROOT_UID);
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;
     }
 }