Settings new dashboard - part 2

Introduce the new Dashboard (a grid like presentation of
Settings top categories) per UX specification.

- the Dashboard is composed of "categories" and in each of them
you have "tiles"
- implement a new layout for showing top categories
(DashboardContainerView). This layout basically acts like a
grid
- depending on the device configuration make the grid with 1
column in portrait / 2 colums in landscape (phones) OR 2 columns
in portrait and 3 in landscape (tablets)
- take care of Accounts adding and removing (as it changes the
number of tiles to show)

Also remove all the old code related to Headers

Change-Id: Ie29944132c1b4c3f7b073d5a7d4453b8f5ec19a7
diff --git a/res/layout/dashboard.xml b/res/layout/dashboard.xml
index 8a29289..116580a 100644
--- a/res/layout/dashboard.xml
+++ b/res/layout/dashboard.xml
@@ -14,21 +14,21 @@
      limitations under the License.
 -->
 
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/dashboard"
     android:layout_width="match_parent"
-    android:layout_height="match_parent">
+    android:layout_height="match_parent"
+    android:paddingStart="12dp"
+    android:paddingEnd="12dp"
+    android:scrollbarStyle="outsideOverlay"
+    android:background="@color/dashboard_background_color">
 
-    <LinearLayout android:layout_width="match_parent"
-                  android:layout_height="match_parent"
-                  android:layout_gravity="center"
-                  android:orientation="vertical">
+        <LinearLayout
+                android:id="@+id/dashboard_container"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:layout_gravity="center_horizontal"
+                android:orientation="vertical"
+                />
 
-        <ListView android:id="@id/android:list"
-                  android:layout_width="match_parent"
-                  android:layout_height="match_parent"
-                  android:background="@color/background_drawer" />
-
-    </LinearLayout>
-
-</FrameLayout>
+</ScrollView>
diff --git a/res/layout/dashboard_category.xml b/res/layout/dashboard_category.xml
new file mode 100644
index 0000000..8abbee2
--- /dev/null
+++ b/res/layout/dashboard_category.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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:id="@+id/category"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical">
+
+    <TextView android:id="@+id/category_title"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:singleLine="true"
+            android:ellipsize="marquee"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:textAlignment="viewStart"
+            />
+
+    <com.android.settings.dashboard.DashboardContainerView
+            android:id="@+id/category_content"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            />
+
+</LinearLayout>
diff --git a/res/layout/dashboard_tile.xml b/res/layout/dashboard_tile.xml
new file mode 100644
index 0000000..03b4b09
--- /dev/null
+++ b/res/layout/dashboard_tile.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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="match_parent"
+        android:gravity="center_vertical"
+        android:minHeight="72dp"
+        android:background="@android:color/white">
+
+    <ImageView
+            android:id="@+id/icon"
+            android:layout_width="40dp"
+            android:layout_height="40dp"
+            android:scaleType="centerInside"
+            android:layout_marginStart="12dp"
+            android:layout_marginEnd="16dp"
+            />
+
+    <RelativeLayout
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1" >
+
+        <TextView android:id="@+id/title"
+                  android:layout_width="wrap_content"
+                  android:layout_height="wrap_content"
+                  android:singleLine="true"
+                  android:textAppearance="?android:attr/textAppearanceMedium"
+                  android:ellipsize="marquee"
+                  android:fadingEdge="horizontal" />
+
+        <TextView android:id="@+id/status"
+                  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/textAppearanceSmall"
+                  android:textColor="?android:attr/textColorSecondary"
+                  />
+
+    </RelativeLayout>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/res/layout/settings_main.xml b/res/layout/settings_main.xml
index db732dc..47ed02b 100644
--- a/res/layout/settings_main.xml
+++ b/res/layout/settings_main.xml
@@ -27,12 +27,13 @@
             android:layout_height="match_parent"
             android:layout_width="match_parent">
 
-        <android.preference.PreferenceFrameLayout
+        <FrameLayout
                 android:id="@+id/prefs"
                 android:layout_width="match_parent"
                 android:layout_height="match_parent"
                 android:layout_weight="1"
                 />
+
     </LinearLayout>
 
     <RelativeLayout android:id="@+id/button_bar"
diff --git a/res/values-land/config.xml b/res/values-land/config.xml
new file mode 100644
index 0000000..543dfee
--- /dev/null
+++ b/res/values-land/config.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Dashboard number of columns -->
+    <integer name="dashboard_num_columns">2</integer>
+
+</resources>
diff --git a/res/values-sw600dp-land/config.xml b/res/values-sw600dp-land/config.xml
new file mode 100644
index 0000000..eb1a7c3
--- /dev/null
+++ b/res/values-sw600dp-land/config.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Dashboard number of columns -->
+    <integer name="dashboard_num_columns">3</integer>
+
+</resources>
diff --git a/res/values-sw600dp/config.xml b/res/values-sw600dp/config.xml
new file mode 100644
index 0000000..543dfee
--- /dev/null
+++ b/res/values-sw600dp/config.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Dashboard number of columns -->
+    <integer name="dashboard_num_columns">2</integer>
+
+</resources>
diff --git a/res/values-sw600dp/dimens.xml b/res/values-sw600dp/dimens.xml
index 4f4a221..154b34f 100755
--- a/res/values-sw600dp/dimens.xml
+++ b/res/values-sw600dp/dimens.xml
@@ -38,4 +38,8 @@
     <dimen name="keyguard_appwidget_picker_margin_left">2dip</dimen>
     <dimen name="keyguard_appwidget_picker_margin_right">2dip</dimen>
     <integer name="keyguard_appwidget_picker_cols">2</integer>
+
+    <!-- Dashboard padding between each tiles within the layout -->
+    <dimen name="dashboard_cell_gap">8dp</dimen>
+
 </resources>
diff --git a/res/values/colors.xml b/res/values/colors.xml
index acbccaa..ce60cf3 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -15,9 +15,8 @@
 -->
 
 <resources>
-    <color name="background_drawer">@android:color/white</color>
-    <color name="background_drawer_icon">#ffcccccc</color>
-    <color name="background_search_result_icon">#ffcccccc</color>
+    <!-- TODO: remove this as this is temporary. Waiting for the new Assets. -->
+    <color name="temporary_background_icon">#ffcccccc</color>
 
     <color name="black">#000</color>
     <color name="red">#F00</color>
@@ -60,4 +59,6 @@
     <color name="quantum_orange_700">#fff57c00</color>
     <color name="quantum_orange_A200">#ffffab40</color>
     <color name="quantum_orange_A400">#ffff9100</color>
+
+    <color name="dashboard_background_color">#ffe1e1e0</color>
 </resources>
diff --git a/res/values/config.xml b/res/values/config.xml
index 557dadb..86d47fe 100755
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -29,4 +29,7 @@
          very long strings too. -->
     <integer name="maximum_user_dictionary_word_length" translatable="false">48</integer>
 
+    <!-- Dashboard number of columns -->
+    <integer name="dashboard_num_columns">1</integer>
+
 </resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 8188164..562dd80 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -84,4 +84,8 @@
     <dimen name="notification_app_icon_badge_margin">4dp</dimen>
     <dimen name="notification_app_settings_divider_height">48dp</dimen>
     <dimen name="zen_mode_dropdown_width">160dp</dimen>
+
+    <!-- Dashboard padding between each tiles within the layout -->
+    <dimen name="dashboard_cell_gap">4dp</dimen>
+
 </resources>
diff --git a/res/xml/settings_headers.xml b/res/xml/settings_headers.xml
deleted file mode 100644
index bf44854..0000000
--- a/res/xml/settings_headers.xml
+++ /dev/null
@@ -1,217 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 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.
--->
-
-<preference-headers
-        xmlns:android="http://schemas.android.com/apk/res/android">
-
-    <!-- WIRELESS and NETWORKS -->
-    <header android:id="@+id/wireless_section"
-            android:title="@string/header_category_wireless_networks" />
-
-    <!-- Wifi -->
-    <header
-        android:id="@+id/wifi_settings"
-        android:fragment="com.android.settings.wifi.WifiSettings"
-        android:title="@string/wifi_settings_title"
-        android:icon="@drawable/ic_settings_wireless" />
-
-    <!-- Bluetooth -->
-    <header
-        android:id="@+id/bluetooth_settings"
-        android:fragment="com.android.settings.bluetooth.BluetoothSettings"
-        android:title="@string/bluetooth_settings_title"
-        android:icon="@drawable/ic_settings_bluetooth2" />
-
-    <!-- Data Usage -->
-    <header
-        android:id="@+id/data_usage_settings"
-        android:fragment="com.android.settings.DataUsageSummary"
-        android:title="@string/data_usage_summary_title"
-        android:icon="@drawable/ic_settings_data_usage" />
-
-    <!-- Operator hook -->
-    <header
-        android:fragment="com.android.settings.WirelessSettings"
-        android:id="@+id/operator_settings">
-        <intent android:action="com.android.settings.OPERATOR_APPLICATION_SETTING" />
-    </header>
-
-    <!-- Other wireless and network controls -->
-    <header
-        android:id="@+id/wireless_settings"
-        android:title="@string/radio_controls_title"
-        android:breadCrumbTitle="@string/wireless_networks_settings_title"
-        android:fragment="com.android.settings.WirelessSettings" />
-
-    <!-- DEVICE -->
-    <header android:id="@+id/device_section"
-        android:title="@string/header_category_device" />
-
-    <!-- Home -->
-    <header
-        android:id="@+id/home_settings"
-        android:icon="@drawable/ic_settings_home"
-        android:fragment="com.android.settings.HomeSettings"
-        android:title="@string/home_settings" />
-
-    <!-- Sound -->
-    <header
-        android:id="@+id/sound_settings"
-        android:icon="@drawable/ic_settings_sound"
-        android:fragment="com.android.settings.SoundSettings"
-        android:title="@string/sound_settings" />
-
-    <!-- Display -->
-    <header
-        android:id="@+id/display_settings"
-        android:icon="@drawable/ic_settings_display"
-        android:fragment="com.android.settings.DisplaySettings"
-        android:title="@string/display_settings" />
-
-    <!-- Notifications -->
-    <header
-        android:id="@+id/notification_settings"
-        android:icon="@drawable/ic_settings_notifications"
-        android:fragment="com.android.settings.notification.NotificationSettings"
-        android:title="@string/notification_settings" />
-
-    <!-- Storage -->
-    <header
-        android:id="@+id/storage_settings"
-        android:fragment="com.android.settings.deviceinfo.Memory"
-        android:icon="@drawable/ic_settings_storage"
-        android:title="@string/storage_settings" />
-
-    <!-- Battery -->
-    <header
-        android:id="@+id/battery_settings"
-        android:fragment="com.android.settings.fuelgauge.PowerUsageSummary"
-        android:icon="@drawable/ic_settings_battery"
-        android:title="@string/power_usage_summary_title" />
-
-    <!-- Application Settings -->
-    <header
-        android:fragment="com.android.settings.applications.ManageApplications"
-        android:icon="@drawable/ic_settings_applications"
-        android:title="@string/applications_settings"
-        android:id="@+id/application_settings" />
-
-    <!-- Manage users -->
-    <header
-        android:fragment="com.android.settings.users.UserSettings"
-        android:icon="@drawable/ic_settings_multiuser"
-        android:title="@string/user_settings_title"
-        android:id="@+id/user_settings" />
-
-    <!-- Manage NFC payment apps -->
-    <header
-        android:fragment="com.android.settings.nfc.PaymentSettings"
-        android:icon="@drawable/ic_settings_nfc_payment"
-        android:title="@string/nfc_payment_settings_title"
-        android:id="@+id/nfc_payment_settings" />
-
-    <!-- Manufacturer hook -->
-    <header
-        android:fragment="com.android.settings.WirelessSettings"
-        android:id="@+id/manufacturer_settings">
-        <intent android:action="com.android.settings.MANUFACTURER_APPLICATION_SETTING" />
-    </header>
-
-    <!-- PERSONAL -->
-    <header android:id="@+id/personal_section"
-        android:title="@string/header_category_personal" />
-
-    <!-- Location -->
-    <header
-        android:fragment="com.android.settings.location.LocationSettings"
-        android:icon="@drawable/ic_settings_location"
-        android:title="@string/location_settings_title"
-        android:id="@+id/location_settings" />
-
-    <!-- Security -->
-    <header
-        android:fragment="com.android.settings.SecuritySettings"
-        android:icon="@drawable/ic_settings_security"
-        android:title="@string/security_settings_title"
-        android:id="@+id/security_settings" />
-
-    <!-- Language -->
-    <header
-        android:id="@+id/language_settings"
-        android:fragment="com.android.settings.inputmethod.InputMethodAndLanguageSettings"
-        android:icon="@drawable/ic_settings_language"
-        android:title="@string/language_settings" />
-
-    <!-- Backup and reset -->
-    <header
-        android:fragment="com.android.settings.PrivacySettings"
-        android:icon="@drawable/ic_settings_backup"
-        android:title="@string/privacy_settings"
-        android:id="@+id/privacy_settings" />
-
-    <!--  ACCOUNTS section -->
-    <header
-            android:id="@+id/account_settings"
-            android:title="@string/account_settings" />
-
-    <header
-            android:id="@+id/account_add"
-            android:title="@string/add_account_label"
-            android:icon="@drawable/ic_menu_add_dark">
-        <intent
-            android:action="android.settings.ADD_ACCOUNT_SETTINGS"/>
-    </header>
-
-    <!-- SYSTEM -->
-    <header android:id="@+id/system_section"
-        android:title="@string/header_category_system" />
-
-    <!-- Date & Time -->
-    <header
-        android:id="@+id/date_time_settings"
-        android:fragment="com.android.settings.DateTimeSettings"
-        android:icon="@drawable/ic_settings_date_time"
-        android:title="@string/date_and_time_settings_title" />
-
-    <!-- Accessibility feedback -->
-    <header
-        android:id="@+id/accessibility_settings"
-        android:fragment="com.android.settings.accessibility.AccessibilitySettings"
-        android:icon="@drawable/ic_settings_accessibility"
-        android:title="@string/accessibility_settings" />
-
-    <!-- Print -->
-    <header
-        android:id="@+id/print_settings"
-        android:fragment="com.android.settings.print.PrintSettingsFragment"
-        android:icon="@*android:drawable/ic_print"
-        android:title="@string/print_settings" />
-
-    <!-- Development -->
-    <header
-        android:id="@+id/development_settings"
-        android:fragment="com.android.settings.DevelopmentSettings"
-        android:icon="@drawable/ic_settings_development"
-        android:title="@string/development_settings_title" />
-
-    <!-- About Device -->
-    <header
-        android:id="@+id/about_settings"
-        android:fragment="com.android.settings.DeviceInfoSettings"
-        android:icon="@drawable/ic_settings_about"
-        android:title="@string/about_settings" />
-
-</preference-headers>
diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java
index 699955a..1bc0501 100644
--- a/src/com/android/settings/SettingsActivity.java
+++ b/src/com/android/settings/SettingsActivity.java
@@ -24,7 +24,6 @@
 import android.app.Fragment;
 import android.app.FragmentManager;
 import android.app.FragmentTransaction;
-import android.app.admin.DevicePolicyManager;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
@@ -62,7 +61,6 @@
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.widget.Button;
-import android.widget.ListView;
 
 import android.widget.SearchView;
 import com.android.internal.util.ArrayUtils;
@@ -80,7 +78,6 @@
 import com.android.settings.dashboard.DashboardSummary;
 import com.android.settings.dashboard.DashboardTile;
 import com.android.settings.dashboard.Header;
-import com.android.settings.dashboard.HeaderAdapter;
 import com.android.settings.dashboard.NoHomeDialogFragment;
 import com.android.settings.dashboard.SearchResultsSummary;
 import com.android.settings.deviceinfo.Memory;
@@ -115,7 +112,6 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
-import java.util.HashMap;
 import java.util.List;
 
 import static com.android.settings.dashboard.Header.HEADER_ID_UNDEFINED;
@@ -130,7 +126,7 @@
     private static final String LOG_TAG = "Settings";
 
     // Constants for state save/restore
-    private static final String SAVE_KEY_HEADERS = ":settings:headers";
+    private static final String SAVE_KEY_CATEGORIES = ":settings:categories";
     private static final String SAVE_KEY_SEARCH_MENU_EXPANDED = ":settings:search_menu_expanded";
     private static final String SAVE_KEY_SEARCH_QUERY = ":settings:search_query";
     private static final String SAVE_KEY_SHOW_HOME_AS_UP = ":settings:show_home_as_up";
@@ -199,7 +195,6 @@
     private static boolean sShowNoHomeNotice = false;
 
     private String mFragmentClass;
-    private Header mSelectedHeader;
 
     private CharSequence mInitialTitle;
 
@@ -305,7 +300,7 @@
 
                 if (mBatteryPresent != batteryPresent) {
                     mBatteryPresent = batteryPresent;
-                    invalidateHeaders();
+                    invalidateCategories();
                 }
             }
         }
@@ -324,21 +319,17 @@
     private SearchResultsSummary mSearchResultsFragment;
     private String mSearchQuery;
 
-    // Headers
-    private final ArrayList<Header> mHeaders = new ArrayList<Header>();
-    private HeaderAdapter mHeaderAdapter;
+    // Categories
+    private ArrayList<DashboardCategory> mCategories = new ArrayList<DashboardCategory>();
+    private boolean mNeedToRebuildCategories;
 
-    private List<DashboardCategory> mCategories = new ArrayList<DashboardCategory>();
-
-    private static final int MSG_BUILD_HEADERS = 1;
+    private static final int MSG_BUILD_CATEGORIES = 1;
     private Handler mHandler = new Handler() {
         @Override
         public void handleMessage(Message msg) {
             switch (msg.what) {
-                case MSG_BUILD_HEADERS: {
-                    mHeaders.clear();
-                    onBuildHeaders(mHeaders);
-                    mHeaderAdapter.notifyDataSetChanged();
+                case MSG_BUILD_CATEGORIES: {
+                    buildDashboardCategories(mCategories);
                 } break;
             }
         }
@@ -346,6 +337,18 @@
 
     private boolean mNeedToRevertToInitialFragment = false;
 
+    public AuthenticatorHelper getAuthenticatorHelper() {
+        return mAuthenticatorHelper;
+    }
+
+    public List<DashboardCategory> getDashboardCategories() {
+        if (mNeedToRebuildCategories) {
+            buildDashboardCategories(mCategories);
+            mNeedToRebuildCategories = false;
+        }
+        return mCategories;
+    }
+
     @Override
     public boolean onPreferenceStartFragment(PreferenceFragment caller, Preference pref) {
         // Override the fragment title for Wallpaper settings
@@ -370,9 +373,9 @@
         return false;
     }
 
-    private void invalidateHeaders() {
-        if (!mHandler.hasMessages(MSG_BUILD_HEADERS)) {
-            mHandler.sendEmptyMessage(MSG_BUILD_HEADERS);
+    private void invalidateCategories() {
+        if (!mHandler.hasMessages(MSG_BUILD_CATEGORIES)) {
+            mHandler.sendEmptyMessage(MSG_BUILD_CATEGORIES);
         }
     }
 
@@ -428,11 +431,6 @@
         mAuthenticatorHelper.updateAuthDescriptions(this);
         mAuthenticatorHelper.onAccountsUpdated(this, null);
 
-        DevicePolicyManager dpm =
-                (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
-
-        mHeaderAdapter = new HeaderAdapter(this, mHeaders, mAuthenticatorHelper, dpm);
-
         mDevelopmentPreferences = getSharedPreferences(DevelopmentSettings.PREF_FILE,
                 Context.MODE_PRIVATE);
 
@@ -463,16 +461,17 @@
             mInitialTitle = (initialTitle != null) ? initialTitle : getTitle();
             setTitle(mInitialTitle);
 
-            ArrayList<Header> headers = savedState.getParcelableArrayList(SAVE_KEY_HEADERS);
-            if (headers != null) {
-                mHeaders.addAll(headers);
+            ArrayList<DashboardCategory> categories =
+                    savedState.getParcelableArrayList(SAVE_KEY_CATEGORIES);
+            if (categories != null) {
+                mCategories.addAll(categories);
                 setTitleFromBackStack();
             }
 
             mDisplayHomeAsUpEnabled = savedState.getBoolean(SAVE_KEY_SHOW_HOME_AS_UP);
         } else {
-            // We need to build the Headers in all cases
-            onBuildHeaders(mHeaders);
+            // We need to build the Categories in all cases
+            buildDashboardCategories(mCategories);
 
             if (initialFragmentName != null) {
                 final ComponentName cn = getIntent().getComponent();
@@ -490,7 +489,7 @@
             } else {
                 // No UP if we are displaying the Headers
                 mDisplayHomeAsUpEnabled = false;
-                if (mHeaders.size() > 0) {
+                if (mCategories.size() > 0) {
                     mInitialTitle = getText(R.string.dashboard_title);
                     switchToFragment(DashboardSummary.class.getName(), null, false, false,
                             mInitialTitle, false);
@@ -594,8 +593,8 @@
     protected void onSaveInstanceState(Bundle outState) {
         super.onSaveInstanceState(outState);
 
-        if (mHeaders.size() > 0) {
-            outState.putParcelableArrayList(SAVE_KEY_HEADERS, mHeaders);
+        if (mCategories.size() > 0) {
+            outState.putParcelableArrayList(SAVE_KEY_CATEGORIES, mCategories);
         }
 
         outState.putBoolean(SAVE_KEY_SHOW_HOME_AS_UP, mDisplayHomeAsUpEnabled);
@@ -619,13 +618,13 @@
         mDevelopmentPreferencesListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
             @Override
             public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
-                invalidateHeaders();
+                invalidateCategories();
             }
         };
         mDevelopmentPreferences.registerOnSharedPreferenceChangeListener(
                 mDevelopmentPreferencesListener);
 
-        invalidateHeaders();
+        invalidateCategories();
 
         registerReceiver(mBatteryInfoReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
 
@@ -679,7 +678,7 @@
             return;
         }
         if (header.fragment != null) {
-            startWithFragment(header.fragment, header.fragmentArguments, null, 0,
+            Utils.startWithFragment(this, header.fragment, header.fragmentArguments, null, 0,
                     header.getTitle(getResources()));
         } else if (header.intent != null) {
             startActivity(header.intent);
@@ -769,7 +768,7 @@
             // There not much we can do in that case
             title = "";
         }
-        startWithFragment(fragmentClass, args, resultTo, resultRequestCode, title);
+        Utils.startWithFragment(this, fragmentClass, args, resultTo, resultRequestCode, title);
     }
 
     /**
@@ -829,359 +828,17 @@
         return f;
     }
 
-    /**
-     * Start a new instance of this activity, showing only the given fragment.
-     * When launched in this mode, the given preference fragment will be instantiated and fill the
-     * entire activity.
-     *
-     * @param fragmentName The name of the fragment to display.
-     * @param args Optional arguments to supply to the fragment.
-     * @param resultTo Option fragment that should receive the result of
-     * the activity launch.
-     * @param resultRequestCode If resultTo is non-null, this is the request
-     * code in which to report the result.
-     * @param title String to display for the title of this set of preferences.
-     */
-    public void startWithFragment(String fragmentName, Bundle args,
-                                  Fragment resultTo, int resultRequestCode, CharSequence title) {
-        Intent intent = onBuildStartFragmentIntent(fragmentName, args, title);
-        if (resultTo == null) {
-            startActivity(intent);
-        } else {
-            resultTo.startActivityForResult(intent, resultRequestCode);
-        }
+    public void setNeedToRebuildCategories(boolean need) {
+        mNeedToRebuildCategories = need;
     }
 
     /**
-     * Build an Intent to launch a new activity showing the selected fragment.
-     * The implementation constructs an Intent that re-launches the current activity with the
-     * appropriate arguments to display the fragment.
-     *
-     * @param fragmentName The name of the fragment to display.
-     * @param args Optional arguments to supply to the fragment.
-     * @param title Optional title to show for this item.
-     * @return Returns an Intent that can be launched to display the given
-     * fragment.
-     */
-    public Intent onBuildStartFragmentIntent(String fragmentName, Bundle args, CharSequence title) {
-        Intent intent = new Intent(Intent.ACTION_MAIN);
-        intent.setClass(this, SubSettings.class);
-        intent.putExtra(EXTRA_SHOW_FRAGMENT, fragmentName);
-        intent.putExtra(EXTRA_SHOW_FRAGMENT_ARGUMENTS, args);
-        intent.putExtra(EXTRA_SHOW_FRAGMENT_TITLE, title);
-        intent.putExtra(EXTRA_NO_HEADERS, true);
-        return intent;
-    }
-
-    /**
-     * Called when the activity needs its list of headers build.
-     *
-     * @param headers The list in which to place the headers.
-     */
-    private void onBuildHeaders(List<Header> headers) {
-        loadHeadersFromResource(R.xml.settings_headers, headers);
-        updateHeaderList(headers);
-    }
-
-    /**
-     * Parse the given XML file as a header description, adding each
-     * parsed Header into the target list.
-     *
-     * @param resid The XML resource to load and parse.
-     * @param target The list in which the parsed headers should be placed.
-     */
-    private void loadHeadersFromResource(int resid, List<Header> target) {
-        XmlResourceParser parser = null;
-        try {
-            parser = getResources().getXml(resid);
-            AttributeSet attrs = Xml.asAttributeSet(parser);
-
-            int type;
-            while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
-                    && type != XmlPullParser.START_TAG) {
-                // Parse next until start tag is found
-            }
-
-            String nodeName = parser.getName();
-            if (!"preference-headers".equals(nodeName)) {
-                throw new RuntimeException(
-                        "XML document must start with <preference-headers> tag; found"
-                                + nodeName + " at " + parser.getPositionDescription());
-            }
-
-            Bundle curBundle = null;
-
-            final int outerDepth = parser.getDepth();
-            while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
-                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
-                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
-                    continue;
-                }
-
-                nodeName = parser.getName();
-                if ("header".equals(nodeName)) {
-                    Header header = new Header();
-
-                    TypedArray sa = obtainStyledAttributes(
-                            attrs, com.android.internal.R.styleable.PreferenceHeader);
-                    header.id = sa.getResourceId(
-                            com.android.internal.R.styleable.PreferenceHeader_id,
-                            (int)HEADER_ID_UNDEFINED);
-                    TypedValue tv = sa.peekValue(
-                            com.android.internal.R.styleable.PreferenceHeader_title);
-                    if (tv != null && tv.type == TypedValue.TYPE_STRING) {
-                        if (tv.resourceId != 0) {
-                            header.titleRes = tv.resourceId;
-                        } else {
-                            header.title = tv.string;
-                        }
-                    }
-                    tv = sa.peekValue(
-                            com.android.internal.R.styleable.PreferenceHeader_summary);
-                    if (tv != null && tv.type == TypedValue.TYPE_STRING) {
-                        if (tv.resourceId != 0) {
-                            header.summaryRes = tv.resourceId;
-                        } else {
-                            header.summary = tv.string;
-                        }
-                    }
-                    header.iconRes = sa.getResourceId(
-                            com.android.internal.R.styleable.PreferenceHeader_icon, 0);
-                    header.fragment = sa.getString(
-                            com.android.internal.R.styleable.PreferenceHeader_fragment);
-                    sa.recycle();
-
-                    if (curBundle == null) {
-                        curBundle = new Bundle();
-                    }
-
-                    final int innerDepth = parser.getDepth();
-                    while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
-                            && (type != XmlPullParser.END_TAG || parser.getDepth() > innerDepth)) {
-                        if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
-                            continue;
-                        }
-
-                        String innerNodeName = parser.getName();
-                        if (innerNodeName.equals("extra")) {
-                            getResources().parseBundleExtra("extra", attrs, curBundle);
-                            XmlUtils.skipCurrentTag(parser);
-
-                        } else if (innerNodeName.equals("intent")) {
-                            header.intent = Intent.parseIntent(getResources(), parser, attrs);
-
-                        } else {
-                            XmlUtils.skipCurrentTag(parser);
-                        }
-                    }
-
-                    if (curBundle.size() > 0) {
-                        header.fragmentArguments = curBundle;
-                        curBundle = null;
-                    }
-
-                    target.add(header);
-                } else {
-                    XmlUtils.skipCurrentTag(parser);
-                }
-            }
-
-        } catch (XmlPullParserException e) {
-            throw new RuntimeException("Error parsing headers", e);
-        } catch (IOException e) {
-            throw new RuntimeException("Error parsing headers", e);
-        } finally {
-            if (parser != null) parser.close();
-        }
-    }
-
-    private void updateHeaderList(List<Header> target) {
-        final boolean showDev = mDevelopmentPreferences.getBoolean(
-                DevelopmentSettings.PREF_SHOW,
-                android.os.Build.TYPE.equals("eng"));
-        int i = 0;
-
-        final UserManager um = (UserManager) getSystemService(Context.USER_SERVICE);
-        while (i < target.size()) {
-            Header header = target.get(i);
-            // Ids are integers, so downcasting
-            int id = (int) header.id;
-            if (id == R.id.operator_settings || id == R.id.manufacturer_settings) {
-                Utils.updateHeaderToSpecificActivityFromMetaDataOrRemove(this, target, header);
-            } else if (id == R.id.wifi_settings) {
-                // Remove WiFi Settings if WiFi service is not available.
-                if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI)) {
-                    target.remove(i);
-                }
-            } else if (id == R.id.bluetooth_settings) {
-                // Remove Bluetooth Settings if Bluetooth service is not available.
-                if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)) {
-                    target.remove(i);
-                }
-            } else if (id == R.id.data_usage_settings) {
-                // Remove data usage when kernel module not enabled
-                final INetworkManagementService netManager = INetworkManagementService.Stub
-                        .asInterface(ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE));
-                try {
-                    if (!netManager.isBandwidthControlEnabled()) {
-                        target.remove(i);
-                    }
-                } catch (RemoteException e) {
-                    // ignored
-                }
-            } else if (id == R.id.battery_settings) {
-                // Remove battery settings when battery is not available. (e.g. TV)
-
-                if (!mBatteryPresent) {
-                    target.remove(i);
-                }
-            } else if (id == R.id.account_settings) {
-                int headerIndex = i + 1;
-                i = insertAccountsHeaders(target, headerIndex);
-            } else if (id == R.id.home_settings) {
-                if (!updateHomeSettingHeaders(header)) {
-                    target.remove(i);
-                }
-            } else if (id == R.id.user_settings) {
-                if (!UserHandle.MU_ENABLED
-                        || !UserManager.supportsMultipleUsers()
-                        || Utils.isMonkeyRunning()) {
-                    target.remove(i);
-                }
-            } else if (id == R.id.nfc_payment_settings) {
-                if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_NFC)) {
-                    target.remove(i);
-                } else {
-                    // Only show if NFC is on and we have the HCE feature
-                    NfcAdapter adapter = NfcAdapter.getDefaultAdapter(this);
-                    if (!adapter.isEnabled() || !getPackageManager().hasSystemFeature(
-                            PackageManager.FEATURE_NFC_HOST_CARD_EMULATION)) {
-                        target.remove(i);
-                    }
-                }
-            } else if (id == R.id.development_settings) {
-                if (!showDev) {
-                    target.remove(i);
-                }
-            } else if (id == R.id.account_add) {
-                if (um.hasUserRestriction(UserManager.DISALLOW_MODIFY_ACCOUNTS)) {
-                    target.remove(i);
-                }
-            }
-
-            if (i < target.size() && target.get(i) == header
-                    && UserHandle.MU_ENABLED && UserHandle.myUserId() != 0
-                    && !ArrayUtils.contains(SETTINGS_FOR_RESTRICTED, id)) {
-                target.remove(i);
-            }
-
-            // Increment if the current one wasn't removed by the Utils code.
-            if (i < target.size() && target.get(i) == header) {
-                i++;
-            }
-        }
-    }
-
-    private int insertAccountsHeaders(List<Header> target, int headerIndex) {
-        String[] accountTypes = mAuthenticatorHelper.getEnabledAccountTypes();
-        List<Header> accountHeaders = new ArrayList<Header>(accountTypes.length);
-        for (String accountType : accountTypes) {
-            CharSequence label = mAuthenticatorHelper.getLabelForType(this, accountType);
-            if (label == null) {
-                continue;
-            }
-
-            Account[] accounts = AccountManager.get(this).getAccountsByType(accountType);
-            boolean skipToAccount = accounts.length == 1
-                    && !mAuthenticatorHelper.hasAccountPreferences(accountType);
-            Header accHeader = new Header();
-            accHeader.title = label;
-            if (accHeader.extras == null) {
-                accHeader.extras = new Bundle();
-            }
-            if (skipToAccount) {
-                accHeader.fragment = AccountSyncSettings.class.getName();
-                accHeader.fragmentArguments = new Bundle();
-                // Need this for the icon
-                accHeader.extras.putString(ManageAccountsSettings.KEY_ACCOUNT_TYPE, accountType);
-                accHeader.extras.putParcelable(AccountSyncSettings.ACCOUNT_KEY, accounts[0]);
-                accHeader.fragmentArguments.putParcelable(AccountSyncSettings.ACCOUNT_KEY,
-                        accounts[0]);
-            } else {
-                accHeader.fragment = ManageAccountsSettings.class.getName();
-                accHeader.fragmentArguments = new Bundle();
-                accHeader.extras.putString(ManageAccountsSettings.KEY_ACCOUNT_TYPE, accountType);
-                accHeader.fragmentArguments.putString(ManageAccountsSettings.KEY_ACCOUNT_TYPE,
-                        accountType);
-                    accHeader.fragmentArguments.putString(ManageAccountsSettings.KEY_ACCOUNT_LABEL,
-                            label.toString());
-            }
-            accountHeaders.add(accHeader);
-            mAuthenticatorHelper.preloadDrawableForType(this, accountType);
-        }
-
-        // Sort by label
-        Collections.sort(accountHeaders, new Comparator<Header>() {
-            @Override
-            public int compare(Header h1, Header h2) {
-                return h1.title.toString().compareTo(h2.title.toString());
-            }
-        });
-
-        for (Header header : accountHeaders) {
-            target.add(headerIndex++, header);
-        }
-        if (!mListeningToAccountUpdates) {
-            AccountManager.get(this).addOnAccountsUpdatedListener(this, null, true);
-            mListeningToAccountUpdates = true;
-        }
-        return headerIndex;
-    }
-
-    private boolean updateHomeSettingHeaders(Header header) {
-        // Once we decide to show Home settings, keep showing it forever
-        SharedPreferences sp = getSharedPreferences(HomeSettings.HOME_PREFS, Context.MODE_PRIVATE);
-        if (sp.getBoolean(HomeSettings.HOME_PREFS_DO_SHOW, false)) {
-            return true;
-        }
-
-        try {
-            final ArrayList<ResolveInfo> homeApps = new ArrayList<ResolveInfo>();
-            getPackageManager().getHomeActivities(homeApps);
-            if (homeApps.size() < 2) {
-                // When there's only one available home app, omit this settings
-                // category entirely at the top level UI.  If the user just
-                // uninstalled the penultimate home app candidiate, we also
-                // now tell them about why they aren't seeing 'Home' in the list.
-                if (sShowNoHomeNotice) {
-                    sShowNoHomeNotice = false;
-                    NoHomeDialogFragment.show(this);
-                }
-                return false;
-            } else {
-                // Okay, we're allowing the Home settings category.  Tell it, when
-                // invoked via this front door, that we'll need to be told about the
-                // case when the user uninstalls all but one home app.
-                if (header.fragmentArguments == null) {
-                    header.fragmentArguments = new Bundle();
-                }
-                header.fragmentArguments.putBoolean(HomeSettings.HOME_SHOW_NOTICE, true);
-            }
-        } catch (Exception e) {
-            // Can't look up the home activity; bail on configuring the icon
-            Log.w(LOG_TAG, "Problem looking up home activity!", e);
-        }
-
-        sp.edit().putBoolean(HomeSettings.HOME_PREFS_DO_SHOW, true).apply();
-        return true;
-    }
-
-    /**
-     * Called when the activity needs its list of categories/tiles build.
+     * Called when the activity needs its list of categories/tiles built.
      *
      * @param categories The list in which to place the tiles categories.
      */
-    private void onBuildDashboardCategories(List<DashboardCategory> categories) {
+    private void buildDashboardCategories(List<DashboardCategory> categories) {
+        mCategories.clear();
         loadCategoriesFromResource(R.xml.dashboard_categories, categories);
         updateTilesList(categories);
     }
@@ -1542,22 +1199,6 @@
         return mNextButton;
     }
 
-    public HeaderAdapter getHeaderAdapter() {
-        return mHeaderAdapter;
-    }
-
-    public void onListItemClick(ListView l, View v, int position, long id) {
-        if (!isResumed()) {
-            return;
-        }
-        Object item = mHeaderAdapter.getItem(position);
-        if (item instanceof Header) {
-            mSelectedHeader = (Header) item;
-            onHeaderClick(mSelectedHeader, position);
-            revertToInitialFragment();
-        }
-    }
-
     @Override
     public boolean shouldUpRecreateTask(Intent targetIntent) {
         return super.shouldUpRecreateTask(new Intent(this, SettingsActivity.class));
@@ -1568,7 +1209,7 @@
         // TODO: watch for package upgrades to invalidate cache; see 7206643
         mAuthenticatorHelper.updateAuthDescriptions(this);
         mAuthenticatorHelper.onAccountsUpdated(this, accounts);
-        invalidateHeaders();
+        invalidateCategories();
     }
 
     public static void requestHomeNotice() {
diff --git a/src/com/android/settings/SoundSettings.java b/src/com/android/settings/SoundSettings.java
index 49928f5..eadd482 100644
--- a/src/com/android/settings/SoundSettings.java
+++ b/src/com/android/settings/SoundSettings.java
@@ -141,7 +141,10 @@
 
         if (TelephonyManager.PHONE_TYPE_CDMA != activePhoneType) {
             // device is not CDMA, do not display CDMA emergency_tone
-            getPreferenceScreen().removePreference(findPreference(KEY_EMERGENCY_TONE));
+            Preference pref = findPreference(KEY_EMERGENCY_TONE);
+            if (pref != null) {
+                getPreferenceScreen().removePreference(pref);
+            }
         }
 
         if (!getResources().getBoolean(R.bool.has_silent_mode)) {
@@ -150,7 +153,10 @@
 
         if (getResources().getBoolean(com.android.internal.R.bool.config_useFixedVolume)) {
             // device with fixed volume policy, do not display volumes submenu
-            getPreferenceScreen().removePreference(findPreference(KEY_RING_VOLUME));
+            Preference pref = findPreference(KEY_RING_VOLUME);
+            if (pref != null) {
+                getPreferenceScreen().removePreference(pref);
+            }
         }
 
         mVibrateWhenRinging = (CheckBoxPreference) findPreference(KEY_VIBRATE);
diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java
index d743b6f..8abe30d 100644
--- a/src/com/android/settings/Utils.java
+++ b/src/com/android/settings/Utils.java
@@ -19,6 +19,7 @@
 import android.app.ActivityManager;
 import android.app.AlertDialog;
 import android.app.Dialog;
+import android.app.Fragment;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.DialogInterface;
@@ -655,4 +656,51 @@
         return ((UserManager) context.getSystemService(Context.USER_SERVICE))
                 .getUsers().size() > 1;
     }
+
+    /**
+     * Start a new instance of the activity, showing only the given fragment.
+     * When launched in this mode, the given preference fragment will be instantiated and fill the
+     * entire activity.
+     *
+     * @param context The context.
+     * @param fragmentName The name of the fragment to display.
+     * @param args Optional arguments to supply to the fragment.
+     * @param resultTo Option fragment that should receive the result of
+     * the activity launch.
+     * @param resultRequestCode If resultTo is non-null, this is the request
+     * code in which to report the result.
+     * @param title String to display for the title of this set of preferences.
+     */
+    public static void startWithFragment(Context context, String fragmentName, Bundle args,
+            Fragment resultTo, int resultRequestCode, CharSequence title) {
+        Intent intent = onBuildStartFragmentIntent(context, fragmentName, args, title);
+        if (resultTo == null) {
+            context.startActivity(intent);
+        } else {
+            resultTo.startActivityForResult(intent, resultRequestCode);
+        }
+    }
+
+    /**
+     * Build an Intent to launch a new activity showing the selected fragment.
+     * The implementation constructs an Intent that re-launches the current activity with the
+     * appropriate arguments to display the fragment.
+     *
+     * @param context The Context.
+     * @param fragmentName The name of the fragment to display.
+     * @param args Optional arguments to supply to the fragment.
+     * @param title Optional title to show for this item.
+     * @return Returns an Intent that can be launched to display the given
+     * fragment.
+     */
+    public static Intent onBuildStartFragmentIntent(Context context, String fragmentName,
+            Bundle args, CharSequence title) {
+        Intent intent = new Intent(Intent.ACTION_MAIN);
+        intent.setClass(context, SubSettings.class);
+        intent.putExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT, fragmentName);
+        intent.putExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS, args);
+        intent.putExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_TITLE, title);
+        intent.putExtra(SettingsActivity.EXTRA_NO_HEADERS, true);
+        return intent;
+    }
 }
diff --git a/src/com/android/settings/dashboard/DashboardContainerView.java b/src/com/android/settings/dashboard/DashboardContainerView.java
new file mode 100644
index 0000000..d4512e6
--- /dev/null
+++ b/src/com/android/settings/dashboard/DashboardContainerView.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2014 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.content.res.Resources;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.ViewGroup;
+import com.android.settings.R;
+
+public class DashboardContainerView extends ViewGroup {
+
+    private int mNumColumns;
+    private float mCellGap;
+
+    public DashboardContainerView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+
+        final Resources res = context.getResources();
+        mCellGap = res.getDimension(R.dimen.dashboard_cell_gap);
+        mNumColumns = res.getInteger(R.integer.dashboard_num_columns);
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        final int width = MeasureSpec.getSize(widthMeasureSpec);
+        final int availableWidth = (int) (width - getPaddingLeft() - getPaddingRight() -
+                (mNumColumns - 1) * mCellGap);
+        float cellWidth = (float) Math.ceil(((float) availableWidth) / mNumColumns);
+        final int N = getChildCount();
+
+        int cellHeight = 0;
+        int cursor = 0;
+
+        for (int i = 0; i < N; ++i) {
+            DashboardTileView v = (DashboardTileView) getChildAt(i);
+            if (v.getVisibility() == View.GONE) {
+                continue;
+            }
+
+            ViewGroup.LayoutParams lp = v.getLayoutParams();
+            int colSpan = v.getColumnSpan();
+            lp.width = (int) ((colSpan * cellWidth) + (colSpan - 1) * mCellGap);
+
+            // Measure the child
+            int newWidthSpec = getChildMeasureSpec(widthMeasureSpec, 0, lp.width);
+            int newHeightSpec = getChildMeasureSpec(heightMeasureSpec, 0, lp.height);
+            v.measure(newWidthSpec, newHeightSpec);
+
+            // Save the cell height
+            if (cellHeight <= 0) {
+                cellHeight = v.getMeasuredHeight();
+            }
+
+            lp.height = cellHeight;
+
+            cursor += colSpan;
+        }
+
+        final int numRows = (int) Math.ceil((float) cursor / mNumColumns);
+        final int newHeight = (int) ((numRows * cellHeight) + ((numRows - 1) * mCellGap)) +
+                getPaddingTop() + getPaddingBottom();
+
+        setMeasuredDimension(width, newHeight);
+    }
+
+    @Override
+    protected void onLayout(boolean changed, int l, int t, int r, int b) {
+        final int N = getChildCount();
+        final boolean isLayoutRtl = isLayoutRtl();
+        final int width = getWidth();
+
+        int x = getPaddingStart();
+        int y = getPaddingTop();
+        int cursor = 0;
+
+        for (int i = 0; i < N; ++i) {
+            final DashboardTileView child = (DashboardTileView) getChildAt(i);
+            final ViewGroup.LayoutParams lp = child.getLayoutParams();
+            if (child.getVisibility() == GONE) {
+                continue;
+            }
+
+            final int col = cursor % mNumColumns;
+            final int colSpan = child.getColumnSpan();
+
+            final int childWidth = lp.width;
+            final int childHeight = lp.height;
+
+            int row = cursor / mNumColumns;
+
+            // Push the item to the next row if it can't fit on this one
+            if ((col + colSpan) > mNumColumns) {
+                x = getPaddingStart();
+                y += childHeight + mCellGap;
+                row++;
+            }
+
+            final int childLeft = (isLayoutRtl) ? width - x - childWidth : x;
+            final int childRight = childLeft + childWidth;
+
+            final int childTop = y;
+            final int childBottom = childTop + childHeight;
+
+            // Layout the container
+            child.layout(childLeft, childTop, childRight, childBottom);
+
+            // Offset the position by the cell gap or reset the position and cursor when we
+            // reach the end of the row
+            cursor += child.getColumnSpan();
+            if (cursor < (((row + 1) * mNumColumns))) {
+                x += childWidth + mCellGap;
+            } else {
+                x = getPaddingStart();
+                y += childHeight + mCellGap;
+            }
+        }
+    }
+}
diff --git a/src/com/android/settings/dashboard/DashboardSummary.java b/src/com/android/settings/dashboard/DashboardSummary.java
index f023dec..54a56ab 100644
--- a/src/com/android/settings/dashboard/DashboardSummary.java
+++ b/src/com/android/settings/dashboard/DashboardSummary.java
@@ -16,35 +16,166 @@
 
 package com.android.settings.dashboard;
 
-import android.app.ListFragment;
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.accounts.OnAccountsUpdateListener;
+import android.app.Fragment;
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.drawable.Drawable;
 import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.text.TextUtils;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
-import android.widget.ListAdapter;
-import android.widget.ListView;
+import android.widget.ImageView;
+import android.widget.TextView;
 import com.android.settings.R;
 import com.android.settings.SettingsActivity;
+import com.android.settings.accounts.AuthenticatorHelper;
+import com.android.settings.accounts.ManageAccountsSettings;
 
-public class DashboardSummary extends ListFragment {
+import java.util.List;
+
+public class DashboardSummary extends Fragment implements OnAccountsUpdateListener {
     private static final String LOG_TAG = "DashboardSummary";
 
+    private LayoutInflater mLayoutInflater;
+    private ViewGroup mContainer;
+    private ViewGroup mDashboard;
+    private AuthenticatorHelper mAuthHelper;
+
+    private static final int MSG_BUILD_CATEGORIES = 1;
+    private Handler mHandler = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MSG_BUILD_CATEGORIES: {
+                    final Context context = getActivity();
+                    rebuildUI(context);
+                } break;
+            }
+        }
+    };
+
     @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container,
                              Bundle savedInstanceState) {
 
-        final View view = inflater.inflate(R.layout.dashboard, container, false);
+        final Context context = getActivity();
 
-        ListView listView = (ListView) view.findViewById(android.R.id.list);
+        mLayoutInflater = inflater;
+        mContainer = container;
 
-        ListAdapter adapter = ((SettingsActivity) getActivity()).getHeaderAdapter();
-        listView.setAdapter(adapter);
+        final View rootView = inflater.inflate(R.layout.dashboard, container, false);
+        mDashboard = (ViewGroup) rootView.findViewById(R.id.dashboard_container);
 
-        return view;
+        mAuthHelper = ((SettingsActivity) context).getAuthenticatorHelper();
+
+        rebuildUI(getActivity());
+
+        return rootView;
+    }
+
+    private void rebuildUI(Context context) {
+        final Resources res = getResources();
+
+        mDashboard.removeAllViews();
+
+        List<DashboardCategory> categories =
+                ((SettingsActivity) context).getDashboardCategories();
+
+        final int count = categories.size();
+
+        for (int n = 0; n < count; n++) {
+            DashboardCategory category = categories.get(n);
+
+            View categoryView = mLayoutInflater.inflate(R.layout.dashboard_category, mContainer,
+                    false);
+
+            TextView categoryLabel = (TextView) categoryView.findViewById(R.id.category_title);
+            categoryLabel.setText(category.getTitle(res));
+
+            ViewGroup categoryContent =
+                    (ViewGroup) categoryView.findViewById(R.id.category_content);
+
+            final int tilesCount = category.getTilesCount();
+            for (int i = 0; i < tilesCount; i++) {
+                DashboardTile tile = category.getTile(i);
+
+                DashboardTileView tileView = new DashboardTileView(context);
+                updateTileView(context, res, tile, tileView.getImageView(),
+                        tileView.getTitleTextView(), tileView.getStatusTextView());
+
+                tileView.setTile(tile);
+
+                categoryContent.addView(tileView);
+            }
+
+            // Add the category
+            mDashboard.addView(categoryView);
+        }
     }
 
     @Override
-    public void onListItemClick(ListView l, View v, int position, long id) {
-        ((SettingsActivity) getActivity()).onListItemClick(l, v, position, id);
+    public void onStart() {
+        super.onStart();
+
+        AccountManager.get(getActivity()).addOnAccountsUpdatedListener(this, null, false);
+    }
+
+    @Override
+    public void onPause() {
+        super.onPause();
+
+        AccountManager.get(getActivity()).removeOnAccountsUpdatedListener(this);
+    }
+
+    private void updateTileView(Context context, Resources res, DashboardTile tile,
+            ImageView tileIcon, TextView tileTextView, TextView statusTextView) {
+
+        if (tile.extras != null
+                && tile.extras.containsKey(ManageAccountsSettings.KEY_ACCOUNT_TYPE)) {
+            String accType = tile.extras.getString(ManageAccountsSettings.KEY_ACCOUNT_TYPE);
+            Drawable drawable = mAuthHelper.getDrawableForType(context, accType);
+            tileIcon.setImageDrawable(drawable);
+        } else {
+            if (tile.iconRes > 0) {
+                tileIcon.setImageResource(tile.iconRes);
+            } else {
+                tileIcon.setImageDrawable(null);
+            }
+        }
+        if (tileIcon != null) {
+            if (tile.iconRes > 0) {
+                tileIcon.setBackgroundResource(R.color.temporary_background_icon);
+            } else {
+                tileIcon.setBackground(null);
+            }
+        }
+        tileTextView.setText(tile.getTitle(res));
+
+        CharSequence summary = tile.getSummary(res);
+        if (!TextUtils.isEmpty(summary)) {
+            statusTextView.setVisibility(View.VISIBLE);
+            statusTextView.setText(summary);
+        } else {
+            statusTextView.setVisibility(View.GONE);
+        }
+    }
+
+    private void rebuildCategories() {
+        if (!mHandler.hasMessages(MSG_BUILD_CATEGORIES)) {
+            mHandler.sendEmptyMessage(MSG_BUILD_CATEGORIES);
+        }
+    }
+
+    @Override
+    public void onAccountsUpdated(Account[] accounts) {
+        final SettingsActivity sa = (SettingsActivity) getActivity();
+        sa.setNeedToRebuildCategories(true);
+        rebuildCategories();
     }
 }
diff --git a/src/com/android/settings/dashboard/DashboardTileView.java b/src/com/android/settings/dashboard/DashboardTileView.java
new file mode 100644
index 0000000..250689e
--- /dev/null
+++ b/src/com/android/settings/dashboard/DashboardTileView.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2014 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.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.FrameLayout;
+
+import android.widget.ImageView;
+import android.widget.TextView;
+import com.android.settings.R;
+import com.android.settings.Utils;
+
+public class DashboardTileView extends FrameLayout implements View.OnClickListener {
+
+    private static final int DEFAULT_COL_SPAN = 1;
+
+    private ImageView mImageView;
+    private TextView mTitleTextView;
+    private TextView mStatusTextView;
+
+    private int mColSpan = DEFAULT_COL_SPAN;
+
+    private DashboardTile mTile;
+
+    public DashboardTileView(Context context) {
+        this(context, null);
+    }
+
+    public DashboardTileView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+
+        final View view = LayoutInflater.from(context).inflate(R.layout.dashboard_tile, this);
+
+        mImageView = (ImageView) view.findViewById(R.id.icon);
+        mTitleTextView = (TextView) view.findViewById(R.id.title);
+        mStatusTextView = (TextView) view.findViewById(R.id.status);
+
+        setOnClickListener(this);
+    }
+
+    public TextView getTitleTextView() {
+        return mTitleTextView;
+    }
+
+    public TextView getStatusTextView() {
+        return mStatusTextView;
+    }
+
+    public ImageView getImageView() {
+        return mImageView;
+    }
+
+    public void setTile(DashboardTile tile) {
+        mTile = tile;
+    }
+
+    void setColumnSpan(int span) {
+        mColSpan = span;
+    }
+
+    int getColumnSpan() {
+        return mColSpan;
+    }
+
+    @Override
+    public void onClick(View v) {
+        if (mTile.fragment != null) {
+            Utils.startWithFragment(getContext(), mTile.fragment, mTile.fragmentArguments, null, 0,
+                    mTile.getTitle(getResources()));
+        } else if (mTile.intent != null) {
+            getContext().startActivity(mTile.intent);
+        }
+    }
+}
diff --git a/src/com/android/settings/dashboard/HeaderAdapter.java b/src/com/android/settings/dashboard/HeaderAdapter.java
deleted file mode 100644
index 2f79c18..0000000
--- a/src/com/android/settings/dashboard/HeaderAdapter.java
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- * Copyright (C) 2014 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.app.admin.DevicePolicyManager;
-import android.content.Context;
-import android.content.Intent;
-import android.graphics.drawable.Drawable;
-import android.text.TextUtils;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ArrayAdapter;
-import android.widget.ImageButton;
-import android.widget.ImageView;
-import android.widget.Switch;
-import android.widget.TextView;
-import com.android.settings.R;
-import com.android.settings.accounts.AuthenticatorHelper;
-import com.android.settings.accounts.ManageAccountsSettings;
-import com.android.settings.bluetooth.BluetoothEnabler;
-import com.android.settings.wifi.WifiEnabler;
-
-import java.util.List;
-
-/**
- * A basic ArrayAdapter for dealing with the Headers
- */
-public class HeaderAdapter extends ArrayAdapter<Header> {
-    public static final int HEADER_TYPE_CATEGORY = 0;
-    public static final int HEADER_TYPE_NORMAL = 1;
-    public static final int HEADER_TYPE_SWITCH = 2;
-    public static final int HEADER_TYPE_BUTTON = 3;
-
-    private static final int HEADER_TYPE_COUNT = HEADER_TYPE_BUTTON + 1;
-
-    private final WifiEnabler mWifiEnabler;
-    private final BluetoothEnabler mBluetoothEnabler;
-    private AuthenticatorHelper mAuthHelper;
-    private DevicePolicyManager mDevicePolicyManager;
-
-    private static class HeaderViewHolder {
-        ImageView mIcon;
-        TextView mTitle;
-        TextView mSummary;
-        Switch mSwitch;
-        ImageButton mButton;
-        View mDivider;
-    }
-
-    private LayoutInflater mInflater;
-
-    public static int getHeaderType(Header header) {
-        if (header.fragment == null && header.intent == null) {
-            return HEADER_TYPE_CATEGORY;
-        } else if (header.id == R.id.security_settings) {
-            return HEADER_TYPE_BUTTON;
-        } else {
-            return HEADER_TYPE_NORMAL;
-        }
-    }
-
-    @Override
-    public int getItemViewType(int position) {
-        Header header = getItem(position);
-        return getHeaderType(header);
-    }
-
-    @Override
-    public boolean areAllItemsEnabled() {
-        return false; // because of categories
-    }
-
-    @Override
-    public boolean isEnabled(int position) {
-        return getItemViewType(position) != HEADER_TYPE_CATEGORY;
-    }
-
-    @Override
-    public int getViewTypeCount() {
-        return HEADER_TYPE_COUNT;
-    }
-
-    @Override
-    public boolean hasStableIds() {
-        return true;
-    }
-
-    public HeaderAdapter(Context context, List<Header> objects,
-                         AuthenticatorHelper authenticatorHelper, DevicePolicyManager dpm) {
-        super(context, 0, objects);
-
-        mAuthHelper = authenticatorHelper;
-        mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-
-        // Temp Switches provided as placeholder until the adapter replaces these with actual
-        // Switches inflated from their layouts. Must be done before adapter is set in super
-        mWifiEnabler = new WifiEnabler(context, new Switch(context));
-        mBluetoothEnabler = new BluetoothEnabler(context, new Switch(context));
-        mDevicePolicyManager = dpm;
-    }
-
-    @Override
-    public View getView(int position, View convertView, ViewGroup parent) {
-        HeaderViewHolder holder;
-        Header header = getItem(position);
-        int headerType = getHeaderType(header);
-        View view = null;
-
-        if (convertView == null) {
-            holder = new HeaderViewHolder();
-            switch (headerType) {
-                case HEADER_TYPE_CATEGORY:
-                    view = new TextView(getContext(), null,
-                            android.R.attr.listSeparatorTextViewStyle);
-                    holder.mTitle = (TextView) view;
-                    break;
-
-                case HEADER_TYPE_SWITCH:
-                    view = mInflater.inflate(R.layout.preference_header_switch_item, parent,
-                            false);
-                    holder.mIcon = (ImageView) view.findViewById(R.id.icon);
-                    holder.mTitle = (TextView)
-                            view.findViewById(com.android.internal.R.id.title);
-                    holder.mSummary = (TextView)
-                            view.findViewById(com.android.internal.R.id.summary);
-                    holder.mSwitch = (Switch) view.findViewById(R.id.switchWidget);
-                    break;
-
-                case HEADER_TYPE_BUTTON:
-                    view = mInflater.inflate(R.layout.preference_header_button_item, parent,
-                            false);
-                    holder.mIcon = (ImageView) view.findViewById(R.id.icon);
-                    holder.mTitle = (TextView)
-                            view.findViewById(com.android.internal.R.id.title);
-                    holder.mSummary = (TextView)
-                            view.findViewById(com.android.internal.R.id.summary);
-                    holder.mButton = (ImageButton) view.findViewById(R.id.buttonWidget);
-                    holder.mDivider = view.findViewById(R.id.divider);
-                    break;
-
-                case HEADER_TYPE_NORMAL:
-                    view = mInflater.inflate(
-                            R.layout.preference_header_item, parent,
-                            false);
-                    holder.mIcon = (ImageView) view.findViewById(R.id.icon);
-                    holder.mTitle = (TextView)
-                            view.findViewById(com.android.internal.R.id.title);
-                    holder.mSummary = (TextView)
-                            view.findViewById(com.android.internal.R.id.summary);
-                    break;
-            }
-            view.setTag(holder);
-        } else {
-            view = convertView;
-            holder = (HeaderViewHolder) view.getTag();
-        }
-
-        // All view fields must be updated every time, because the view may be recycled
-        switch (headerType) {
-            case HEADER_TYPE_CATEGORY:
-                holder.mTitle.setText(header.getTitle(getContext().getResources()));
-                break;
-
-            case HEADER_TYPE_SWITCH:
-                // Would need a different treatment if the main menu had more switches
-                if (header.id == R.id.wifi_settings) {
-                    mWifiEnabler.setSwitch(holder.mSwitch);
-                } else {
-                    mBluetoothEnabler.setSwitch(holder.mSwitch);
-                }
-                updateCommonHeaderView(header, holder);
-                break;
-
-            case HEADER_TYPE_BUTTON:
-                if (header.id == R.id.security_settings) {
-                    boolean hasCert = DevicePolicyManager.hasAnyCaCertsInstalled();
-                    if (hasCert) {
-                        holder.mButton.setVisibility(View.VISIBLE);
-                        holder.mDivider.setVisibility(View.VISIBLE);
-                        boolean isManaged = mDevicePolicyManager.getDeviceOwner() != null;
-                        if (isManaged) {
-                            holder.mButton.setImageResource(R.drawable.ic_settings_about);
-                        } else {
-                            holder.mButton.setImageResource(
-                                    android.R.drawable.stat_notify_error);
-                        }
-                        holder.mButton.setOnClickListener(new View.OnClickListener() {
-                            @Override
-                            public void onClick(View v) {
-                                Intent intent = new Intent(
-                                        android.provider.Settings.ACTION_MONITORING_CERT_INFO);
-                                getContext().startActivity(intent);
-                            }
-                        });
-                    } else {
-                        holder.mButton.setVisibility(View.GONE);
-                        holder.mDivider.setVisibility(View.GONE);
-                    }
-                }
-                updateCommonHeaderView(header, holder);
-                break;
-
-            case HEADER_TYPE_NORMAL:
-                updateCommonHeaderView(header, holder);
-                break;
-        }
-
-        return view;
-    }
-
-    private void updateCommonHeaderView(Header header, HeaderViewHolder holder) {
-        if (header.extras != null
-                && header.extras.containsKey(ManageAccountsSettings.KEY_ACCOUNT_TYPE)) {
-            String accType = header.extras.getString(
-                    ManageAccountsSettings.KEY_ACCOUNT_TYPE);
-            Drawable icon = mAuthHelper.getDrawableForType(getContext(), accType);
-            setHeaderIcon(holder, icon);
-        } else {
-            if (header.iconRes > 0) {
-                holder.mIcon.setImageResource(header.iconRes);
-            } else {
-                holder.mIcon.setImageDrawable(null);
-            }
-        }
-        if (holder.mIcon != null) {
-            if (header.iconRes > 0) {
-                holder.mIcon.setBackgroundResource(R.color.background_drawer_icon);
-            } else {
-                holder.mIcon.setBackground(null);
-            }
-        }
-        holder.mTitle.setText(header.getTitle(getContext().getResources()));
-        CharSequence summary = header.getSummary(getContext().getResources());
-        if (!TextUtils.isEmpty(summary)) {
-            holder.mSummary.setVisibility(View.VISIBLE);
-            holder.mSummary.setText(summary);
-        } else {
-            holder.mSummary.setVisibility(View.GONE);
-        }
-    }
-
-    private void setHeaderIcon(HeaderViewHolder holder, Drawable icon) {
-        ViewGroup.LayoutParams lp = holder.mIcon.getLayoutParams();
-        lp.width = getContext().getResources().getDimensionPixelSize(
-                R.dimen.header_icon_width);
-        lp.height = lp.width;
-        holder.mIcon.setLayoutParams(lp);
-        holder.mIcon.setImageDrawable(icon);
-    }
-}
\ No newline at end of file
diff --git a/src/com/android/settings/dashboard/SearchResultsSummary.java b/src/com/android/settings/dashboard/SearchResultsSummary.java
index 89e33f6..e8544ae 100644
--- a/src/com/android/settings/dashboard/SearchResultsSummary.java
+++ b/src/com/android/settings/dashboard/SearchResultsSummary.java
@@ -18,13 +18,11 @@
 
 import android.app.Fragment;
 import android.content.ComponentName;
-import android.content.ContentValues;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.content.res.Resources;
 import android.database.Cursor;
-import android.database.sqlite.SQLiteDatabase;
 import android.graphics.drawable.Drawable;
 import android.os.AsyncTask;
 import android.os.Bundle;
@@ -41,15 +39,11 @@
 import android.widget.TextView;
 import com.android.settings.R;
 import com.android.settings.SettingsActivity;
+import com.android.settings.Utils;
 import com.android.settings.search.Index;
-import com.android.settings.search.IndexDatabaseHelper;
 
-import java.util.Date;
 import java.util.HashMap;
 
-import static com.android.settings.search.IndexDatabaseHelper.SavedQueriesColums;
-import static com.android.settings.search.IndexDatabaseHelper.Tables;
-
 public class SearchResultsSummary extends Fragment {
 
     private static final String LOG_TAG = "SearchResultsSummary";
@@ -164,14 +158,13 @@
                 final String key = cursor.getString(Index.COLUMN_INDEX_KEY);
 
                 final SettingsActivity sa = (SettingsActivity) getActivity();
-
                 sa.needToRevertToInitialFragment();
 
                 if (TextUtils.isEmpty(action)) {
                     Bundle args = new Bundle();
                     args.putString(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY, key);
 
-                    sa.startWithFragment(className, args, null, 0, screenTitle);
+                    Utils.startWithFragment(sa, className, args, null, 0, screenTitle);
                 } else {
                     final Intent intent = new Intent(action);
 
@@ -588,7 +581,7 @@
                     // Not much we can do except logging
                     Log.e(LOG_TAG, "Cannot load Drawable for " + result.title);
                 }
-                imageView.setBackgroundResource(R.color.background_search_result_icon);
+                imageView.setBackgroundResource(R.color.temporary_background_icon);
             } else {
                 imageView.setImageDrawable(null);
                 imageView.setBackgroundResource(R.drawable.empty_icon);