Merge "Fixed spans getting stripped from disclaimer"
diff --git a/res/layout/display.xml b/res/layout/display.xml
deleted file mode 100644
index f35730b..0000000
--- a/res/layout/display.xml
+++ /dev/null
@@ -1,49 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* //device/apps/Settings/res/layout/display.xml
-**
-** Copyright 2007, 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" style="@style/info_layout">        
-    <LinearLayout style="@style/entry_layout"
-        android:orientation="vertical">
-
-        <TextView
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:text="@string/display_font_size_label" />
-
-        <Spinner android:id="@+id/fontSize"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content">
-        </Spinner>
-
-        <TextView
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:text="@string/display_preview_label" />
-
-        <TextView android:id="@+id/preview"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content" />
-
-        <Button android:id="@+id/save"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content" />
-    </LinearLayout>
-
-</LinearLayout>
diff --git a/res/layout/support_fragment.xml b/res/layout/support_fragment.xml
index 913e607..7c79a63 100644
--- a/res/layout/support_fragment.xml
+++ b/res/layout/support_fragment.xml
@@ -15,13 +15,18 @@
      limitations under the License.
 -->
 
-<android.support.v7.widget.RecyclerView
+<FrameLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/support_items"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:clipChildren="false"
     android:clipToPadding="false"
     android:focusable="false"
     android:paddingStart="@dimen/dashboard_padding_start"
-    android:paddingEnd="@dimen/dashboard_padding_end"/>
\ No newline at end of file
+    android:paddingEnd="@dimen/dashboard_padding_end">
+    <android.support.v7.widget.RecyclerView
+        android:id="@+id/support_items"
+        android:layout_height="match_parent"
+        android:layout_width="match_parent"
+        android:background="@color/card_background"/>
+</FrameLayout>
diff --git a/res/values/config.xml b/res/values/config.xml
index 75d8697..7513cef 100755
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -58,4 +58,7 @@
     <!-- If the Storage Manager settings are enabled. -->
     <bool name="config_storage_manager_settings_enabled">false</bool>
 
+    <!-- When true show double-tap gesture setting. -->
+    <bool name="config_gesture_double_tap_settings_enabled">false</bool>
+
 </resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 7406577..415d96a 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -146,13 +146,6 @@
     <!-- Summary of font size setting screen. [CHAR LIMIT=NONE] -->
     <string name="font_size_summary">Make the text on screen smaller or larger.</string>
 
-    <!-- choice for the font size spinner -->
-    <string name="small_font">Small</string>
-    <!-- choice for the font size spinner -->
-    <string name="medium_font">Medium</string>
-    <!-- choice for the font size spinner -->
-    <string name="large_font">Large</string>
-
     <!-- Description for the button that makes interface elements smaller. [CHAR_LIMIT=NONE] -->
     <string name="font_size_make_smaller_desc">Make smaller</string>
     <!-- Description for the button that makes interface elements larger. [CHAR_LIMIT=NONE] -->
@@ -359,11 +352,6 @@
     <!-- The title of the activity to pick a time zone. -->
     <string name="choose_timezone">Choose time zone</string>
 
-    <!-- Label of preview text when tweaking font size -->
-    <string name="display_preview_label">Preview:</string>
-    <!-- Label for chosen font size -->
-    <string name="display_font_size_label">Font size:</string>
-
     <!-- Used for diagnostic screens, precise translation is not necessary -->
     <string name="intent_sender_data_label"><xliff:g id="data">Data:</xliff:g></string>
     <!-- Used for diagnostic screens, precise translation is not necessary -->
@@ -1620,7 +1608,7 @@
     <!-- Preference title for option to automatically switch away from bad wifi networks [CHAR LIMIT=60]-->
     <string name="wifi_cellular_data_fallback_title">Switch to cellular data automatically</string>
     <!-- Preference summary for option to automatically switch away from bad wifi networks [CHAR LIMIT=None]-->
-    <string name="wifi_cellular_data_fallback_summary">Use cellular data when Wi\u2011Fi loses Internet access. Data usage may apply.</string>
+    <string name="wifi_cellular_data_fallback_summary">Use cellular data when Wi\u2011Fi has no Internet access. Data usage may apply.</string>
     <!-- Action bar text message to manually add a wifi network [CHAR LIMIT=20]-->
     <string name="wifi_add_network">Add network</string>
     <!-- Header for the list of wifi networks-->
diff --git a/src/com/android/settings/DateTimeSettings.java b/src/com/android/settings/DateTimeSettings.java
index 1fed189..f33ca85 100644
--- a/src/com/android/settings/DateTimeSettings.java
+++ b/src/com/android/settings/DateTimeSettings.java
@@ -168,7 +168,8 @@
         Date dummyDate = mDummyDate.getTime();
         mDatePref.setSummary(DateFormat.getLongDateFormat(context).format(now.getTime()));
         mTimePref.setSummary(DateFormat.getTimeFormat(getActivity()).format(now.getTime()));
-        mTimeZone.setSummary(ZoneGetter.getTimeZoneOffsetAndName(now.getTimeZone(), now.getTime()));
+        mTimeZone.setSummary(ZoneGetter.getTimeZoneOffsetAndName(context,
+                now.getTimeZone(), now.getTime()));
         mTime24Pref.setSummary(DateFormat.getTimeFormat(getActivity()).format(dummyDate));
     }
 
@@ -385,7 +386,7 @@
         public void setListening(boolean listening) {
             if (listening) {
                 final Calendar now = Calendar.getInstance();
-                mSummaryLoader.setSummary(this, ZoneGetter.getTimeZoneOffsetAndName(
+                mSummaryLoader.setSummary(this, ZoneGetter.getTimeZoneOffsetAndName(mContext,
                         now.getTimeZone(), now.getTime()));
             }
         }
diff --git a/src/com/android/settings/Display.java b/src/com/android/settings/Display.java
deleted file mode 100644
index 14e7b04..0000000
--- a/src/com/android/settings/Display.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright (C) 2006 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;
-
-import android.app.Activity;
-import android.content.ContentResolver;
-import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.os.Bundle;
-import android.provider.Settings;
-import android.util.DisplayMetrics;
-import android.util.TypedValue;
-import android.view.View;
-import android.widget.ArrayAdapter;
-import android.widget.Button;
-import android.widget.Spinner;
-import android.widget.TextView;
-
-
-public class Display extends Activity implements View.OnClickListener {
-    @Override
-    public void onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-
-        setContentView(R.layout.display);
-
-        mFontSize = (Spinner) findViewById(R.id.fontSize);
-        mFontSize.setOnItemSelectedListener(mFontSizeChanged);
-        String[] states = new String[3];
-        Resources r = getResources();
-        states[0] = r.getString(R.string.small_font);
-        states[1] = r.getString(R.string.medium_font);
-        states[2] = r.getString(R.string.large_font);
-        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
-                android.R.layout.simple_spinner_item, states);
-        adapter.setDropDownViewResource(
-                android.R.layout.simple_spinner_dropdown_item);
-        mFontSize.setAdapter(adapter);
-
-        mPreview = (TextView) findViewById(R.id.preview);
-        mPreview.setText(r.getText(R.string.font_size_preview_text));
-
-        Button save = (Button) findViewById(R.id.save);
-        save.setText(r.getText(R.string.font_size_save));
-        save.setOnClickListener(this);
-
-        mTextSizeTyped = new TypedValue();
-        TypedArray styledAttributes = 
-            obtainStyledAttributes(android.R.styleable.TextView);
-        styledAttributes.getValue(android.R.styleable.TextView_textSize,
-                mTextSizeTyped);
-
-        DisplayMetrics metrics = getResources().getDisplayMetrics();
-        mDisplayMetrics = new DisplayMetrics();
-        mDisplayMetrics.density = metrics.density;
-        mDisplayMetrics.heightPixels = metrics.heightPixels;
-        mDisplayMetrics.scaledDensity = metrics.scaledDensity;
-        mDisplayMetrics.widthPixels = metrics.widthPixels;
-        mDisplayMetrics.xdpi = metrics.xdpi;
-        mDisplayMetrics.ydpi = metrics.ydpi;
-
-        styledAttributes.recycle();
-    }
-
-    @Override
-    public void onResume() {
-        super.onResume();
-        final ContentResolver resolver = getContentResolver();
-        mFontScale = Settings.System.getFloat(resolver, Settings.System.FONT_SCALE, 1.0f);
-
-        if (mFontScale < 1) {
-            mFontSize.setSelection(0);
-        } else if (mFontScale > 1) {
-            mFontSize.setSelection(2);
-        } else {
-            mFontSize.setSelection(1);
-        }
-        updateFontScale();
-    }
-
-    private void updateFontScale() {
-        mDisplayMetrics.scaledDensity = mDisplayMetrics.density * mFontScale;
-        float size = mTextSizeTyped.getDimension(mDisplayMetrics);
-        mPreview.setTextSize(TypedValue.COMPLEX_UNIT_PX, size);
-    }
-
-    public void onClick(View v) {
-        final ContentResolver resolver = getContentResolver();
-        Settings.System.putFloat(resolver, Settings.System.FONT_SCALE, mFontScale);
-        finish();
-    }
-
-    private Spinner.OnItemSelectedListener mFontSizeChanged
-                                    = new Spinner.OnItemSelectedListener() {
-        public void onItemSelected(android.widget.AdapterView av, View v,
-                                    int position, long id) {
-            if (position == 0) {
-                mFontScale = .75f;
-            } else if (position == 2) {
-                mFontScale = 1.25f;
-            } else {
-                mFontScale = 1.0f;
-            }
-
-            updateFontScale();
-        }
-
-        public void onNothingSelected(android.widget.AdapterView av) {
-        }
-    };
-
-    private Spinner mFontSize;
-    private TextView mPreview;
-    private TypedValue mTextSizeTyped;
-    private DisplayMetrics mDisplayMetrics;
-    private float mFontScale = 1.0f;
-}
diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java
index a049d85..9f86860 100644
--- a/src/com/android/settings/SettingsActivity.java
+++ b/src/com/android/settings/SettingsActivity.java
@@ -16,10 +16,11 @@
 
 package com.android.settings;
 
-import android.app.ActionBar;
+import android.app.ActivityManager;
 import android.app.Fragment;
 import android.app.FragmentManager;
 import android.app.FragmentTransaction;
+import android.app.ActionBar;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
@@ -1322,14 +1323,10 @@
     }
 
     public void startSuggestion(Intent intent) {
-        if (intent == null) {
+        if (intent == null || ActivityManager.isUserAMonkey()) {
             return;
         }
-        final ComponentName componentName = intent.getComponent();
-        if (componentName.equals(mCurrentSuggestion)) {
-            return;
-        }
-        mCurrentSuggestion = componentName;
+        mCurrentSuggestion = intent.getComponent();
         startActivityForResult(intent, REQUEST_SUGGESTION);
     }
 
diff --git a/src/com/android/settings/applications/ManageApplications.java b/src/com/android/settings/applications/ManageApplications.java
index 5908373..f868c1b 100644
--- a/src/com/android/settings/applications/ManageApplications.java
+++ b/src/com/android/settings/applications/ManageApplications.java
@@ -887,6 +887,8 @@
                     comparatorObj = ApplicationsState.ALPHA_COMPARATOR;
                     break;
             }
+            filterObj = new CompoundFilter(filterObj, ApplicationsState.FILTER_NOT_HIDE);
+
             AppFilter finalFilterObj = filterObj;
             mBgHandler.post(() -> {
                 final ArrayList<AppEntry> entries = mSession.rebuild(finalFilterObj,
diff --git a/src/com/android/settings/applications/ManageDomainUrls.java b/src/com/android/settings/applications/ManageDomainUrls.java
index a16a865..a011fe4 100644
--- a/src/com/android/settings/applications/ManageDomainUrls.java
+++ b/src/com/android/settings/applications/ManageDomainUrls.java
@@ -16,9 +16,7 @@
 
 import android.app.Application;
 import android.content.Context;
-import android.content.DialogInterface;
 import android.content.pm.PackageManager;
-import android.os.Build;
 import android.os.Bundle;
 import android.os.UserHandle;
 import android.provider.Settings;
@@ -26,28 +24,19 @@
 import android.support.v14.preference.SwitchPreference;
 import android.support.v7.preference.Preference;
 import android.support.v7.preference.Preference.OnPreferenceChangeListener;
+import android.support.v7.preference.Preference.OnPreferenceClickListener;
 import android.support.v7.preference.PreferenceCategory;
 import android.support.v7.preference.PreferenceGroup;
 import android.support.v7.preference.PreferenceViewHolder;
 import android.util.ArraySet;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
 import android.view.View;
 
 import com.android.internal.logging.MetricsProto.MetricsEvent;
-import com.android.settings.AppHeader;
 import com.android.settings.R;
-import com.android.settings.SettingsActivity;
 import com.android.settings.SettingsPreferenceFragment;
 import com.android.settings.Utils;
-import com.android.settings.applications.AppInfoBase;
-import com.android.settings.applications.AppStateBaseBridge;
-import com.android.settings.applications.InstalledAppDetails;
-import com.android.settings.datausage.AppStateDataUsageBridge.DataUsageState;
 import com.android.settingslib.applications.ApplicationsState;
 import com.android.settingslib.applications.ApplicationsState.AppEntry;
-import com.android.settingslib.applications.ApplicationsState.AppFilter;
 
 import java.util.ArrayList;
 
@@ -56,7 +45,11 @@
  * handling as well as system handling for Web Actions.
  */
 public class ManageDomainUrls extends SettingsPreferenceFragment
-        implements ApplicationsState.Callbacks, OnPreferenceChangeListener {
+        implements ApplicationsState.Callbacks, OnPreferenceChangeListener,
+        OnPreferenceClickListener {
+
+    // constant value that can be used to check return code from sub activity.
+    private static final int INSTALLED_APP_DETAILS = 1;
 
     private ApplicationsState mApplicationsState;
     private ApplicationsState.Session mSession;
@@ -77,7 +70,6 @@
     @Override
     public void onViewCreated(View view, Bundle savedInstanceState) {
         super.onViewCreated(view, savedInstanceState);
-        setLoading(true, false);
     }
 
     @Override
@@ -141,7 +133,6 @@
             }
         }
         rebuildAppList(mDomainAppList, apps);
-        setLoading(false, true);
     }
 
     @Override
@@ -173,6 +164,7 @@
             if (preference == null) {
                 preference = new DomainAppPreference(getPrefContext(), entry);
                 preference.setKey(key);
+                preference.setOnPreferenceClickListener(this);
                 group.addPreference(preference);
             } else {
                 preference.reuse();
@@ -208,6 +200,18 @@
         return MetricsEvent.MANAGE_DOMAIN_URLS;
     }
 
+    @Override
+    public boolean onPreferenceClick(Preference preference) {
+        if (preference.getClass() == DomainAppPreference.class) {
+            ApplicationsState.AppEntry entry = ((DomainAppPreference) preference).mEntry;
+            AppInfoBase.startAppInfoFragment(AppLaunchSettings.class, R.string.auto_launch_label,
+                    entry.info.packageName, entry.info.uid, this,
+                    INSTALLED_APP_DETAILS);
+            return true;
+        }
+        return false;
+    }
+
     private class DomainAppPreference extends Preference {
         private final AppEntry mEntry;
         private final PackageManager mPm;
diff --git a/src/com/android/settings/bluetooth/BluetoothPairingDialog.java b/src/com/android/settings/bluetooth/BluetoothPairingDialog.java
index fe48148..27cd532 100755
--- a/src/com/android/settings/bluetooth/BluetoothPairingDialog.java
+++ b/src/com/android/settings/bluetooth/BluetoothPairingDialog.java
@@ -29,7 +29,10 @@
 import android.text.InputFilter;
 import android.text.InputFilter.LengthFilter;
 import android.text.InputType;
+import android.text.SpannableString;
+import android.text.Spanned;
 import android.text.TextWatcher;
+import android.text.style.TtsSpan;
 import android.util.Log;
 import android.view.KeyEvent;
 import android.view.View;
@@ -298,16 +301,17 @@
             }
         });
 
-        String messageCaption = null;
-        String pairingContent = null;
+        SpannableString pairingContent = null;
         switch (mType) {
             case BluetoothDevice.PAIRING_VARIANT_DISPLAY_PASSKEY:
             case BluetoothDevice.PAIRING_VARIANT_DISPLAY_PIN:
                 messagePairing.setVisibility(View.VISIBLE);
-            case BluetoothDevice.PAIRING_VARIANT_PASSKEY_CONFIRMATION:
-                pairingContent = mPairingKey;
+            case BluetoothDevice.PAIRING_VARIANT_PASSKEY_CONFIRMATION: {
+                pairingContent = new SpannableString(mPairingKey);
+                pairingContent.setSpan(new TtsSpan.DigitsBuilder(mPairingKey).build(),
+                        0, mPairingKey.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
                 break;
-
+            }
             case BluetoothDevice.PAIRING_VARIANT_CONSENT:
                 messagePairing.setVisibility(view.GONE);
                 break;
diff --git a/src/com/android/settings/dashboard/DashboardFragment.java b/src/com/android/settings/dashboard/DashboardFragment.java
index 28d153e..1388be7 100644
--- a/src/com/android/settings/dashboard/DashboardFragment.java
+++ b/src/com/android/settings/dashboard/DashboardFragment.java
@@ -17,6 +17,7 @@
 
 import android.app.Activity;
 import android.content.Context;
+import android.os.Bundle;
 import android.support.v7.preference.Preference;
 import android.support.v7.preference.PreferenceScreen;
 import android.text.TextUtils;
@@ -45,6 +46,7 @@
             new ArrayMap<>();
 
     protected DashboardFeatureProvider mDashboardFeatureProvider;
+    private boolean mListeningToCategoryChange;
 
     @Override
     public void onAttach(Context context) {
@@ -54,10 +56,31 @@
     }
 
     @Override
+    public void onCategoriesChanged() {
+        final DashboardCategory category = getDashboardTiles();
+        if (category == null) {
+            return;
+        }
+        refreshAllPreferences(getLogTag());
+    }
+
+    @Override
+    public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
+        super.onCreatePreferences(savedInstanceState, rootKey);
+        refreshAllPreferences(getLogTag());
+    }
+
+    @Override
     public void onStart() {
         super.onStart();
+        final DashboardCategory category = getDashboardTiles();
+        if (category == null) {
+            return;
+        }
+
         final Activity activity = getActivity();
         if (activity instanceof SettingsDrawerActivity) {
+            mListeningToCategoryChange = true;
             ((SettingsDrawerActivity) activity).addCategoryListener(this);
         }
     }
@@ -77,9 +100,12 @@
     @Override
     public void onStop() {
         super.onStop();
-        final Activity activity = getActivity();
-        if (activity instanceof SettingsDrawerActivity) {
-            ((SettingsDrawerActivity) activity).remCategoryListener(this);
+        if (mListeningToCategoryChange) {
+            final Activity activity = getActivity();
+            if (activity instanceof SettingsDrawerActivity) {
+                ((SettingsDrawerActivity) activity).remCategoryListener(this);
+            }
+            mListeningToCategoryChange = false;
         }
     }
 
@@ -92,10 +118,33 @@
         mPreferenceControllers.put(controller.getClass(), controller);
     }
 
-    protected final void displayTilesAsPreference(String TAG, PreferenceScreen screen,
-            DashboardCategory category) {
+    /**
+     * Returns {@link DashboardCategory} for this fragment.
+     */
+    protected abstract DashboardCategory getDashboardTiles();
+
+    /**
+     * Displays resource based tiles.
+     */
+    protected abstract void displayResourceTiles();
+
+    protected abstract String getLogTag();
+
+    /**
+     * Displays dashboard tiles as preference.
+     */
+    private final void displayDashboardTiles(final String TAG, PreferenceScreen screen) {
         final Context context = getContext();
+        final DashboardCategory category = getDashboardTiles();
+        if (category == null) {
+            Log.d(TAG, "NO dynamic tiles for " + TAG);
+            return;
+        }
         List<Tile> tiles = category.tiles;
+        if (tiles == null) {
+            Log.d(TAG, "tile list is empty, skipping category " + category.title);
+            return;
+        }
         for (Tile tile : tiles) {
             final String key = mDashboardFeatureProvider.getDashboardKeyForTile(tile);
             if (TextUtils.isEmpty(key)) {
@@ -119,4 +168,19 @@
             screen.addPreference(pref);
         }
     }
+
+    /**
+     * Refresh preference items using system category dashboard items.
+     */
+    private void refreshAllPreferences(final String TAG) {
+        // First remove old preferences.
+        PreferenceScreen screen = getPreferenceScreen();
+        if (screen != null) {
+            screen.removeAll();
+        }
+        // Add resource based tiles.
+        displayResourceTiles();
+        // Add dashboard tiles.
+        displayDashboardTiles(TAG, getPreferenceScreen());
+    }
 }
diff --git a/src/com/android/settings/dashboard/SummaryLoader.java b/src/com/android/settings/dashboard/SummaryLoader.java
index d55ec06..9a6c944 100644
--- a/src/com/android/settings/dashboard/SummaryLoader.java
+++ b/src/com/android/settings/dashboard/SummaryLoader.java
@@ -80,8 +80,7 @@
         mWorker = new Worker(mWorkerThread.getLooper());
         mActivity = activity;
         List<Tile> tiles = categories.tiles;
-        for (int j = 0; j < tiles.size(); j++) {
-            Tile tile = tiles.get(j);
+        for (Tile tile :tiles) {
             mWorker.obtainMessage(Worker.MSG_GET_PROVIDER, tile).sendToTarget();
         }
     }
diff --git a/src/com/android/settings/deviceinfo/StorageDashboardFragment.java b/src/com/android/settings/deviceinfo/StorageDashboardFragment.java
index cb6343a..92de6b7 100644
--- a/src/com/android/settings/deviceinfo/StorageDashboardFragment.java
+++ b/src/com/android/settings/deviceinfo/StorageDashboardFragment.java
@@ -17,16 +17,14 @@
 package com.android.settings.deviceinfo;
 
 import android.content.Context;
-import android.os.Bundle;
-import android.os.UserManager;
 import android.provider.SearchIndexableResource;
-import android.support.v7.preference.PreferenceScreen;
 
 import com.android.settings.R;
 import com.android.settings.dashboard.DashboardFragment;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settings.search.Indexable;
+import com.android.settingslib.drawer.DashboardCategory;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -42,34 +40,27 @@
     }
 
     @Override
+    protected String getLogTag() {
+        return TAG;
+    }
+
+    @Override
     public void onAttach(Context context) {
         super.onAttach(context);
         addPreferenceController(new ManageStoragePreferenceController(context));
     }
 
     @Override
-    public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
-        super.onCreatePreferences(savedInstanceState, rootKey);
-        refreshAllPreferences();
+    protected DashboardCategory getDashboardTiles() {
+        return mDashboardFeatureProvider.getTilesForStorageCategory();
     }
 
     @Override
-    public void onCategoriesChanged() {
-        refreshAllPreferences();
-    }
-
-    private void refreshAllPreferences() {
-        PreferenceScreen screen = getPreferenceScreen();
-        if (screen != null) {
-            screen.removeAll();
-        }
+    protected void displayResourceTiles() {
         addPreferencesFromResource(R.xml.storage_dashboard_fragment);
 
         getPreferenceController(ManageStoragePreferenceController.class)
                 .displayPreference(getPreferenceScreen());
-
-        displayTilesAsPreference(TAG, getPreferenceScreen(),
-                mDashboardFeatureProvider.getTilesForStorageCategory());
     }
 
     /**
diff --git a/src/com/android/settings/gestures/GestureSettings.java b/src/com/android/settings/gestures/GestureSettings.java
index 8cb329b..32c8438 100644
--- a/src/com/android/settings/gestures/GestureSettings.java
+++ b/src/com/android/settings/gestures/GestureSettings.java
@@ -71,7 +71,7 @@
         Context context = getActivity();
         mPreferences = new ArrayList();
 
-         // Double tap power for camera
+        // Double tap power for camera
         if (isCameraDoubleTapPowerGestureAvailable(getResources())) {
             int cameraDisabled = Secure.getInt(
                     getContentResolver(), Secure.CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED, 0);
@@ -81,13 +81,17 @@
         }
 
         // Ambient Display
-        if (isDozeAvailable(context)) {
+        boolean dozeEnabled = isDozeAvailable(context);
+        if (dozeEnabled) {
             int pickup = Secure.getInt(getContentResolver(), Secure.DOZE_PULSE_ON_PICK_UP, 1);
             addPreference(PREF_KEY_PICK_UP, pickup != 0, PREF_ID_PICK_UP);
+        } else {
+            removePreference(PREF_KEY_PICK_UP);
+        }
+        if (dozeEnabled && isDoubleTapAvailable(context)) {
             int doubleTap = Secure.getInt(getContentResolver(), Secure.DOZE_PULSE_ON_DOUBLE_TAP, 1);
             addPreference(PREF_KEY_DOUBLE_TAP_SCREEN, doubleTap != 0, PREF_ID_DOUBLE_TAP_SCREEN);
         } else {
-            removePreference(PREF_KEY_PICK_UP);
             removePreference(PREF_KEY_DOUBLE_TAP_SCREEN);
         }
 
@@ -215,6 +219,11 @@
         return false;
     }
 
+    private static boolean isDoubleTapAvailable(Context context) {
+        return context.getResources().getBoolean(
+                R.bool.config_gesture_double_tap_settings_enabled);
+    }
+
     private void addPreference(String key, boolean enabled, int id) {
         GesturePreference preference = (GesturePreference) findPreference(key);
         preference.setChecked(enabled);
@@ -247,6 +256,8 @@
                 if (!isDozeAvailable(context)) {
                     result.add(PREF_KEY_PICK_UP);
                     result.add(PREF_KEY_DOUBLE_TAP_SCREEN);
+                } else if (!isDoubleTapAvailable(context)) {
+                    result.add(PREF_KEY_DOUBLE_TAP_SCREEN);
                 }
                 if (!isSystemUINavigationAvailable(context)) {
                     result.add(PREF_KEY_SWIPE_DOWN_FINGERPRINT);
diff --git a/src/com/android/settings/overlay/FeatureFactory.java b/src/com/android/settings/overlay/FeatureFactory.java
index dd3e9c8..485abd0 100644
--- a/src/com/android/settings/overlay/FeatureFactory.java
+++ b/src/com/android/settings/overlay/FeatureFactory.java
@@ -35,7 +35,7 @@
     private static final String LOG_TAG = "FeatureFactory";
     private static final boolean DEBUG = false;
 
-    private static FeatureFactory sFactory;
+    protected static FeatureFactory sFactory;
 
     /**
      * Returns a factory for creating feature controllers. Creates the factory if it does not
diff --git a/src/com/android/settings/system/SystemDashboardFragment.java b/src/com/android/settings/system/SystemDashboardFragment.java
index 54bd3e6..a2e9152 100644
--- a/src/com/android/settings/system/SystemDashboardFragment.java
+++ b/src/com/android/settings/system/SystemDashboardFragment.java
@@ -16,10 +16,8 @@
 package com.android.settings.system;
 
 import android.content.Context;
-import android.os.Bundle;
 import android.os.UserManager;
 import android.provider.SearchIndexableResource;
-import android.support.v7.preference.PreferenceScreen;
 
 import com.android.settings.R;
 import com.android.settings.dashboard.DashboardFragment;
@@ -27,15 +25,14 @@
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settings.search.Indexable;
-import com.android.settingslib.drawer.SettingsDrawerActivity;
+import com.android.settingslib.drawer.DashboardCategory;
 
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 
 
-public class SystemDashboardFragment extends DashboardFragment
-        implements SettingsDrawerActivity.CategoryListener, Indexable {
+public class SystemDashboardFragment extends DashboardFragment {
 
     private static final String TAG = "SystemDashboardFrag";
 
@@ -45,6 +42,11 @@
     }
 
     @Override
+    protected String getLogTag() {
+        return TAG;
+    }
+
+    @Override
     public void onAttach(Context context) {
         super.onAttach(context);
         addPreferenceController(
@@ -52,32 +54,16 @@
     }
 
     @Override
-    public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
-        super.onCreatePreferences(savedInstanceState, rootKey);
-        refreshAllPreferences();
-    }
-
-    @Override
-    public void onCategoriesChanged() {
-        refreshAllPreferences();
-    }
-
-    /**
-     * Refresh preference items using system category dashboard items.
-     */
-    private void refreshAllPreferences() {
-        PreferenceScreen screen = getPreferenceScreen();
-        if (screen != null) {
-            screen.removeAll();
-        }
-
+    protected void displayResourceTiles() {
         addPreferencesFromResource(R.xml.system_dashboard_fragment);
 
         getPreferenceController(SystemUpdatePreferenceController.class)
                 .displayPreference(getPreferenceScreen());
+    }
 
-        displayTilesAsPreference(TAG, getPreferenceScreen(),
-                mDashboardFeatureProvider.getTilesForSystemCategory());
+    @Override
+    protected DashboardCategory getDashboardTiles() {
+        return mDashboardFeatureProvider.getTilesForSystemCategory();
     }
 
     /**
diff --git a/src/com/android/settings/users/UserSettings.java b/src/com/android/settings/users/UserSettings.java
index d070838..88ae259 100644
--- a/src/com/android/settings/users/UserSettings.java
+++ b/src/com/android/settings/users/UserSettings.java
@@ -610,7 +610,7 @@
             case DIALOG_USER_PROFILE_EDITOR: {
                 Dialog dlg = mEditUserInfoController.createDialog(
                         this,
-                        mMePreference.getIcon(),
+                        null,
                         mMePreference.getTitle(),
                         R.string.profile_info_settings_title,
                         this /* callback */,
diff --git a/tests/robotests/src/com/android/settings/core/PreferenceControllerTest.java b/tests/robotests/src/com/android/settings/core/PreferenceControllerTest.java
new file mode 100644
index 0000000..e20efbe
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/core/PreferenceControllerTest.java
@@ -0,0 +1,97 @@
+/*
+ * 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.core;
+
+import android.content.Context;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settings.TestConfig;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.annotation.Config;
+
+import java.util.List;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+@RunWith(RobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class PreferenceControllerTest {
+    private static final String KEY_PREF = "test_pref";
+
+    @Mock
+    private Context mContext;
+    @Mock
+    private PreferenceScreen mScreen;
+    @Mock
+    private Preference mPreference;
+
+    private TestPrefController mTestPrefController;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mTestPrefController = new TestPrefController(mContext);
+    }
+
+    @Test
+    public void removeExistingPref_shouldBeRemoved() {
+        when(mScreen.findPreference(KEY_PREF)).thenReturn(mPreference);
+
+        mTestPrefController.removePreference(mScreen, KEY_PREF);
+
+        verify(mScreen).removePreference(mPreference);
+    }
+
+    @Test
+    public void removeNonExistingPref_shouldNotRemoveAnything() {
+        mTestPrefController.removePreference(mScreen, KEY_PREF);
+
+        verify(mScreen, never()).removePreference(any(Preference.class));
+    }
+
+    private class TestPrefController extends PreferenceController {
+
+        public TestPrefController(Context context) {
+            super(context);
+        }
+
+        @Override
+        public void displayPreference(PreferenceScreen screen) {
+
+        }
+
+        @Override
+        public boolean handlePreferenceTreeClick(Preference preference) {
+            return false;
+        }
+
+        @Override
+        public void updateNonIndexableKeys(List<String> keys) {
+
+        }
+    }
+
+}
diff --git a/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentTest.java b/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentTest.java
new file mode 100644
index 0000000..f4371a6
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentTest.java
@@ -0,0 +1,174 @@
+/*
+ * 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.dashboard;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settings.TestConfig;
+import com.android.settings.core.PreferenceController;
+import com.android.settings.overlay.FeatureFactory;
+import com.android.settings.testutils.FakeFeatureFactory;
+import com.android.settingslib.drawer.DashboardCategory;
+import com.android.settingslib.drawer.Tile;
+
+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.RobolectricTestRunner;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowApplication;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+@RunWith(RobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class DashboardFragmentTest {
+
+    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+    private Context mContext;
+    @Mock
+    private DashboardCategory mDashboardCategory;
+    @Mock
+    private FakeFeatureFactory mFakeFeatureFactory;
+    private TestFragment mTestFragment;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        FakeFeatureFactory.setupForTest(mContext);
+        mFakeFeatureFactory = (FakeFeatureFactory) FeatureFactory.getFactory(mContext);
+        mDashboardCategory.tiles = new ArrayList<>();
+        mDashboardCategory.tiles.add(new Tile());
+        mTestFragment = new TestFragment(ShadowApplication.getInstance().getApplicationContext());
+        mTestFragment.onAttach(mContext);
+        mTestFragment.mCategory = mDashboardCategory;
+    }
+
+    @Test
+    public void testPreferenceControllerGetterSetter_shouldAddAndGetProperly() {
+        final TestPreferenceController controller = new TestPreferenceController(mContext);
+        mTestFragment.addPreferenceController(controller);
+
+        final TestPreferenceController retrievedController = mTestFragment.getPreferenceController
+                (TestPreferenceController.class);
+
+        assertThat(controller).isSameAs(retrievedController);
+    }
+
+    @Test
+    public void displayTilesAsPreference_shouldAddTilesWithIntent() {
+        when(mFakeFeatureFactory.dashboardFeatureProvider.getDashboardKeyForTile(any(Tile.class)))
+                .thenReturn("test_key");
+        mTestFragment.onCreatePreferences(new Bundle(), "rootKey");
+
+        verify(mTestFragment.mScreen).addPreference(any(DashboardTilePreference.class));
+    }
+
+    @Test
+    public void displayTilesAsPreference_shouldNotAddTilesWithoutIntent() {
+        mTestFragment.onCreatePreferences(new Bundle(), "rootKey");
+
+        verify(mTestFragment.mScreen, never()).addPreference(any(DashboardTilePreference.class));
+    }
+
+    @Test
+    public void displayTilesAsPreference_withEmptyCategory_shouldNotAddTiles() {
+        mTestFragment.mCategory.tiles = null;
+        mTestFragment.onCreatePreferences(new Bundle(), "rootKey");
+
+        verify(mTestFragment.mScreen, never()).addPreference(any(DashboardTilePreference.class));
+    }
+
+    public static class TestPreferenceController extends PreferenceController {
+
+        public TestPreferenceController(Context context) {
+            super(context);
+        }
+
+        @Override
+        public void displayPreference(PreferenceScreen screen) {
+
+        }
+
+        @Override
+        public boolean handlePreferenceTreeClick(Preference preference) {
+            return false;
+        }
+
+        @Override
+        public void updateNonIndexableKeys(List<String> keys) {
+
+        }
+    }
+
+    public static class TestFragment extends DashboardFragment {
+
+        private final Context mContext;
+        @Mock
+        public PreferenceScreen mScreen;
+        public DashboardCategory mCategory;
+
+
+        public TestFragment(Context context) {
+            mContext = context;
+            mScreen = mock(PreferenceScreen.class);
+        }
+
+        @Override
+        public Context getContext() {
+            return mContext;
+        }
+
+        @Override
+        public int getMetricsCategory() {
+            return 0;
+        }
+
+        @Override
+        protected DashboardCategory getDashboardTiles() {
+            return mCategory;
+        }
+
+        @Override
+        protected void displayResourceTiles() {
+        }
+
+        @Override
+        public PreferenceScreen getPreferenceScreen() {
+            return mScreen;
+        }
+
+        @Override
+        protected String getLogTag() {
+            return "TEST_FRAG";
+        }
+    }
+
+}
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/ManageStoragePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/ManageStoragePreferenceControllerTest.java
new file mode 100644
index 0000000..d2c169e
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/deviceinfo/ManageStoragePreferenceControllerTest.java
@@ -0,0 +1,99 @@
+/*
+ * 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.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settings.TestConfig;
+
+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.RobolectricTestRunner;
+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.Answers.RETURNS_DEEP_STUBS;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+@RunWith(RobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class ManageStoragePreferenceControllerTest {
+
+
+    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+    private Context mContext;
+    @Mock(answer = RETURNS_DEEP_STUBS)
+    private PreferenceScreen mScreen;
+
+    private ManageStoragePreferenceController mController;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mController = new ManageStoragePreferenceController(mContext);
+    }
+
+    @Test
+    public void updateNonIndexableKey_prefUnavaiable_shouldUpdate() {
+        final List<String> keys = new ArrayList<>();
+        mController.updateNonIndexableKeys(keys);
+
+        assertThat(keys).isNotEmpty();
+    }
+
+    @Test
+    public void updateNonIndexableKey_prefAvaiable_shouldNotUpdate() {
+        final List<String> keys = new ArrayList<>();
+        when(mContext.getResources().getBoolean(
+                com.android.settings.R.bool.config_storage_manager_settings_enabled))
+                .thenReturn(true);
+
+        mController.updateNonIndexableKeys(keys);
+
+        assertThat(keys).isEmpty();
+    }
+
+    @Test
+    public void displayPref_prefAvaiable_shouldDisplay() {
+        when(mContext.getResources().getBoolean(
+                com.android.settings.R.bool.config_storage_manager_settings_enabled))
+                .thenReturn(true);
+
+        mController.displayPreference(mScreen);
+
+        verify(mScreen, never()).removePreference(any(Preference.class));
+    }
+
+    @Test
+    public void displayPref_prefAvaiable_shouldNotDisplay() {
+        mController.displayPreference(mScreen);
+
+        verify(mScreen).removePreference(any(Preference.class));
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java b/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java
new file mode 100644
index 0000000..0aaec5a
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java
@@ -0,0 +1,87 @@
+/*
+ * 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.testutils;
+
+import android.content.Context;
+
+import com.android.settings.core.instrumentation.MetricsFeatureProvider;
+import com.android.settings.dashboard.DashboardFeatureProvider;
+import com.android.settings.fuelgauge.PowerUsageFeatureProvider;
+import com.android.settings.overlay.FeatureFactory;
+import com.android.settings.overlay.SupportFeatureProvider;
+
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+/**
+ * Test util to provide fake FeatureFactory. To use this factory, call {@code setupForTest} in
+ * {@code @Before} method of the test class.
+ */
+public class FakeFeatureFactory extends FeatureFactory {
+
+    public final SupportFeatureProvider supportFeatureProvider;
+    public final MetricsFeatureProvider metricsFeatureProvider;
+    public final PowerUsageFeatureProvider powerUsageFeatureProvider;
+    public final DashboardFeatureProvider dashboardFeatureProvider;
+
+    /**
+     * Call this in {@code @Before} method of the test class to use fake factory.
+     *
+     * @param context The context must be a deep mock.
+     */
+    public static void setupForTest(Context context) {
+        sFactory = null;
+        when(context.getString(com.android.settings.R.string.config_featureFactory))
+                .thenReturn(FakeFeatureFactory.class.getName());
+        try {
+            Class c = FakeFeatureFactory.class;
+            when(context.getClassLoader().loadClass(anyString())).thenReturn(c);
+        } catch (ClassNotFoundException e) {
+            // Ignore.
+        }
+    }
+
+    /**
+     * Used by reflection. Do not call directly.
+     */
+    public FakeFeatureFactory() {
+        supportFeatureProvider = mock(SupportFeatureProvider.class);
+        metricsFeatureProvider = mock(MetricsFeatureProvider.class);
+        powerUsageFeatureProvider = mock(PowerUsageFeatureProvider.class);
+        dashboardFeatureProvider = mock(DashboardFeatureProvider.class);
+    }
+
+    @Override
+    public SupportFeatureProvider getSupportFeatureProvider(Context context) {
+        return supportFeatureProvider;
+    }
+
+    @Override
+    public MetricsFeatureProvider getMetricsFeatureProvider() {
+        return metricsFeatureProvider;
+    }
+
+    @Override
+    public PowerUsageFeatureProvider getPowerUsageFeatureProvider() {
+        return powerUsageFeatureProvider;
+    }
+
+    @Override
+    public DashboardFeatureProvider getDashboardFeatureProvider(Context context) {
+        return dashboardFeatureProvider;
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/shadow/ShadowTextUtils.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowTextUtils.java
similarity index 96%
rename from tests/robotests/src/com/android/settings/shadow/ShadowTextUtils.java
rename to tests/robotests/src/com/android/settings/testutils/shadow/ShadowTextUtils.java
index 4a98f6a..c6ed2fa 100644
--- a/tests/robotests/src/com/android/settings/shadow/ShadowTextUtils.java
+++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowTextUtils.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.settings.shadow;
+package com.android.settings.testutils.shadow;
 
 import android.icu.util.ULocale;
 import android.os.SystemProperties;
diff --git a/tests/robotests/src/com/android/settings/widget/RtlCompatibleViewPagerTest.java b/tests/robotests/src/com/android/settings/widget/RtlCompatibleViewPagerTest.java
index b5213f1..cce0f32 100644
--- a/tests/robotests/src/com/android/settings/widget/RtlCompatibleViewPagerTest.java
+++ b/tests/robotests/src/com/android/settings/widget/RtlCompatibleViewPagerTest.java
@@ -23,7 +23,7 @@
 import android.view.ViewGroup;
 
 import com.android.settings.TestConfig;
-import com.android.settings.shadow.ShadowTextUtils;
+import com.android.settings.testutils.shadow.ShadowTextUtils;
 
 import org.junit.Before;
 import org.junit.Test;