Add first pass at a new Storage screen.

This patch begins setting up the structure for the screen.
The functionality for populating the data in the preferences
is coming in a later patch.

Bug: 33199077
Test: Settings Robo Tests
Change-Id: I9ebad9d3896501e31ac715704ca986eceb36877d
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index f4a972b..aab5ee5 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -3090,7 +3090,7 @@
         </activity-alias>
 
         <activity android:name=".Settings$StorageDashboardActivity"
-                  android:label="@string/storage_settings"
+                  android:label="@string/storage_settings_2"
                   android:icon="@drawable/ic_settings_storage">
             <intent-filter android:priority="5">
                 <action android:name="com.android.settings.action.SETTINGS" />
@@ -3103,20 +3103,6 @@
                        android:value="true" />
         </activity>
 
-        <activity-alias android:name="InternalStorageDashboardAlias"
-                        android:targetActivity="Settings$StorageSettingsActivity"
-                        android:label="@string/storage_internal_title">
-            <intent-filter android:priority="5">
-                <action android:name="com.android.settings.action.SETTINGS" />
-            </intent-filter>
-            <meta-data android:name="com.android.settings.category"
-                       android:value="com.android.settings.category.ia.storage" />
-            <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
-                       android:value="com.android.settings.deviceinfo.StorageSettings" />
-            <meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
-                       android:value="true" />
-        </activity-alias>
-
         <activity-alias android:name="SecurityDashboardAlias"
                 android:targetActivity="Settings$SecuritySettingsActivity">
             <intent-filter android:priority="4">
diff --git a/res/layout/storage_item_alternate.xml b/res/layout/storage_item_alternate.xml
new file mode 100644
index 0000000..b41c82b
--- /dev/null
+++ b/res/layout/storage_item_alternate.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:layout_width="match_parent"
+              android:layout_height="wrap_content"
+              android:orientation="vertical"
+              android:minHeight="?android:attr/listPreferredItemHeightSmall"
+              android:gravity="center_vertical"
+              android:paddingStart="@dimen/preference_no_icon_padding_start"
+              android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+              android:paddingTop="16dip"
+              android:paddingBottom="16dip"
+              android:background="?android:attr/selectableItemBackground">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal">
+
+        <TextView
+            android:id="@android:id/title"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:singleLine="true"
+            android:textAppearance="@android:style/TextAppearance.Material.Subhead"
+            android:textAlignment="viewStart"
+            android:ellipsize="marquee"
+            android:fadingEdge="horizontal" />
+
+        <TextView
+            android:id="@android:id/summary"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:textAlignment="viewStart"
+            android:textAppearance="@android:style/TextAppearance.Material.Body1"
+            android:textColor="?android:attr/textColorSecondaryNoDisable"
+            android:maxLines="10" />
+
+    </LinearLayout>
+
+</LinearLayout>
diff --git a/res/layout/storage_summary_donut.xml b/res/layout/storage_summary_donut.xml
new file mode 100644
index 0000000..9cffe69
--- /dev/null
+++ b/res/layout/storage_summary_donut.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 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.
+-->
+
+<!-- TODO: Update this view to not match the existing storage summary.-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:layout_width="match_parent"
+              android:layout_height="wrap_content"
+              android:orientation="vertical"
+              android:minHeight="?android:attr/listPreferredItemHeightSmall"
+              android:gravity="center_vertical"
+              android:paddingStart="@dimen/preference_no_icon_padding_start"
+              android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+              android:paddingTop="16dip"
+              android:paddingBottom="16dip"
+              android:background="?android:attr/selectableItemBackground">
+
+    <TextView
+        android:id="@android:id/title"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:singleLine="true"
+        android:textAlignment="viewStart"
+        android:textAppearance="@android:style/TextAppearance.Material.Subhead"
+        android:textColor="?android:attr/colorAccent"
+        android:textSize="36sp"
+        android:ellipsize="marquee"
+        android:fadingEdge="horizontal" />
+
+    <TextView
+        android:id="@android:id/summary"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:textAlignment="viewStart"
+        android:textAppearance="@android:style/TextAppearance.Material.Body1"
+        android:maxLines="10" />
+
+    <ProgressBar
+        android:id="@android:id/progress"
+        android:layout_width="match_parent"
+        android:layout_height="8dp"
+        android:layout_marginTop="16dp"
+        android:layout_marginBottom="8dp"
+        android:visibility="gone"
+        android:max="100"
+        style="?android:attr/progressBarStyleHorizontal" />
+
+</LinearLayout>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 955b8cc..a9f81ed 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -7996,4 +7996,23 @@
     <string name="enterprise_privacy_security_logs">Your most recent security log</string>
     <!-- Label indicating that the date at which the admin last took a particular action was "never" (i.e. the admin never took the action so far). -->
     <string name="enterprise_privacy_never">Never</string>
+
+    <!-- Preference label for the Photos & Videos storage section. [CHAR LIMIT=50] -->
+    <string name="storage_photos_videos">Photos &amp; Videos</string>
+
+    <!-- Preference label for the Music & Audio storage section. [CHAR LIMIT=50] -->
+    <string name="storage_music_audio">Music &amp; Audio</string>
+
+    <!-- Preference label for the Games storage section. [CHAR LIMIT=50] -->
+    <string name="storage_games">Games</string>
+
+    <!-- Preference label for the Other apps storage section. [CHAR LIMIT=50] -->
+    <string name="storage_other_apps">Other apps</string>
+
+    <!-- Preference label for the Files storage section. [CHAR LIMIT=50] -->
+    <string name="storage_files">Files</string>
+
+    <!-- Main settings screen item's title to go into the storage settings screen [CHAR LIMIT=25] -->
+    <string name="storage_settings_2" >Phone Storage</string>
+
 </resources>
diff --git a/res/xml/storage_dashboard_fragment.xml b/res/xml/storage_dashboard_fragment.xml
index 92e3ddb..d577267 100644
--- a/res/xml/storage_dashboard_fragment.xml
+++ b/res/xml/storage_dashboard_fragment.xml
@@ -17,9 +17,36 @@
 <PreferenceScreen
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:title="@string/storage_settings">
-    <Preference
-        android:key="pref_manage_storage"
-        android:title="@string/storage_menu_manage"
+    <com.android.settings.deviceinfo.storage.StorageSummaryDonutPreference
+        android:key="pref_summary" />
+    <com.android.settings.deviceinfo.storage.StorageItemPreferenceAlternate
+        android:key="pref_photos_videos"
+        android:title="@string/storage_photos_videos"
         android:fragment="com.android.settings.deletionhelper.AutomaticStorageManagerSettings">
-    </Preference>
+    </com.android.settings.deviceinfo.storage.StorageItemPreferenceAlternate>
+    <com.android.settings.deviceinfo.storage.StorageItemPreferenceAlternate
+        android:key="pref_music_audio"
+        android:title="@string/storage_music_audio"
+        android:fragment="com.android.settings.deletionhelper.AutomaticStorageManagerSettings">
+    </com.android.settings.deviceinfo.storage.StorageItemPreferenceAlternate>
+    <com.android.settings.deviceinfo.storage.StorageItemPreferenceAlternate
+        android:key="pref_games"
+        android:title="@string/storage_games"
+        android:fragment="com.android.settings.deletionhelper.AutomaticStorageManagerSettings">
+    </com.android.settings.deviceinfo.storage.StorageItemPreferenceAlternate>
+    <com.android.settings.deviceinfo.storage.StorageItemPreferenceAlternate
+        android:key="pref_other_apps"
+        android:title="@string/storage_other_apps"
+        android:fragment="com.android.settings.deletionhelper.AutomaticStorageManagerSettings">
+    </com.android.settings.deviceinfo.storage.StorageItemPreferenceAlternate>
+    <com.android.settings.deviceinfo.storage.StorageItemPreferenceAlternate
+        android:key="pref_system"
+        android:title="@string/storage_detail_system"
+        android:fragment="com.android.settings.deletionhelper.AutomaticStorageManagerSettings">
+    </com.android.settings.deviceinfo.storage.StorageItemPreferenceAlternate>
+    <com.android.settings.deviceinfo.storage.StorageItemPreferenceAlternate
+        android:key="pref_files"
+        android:title="@string/storage_files"
+        android:fragment="com.android.settings.deletionhelper.AutomaticStorageManagerSettings">
+    </com.android.settings.deviceinfo.storage.StorageItemPreferenceAlternate>
 </PreferenceScreen>
\ No newline at end of file
diff --git a/src/com/android/settings/deviceinfo/ManageStoragePreferenceController.java b/src/com/android/settings/deviceinfo/ManageStoragePreferenceController.java
index f4dd14e..3170a87 100644
--- a/src/com/android/settings/deviceinfo/ManageStoragePreferenceController.java
+++ b/src/com/android/settings/deviceinfo/ManageStoragePreferenceController.java
@@ -23,7 +23,7 @@
 
 public class ManageStoragePreferenceController extends PreferenceController {
 
-    public static final String KEY_MANAGE_STORAGE = "pref_manage_storage";
+    public static final String KEY_MANAGE_STORAGE = "footer_preference";
 
     public ManageStoragePreferenceController(Context context) {
         super(context);
diff --git a/src/com/android/settings/deviceinfo/StorageDashboardFragment.java b/src/com/android/settings/deviceinfo/StorageDashboardFragment.java
index 8992830..5d1ac4a 100644
--- a/src/com/android/settings/deviceinfo/StorageDashboardFragment.java
+++ b/src/com/android/settings/deviceinfo/StorageDashboardFragment.java
@@ -17,15 +17,24 @@
 package com.android.settings.deviceinfo;
 
 import android.content.Context;
+import android.os.Bundle;
+import android.os.storage.StorageManager;
+import android.os.storage.VolumeInfo;
 import android.provider.SearchIndexableResource;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
 
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.settings.R;
 import com.android.settings.core.PreferenceController;
 import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.deviceinfo.storage.StorageItemPreferenceController;
+import com.android.settings.deviceinfo.storage.StorageSummaryDonutPreferenceController;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settings.search.Indexable;
+import com.android.settings.widget.FooterPreference;
 import com.android.settingslib.drawer.CategoryKey;
 
 import java.util.ArrayList;
@@ -33,9 +42,53 @@
 import java.util.List;
 
 public class StorageDashboardFragment extends DashboardFragment {
-
     private static final String TAG = "StorageDashboardFrag";
 
+    private VolumeInfo mVolume;
+    private long mTotalSize;
+
+    private StorageSummaryDonutPreferenceController mSummaryController;
+
+    private boolean isVolumeValid() {
+        return (mVolume != null) && (mVolume.getType() == VolumeInfo.TYPE_PRIVATE)
+                && mVolume.isMountedReadable();
+    }
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        final Context context = getActivity();
+
+        // Initialize the storage sizes that we can quickly calc.
+        StorageManager sm = context.getSystemService(StorageManager.class);
+        mVolume = sm.findVolumeById(VolumeInfo.ID_PRIVATE_INTERNAL);
+        if (!isVolumeValid()) {
+            getActivity().finish();
+            return;
+        }
+
+        final long sharedDataSize = mVolume.getPath().getTotalSpace();
+        mTotalSize = sm.getPrimaryStorageSize();
+        long systemSize = mTotalSize - sharedDataSize;
+
+        if (mTotalSize <= 0) {
+            mTotalSize = sharedDataSize;
+            systemSize = 0;
+        }
+
+        final long usedBytes = mTotalSize - mVolume.getPath().getFreeSpace();
+        mSummaryController.updateBytes(usedBytes, mTotalSize);
+
+        // Initialize the footer preference to go to the smart storage management.
+        final FooterPreference pref = mFooterPreferenceMixin.createFooterPreference();
+        pref.setTitle(R.string.storage_menu_manage);
+        pref.setFragment("com.android.settings.deletionhelper.AutomaticStorageManagerSettings");
+        pref.setIcon(R.drawable.ic_settings_storage);
+        pref.setEnabled(true);
+
+
+    }
+
     @Override
     public int getMetricsCategory() {
         return MetricsProto.MetricsEvent.SETTINGS_STORAGE_CATEGORY;
@@ -59,10 +112,25 @@
     @Override
     protected List<PreferenceController> getPreferenceControllers(Context context) {
         final List<PreferenceController> controllers = new ArrayList<>();
+        mSummaryController = new StorageSummaryDonutPreferenceController(context);
+        controllers.add(mSummaryController);
         controllers.add(new ManageStoragePreferenceController(context));
+        controllers.add(new StorageItemPreferenceController(context, "pref_photos_videos"));
+        controllers.add(new StorageItemPreferenceController(context, "pref_music_audio"));
+        controllers.add(new StorageItemPreferenceController(context, "pref_games"));
+        controllers.add(new StorageItemPreferenceController(context, "pref_other_apps"));
+        controllers.add(new StorageItemPreferenceController(context, "pref_system"));
+        controllers.add(new StorageItemPreferenceController(context, "pref_files"));
         return controllers;
     }
 
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+            Bundle savedInstanceState) {
+        View root = super.onCreateView(inflater, container, savedInstanceState);
+        // TODO: Add loader to load the storage sizes for the StorageItemPreferenceControllers.
+        return root;
+    }
     /**
      * For Search.
      */
diff --git a/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceAlternate.java b/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceAlternate.java
new file mode 100644
index 0000000..932a779
--- /dev/null
+++ b/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceAlternate.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2011 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.deviceinfo.storage;
+
+import android.content.Context;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceViewHolder;
+import android.text.format.Formatter;
+import android.util.AttributeSet;
+import android.view.View;
+
+import com.android.settings.R;
+
+public class StorageItemPreferenceAlternate extends Preference {
+    public StorageItemPreferenceAlternate(Context context) {
+        this(context, null);
+    }
+
+    public StorageItemPreferenceAlternate(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        setLayoutResource(R.layout.storage_item_alternate);
+        setSummary(R.string.memory_calculating_size);
+    }
+
+    public void setStorageSize(long size) {
+        setSummary(size == 0
+                ? String.valueOf(0)
+                : Formatter.formatFileSize(getContext(), size));
+    }
+}
\ No newline at end of file
diff --git a/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java b/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java
new file mode 100644
index 0000000..6a61072
--- /dev/null
+++ b/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2016 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.deviceinfo.storage;
+
+import android.content.Context;
+import android.support.v7.preference.Preference;
+
+import com.android.settings.core.PreferenceController;
+
+/**
+ * StorageItemPreferenceController handles the updating of a single storage preference line item.
+ */
+public class StorageItemPreferenceController extends PreferenceController {
+    private static final long NOT_YET_SET = -1;
+    private final String mKey;
+    private long mStorageSize;
+
+    public StorageItemPreferenceController(Context context, String key) {
+        super(context);
+        mKey = key;
+        mStorageSize = NOT_YET_SET;
+    }
+
+    @Override
+    public boolean isAvailable() {
+        return true;
+    }
+
+    @Override
+    public boolean handlePreferenceTreeClick(Preference preference) {
+        return false;
+    }
+
+    @Override
+    public String getPreferenceKey() {
+        return mKey;
+    }
+
+    @Override
+    public void updateState(Preference preference) {
+        if (preference == null || mStorageSize == NOT_YET_SET) {
+            return;
+        }
+
+        StorageItemPreferenceAlternate summary = (StorageItemPreferenceAlternate) preference;
+        summary.setStorageSize(mStorageSize);
+    }
+
+    /**
+     * Sets the amount of bytes used by this storage item.
+     */
+    public void setStorageSize(long size) {
+        mStorageSize = size;
+    }
+}
diff --git a/src/com/android/settings/deviceinfo/storage/StorageSummaryDonutPreference.java b/src/com/android/settings/deviceinfo/storage/StorageSummaryDonutPreference.java
new file mode 100644
index 0000000..d6fd354
--- /dev/null
+++ b/src/com/android/settings/deviceinfo/storage/StorageSummaryDonutPreference.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2016 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.deviceinfo.storage;
+
+import android.content.Context;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceViewHolder;
+import android.util.AttributeSet;
+import android.util.MathUtils;
+import android.view.View;
+import android.widget.ProgressBar;
+
+import com.android.settings.R;
+
+/**
+ * StorageSummaryDonutPreference is a preference which summarizes the used and remaining storage left
+ * on a given storage volume. It is visualized with a donut graphing the % used.
+ */
+public class StorageSummaryDonutPreference extends Preference {
+    private int mPercent = -1;
+
+    public StorageSummaryDonutPreference(Context context) {
+        this(context, null);
+    }
+
+    public StorageSummaryDonutPreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+
+        setLayoutResource(R.layout.storage_summary_donut);
+        setEnabled(false);
+    }
+
+    public void setPercent(long usedBytes, long totalBytes) {
+        if (totalBytes == 0) {
+            return;
+        }
+
+        mPercent = MathUtils.constrain((int) ((usedBytes * 100) / totalBytes),
+                (usedBytes > 0) ? 1 : 0, 100);
+    }
+
+    @Override
+    public void onBindViewHolder(PreferenceViewHolder view) {
+        // TODO: Replace the progress bar with a donut.
+        final ProgressBar progress = (ProgressBar) view.findViewById(android.R.id.progress);
+        if (mPercent != -1) {
+            progress.setVisibility(View.VISIBLE);
+            progress.setProgress(mPercent);
+            progress.setScaleY(7f);
+        } else {
+            progress.setVisibility(View.GONE);
+        }
+
+        super.onBindViewHolder(view);
+    }
+
+}
diff --git a/src/com/android/settings/deviceinfo/storage/StorageSummaryDonutPreferenceController.java b/src/com/android/settings/deviceinfo/storage/StorageSummaryDonutPreferenceController.java
new file mode 100644
index 0000000..45a81e8
--- /dev/null
+++ b/src/com/android/settings/deviceinfo/storage/StorageSummaryDonutPreferenceController.java
@@ -0,0 +1,73 @@
+package com.android.settings.deviceinfo.storage;
+
+import android.content.Context;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceGroup;
+import android.support.v7.preference.PreferenceScreen;
+import android.text.TextUtils;
+import android.text.format.Formatter;
+import android.util.Log;
+import android.widget.TextView;
+
+import com.android.settings.core.PreferenceController;
+import com.android.settings.R;
+
+/**
+ * StorgaeSummaryPreferenceController updates the donut storage summary preference to have the
+ * correct sizes showing.
+ */
+public class StorageSummaryDonutPreferenceController extends PreferenceController {
+    private long mUsedBytes;
+    private long mTotalBytes;
+
+    public StorageSummaryDonutPreferenceController(Context context) {
+        super(context);
+    }
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        Log.d("dhnishi", "Preference displayed!");
+        StorageSummaryDonutPreference summary = (StorageSummaryDonutPreference)
+                screen.findPreference("pref_summary");
+        summary.setEnabled(true);
+    }
+
+    @Override
+    public void updateState(Preference preference) {
+        super.updateState(preference);
+        StorageSummaryDonutPreference summary = (StorageSummaryDonutPreference) preference;
+        final Formatter.BytesResult result = Formatter.formatBytes(mContext.getResources(),
+                mUsedBytes, 0);
+        summary.setTitle(TextUtils.expandTemplate(mContext.getText(R.string.storage_size_large),
+                result.value, result.units));
+        summary.setSummary(mContext.getString(R.string.storage_volume_used,
+                Formatter.formatFileSize(mContext, mTotalBytes)));
+        summary.setEnabled(true);
+        summary.setPercent(mUsedBytes, mTotalBytes);
+    }
+
+    @Override
+    public boolean isAvailable() {
+        return true;
+    }
+
+    @Override
+    public boolean handlePreferenceTreeClick(Preference preference) {
+        return false;
+    }
+
+    @Override
+    public String getPreferenceKey() {
+        return "pref_summary";
+    }
+
+    /**
+     * Updates the state of the donut preference for the next update.
+     * @param used Total number of used bytes on the summarized volume.
+     * @param total Total number of bytes on the summarized volume.
+     */
+    public void updateBytes(long used, long total) {
+        mUsedBytes = used;
+        mTotalBytes = total;
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/StorageDashboardFragmentTest.java b/tests/robotests/src/com/android/settings/deviceinfo/StorageDashboardFragmentTest.java
new file mode 100644
index 0000000..5775aeb
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/deviceinfo/StorageDashboardFragmentTest.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2016 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.deviceinfo;
+
+import android.content.Context;
+import android.provider.SearchIndexableResource;
+
+import com.android.settings.SettingsRobolectricTestRunner;
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.FakeFeatureFactory;
+import com.android.settingslib.drawer.CategoryKey;
+
+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;
+import org.robolectric.shadows.ShadowApplication;
+
+import java.util.List;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.when;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class StorageDashboardFragmentTest {
+
+    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+    private Context mContext;
+
+    private StorageDashboardFragment mFragment;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        FakeFeatureFactory.setupForTest(mContext);
+        final FakeFeatureFactory factory =
+                (FakeFeatureFactory) FakeFeatureFactory.getFactory(mContext);
+        when(factory.dashboardFeatureProvider.isEnabled()).thenReturn(true);
+        mFragment = new StorageDashboardFragment();
+    }
+
+    @Test
+    public void testCategory_isConnectedDevice() {
+        assertThat(mFragment.getCategoryKey()).isEqualTo(CategoryKey.CATEGORY_STORAGE);
+    }
+
+    @Test
+    public void testSearchIndexProvider_shouldIndexResource() {
+        final List<SearchIndexableResource> indexRes =
+                StorageDashboardFragment.SEARCH_INDEX_DATA_PROVIDER.getXmlResourcesToIndex(
+                        ShadowApplication.getInstance().getApplicationContext(),
+                        true /* enabled */);
+
+        assertThat(indexRes).isNotNull();
+        assertThat(indexRes.get(0).xmlResId).isEqualTo(mFragment.getPreferenceScreenResId());
+    }
+}
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceAlternateTest.java b/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceAlternateTest.java
new file mode 100644
index 0000000..d2fc504
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceAlternateTest.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2016 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.deviceinfo.storage;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+
+import com.android.settings.R;
+import com.android.settings.SettingsRobolectricTestRunner;
+import com.android.settings.TestConfig;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class StorageItemPreferenceAlternateTest {
+    private Context mContext;
+
+    @Before
+    public void setUp() throws Exception {
+        mContext = RuntimeEnvironment.application;
+    }
+
+    @Test
+    public void testBeforeLoad() {
+        StorageItemPreferenceAlternate pref = new StorageItemPreferenceAlternate(mContext);
+        assertThat(((String) pref.getSummary())).isEqualTo(
+                mContext.getString(R.string.memory_calculating_size));
+    }
+
+    @Test
+    public void testAfterLoad() {
+        StorageItemPreferenceAlternate pref = new StorageItemPreferenceAlternate(mContext);
+        pref.setStorageSize(1024L);
+        assertThat(((String) pref.getSummary())).isEqualTo("1.00KB");
+    }
+}
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java
new file mode 100644
index 0000000..1862dd0
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceControllerTest.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2016 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.deviceinfo.storage;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceViewHolder;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.LinearLayout;
+
+import com.android.settings.SettingsRobolectricTestRunner;
+import com.android.settings.TestConfig;
+import com.android.settings.deviceinfo.StorageItemPreference;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class StorageItemPreferenceControllerTest {
+    private static final String KEY = "pref";
+    private Context mContext;
+    private StorageItemPreferenceController mController;
+    private PreferenceViewHolder mHolder;
+    private StorageItemPreferenceAlternate mPreference;
+
+    @Before
+    public void setUp() throws Exception {
+        mContext = RuntimeEnvironment.application;
+        mController = new StorageItemPreferenceController(mContext, KEY);
+        mPreference = new StorageItemPreferenceAlternate(mContext);
+
+        // Inflate the preference and the widget.
+        LayoutInflater inflater = LayoutInflater.from(mContext);
+        final View view = inflater.inflate(mPreference.getLayoutResource(),
+                new LinearLayout(mContext), false);
+
+        mHolder = new PreferenceViewHolder(view);
+    }
+
+    @Test
+    public void testGetKey() {
+        assertThat(mController.getPreferenceKey()).isEqualTo(KEY);
+    }
+
+    @Test
+    public void testUpdateStateWithInitialState() {
+        mController.updateState(mPreference);
+        assertThat(mPreference.getSummary().toString()).isEqualTo("Calculating…");
+    }
+
+    @Test
+    public void testPreferenceShouldUpdateAfterPopulatingData() {
+        mController.setStorageSize(1024L);
+        mController.updateState(mPreference);
+        assertThat(mPreference.getSummary().toString()).isEqualTo("1.00KB");
+
+    }
+}
\ No newline at end of file