Merge "Popup a dialog to display user IMEI information"
diff --git a/res/layout/app_preference_item.xml b/res/layout/app_preference_item.xml
index f13ced7..5653920 100755
--- a/res/layout/app_preference_item.xml
+++ b/res/layout/app_preference_item.xml
@@ -27,11 +27,10 @@
     android:paddingEnd="?android:attr/listPreferredItemPaddingEnd">
     <FrameLayout
         android:id="@+id/icon_frame"
-        style="@style/preference_icon_frame"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:gravity="start|center_vertical"
-        android:paddingEnd="12dp"
+        android:minWidth="56dp"
         android:paddingTop="4dp"
         android:paddingBottom="4dp">
         <android.support.v7.internal.widget.PreferenceImageView
diff --git a/res/layout/preference_small_icon.xml b/res/layout/preference_small_icon.xml
deleted file mode 100644
index e734b4b..0000000
--- a/res/layout/preference_small_icon.xml
+++ /dev/null
@@ -1,82 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  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.
-  -->
-
-<!-- Same as preference_material except that it uses a 24dp fixed size icon -->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-              xmlns:app="http://schemas.android.com/apk/res-auto"
-              android:layout_width="match_parent"
-              android:layout_height="wrap_content"
-              android:minHeight="?android:attr/listPreferredItemHeightSmall"
-              android:gravity="center_vertical"
-              android:paddingStart="?android:attr/listPreferredItemPaddingStart"
-              android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
-              android:background="?android:attr/selectableItemBackground"
-              android:clipToPadding="false"
-              android:focusable="true" >
-
-    <LinearLayout
-        android:id="@+id/icon_frame"
-        style="@style/preference_icon_frame"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:gravity="start|center_vertical"
-        android:orientation="horizontal"
-        android:paddingEnd="12dp"
-        android:paddingTop="4dp"
-        android:paddingBottom="4dp">
-        <android.support.v7.internal.widget.PreferenceImageView
-            android:id="@android:id/icon"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            app:maxWidth="24dp"
-            app:maxHeight="24dp" />
-    </LinearLayout>
-
-    <RelativeLayout
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_weight="1"
-        android:paddingTop="16dp"
-        android:paddingBottom="16dp">
-
-        <TextView android:id="@android:id/title"
-                  android:layout_width="wrap_content"
-                  android:layout_height="wrap_content"
-                  android:singleLine="true"
-                  android:textAppearance="?android:attr/textAppearanceListItem"
-                  android:ellipsize="marquee" />
-
-        <TextView android:id="@android:id/summary"
-                  android:layout_width="wrap_content"
-                  android:layout_height="wrap_content"
-                  android:layout_below="@android:id/title"
-                  android:layout_alignStart="@android:id/title"
-                  android:textAppearance="?android:attr/textAppearanceListItemSecondary"
-                  android:textColor="?android:attr/textColorSecondary"
-                  android:maxLines="10" />
-
-    </RelativeLayout>
-
-    <!-- Preference should place its actual preference widget here. -->
-    <LinearLayout android:id="@android:id/widget_frame"
-                  android:layout_width="wrap_content"
-                  android:layout_height="match_parent"
-                  android:gravity="end|center_vertical"
-                  android:paddingStart="16dp"
-                  android:orientation="vertical" />
-
-</LinearLayout>
\ No newline at end of file
diff --git a/res/layout/storage_item.xml b/res/layout/storage_item.xml
index 4b14bb3..ba1c697 100644
--- a/res/layout/storage_item.xml
+++ b/res/layout/storage_item.xml
@@ -36,12 +36,11 @@
 
         <LinearLayout
             android:id="@+id/icon_frame"
-            style="@style/preference_icon_frame"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:gravity="start|center_vertical"
+            android:minWidth="56dp"
             android:orientation="horizontal"
-            android:paddingEnd="12dp"
             android:paddingTop="4dp"
             android:paddingBottom="4dp">
             <com.android.internal.widget.PreferenceImageView
diff --git a/res/layout/storage_volume.xml b/res/layout/storage_volume.xml
index 39a6f85..ca368b9 100644
--- a/res/layout/storage_volume.xml
+++ b/res/layout/storage_volume.xml
@@ -26,12 +26,11 @@
 
     <LinearLayout
         android:id="@+id/icon_frame"
-        style="@style/preference_icon_frame"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:gravity="start|center_vertical"
+        android:minWidth="56dp"
         android:orientation="horizontal"
-        android:paddingEnd="12dp"
         android:paddingTop="4dp"
         android:paddingBottom="4dp">
         <com.android.internal.widget.PreferenceImageView
diff --git a/res/values/strings.xml b/res/values/strings.xml
index fb79df5..b5108e6 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -6479,7 +6479,7 @@
     <string name="dashboard_suggestion_condition_footer_content_description">Collapse</string>
 
     <!-- Title for setting tile leading to network and Internet settings [CHAR LIMIT=40]-->
-    <string name="network_dashboard_title">Network &amp; Internet</string>
+    <string name="network_dashboard_title">Network &amp; internet</string>
     <!-- Summary for Network and Internet settings, explaining it contains mobile network setting [CHAR LIMIT=NONE]-->
     <string name="network_dashboard_summary_mobile">mobile</string>
     <!-- Summary for Network and Internet settings, explaining it contains network data usage setting [CHAR LIMIT=NONE]-->
diff --git a/res/xml/color_mode_settings.xml b/res/xml/color_mode_settings.xml
new file mode 100644
index 0000000..b7f58d2
--- /dev/null
+++ b/res/xml/color_mode_settings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  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.
+  -->
+
+<PreferenceScreen
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:key="color_mode_settings_screen"
+    android:title="@string/color_mode_title" />
diff --git a/res/xml/security_settings_misc.xml b/res/xml/security_settings_misc.xml
index ee2c534..6a71033 100644
--- a/res/xml/security_settings_misc.xml
+++ b/res/xml/security_settings_misc.xml
@@ -64,7 +64,7 @@
         android:key="encryption_and_credential"
         android:title="@string/encryption_and_credential_settings_title"
         android:summary="@string/encryption_and_credential_settings_summary"
-        android:fragment="com.android.settings.EncryptionAndCredential"/>
+        android:fragment="com.android.settings.security.EncryptionAndCredential"/>
 
     <Preference android:key="manage_trust_agents"
         android:title="@string/manage_trust_agents"
diff --git a/src/com/android/settings/dashboard/DashboardFragment.java b/src/com/android/settings/dashboard/DashboardFragment.java
index e7f36e1..6796c26 100644
--- a/src/com/android/settings/dashboard/DashboardFragment.java
+++ b/src/com/android/settings/dashboard/DashboardFragment.java
@@ -183,6 +183,9 @@
         }
     }
 
+    @Override
+    protected abstract int getPreferenceScreenResId();
+
     protected <T extends AbstractPreferenceController> T getPreferenceController(Class<T> clazz) {
         AbstractPreferenceController controller = mPreferenceControllers.get(clazz);
         return (T) controller;
diff --git a/src/com/android/settings/dashboard/DashboardSummary.java b/src/com/android/settings/dashboard/DashboardSummary.java
index 30a2fce..8f66b67 100644
--- a/src/com/android/settings/dashboard/DashboardSummary.java
+++ b/src/com/android/settings/dashboard/DashboardSummary.java
@@ -17,12 +17,14 @@
 package com.android.settings.dashboard;
 
 import android.app.Activity;
+import android.app.LoaderManager;
 import android.content.Context;
 import android.os.AsyncTask;
 import android.os.Bundle;
 import android.os.Handler;
 import android.service.settings.suggestions.Suggestion;
 import android.support.annotation.VisibleForTesting;
+import android.support.annotation.WorkerThread;
 import android.support.v7.widget.LinearLayoutManager;
 import android.util.Log;
 import android.view.LayoutInflater;
@@ -49,6 +51,7 @@
 import com.android.settingslib.drawer.Tile;
 import com.android.settingslib.suggestions.SuggestionList;
 import com.android.settingslib.suggestions.SuggestionParser;
+import com.android.settingslib.utils.ThreadUtils;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -96,6 +99,14 @@
     }
 
     @Override
+    public LoaderManager getLoaderManager() {
+        if (!isAdded()) {
+            return null;
+        }
+        return super.getLoaderManager();
+    }
+
+    @Override
     public void onCreate(Bundle savedInstanceState) {
         long startTime = System.currentTimeMillis();
         super.onCreate(savedInstanceState);
@@ -173,12 +184,6 @@
     }
 
     @Override
-    public View onCreateView(LayoutInflater inflater, ViewGroup container,
-            Bundle savedInstanceState) {
-        return inflater.inflate(R.layout.dashboard, container, false);
-    }
-
-    @Override
     public void onSaveInstanceState(Bundle outState) {
         super.onSaveInstanceState(outState);
         if (mLayoutManager == null) return;
@@ -189,9 +194,10 @@
     }
 
     @Override
-    public void onViewCreated(View view, Bundle bundle) {
+    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bundle) {
         long startTime = System.currentTimeMillis();
-        mDashboard = view.findViewById(R.id.dashboard_container);
+        final View root = inflater.inflate(R.layout.dashboard, container, false);
+        mDashboard = root.findViewById(R.id.dashboard_container);
         mLayoutManager = new LinearLayoutManager(getContext());
         mLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
         if (bundle != null) {
@@ -209,19 +215,19 @@
         mSummaryLoader.setSummaryConsumer(mAdapter);
         ActionBarShadowController.attachToRecyclerView(
                 getActivity().findViewById(R.id.search_bar_container), getLifecycle(), mDashboard);
-
+        rebuildUI();
         if (DEBUG_TIMING) {
-            Log.d(TAG, "onViewCreated took "
+            Log.d(TAG, "onCreateView took "
                     + (System.currentTimeMillis() - startTime) + " ms");
         }
-        rebuildUI();
+        return root;
     }
 
     @VisibleForTesting
     void rebuildUI() {
         if (!mSuggestionFeatureProvider.isSuggestionEnabled(getContext())) {
             Log.d(TAG, "Suggestion v1 feature is disabled, skipping suggestion v1");
-            updateCategory();
+            ThreadUtils.postOnBackgroundThread(() -> updateCategory());
         } else {
             new SuggestionLoader().execute();
             // Set categories on their own if loading suggestions takes too long.
@@ -331,11 +337,12 @@
         }
     }
 
+    @WorkerThread
     void updateCategory() {
         final DashboardCategory category = mDashboardFeatureProvider.getTilesForCategory(
                 CategoryKey.CATEGORY_HOMEPAGE);
         mSummaryLoader.updateSummaryToCache(category);
-        mAdapter.setCategory(category);
+        ThreadUtils.postOnMainThread(() -> mAdapter.setCategory(category));
     }
 
     /**
diff --git a/src/com/android/settings/dashboard/SummaryLoader.java b/src/com/android/settings/dashboard/SummaryLoader.java
index 5816bba8..fe55be8 100644
--- a/src/com/android/settings/dashboard/SummaryLoader.java
+++ b/src/com/android/settings/dashboard/SummaryLoader.java
@@ -60,23 +60,6 @@
     private boolean mWorkerListening;
     private ArraySet<BroadcastReceiver> mReceivers = new ArraySet<>();
 
-    public SummaryLoader(Activity activity, List<DashboardCategory> categories) {
-        mDashboardFeatureProvider = FeatureFactory.getFactory(activity)
-                .getDashboardFeatureProvider(activity);
-        mCategoryKey = null;
-        mWorkerThread = new HandlerThread("SummaryLoader", Process.THREAD_PRIORITY_BACKGROUND);
-        mWorkerThread.start();
-        mWorker = new Worker(mWorkerThread.getLooper());
-        mActivity = activity;
-        for (int i = 0; i < categories.size(); i++) {
-            List<Tile> tiles = categories.get(i).tiles;
-            for (int j = 0; j < tiles.size(); j++) {
-                Tile tile = tiles.get(j);
-                mWorker.obtainMessage(Worker.MSG_GET_PROVIDER, tile).sendToTarget();
-            }
-        }
-    }
-
     public SummaryLoader(Activity activity, String categoryKey) {
         mDashboardFeatureProvider = FeatureFactory.getFactory(activity)
                 .getDashboardFeatureProvider(activity);
@@ -85,17 +68,6 @@
         mWorkerThread.start();
         mWorker = new Worker(mWorkerThread.getLooper());
         mActivity = activity;
-
-        final DashboardCategory category =
-                mDashboardFeatureProvider.getTilesForCategory(categoryKey);
-        if (category == null || category.tiles == null) {
-            return;
-        }
-
-        List<Tile> tiles = category.tiles;
-        for (Tile tile : tiles) {
-            mWorker.obtainMessage(Worker.MSG_GET_PROVIDER, tile).sendToTarget();
-        }
     }
 
     public void release() {
@@ -153,15 +125,32 @@
      * Only call from the main thread.
      */
     public void setListening(boolean listening) {
-        if (mListening == listening) return;
+        if (mListening == listening) {
+            return;
+        }
         mListening = listening;
         // Unregister listeners immediately.
         for (int i = 0; i < mReceivers.size(); i++) {
             mActivity.unregisterReceiver(mReceivers.valueAt(i));
         }
         mReceivers.clear();
+
         mWorker.removeMessages(Worker.MSG_SET_LISTENING);
-        mWorker.obtainMessage(Worker.MSG_SET_LISTENING, listening ? 1 : 0, 0).sendToTarget();
+        if (!listening) {
+            // Stop listen
+            mWorker.obtainMessage(Worker.MSG_SET_LISTENING, 0 /* listening */).sendToTarget();
+        } else {
+            // Start listen
+            if (mSummaryProviderMap.isEmpty()) {
+                // Category not initialized yet, init before starting to listen
+                if (!mWorker.hasMessages(Worker.MSG_GET_CATEGORY_TILES_AND_SET_LISTENING)) {
+                    mWorker.sendEmptyMessage(Worker.MSG_GET_CATEGORY_TILES_AND_SET_LISTENING);
+                }
+            } else {
+                // Category already initialized, start listening immediately
+                mWorker.obtainMessage(Worker.MSG_SET_LISTENING, 1 /* listening */).sendToTarget();
+            }
+        }
     }
 
     private SummaryProvider getSummaryProvider(Tile tile) {
@@ -236,9 +225,13 @@
     }
 
     private synchronized void setListeningW(boolean listening) {
-        if (mWorkerListening == listening) return;
+        if (mWorkerListening == listening) {
+            return;
+        }
         mWorkerListening = listening;
-        if (DEBUG) Log.d(TAG, "Listening " + listening);
+        if (DEBUG) {
+            Log.d(TAG, "Listening " + listening);
+        }
         for (SummaryProvider p : mSummaryProviderMap.keySet()) {
             try {
                 p.setListening(listening);
@@ -271,7 +264,6 @@
     }
 
 
-
     public interface SummaryProvider {
         void setListening(boolean listening);
     }
@@ -285,8 +277,9 @@
     }
 
     private class Worker extends Handler {
-        private static final int MSG_GET_PROVIDER = 1;
-        private static final int MSG_SET_LISTENING = 2;
+        private static final int MSG_GET_CATEGORY_TILES_AND_SET_LISTENING = 1;
+        private static final int MSG_GET_PROVIDER = 2;
+        private static final int MSG_SET_LISTENING = 3;
 
         public Worker(Looper looper) {
             super(looper);
@@ -295,6 +288,18 @@
         @Override
         public void handleMessage(Message msg) {
             switch (msg.what) {
+                case MSG_GET_CATEGORY_TILES_AND_SET_LISTENING:
+                    final DashboardCategory category =
+                            mDashboardFeatureProvider.getTilesForCategory(mCategoryKey);
+                    if (category == null || category.tiles == null) {
+                        return;
+                    }
+                    final List<Tile> tiles = category.tiles;
+                    for (Tile tile : tiles) {
+                        makeProviderW(tile);
+                    }
+                    setListeningW(true);
+                    break;
                 case MSG_GET_PROVIDER:
                     Tile tile = (Tile) msg.obj;
                     makeProviderW(tile);
diff --git a/src/com/android/settings/dashboard/suggestions/SuggestionControllerMixin.java b/src/com/android/settings/dashboard/suggestions/SuggestionControllerMixin.java
index 7c2226d..e77881e 100644
--- a/src/com/android/settings/dashboard/suggestions/SuggestionControllerMixin.java
+++ b/src/com/android/settings/dashboard/suggestions/SuggestionControllerMixin.java
@@ -21,6 +21,7 @@
 import android.content.Loader;
 import android.os.Bundle;
 import android.service.settings.suggestions.Suggestion;
+import android.support.annotation.Nullable;
 import android.util.Log;
 
 import com.android.settings.overlay.FeatureFactory;
@@ -44,8 +45,10 @@
         void onSuggestionReady(List<Suggestion> data);
 
         /**
-         * Returns {@link LoaderManager} associated with the host.
+         * Returns {@link LoaderManager} associated with the host. If host is not attached to
+         * activity then return null.
          */
+        @Nullable
         LoaderManager getLoaderManager();
     }
 
@@ -82,8 +85,11 @@
 
     @Override
     public void onServiceConnected() {
-        mHost.getLoaderManager().restartLoader(SuggestionLoader.LOADER_ID_SUGGESTIONS,
-                null /* args */, this /* callback */);
+        final LoaderManager loaderManager = mHost.getLoaderManager();
+        if (loaderManager != null) {
+            loaderManager.restartLoader(SuggestionLoader.LOADER_ID_SUGGESTIONS,
+                    null /* args */, this /* callback */);
+        }
     }
 
     @Override
diff --git a/src/com/android/settings/display/ColorModePreferenceFragment.java b/src/com/android/settings/display/ColorModePreferenceFragment.java
index 07cf82e..9f18fd8 100644
--- a/src/com/android/settings/display/ColorModePreferenceFragment.java
+++ b/src/com/android/settings/display/ColorModePreferenceFragment.java
@@ -45,6 +45,11 @@
     }
 
     @Override
+    protected int getPreferenceScreenResId() {
+        return R.xml.color_mode_settings;
+    }
+
+    @Override
     protected List<? extends CandidateInfo> getCandidates() {
         Context c = getContext();
         return Arrays.asList(
diff --git a/src/com/android/settings/search/SearchIndexableResources.java b/src/com/android/settings/search/SearchIndexableResources.java
index cb39970..69b2f9f 100644
--- a/src/com/android/settings/search/SearchIndexableResources.java
+++ b/src/com/android/settings/search/SearchIndexableResources.java
@@ -23,7 +23,6 @@
 import com.android.settings.DateTimeSettings;
 import com.android.settings.DeviceInfoSettings;
 import com.android.settings.DisplaySettings;
-import com.android.settings.EncryptionAndCredential;
 import com.android.settings.LegalSettings;
 import com.android.settings.ScreenPinningSettings;
 import com.android.settings.SecuritySettings;
@@ -75,6 +74,7 @@
 import com.android.settings.notification.ZenModeBehaviorSettings;
 import com.android.settings.notification.ZenModeSettings;
 import com.android.settings.print.PrintSettingsFragment;
+import com.android.settings.security.EncryptionAndCredential;
 import com.android.settings.security.LockscreenDashboardFragment;
 import com.android.settings.sim.SimSettings;
 import com.android.settings.support.SupportDashboardActivity;
diff --git a/src/com/android/settings/EncryptionAndCredential.java b/src/com/android/settings/security/EncryptionAndCredential.java
similarity index 93%
rename from src/com/android/settings/EncryptionAndCredential.java
rename to src/com/android/settings/security/EncryptionAndCredential.java
index 4892f7e..0972e3e 100644
--- a/src/com/android/settings/EncryptionAndCredential.java
+++ b/src/com/android/settings/security/EncryptionAndCredential.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007 The Android Open Source Project
+ * 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.
@@ -14,13 +14,11 @@
  * limitations under the License.
  */
 
-package com.android.settings;
+package com.android.settings.security;
 
-import android.app.Activity;
 import android.app.admin.DevicePolicyManager;
 import android.content.Context;
 import android.content.Intent;
-import android.os.Bundle;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.provider.SearchIndexableResource;
@@ -30,11 +28,12 @@
 
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.widget.LockPatternUtils;
+import com.android.settings.R;
 import com.android.settings.dashboard.DashboardFragment;
 import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settings.search.Indexable;
 import com.android.settingslib.RestrictedLockUtils;
 import com.android.settingslib.RestrictedPreference;
+import com.android.settingslib.core.AbstractPreferenceController;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -43,7 +42,7 @@
  * Encryption and Credential settings.
  * TODO: Extends this from {@link DashboardFragment} instead
  */
-public class EncryptionAndCredential extends SettingsPreferenceFragment implements Indexable {
+public class EncryptionAndCredential extends DashboardFragment {
 
     private static final String TAG = "EncryptionAndCredential";
 
@@ -69,12 +68,19 @@
     }
 
     @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
+    protected String getLogTag() {
+        return TAG;
+    }
 
-        final Activity activity = getActivity();
+    @Override
+    protected List<AbstractPreferenceController> getPreferenceControllers(Context context) {
+        mUm = (UserManager) context.getSystemService(Context.USER_SERVICE);
+        return null;
+    }
 
-        mUm = UserManager.get(activity);
+    @Override
+    protected int getPreferenceScreenResId() {
+        return 0;
     }
 
     /**
diff --git a/src/com/android/settings/widget/RadioButtonPickerFragment.java b/src/com/android/settings/widget/RadioButtonPickerFragment.java
index 7489a77..c768909 100644
--- a/src/com/android/settings/widget/RadioButtonPickerFragment.java
+++ b/src/com/android/settings/widget/RadioButtonPickerFragment.java
@@ -83,6 +83,9 @@
     }
 
     @Override
+    protected abstract int getPreferenceScreenResId();
+
+    @Override
     public void onRadioButtonClicked(RadioButtonPreference selected) {
         final String selectedKey = selected.getKey();
         onRadioButtonConfirmed(selectedKey);
diff --git a/tests/robotests/README.md b/tests/robotests/README.md
new file mode 100644
index 0000000..648f1af
--- /dev/null
+++ b/tests/robotests/README.md
@@ -0,0 +1,24 @@
+# Running Settings Robolectric tests
+
+
+## The full suite
+```
+$ croot
+$ make RunSettingsRoboTests
+```
+
+## Running a single test class
+
+```
+$ croot
+$ make RunSettingsRoboTests ROBOTEST_FILTER=<ClassName>
+```
+
+For example:
+
+```
+make RunSettingsRoboTests ROBOTEST_FILTER=CodeInspectionTest
+```
+
+You can also use partial class name in ROBOTEST_FILTER. If the partial class name matches
+multiple file names, all of them will be executed.
diff --git a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultAppPickerFragmentTest.java b/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultAppPickerFragmentTest.java
index 3621edd..42a6225 100644
--- a/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultAppPickerFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/applications/defaultapps/DefaultAppPickerFragmentTest.java
@@ -115,6 +115,11 @@
         }
 
         @Override
+        protected int getPreferenceScreenResId() {
+            return 0;
+        }
+
+        @Override
         protected List<DefaultAppInfo> getCandidates() {
             return new ArrayList<>();
         }
diff --git a/tests/robotests/src/com/android/settings/dashboard/SummaryLoaderTest.java b/tests/robotests/src/com/android/settings/dashboard/SummaryLoaderTest.java
index 146be9c..44b6139 100644
--- a/tests/robotests/src/com/android/settings/dashboard/SummaryLoaderTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/SummaryLoaderTest.java
@@ -16,6 +16,10 @@
 
 package com.android.settings.dashboard;
 
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
+
 import android.app.Activity;
 import android.content.Context;
 import android.content.Intent;
@@ -23,6 +27,7 @@
 import com.android.settings.TestConfig;
 import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.drawer.CategoryKey;
 import com.android.settingslib.drawer.DashboardCategory;
 import com.android.settingslib.drawer.Tile;
 
@@ -35,12 +40,6 @@
 import org.robolectric.Robolectric;
 import org.robolectric.annotation.Config;
 
-import java.util.ArrayList;
-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 SummaryLoaderTest {
@@ -65,14 +64,14 @@
         mCallbackInvoked = false;
 
         final Activity activity = Robolectric.buildActivity(Activity.class).get();
-        final List<DashboardCategory> categories = new ArrayList<>();
-        mSummaryLoader = new SummaryLoader(activity, categories);
-        mSummaryLoader.setSummaryConsumer(new SummaryLoader.SummaryConsumer() {
-            @Override
-            public void notifySummaryChanged(Tile tile) {
-                mCallbackInvoked = true;
-            }
-        });
+
+        mSummaryLoader = new SummaryLoader(activity, CategoryKey.CATEGORY_HOMEPAGE);
+        mSummaryLoader.setSummaryConsumer(tile -> mCallbackInvoked = true);
+    }
+
+    @Test
+    public void newInstance_shouldNotLoadCategory() {
+        verifyZeroInteractions(mFeatureFactory.dashboardFeatureProvider);
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionControllerMixinTest.java b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionControllerMixinTest.java
index 6dfd67d..89c45b4 100644
--- a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionControllerMixinTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionControllerMixinTest.java
@@ -23,7 +23,6 @@
 
 import android.app.LoaderManager;
 import android.content.Context;
-import android.database.MatrixCursor;
 
 import com.android.settings.TestConfig;
 import com.android.settings.testutils.FakeFeatureFactory;
@@ -88,4 +87,14 @@
         verify(loaderManager).restartLoader(SuggestionLoader.LOADER_ID_SUGGESTIONS,
                 null /* args */, mMixin /* callback */);
     }
+
+    @Test
+    public void onServiceConnected_hostNotAttached_shouldDoNothing() {
+        when(mHost.getLoaderManager()).thenReturn(null);
+
+        mMixin = new SuggestionControllerMixin(mContext, mHost, mLifecycle);
+        mMixin.onServiceConnected();
+
+        verify(mHost).getLoaderManager();
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/display/ColorModePreferenceFragmentTest.java b/tests/robotests/src/com/android/settings/display/ColorModePreferenceFragmentTest.java
index 9ee79ff..fb9bb9f 100644
--- a/tests/robotests/src/com/android/settings/display/ColorModePreferenceFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/display/ColorModePreferenceFragmentTest.java
@@ -16,11 +16,18 @@
 package com.android.settings.display;
 
 import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.os.Bundle;
+
 import com.android.internal.app.NightDisplayController;
 import com.android.internal.logging.nano.MetricsProto;
+import com.android.settings.R;
 import com.android.settings.TestConfig;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.testutils.shadow.SettingsShadowSystemProperties;
@@ -111,20 +118,31 @@
     @Test
     public void setKey_natural() {
         mFragment.setDefaultKey(ColorModePreferenceFragment.KEY_COLOR_MODE_NATURAL);
-        Mockito.verify(mController).setColorMode(NightDisplayController.COLOR_MODE_NATURAL);
+        verify(mController).setColorMode(NightDisplayController.COLOR_MODE_NATURAL);
     }
 
     @Config(shadows = {SettingsShadowSystemProperties.class})
     @Test
     public void setKey_boosted() {
         mFragment.setDefaultKey(ColorModePreferenceFragment.KEY_COLOR_MODE_BOOSTED);
-        Mockito.verify(mController).setColorMode(NightDisplayController.COLOR_MODE_BOOSTED);
+        verify(mController).setColorMode(NightDisplayController.COLOR_MODE_BOOSTED);
     }
 
     @Config(shadows = {SettingsShadowSystemProperties.class})
     @Test
     public void setKey_saturated() {
         mFragment.setDefaultKey(ColorModePreferenceFragment.KEY_COLOR_MODE_SATURATED);
-        Mockito.verify(mController).setColorMode(NightDisplayController.COLOR_MODE_SATURATED);
+        verify(mController).setColorMode(NightDisplayController.COLOR_MODE_SATURATED);
     }
+
+    @Test
+    public void onCreatePreferences_useNewTitle_shouldAddColorModePreferences() {
+        doNothing().when(mFragment).addPreferencesFromResource(anyInt());
+        doNothing().when(mFragment).updateCandidates();
+
+        mFragment.onCreatePreferences(Bundle.EMPTY, null /* rootKey */);
+
+        verify(mFragment).addPreferencesFromResource(R.xml.color_mode_settings);
+    }
+
 }
diff --git a/tests/robotests/src/com/android/settings/EncryptionAndCredentialTest.java b/tests/robotests/src/com/android/settings/security/EncryptionAndCredentialTest.java
similarity index 95%
rename from tests/robotests/src/com/android/settings/EncryptionAndCredentialTest.java
rename to tests/robotests/src/com/android/settings/security/EncryptionAndCredentialTest.java
index 7a3875e..c87c964 100644
--- a/tests/robotests/src/com/android/settings/EncryptionAndCredentialTest.java
+++ b/tests/robotests/src/com/android/settings/security/EncryptionAndCredentialTest.java
@@ -11,14 +11,14 @@
  * 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
+ * limitations under the License.
  */
 
-package com.android.settings;
+package com.android.settings.security;
 
 import static android.app.admin.DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE;
 import static android.app.admin.DevicePolicyManager.ENCRYPTION_STATUS_INACTIVE;
-import static com.android.settings.EncryptionAndCredential.SEARCH_INDEX_DATA_PROVIDER;
+import static com.android.settings.security.EncryptionAndCredential.SEARCH_INDEX_DATA_PROVIDER;
 import static com.google.common.truth.Truth.assertThat;
 import static org.mockito.Mockito.when;
 
@@ -28,6 +28,8 @@
 import android.provider.SearchIndexableResource;
 
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.settings.R;
+import com.android.settings.TestConfig;
 import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 
diff --git a/tests/robotests/src/com/android/settings/widget/RadioButtonPickerFragmentTest.java b/tests/robotests/src/com/android/settings/widget/RadioButtonPickerFragmentTest.java
index 40d73eb..8ca68ae 100644
--- a/tests/robotests/src/com/android/settings/widget/RadioButtonPickerFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/widget/RadioButtonPickerFragmentTest.java
@@ -114,6 +114,11 @@
         }
 
         @Override
+        protected int getPreferenceScreenResId() {
+            return 0;
+        }
+
+        @Override
         protected List<DefaultAppInfo> getCandidates() {
             return new ArrayList<>();
         }