Merge "Add summary text to Display->Brightness level." into oc-dev
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index ed00054..da88f76 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -902,13 +902,23 @@
                 android:icon="@drawable/ic_settings_night_display"
                 android:taskAffinity="">
             <intent-filter android:priority="1">
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="com.android.settings.suggested.category.SETTINGS_ONLY" />
+            </intent-filter>
+            <intent-filter android:priority="1">
                 <action android:name="android.settings.NIGHT_DISPLAY_SETTINGS" />
                 <category android:name="android.intent.category.DEFAULT" />
             </intent-filter>
-            <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
-                android:value="com.android.settings.display.NightDisplaySettings" />
             <meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
                 android:value="true" />
+            <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
+                android:value="com.android.settings.display.NightDisplaySettings" />
+            <meta-data android:name="com.android.settings.dismiss"
+                android:value="30" />
+            <meta-data android:name="com.android.settings.title"
+                android:resource="@string/night_display_suggestion_title" />
+            <meta-data android:name="com.android.settings.summary"
+                android:resource="@string/night_display_suggestion_summary" />
         </activity>
 
         <activity android:name="Settings$DeviceInfoSettingsActivity"
@@ -2548,6 +2558,7 @@
             <intent-filter android:priority="1">
                 <action android:name="com.android.settings.SOUND_SETTINGS" />
                 <action android:name="android.settings.SOUND_SETTINGS" />
+                <action android:name="android.settings.ACTION_OTHER_SOUND_SETTINGS" />
                 <category android:name="android.intent.category.DEFAULT" />
             </intent-filter>
             <intent-filter>
@@ -2556,10 +2567,6 @@
                 <category android:name="android.intent.category.VOICE_LAUNCH" />
                 <category android:name="com.android.settings.SHORTCUT" />
             </intent-filter>
-            <intent-filter android:priority="1">
-                <action android:name="android.settings.ACTION_OTHER_SOUND_SETTINGS" />
-                <category android:name="android.intent.category.DEFAULT" />
-            </intent-filter>
             <intent-filter android:priority="6">
                 <action android:name="com.android.settings.action.SETTINGS" />
             </intent-filter>
diff --git a/res/layout/battery_header.xml b/res/layout/battery_header.xml
index ef39d8b..04ef74d 100644
--- a/res/layout/battery_header.xml
+++ b/res/layout/battery_header.xml
@@ -27,44 +27,35 @@
     android:background="@drawable/selectable_card_grey"
     style="@style/EntityHeader">
 
-    <com.android.settings.fuelgauge.BatteryMeterView
-        android:id="@+id/battery_header_icon"
-        android:layout_width="@dimen/battery_meter_width"
-        android:layout_height="@dimen/battery_meter_height"/>
-
     <LinearLayout
-        android:layout_width="wrap_content"
+        android:layout_width="216dp"
         android:layout_height="wrap_content"
-        android:layout_marginStart="12dp"
+        android:layout_marginStart="48dp"
         android:layout_marginEnd="12dp"
         android:orientation="vertical">
 
         <TextView
-            android:id="@+id/time"
+            android:id="@+id/battery_percent"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_marginTop="12dp"
-            android:gravity="center"
-            android:textAppearance="@android:style/TextAppearance.Material.Medium"/>
+            android:textAppearance="@android:style/TextAppearance.Material.Display1"/>
 
         <TextView
             android:id="@+id/summary1"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_marginTop="12dp"
-            android:gravity="center"
             android:textAppearance="@android:style/TextAppearance.Material.Small"
             android:text="@string/estimated_time_left"/>
 
-        <TextView
-            android:id="@+id/summary2"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_marginTop="12dp"
-            android:gravity="center"
-            android:textAppearance="@android:style/TextAppearance.Material.Small"
-            android:text="@string/estimated_time_description"/>
-
     </LinearLayout>
 
+    <com.android.settings.fuelgauge.BatteryMeterView
+        android:id="@+id/battery_header_icon"
+        android:layout_width="@dimen/battery_meter_width"
+        android:layout_height="@dimen/battery_meter_height"
+        android:layout_gravity="end"
+        android:layout_marginEnd="24dp"/>
+
 </LinearLayout>
\ No newline at end of file
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 3173e85..2dbd222 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -765,6 +765,8 @@
     <string name="security_status_title">Security status</string>
     <!-- Summary for Security settings, explaining a few important settings under it [CHAR LIMIT=NONE]-->
     <string name="security_dashboard_summary">Location, fingerprint</string>
+    <!-- Summary for Security settings when fingerprint is not supported [CHAR LIMIT=NONE]-->
+    <string name="security_dashboard_summary_no_fingerprint">Location</string>
     <!-- Fingerprint enrollment and settings --><skip />
     <!-- Title shown for menu item that launches fingerprint settings or enrollment [CHAR LIMIT=22] -->
     <string name="security_settings_fingerprint_preference_title">Fingerprint</string>
@@ -1640,13 +1642,20 @@
     <string name="use_open_wifi_automatically_summary">Automatically connect to high\u2011quality public networks</string>
     <!-- Preference title for option to install certificates -->
     <string name="wifi_install_credentials">Install certificates</string>
-    <!-- Message to describe "Wi-Fi scan always available feature" when Wi-Fi is off. The
-      place-holders "LINK_BEGIN" and "LINK_END" must NOT be translated. They mark a link to bring
-      the user to "scanning settings" screen. -->
+    <!-- Message to describe "Wi-Fi scan always available feature" when Wi-Fi is off and Wi-Fi
+      scanning is on. The place-holders "LINK_BEGIN" and "LINK_END" must NOT be translated. They
+      mark a link to bring the user to "scanning settings" screen. -->
     <string name="wifi_scan_notify_text">To improve location accuracy, system apps and services can
         still scan for Wi\u2011Fi networks. You can change this in
         <xliff:g id="link_begin">LINK_BEGIN</xliff:g>scanning
         settings<xliff:g id="link_end">LINK_END</xliff:g>.</string>
+    <!-- Message to describe "Wi-Fi scan always available feature" when Wi-Fi is off and Wi-Fi
+      scanning is also off. The place-holders "LINK_BEGIN" and "LINK_END" must NOT be translated.
+      They mark a link to bring the user to "scanning settings" screen. -->
+    <string name="wifi_scan_notify_text_scanning_off">To improve location accuracy,
+        turn on Wi-Fi scanning in
+        <xliff:g id="link_begin">LINK_BEGIN</xliff:g>scanning
+        settings<xliff:g id="link_end">LINK_END</xliff:g>.</string>
     <!-- Wifi scan always mode checkbox text -->
     <string name="wifi_scan_notify_remember_choice">Don\u2019t show again</string>
     <!-- Setting title for setting the wifi sleep policy. Do we keep Wi-Fi active when the screen turns off? -->
@@ -3880,13 +3889,6 @@
     <string name="show_password">Show passwords</string>
     <!-- On Security & location settings screen. This is a short summary text describing what "Show passwords" setting does -->
     <string name="show_password_summary">Display characters briefly as you type</string>
-    <!-- Warning message about security implications of enabling an input method, displayed as a dialog
-         message when the user selects to enable an IME. -->
-    <string name="ime_security_warning">This input method may be able to collect
-    all the text you type, including personal data like passwords and credit
-    card numbers.  It comes from the app
-    <xliff:g id="ime_application_name">%1$s</xliff:g>.
-    Use this input method?</string>
     <!-- Warning message about security implications of enabling a spell checker, displayed as a dialog
          message when the user selects to enable a spell checker. -->
     <string name="spellchecker_security_warning">This spell checker may be able to collect
@@ -3898,9 +3900,6 @@
     <string name="spellchecker_quick_settings">Settings</string>
     <!-- Image button description for spell checker language. -->
     <string name="spellchecker_language">Language</string>
-    <!-- Toast that settings for an application is failed to open. -->
-    <string name="failed_to_open_app_settings_toast">Failed to open settings for <xliff:g id="spell_application_name">%1$s</xliff:g></string>
-
     <!-- Title for the 'keyboard and input methods' preference category. [CHAR LIMIT=45] -->
     <string name="keyboard_and_input_methods_category">Keyboard &amp; inputs</string>
     <!-- Title for the 'virtual keyboard' preference sub-screen. [CHAR LIMIT=35] -->
@@ -7400,7 +7399,7 @@
         Allowing <xliff:g id="app_name" example="Settings">%1$s</xliff:g> to always run in the background may reduce battery life.
         \n\nYou can change this later from Settings > Apps &amp; notifications.</string>
     <!-- Summary of power usage for an app [CHAR LIMIT=NONE] -->
-    <string name="battery_summary"><xliff:g id="percentage" example="2">%1$d</xliff:g>%% use since last full charge</string>
+    <string name="battery_summary"><xliff:g id="percentage" example="2">%1$s</xliff:g> use since last full charge</string>
 
     <!-- Title of a group of settings that let you manage settings that affect battery life [CHAR LIMIT=60] -->
     <string name="battery_power_management">Power management</string>
@@ -7631,7 +7630,7 @@
     <!-- Link to the apps page for SYSTEM_ALERT_WINDOW settings [CHAR LIMIT=45] -->
     <string name="app_overlay_permission_preference">App display on top permission</string>
     <!-- Description of allowing overlay setting [CHAR LIMIT=NONE] -->
-    <string name="allow_overlay_description">This feature allows an app to display on top of other apps you\u2019re using. It may interfere with your use of those apps or change the way they seem to appear or behave.</string>
+    <string name="allow_overlay_description">Allow this app to display on top of other apps you\u2019re using. It may interfere with your use of those apps or change the way they seem to appear or behave.</string>
 
     <!-- Keyword for VR setting -->
     <string name="keywords_vr_listener">vr virtual reality listener stereo helper service</string>
@@ -8607,8 +8606,11 @@
     <string name="storage_percent_full">full</string>
 
 
-    <!-- Label for button allow user to clear the data for an instant app -->
+    <!-- Label for button allow user to remove the instant app from the device. -->
     <string name="clear_instant_app_data">Clear app</string>
+    <!-- Confirmation message displayed when the user taps Clear app, to ensure they want to remove
+         the instant app from the device. -->
+    <string name="clear_instant_app_confirmation">Do you want to remove this instant app?</string>
 
     <!-- Title of games app storage screen [CHAR LIMIT=30] -->
     <string name="game_storage_settings">Games</string>
diff --git a/res/xml/display_settings.xml b/res/xml/display_settings.xml
index 71825b1..9d4acb4 100644
--- a/res/xml/display_settings.xml
+++ b/res/xml/display_settings.xml
@@ -27,6 +27,19 @@
         <intent android:action="com.android.intent.action.SHOW_BRIGHTNESS_DIALOG" />
     </Preference>
 
+    <com.android.settings.display.NightDisplayPreference
+        android:key="night_display"
+        android:title="@string/night_display_title"
+        android:fragment="com.android.settings.display.NightDisplaySettings"
+        settings:widgetLayout="@null"
+        settings:keywords="@string/keywords_display_night_display" />
+
+    <SwitchPreference
+        android:key="auto_brightness"
+        android:title="@string/auto_brightness_title"
+        settings:keywords="@string/keywords_display_auto_brightness"
+        android:summary="@string/auto_brightness_summary" />
+
     <com.android.settingslib.RestrictedPreference
         android:key="wallpaper"
         android:title="@string/wallpaper_settings_title"
@@ -37,13 +50,6 @@
             android:targetClass="@string/config_wallpaper_picker_class" />
     </com.android.settingslib.RestrictedPreference>
 
-    <com.android.settings.display.NightDisplayPreference
-        android:key="night_display"
-        android:title="@string/night_display_title"
-        android:fragment="com.android.settings.display.NightDisplaySettings"
-        settings:widgetLayout="@null"
-        settings:keywords="@string/keywords_display_night_display" />
-
     <com.android.settings.TimeoutListPreference
         android:key="screen_timeout"
         android:title="@string/screen_timeout"
@@ -56,12 +62,6 @@
         android:summary="%s"
         android:title="@string/display_auto_rotate_title" />
 
-    <SwitchPreference
-        android:key="auto_brightness"
-        android:title="@string/auto_brightness_title"
-        settings:keywords="@string/keywords_display_auto_brightness"
-        android:summary="@string/auto_brightness_summary" />
-
     <Preference
         android:key="font_size"
         android:title="@string/title_font_size"
diff --git a/res/xml/power_usage_summary.xml b/res/xml/power_usage_summary.xml
index a387813..b486776 100644
--- a/res/xml/power_usage_summary.xml
+++ b/res/xml/power_usage_summary.xml
@@ -26,6 +26,19 @@
         android:layout="@layout/battery_header"/>
 
     <PreferenceCategory
+        android:key="device_usage_list">
+
+        <com.android.settings.fuelgauge.PowerGaugePreference
+            android:key="last_full_charge"
+            android:title="@string/battery_last_full_charge"/>
+
+        <com.android.settings.fuelgauge.PowerGaugePreference
+            android:key="screen_usage"
+            android:title="@string/device_screen_usage"/>
+
+    </PreferenceCategory>
+
+    <PreferenceCategory
         android:key="power_management"
         android:title="@string/battery_power_management">
 
@@ -60,22 +73,4 @@
         android:key="app_list"
         android:title="@string/power_usage_list_summary"/>
 
-    <PreferenceCategory
-        android:key="device_usage_list"
-        android:title="@string/device_usage_list_summary">
-
-        <Preference
-            android:key="screen_usage"
-            android:title="@string/device_screen_usage"/>
-
-        <Preference
-            android:key="screen_consumption"
-            android:title="@string/device_screen_consumption"/>
-
-        <Preference
-            android:key="cellular_network"
-            android:title="@string/device_cellular_network"/>
-
-    </PreferenceCategory>
-
 </PreferenceScreen>
diff --git a/src/com/android/settings/applications/ApplicationFeatureProvider.java b/src/com/android/settings/applications/ApplicationFeatureProvider.java
index ef8cb23..5e986db 100644
--- a/src/com/android/settings/applications/ApplicationFeatureProvider.java
+++ b/src/com/android/settings/applications/ApplicationFeatureProvider.java
@@ -37,7 +37,7 @@
      *  only relevant to instant apps.
      */
     InstantAppButtonsController newInstantAppButtonsController(Fragment fragment,
-            View view);
+            View view, InstantAppButtonsController.ShowDialogDelegate showDialogDelegate);
 
     /**
      * Calculates the total number of apps installed on the device via policy in the current user
diff --git a/src/com/android/settings/applications/ApplicationFeatureProviderImpl.java b/src/com/android/settings/applications/ApplicationFeatureProviderImpl.java
index 124a8de..4171857 100644
--- a/src/com/android/settings/applications/ApplicationFeatureProviderImpl.java
+++ b/src/com/android/settings/applications/ApplicationFeatureProviderImpl.java
@@ -58,8 +58,8 @@
 
     @Override
     public InstantAppButtonsController newInstantAppButtonsController(Fragment fragment,
-            View view) {
-        return new InstantAppButtonsController(mContext, fragment, view);
+            View view, InstantAppButtonsController.ShowDialogDelegate showDialogDelegate) {
+        return new InstantAppButtonsController(mContext, fragment, view, showDialogDelegate);
     }
 
     @Override
diff --git a/src/com/android/settings/applications/DrawOverlayDetails.java b/src/com/android/settings/applications/DrawOverlayDetails.java
index 39b8919..72564bc 100644
--- a/src/com/android/settings/applications/DrawOverlayDetails.java
+++ b/src/com/android/settings/applications/DrawOverlayDetails.java
@@ -36,6 +36,7 @@
 import com.android.settings.R;
 import com.android.settings.applications.AppStateAppOpsBridge.PermissionState;
 import com.android.settings.applications.AppStateOverlayBridge.OverlayState;
+import com.android.settings.core.TouchOverlayManager;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settingslib.applications.ApplicationsState.AppEntry;
 
@@ -61,6 +62,8 @@
     private Intent mSettingsIntent;
     private OverlayState mOverlayState;
 
+    private TouchOverlayManager mTouchOverlayManager;
+
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -68,6 +71,7 @@
         Context context = getActivity();
         mOverlayBridge = new AppStateOverlayBridge(context, mState, null);
         mAppOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
+        mTouchOverlayManager = new TouchOverlayManager(context);
 
         // find preferences
         addPreferencesFromResource(R.xml.app_ops_permissions_details);
@@ -90,6 +94,20 @@
     }
 
     @Override
+    public void onStart() {
+        super.onStart();
+
+        mTouchOverlayManager.setOverlayAllowed(false);
+    }
+
+    @Override
+    public void onStop() {
+        super.onStop();
+
+        mTouchOverlayManager.setOverlayAllowed(true);
+    }
+
+    @Override
     public void onDestroy() {
         super.onDestroy();
         mOverlayBridge.release();
diff --git a/src/com/android/settings/applications/InstalledAppDetails.java b/src/com/android/settings/applications/InstalledAppDetails.java
index 1fc5515..9967918 100755
--- a/src/com/android/settings/applications/InstalledAppDetails.java
+++ b/src/com/android/settings/applications/InstalledAppDetails.java
@@ -85,9 +85,11 @@
 import com.android.settings.applications.defaultapps.DefaultHomePreferenceController;
 import com.android.settings.applications.defaultapps.DefaultPhonePreferenceController;
 import com.android.settings.applications.defaultapps.DefaultSmsPreferenceController;
+import com.android.settings.applications.instantapps.InstantAppButtonsController;
 import com.android.settings.datausage.AppDataUsage;
 import com.android.settings.datausage.DataUsageList;
 import com.android.settings.datausage.DataUsageSummary;
+import com.android.settings.fuelgauge.AdvancedPowerUsageDetail;
 import com.android.settings.fuelgauge.BatteryEntry;
 import com.android.settings.fuelgauge.PowerUsageDetail;
 import com.android.settings.notification.AppNotificationSettings;
@@ -182,15 +184,20 @@
     private ChartData mChartData;
     private INetworkStatsSession mStatsSession;
 
-    private Preference mBatteryPreference;
-
-    private BatteryStatsHelper mBatteryHelper;
-    private BatterySipper mSipper;
+    @VisibleForTesting
+    Preference mBatteryPreference;
+    @VisibleForTesting
+    BatterySipper mSipper;
+    @VisibleForTesting
+    BatteryStatsHelper mBatteryHelper;
 
     protected ProcStatsData mStatsManager;
     protected ProcStatsPackageEntry mStats;
 
+    private InstantAppButtonsController mInstantAppButtonsController;
+
     private AppStorageStats mLastResult;
+    private String mBatteryPercent;
 
     private boolean handleDisableable(Button button) {
         boolean disableable = false;
@@ -683,7 +690,8 @@
                     BatteryStats.STATS_SINCE_CHARGED);
             final int percentOfMax = (int) ((mSipper.totalPowerMah)
                     / mBatteryHelper.getTotalPower() * dischargeAmount + .5f);
-            mBatteryPreference.setSummary(getString(R.string.battery_summary, percentOfMax));
+            mBatteryPercent = Utils.formatPercentage(percentOfMax);
+            mBatteryPreference.setSummary(getString(R.string.battery_summary, mBatteryPercent));
         } else {
             mBatteryPreference.setEnabled(false);
             mBatteryPreference.setSummary(getString(R.string.no_battery_summary));
@@ -715,7 +723,7 @@
                     ? R.string.storage_type_external
                     : R.string.storage_type_internal);
             return context.getString(R.string.storage_summary_format,
-                    getSize(context, stats), storageType);
+                    getSize(context, stats), storageType.toString().toLowerCase());
         }
     }
 
@@ -771,6 +779,9 @@
                         .setNegativeButton(R.string.dlg_cancel, null)
                         .create();
         }
+        if (mInstantAppButtonsController != null) {
+            return mInstantAppButtonsController.createDialog(id);
+        }
         return null;
     }
 
@@ -954,9 +965,9 @@
         } else if (preference == mDataPreference) {
             startAppInfoFragment(AppDataUsage.class, getString(R.string.app_data_usage));
         } else if (preference == mBatteryPreference) {
-            BatteryEntry entry = new BatteryEntry(getActivity(), null, mUserManager, mSipper);
-            PowerUsageDetail.startBatteryDetailPage((SettingsActivity) getActivity(), this,
-                    mBatteryHelper, BatteryStats.STATS_SINCE_CHARGED, entry, true, false);
+            BatteryEntry entry = new BatteryEntry(getContext(), null, mUserManager, mSipper);
+            AdvancedPowerUsageDetail.startBatteryDetailPage((SettingsActivity) getActivity(), this,
+                    mBatteryHelper, BatteryStats.STATS_SINCE_CHARGED, entry, mBatteryPercent);
         } else {
             return false;
         }
@@ -1120,10 +1131,11 @@
         if (AppUtils.isInstant(mPackageInfo.applicationInfo)) {
             LayoutPreference buttons = (LayoutPreference) findPreference(KEY_INSTANT_APP_BUTTONS);
             final Activity activity = getActivity();
-            FeatureFactory.getFactory(activity)
+            mInstantAppButtonsController = FeatureFactory.getFactory(activity)
                     .getApplicationFeatureProvider(activity)
                     .newInstantAppButtonsController(this,
-                            buttons.findViewById(R.id.instant_app_button_container))
+                            buttons.findViewById(R.id.instant_app_button_container),
+                            id -> showDialogInner(id, 0))
                     .setPackageName(mPackageName)
                     .show();
         }
diff --git a/src/com/android/settings/applications/ManageApplications.java b/src/com/android/settings/applications/ManageApplications.java
index fde145f..229e294 100644
--- a/src/com/android/settings/applications/ManageApplications.java
+++ b/src/com/android/settings/applications/ManageApplications.java
@@ -33,6 +33,7 @@
 import android.preference.PreferenceFrameLayout;
 import android.support.annotation.VisibleForTesting;
 import android.text.TextUtils;
+import android.util.ArraySet;
 import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.Menu;
@@ -86,10 +87,12 @@
 import com.android.settingslib.applications.StorageStatsSource;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
 import java.util.Locale;
+import java.util.Set;
 
 /**
  * Activity to pick an application that will be used to display installation information and
@@ -253,6 +256,12 @@
     public static final int LIST_TYPE_MANAGE_SOURCES = 8;
     public static final int LIST_TYPE_GAMES = 9;
 
+
+    // List types that should show instant apps.
+    public static final Set<Integer> LIST_TYPES_WITH_INSTANT = new ArraySet<>(Arrays.asList(
+                    LIST_TYPE_MAIN,
+                    LIST_TYPE_STORAGE));
+
     private View mRootView;
 
     private View mSpinnerHeader;
@@ -701,7 +710,9 @@
     }
 
     public void setHasInstant(boolean haveInstantApps) {
-        mFilterAdapter.setFilterEnabled(FILTER_APPS_INSTANT, haveInstantApps);
+        if (LIST_TYPES_WITH_INSTANT.contains(mListType)) {
+            mFilterAdapter.setFilterEnabled(FILTER_APPS_INSTANT, haveInstantApps);
+        }
     }
 
     static class FilterSpinnerAdapter extends ArrayAdapter<CharSequence> {
@@ -956,8 +967,13 @@
                 filterObj = mOverrideFilter;
             }
             if (!mManageApplications.mShowSystem) {
-                filterObj = new CompoundFilter(filterObj,
-                        ApplicationsState.FILTER_DOWNLOADED_AND_LAUNCHER);
+                if (LIST_TYPES_WITH_INSTANT.contains(mManageApplications.mListType)) {
+                    filterObj = new CompoundFilter(filterObj,
+                            ApplicationsState.FILTER_DOWNLOADED_AND_LAUNCHER_AND_INSTANT);
+                } else {
+                    filterObj = new CompoundFilter(filterObj,
+                            ApplicationsState.FILTER_DOWNLOADED_AND_LAUNCHER);
+                }
             }
             switch (mLastSortMode) {
                 case R.id.sort_order_size:
diff --git a/src/com/android/settings/applications/PackageManagerWrapper.java b/src/com/android/settings/applications/PackageManagerWrapper.java
index 2be92ed..8dae417 100644
--- a/src/com/android/settings/applications/PackageManagerWrapper.java
+++ b/src/com/android/settings/applications/PackageManagerWrapper.java
@@ -20,6 +20,7 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.pm.ApplicationInfo;
+import android.content.pm.IPackageDeleteObserver;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.os.UserHandle;
@@ -98,4 +99,10 @@
      */
     void replacePreferredActivity(IntentFilter homeFilter, int matchCategoryEmpty,
             ComponentName[] componentNames, ComponentName component);
+
+    /**
+     * Calls {@code PackageManager.deletePackageAsUser}
+     */
+    void deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int flags,
+            int userId);
 }
diff --git a/src/com/android/settings/applications/PackageManagerWrapperImpl.java b/src/com/android/settings/applications/PackageManagerWrapperImpl.java
index 698c14c..a0d824f 100644
--- a/src/com/android/settings/applications/PackageManagerWrapperImpl.java
+++ b/src/com/android/settings/applications/PackageManagerWrapperImpl.java
@@ -20,6 +20,7 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.pm.ApplicationInfo;
+import android.content.pm.IPackageDeleteObserver;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.os.UserHandle;
@@ -90,4 +91,10 @@
             ComponentName[] componentNames, ComponentName component) {
         mPm.replacePreferredActivity(homeFilter, matchCategoryEmpty, componentNames, component);
     }
+
+    @Override
+    public void deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int flags,
+            int userId) {
+        mPm.deletePackageAsUser(packageName, observer, flags, userId);
+    }
 }
diff --git a/src/com/android/settings/applications/defaultapps/DefaultAutofillPicker.java b/src/com/android/settings/applications/defaultapps/DefaultAutofillPicker.java
index ce9344f..d943de7 100644
--- a/src/com/android/settings/applications/defaultapps/DefaultAutofillPicker.java
+++ b/src/com/android/settings/applications/defaultapps/DefaultAutofillPicker.java
@@ -22,7 +22,6 @@
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
 import android.provider.Settings;
-import android.service.autofill.AutoFillService;
 import android.service.autofill.AutofillService;
 import android.service.autofill.AutofillServiceInfo;
 import android.text.TextUtils;
@@ -36,8 +35,6 @@
 public class DefaultAutofillPicker extends DefaultAppPickerFragment {
 
     static final String SETTING = Settings.Secure.AUTOFILL_SERVICE;
-    // TODO(b/35956626): remove once clients migrated
-    static final Intent OLD_AUTO_FILL_PROBE = new Intent(AutoFillService.OLD_SERVICE_INTERFACE);
     static final Intent AUTOFILL_PROBE = new Intent(AutofillService.SERVICE_INTERFACE);
 
     @Override
@@ -59,12 +56,6 @@
             candidates.add(new DefaultAppInfo(mPm, mUserId, new ComponentName(
                     info.serviceInfo.packageName, info.serviceInfo.name)));
         }
-        final List<ResolveInfo> oldResolveInfos = mPm.getPackageManager()
-                .queryIntentServices(OLD_AUTO_FILL_PROBE, PackageManager.GET_META_DATA);
-        for (ResolveInfo info : oldResolveInfos) {
-            candidates.add(new DefaultAppInfo(mPm, mUserId, new ComponentName(
-                    info.serviceInfo.packageName, info.serviceInfo.name)));
-        }
         return candidates;
     }
 
@@ -122,24 +113,6 @@
                 }
             }
 
-            final List<ResolveInfo> oldResolveInfos = mPackageManager.queryIntentServices(
-                    OLD_AUTO_FILL_PROBE, PackageManager.GET_META_DATA);
-
-            for (ResolveInfo resolveInfo : oldResolveInfos) {
-                final ServiceInfo serviceInfo = resolveInfo.serviceInfo;
-                final String flattenKey = new ComponentName(
-                        serviceInfo.packageName, serviceInfo.name).flattenToString();
-                if (TextUtils.equals(mSelectedKey, flattenKey)) {
-                    final String settingsActivity = new AutofillServiceInfo(
-                            mPackageManager, serviceInfo)
-                            .getSettingsActivity();
-                    if (TextUtils.isEmpty(settingsActivity)) {
-                        return null;
-                    }
-                    return new Intent(Intent.ACTION_MAIN).setComponent(
-                            new ComponentName(serviceInfo.packageName, settingsActivity));
-                }
-            }
             return null;
         }
     }
diff --git a/src/com/android/settings/applications/instantapps/InstantAppButtonsController.java b/src/com/android/settings/applications/instantapps/InstantAppButtonsController.java
index aa7c418..16956df 100644
--- a/src/com/android/settings/applications/instantapps/InstantAppButtonsController.java
+++ b/src/com/android/settings/applications/instantapps/InstantAppButtonsController.java
@@ -16,31 +16,53 @@
 
 package com.android.settings.applications.instantapps;
 
+import android.app.AlertDialog;
+import android.app.Fragment;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.os.UserHandle;
+import android.view.View;
+import android.widget.Button;
+
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settings.R;
 import com.android.settings.applications.AppStoreUtil;
+import com.android.settings.applications.PackageManagerWrapper;
+import com.android.settings.applications.PackageManagerWrapperImpl;
 import com.android.settings.overlay.FeatureFactory;
 
-import android.app.Fragment;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.widget.Button;
-
 /** Encapsulates a container for buttons relevant to instant apps */
-public class InstantAppButtonsController {
+public class InstantAppButtonsController implements DialogInterface.OnClickListener {
+
+    public interface ShowDialogDelegate {
+        /**
+         * Delegate that should be called when this controller wants to show a dialog.
+         */
+        void showDialog(int id);
+    }
 
     private final Context mContext;
     private final Fragment mFragment;
     private final View mView;
+    private final PackageManagerWrapper mPackageManagerWrapper;
+    private final ShowDialogDelegate mShowDialogDelegate;
     private String mPackageName;
 
-    public InstantAppButtonsController(Context context, Fragment fragment, View view) {
+    public static final int DLG_BASE = 0x5032;
+    public static final int DLG_CLEAR_APP = DLG_BASE + 1;
+
+    public InstantAppButtonsController(
+            Context context,
+            Fragment fragment,
+            View view,
+            ShowDialogDelegate showDialogDelegate) {
       mContext = context;
       mFragment = fragment;
       mView = view;
+      mShowDialogDelegate = showDialogDelegate;
+      mPackageManagerWrapper = new PackageManagerWrapperImpl(context.getPackageManager());
     }
 
     public InstantAppButtonsController setPackageName(String packageName) {
@@ -51,17 +73,38 @@
     public void bindButtons() {
         Button installButton = (Button)mView.findViewById(R.id.install);
         Button clearDataButton = (Button)mView.findViewById(R.id.clear_data);
-        Intent installIntent = AppStoreUtil.getAppStoreLink(mContext, mPackageName);
-        if (installIntent != null) {
+        Intent appStoreIntent = AppStoreUtil.getAppStoreLink(mContext, mPackageName);
+        if (appStoreIntent != null) {
             installButton.setEnabled(true);
-            installButton.setOnClickListener(v -> mFragment.startActivity(installIntent));
+            installButton.setOnClickListener(v -> mFragment.startActivity(appStoreIntent));
         }
-        clearDataButton.setOnClickListener(v -> {
-            FeatureFactory.getFactory(mContext).getMetricsFeatureProvider().action(mContext,
-                    MetricsEvent.ACTION_SETTINGS_CLEAR_INSTANT_APP, mPackageName);
-            PackageManager pm = mContext.getPackageManager();
-            pm.clearApplicationUserData(mPackageName, null);
-        });
+
+        clearDataButton.setOnClickListener(v -> mShowDialogDelegate.showDialog(DLG_CLEAR_APP));
+    }
+
+    public AlertDialog createDialog(int id) {
+        if (id == DLG_CLEAR_APP) {
+            AlertDialog dialog = new AlertDialog.Builder(mFragment.getActivity())
+                    .setPositiveButton(R.string.clear_instant_app_data, this)
+                    .setNegativeButton(R.string.cancel, null)
+                    .setTitle(R.string.clear_instant_app_data)
+                    .setMessage(mContext.getString(R.string.clear_instant_app_confirmation))
+                    .create();
+            return dialog;
+        }
+        return null;
+    }
+
+    public void onClick(DialogInterface dialog, int which) {
+        if (which == DialogInterface.BUTTON_POSITIVE) {
+            FeatureFactory.getFactory(mContext)
+                    .getMetricsFeatureProvider()
+                    .action(mContext,
+                            MetricsEvent.ACTION_SETTINGS_CLEAR_INSTANT_APP,
+                            mPackageName);
+            mPackageManagerWrapper.deletePackageAsUser(
+                    mPackageName, null, 0, UserHandle.myUserId());
+        }
     }
 
     public InstantAppButtonsController show() {
diff --git a/src/com/android/settings/bluetooth/RequestPermissionActivity.java b/src/com/android/settings/bluetooth/RequestPermissionActivity.java
index 20788c9..d2e2060 100644
--- a/src/com/android/settings/bluetooth/RequestPermissionActivity.java
+++ b/src/com/android/settings/bluetooth/RequestPermissionActivity.java
@@ -180,8 +180,8 @@
                 builder.setMessage(message);
             } else {
                 CharSequence message = mAppLabel != null
-                        ? getString(R.string.bluetooth_ask_discovery, mAppLabel)
-                        : getString(R.string.bluetooth_ask_discovery_no_name);
+                        ? getString(R.string.bluetooth_ask_discovery, mAppLabel, mTimeout)
+                        : getString(R.string.bluetooth_ask_discovery_no_name, mTimeout);
                 builder.setMessage(message);
             }
             builder.setPositiveButton(getString(R.string.allow), this);
diff --git a/src/com/android/settings/core/TouchOverlayManager.java b/src/com/android/settings/core/TouchOverlayManager.java
new file mode 100644
index 0000000..f69d1bf
--- /dev/null
+++ b/src/com/android/settings/core/TouchOverlayManager.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.settings.core;
+
+import android.app.AppOpsManager;
+import android.content.Context;
+import android.os.Binder;
+import android.os.IBinder;
+
+public class TouchOverlayManager {
+
+    private final Context mContext;
+    private final IBinder mToken = new Binder();
+
+    public TouchOverlayManager(Context context) {
+        mContext = context;
+    }
+
+    public void setOverlayAllowed(boolean allowed) {
+        final AppOpsManager aom = mContext.getSystemService(AppOpsManager.class);
+        if (aom != null) {
+            aom.setUserRestriction(AppOpsManager.OP_SYSTEM_ALERT_WINDOW, !allowed, mToken);
+            aom.setUserRestriction(AppOpsManager.OP_TOAST_WINDOW, !allowed, mToken);
+        }
+    }
+}
diff --git a/src/com/android/settings/fuelgauge/BatteryMeterView.java b/src/com/android/settings/fuelgauge/BatteryMeterView.java
index 9127782..dcbf472 100644
--- a/src/com/android/settings/fuelgauge/BatteryMeterView.java
+++ b/src/com/android/settings/fuelgauge/BatteryMeterView.java
@@ -46,7 +46,7 @@
 
         mDrawable = new BatteryMeterDrawable(context, frameColor);
         mDrawable.setColorFilter(new PorterDuffColorFilter(tintColor, PorterDuff.Mode.SRC_IN));
-        mDrawable.setShowPercent(true);
+        mDrawable.setShowPercent(false);
         setImageDrawable(mDrawable);
     }
 
diff --git a/src/com/android/settings/fuelgauge/PowerGaugePreference.java b/src/com/android/settings/fuelgauge/PowerGaugePreference.java
index d4f2dd2..bdadf4c 100644
--- a/src/com/android/settings/fuelgauge/PowerGaugePreference.java
+++ b/src/com/android/settings/fuelgauge/PowerGaugePreference.java
@@ -29,8 +29,11 @@
 import com.android.settings.Utils;
 
 /**
- * Custom preference for displaying power consumption as a bar and an icon on
+ * Custom preference for displaying battery usage info as a bar and an icon on
  * the left for the subsystem/app type.
+ *
+ * The battery usage info could be usage percentage or usage time. The preference
+ * won't show any icon if it is null.
  */
 public class PowerGaugePreference extends TintablePreference {
     private final int mIconSize;
@@ -41,7 +44,20 @@
 
     public PowerGaugePreference(Context context, Drawable icon, CharSequence contentDescription,
             BatteryEntry info) {
-        super(context, null);
+        this(context, null, icon, contentDescription, info);
+    }
+
+    public PowerGaugePreference(Context context) {
+        this(context, null, null, null, null);
+    }
+
+    public PowerGaugePreference(Context context, AttributeSet attrs) {
+        this(context, attrs, null, null, null);
+    }
+
+    private PowerGaugePreference(Context context, AttributeSet attrs, Drawable icon,
+            CharSequence contentDescription, BatteryEntry info) {
+        super(context, attrs);
         setIcon(icon != null ? icon : new ColorDrawable(0));
         setWidgetLayoutResource(R.layout.preference_widget_summary);
         mInfo = info;
@@ -49,10 +65,6 @@
         mIconSize = context.getResources().getDimensionPixelSize(R.dimen.app_icon_size);
     }
 
-    public PowerGaugePreference(Context context) {
-        this(context, null, null, null);
-    }
-
     public void setContentDescription(String name) {
         mContentDescription = name;
         notifyChanged();
@@ -67,6 +79,11 @@
         return mProgress.toString();
     }
 
+    public void setSubtitle(String subtitle) {
+        mProgress = subtitle;
+        notifyChanged();
+    }
+
     BatteryEntry getInfo() {
         return mInfo;
     }
diff --git a/src/com/android/settings/fuelgauge/PowerUsageSummary.java b/src/com/android/settings/fuelgauge/PowerUsageSummary.java
index 96141f9..2c1fd78 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageSummary.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageSummary.java
@@ -16,7 +16,6 @@
 
 package com.android.settings.fuelgauge;
 
-import android.annotation.StringRes;
 import android.app.Activity;
 import android.content.Context;
 import android.graphics.drawable.Drawable;
@@ -26,6 +25,7 @@
 import android.os.Handler;
 import android.os.Message;
 import android.os.Process;
+import android.os.SystemClock;
 import android.os.UserHandle;
 import android.provider.SearchIndexableResource;
 import android.support.annotation.VisibleForTesting;
@@ -39,7 +39,6 @@
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
-import android.view.View;
 import android.widget.TextView;
 
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -60,6 +59,7 @@
 import com.android.settings.display.TimeoutPreferenceController;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settings.widget.FooterPreferenceMixin;
 import com.android.settingslib.BatteryInfo;
 
 import java.util.ArrayList;
@@ -87,8 +87,7 @@
     private static final int SECONDS_IN_HOUR = 60 * 60;
 
     private static final String KEY_SCREEN_USAGE = "screen_usage";
-    private static final String KEY_SCREEN_CONSUMPTION = "screen_consumption";
-    private static final String KEY_CELLULAR_NETWORK = "cellular_network";
+    private static final String KEY_TIME_SINCE_LAST_FULL_CHARGE = "last_full_charge";
 
 
     private static final int MENU_STATS_TYPE = Menu.FIRST;
@@ -100,14 +99,15 @@
     static final int MENU_TOGGLE_APPS = Menu.FIRST + 5;
     private static final int MENU_HELP = Menu.FIRST + 6;
 
+    private final FooterPreferenceMixin mFooterPreferenceMixin =
+            new FooterPreferenceMixin(this, getLifecycle());
+
     @VisibleForTesting
     boolean mShowAllApps = false;
     @VisibleForTesting
-    Preference mScreenUsagePref;
+    PowerGaugePreference mScreenUsagePref;
     @VisibleForTesting
-    Preference mScreenConsumptionPref;
-    @VisibleForTesting
-    Preference mCellularNetworkPref;
+    PowerGaugePreference mLastFullChargePref;
     @VisibleForTesting
     PowerUsageFeatureProvider mPowerFeatureProvider;
 
@@ -122,9 +122,10 @@
 
         mBatteryLayoutPref = (LayoutPreference) findPreference(KEY_BATTERY_HEADER);
         mAppListGroup = (PreferenceGroup) findPreference(KEY_APP_LIST);
-        mScreenUsagePref = findPreference(KEY_SCREEN_USAGE);
-        mScreenConsumptionPref = findPreference(KEY_SCREEN_CONSUMPTION);
-        mCellularNetworkPref = findPreference(KEY_CELLULAR_NETWORK);
+        mScreenUsagePref = (PowerGaugePreference) findPreference(KEY_SCREEN_USAGE);
+        mLastFullChargePref = (PowerGaugePreference) findPreference(
+                KEY_TIME_SINCE_LAST_FULL_CHARGE);
+        mFooterPreferenceMixin.createFooterPreference().setTitle(R.string.battery_footer_summary);
 
         initFeatureProvider();
     }
@@ -417,8 +418,11 @@
         final int dischargeAmount = USE_FAKE_DATA ? 5000
                 : stats != null ? stats.getDischargeAmount(mStatsType) : 0;
 
-        updateScreenPreference(dischargeAmount);
-        updateCellularPreference(dischargeAmount);
+        final long runningTime = calculateRunningTimeBasedOnStatsType();
+        updateScreenPreference();
+        updateLastFullChargePreference(runningTime);
+        mAppListGroup.setTitle(getString(R.string.power_usage_list_summary,
+                Utils.formatElapsedTime(context, runningTime, false)));
 
         if (averagePower >= MIN_AVERAGE_POWER_THRESHOLD_MILLI_AMP || USE_FAKE_DATA) {
             final List<BatterySipper> usageList = getCoalescedUsageList(
@@ -527,28 +531,27 @@
     }
 
     @VisibleForTesting
-    void updateScreenPreference(final int dischargeAmount) {
+    void updateScreenPreference() {
         final BatterySipper sipper = findBatterySipperByType(
                 mStatsHelper.getUsageList(), DrainType.SCREEN);
         final Context context = getContext();
-        final double totalPowerMah = sipper != null ? sipper.totalPowerMah : 0;
         final long usageTimeMs = sipper != null ? sipper.usageTimeMs : 0;
-        final double percentOfTotal = calculatePercentage(totalPowerMah, dischargeAmount);
 
-        mScreenUsagePref.setSummary(getString(R.string.battery_used_for,
-                Utils.formatElapsedTime(context, usageTimeMs, false)));
-        mScreenConsumptionPref.setSummary(getString(R.string.battery_overall_usage,
-                Utils.formatPercentage(percentOfTotal, true)));
+        mScreenUsagePref.setSubtitle(Utils.formatElapsedTime(context, usageTimeMs, false));
     }
 
     @VisibleForTesting
-    void updateCellularPreference(final int dischargeAmount) {
-        final BatterySipper sipper = findBatterySipperByType(
-                mStatsHelper.getUsageList(), DrainType.CELL);
-        final double totalPowerMah = sipper != null ? sipper.totalPowerMah : 0;
-        final double percentOfTotal = calculatePercentage(totalPowerMah, dischargeAmount);
-        mCellularNetworkPref.setSummary(getString(R.string.battery_overall_usage,
-                Utils.formatPercentage(percentOfTotal, true)));
+    void updateLastFullChargePreference(long timeMs) {
+        mLastFullChargePref.setSubtitle(getString(R.string.power_last_full_charge_summary,
+                Utils.formatElapsedTime(getContext(), timeMs, false)));
+    }
+
+    @VisibleForTesting
+    long calculateRunningTimeBasedOnStatsType() {
+        final long elapsedRealtimeUs = SystemClock.elapsedRealtime() * 1000;
+        // Return the battery time (millisecond) on status mStatsType
+        return mStatsHelper.getStats().computeBatteryRealtime(elapsedRealtimeUs,
+                mStatsType /* STATS_SINCE_CHARGED */) / 1000;
     }
 
     @VisibleForTesting
@@ -559,22 +562,15 @@
         }
         final BatteryMeterView batteryView = (BatteryMeterView) mBatteryLayoutPref
                 .findViewById(R.id.battery_header_icon);
-        final TextView timeText = (TextView) mBatteryLayoutPref.findViewById(R.id.time);
+        final TextView timeText = (TextView) mBatteryLayoutPref.findViewById(R.id.battery_percent);
         final TextView summary1 = (TextView) mBatteryLayoutPref.findViewById(R.id.summary1);
-        final TextView summary2 = (TextView) mBatteryLayoutPref.findViewById(R.id.summary2);
-        final int visible = info.remainingTimeUs != 0 ? View.VISIBLE : View.INVISIBLE;
-        final int summaryResId = info.mDischarging ?
-                R.string.estimated_time_left : R.string.estimated_charging_time_left;
-
-        if (info.remainingTimeUs != 0) {
-            timeText.setText(Utils.formatElapsedTime(context, info.remainingTimeUs / 1000, false));
+        timeText.setText(Utils.formatPercentage(info.mBatteryLevel));
+        if (info.remainingLabel == null ) {
+            summary1.setText(info.statusLabel);
         } else {
-            timeText.setText(info.statusLabel);
+            summary1.setText(info.remainingLabel);
         }
 
-        summary1.setText(summaryResId);
-        summary1.setVisibility(visible);
-        summary2.setVisibility(visible);
         batteryView.setBatteryInfo(info.mBatteryLevel);
     }
 
diff --git a/src/com/android/settings/inputmethod/AvailableVirtualKeyboardFragment.java b/src/com/android/settings/inputmethod/AvailableVirtualKeyboardFragment.java
index a6df7a3..a7862ae 100644
--- a/src/com/android/settings/inputmethod/AvailableVirtualKeyboardFragment.java
+++ b/src/com/android/settings/inputmethod/AvailableVirtualKeyboardFragment.java
@@ -43,12 +43,11 @@
 import com.android.settings.search.Indexable;
 import com.android.settings.search.SearchIndexableRaw;
 import com.android.settingslib.inputmethod.InputMethodAndSubtypeUtil;
+import com.android.settingslib.inputmethod.InputMethodPreference;
 import com.android.settingslib.inputmethod.InputMethodSettingValuesWrapper;
 
 import java.text.Collator;
 import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
 import java.util.List;
 
 public final class AvailableVirtualKeyboardFragment extends SettingsPreferenceFragment
@@ -115,7 +114,7 @@
     private static Drawable getInputMethodIcon(@NonNull final PackageManager packageManager,
             @NonNull final InputMethodInfo imi) {
         final ServiceInfo si = imi.getServiceInfo();
-        final ApplicationInfo ai = si.applicationInfo;
+        final ApplicationInfo ai = si != null ? si.applicationInfo : null;
         final String packageName = imi.getPackageName();
         if (si == null || ai == null || packageName == null) {
             return new ColorDrawable(Color.TRANSPARENT);
@@ -151,8 +150,8 @@
         final Context context = getPrefContext();
         final PackageManager packageManager = getActivity().getPackageManager();
         final List<InputMethodInfo> imis = mInputMethodSettingValues.getInputMethodList();
-        final int N = (imis == null ? 0 : imis.size());
-        for (int i = 0; i < N; ++i) {
+        final int numImis = (imis == null ? 0 : imis.size());
+        for (int i = 0; i < numImis; ++i) {
             final InputMethodInfo imi = imis.get(i);
             final boolean isAllowedByOrganization = permittedList == null
                     || permittedList.contains(imi.getPackageName());
@@ -162,14 +161,9 @@
             mInputMethodPreferenceList.add(pref);
         }
         final Collator collator = Collator.getInstance();
-        Collections.sort(mInputMethodPreferenceList, new Comparator<InputMethodPreference>() {
-            @Override
-            public int compare(InputMethodPreference lhs, InputMethodPreference rhs) {
-                return lhs.compareTo(rhs, collator);
-            }
-        });
+        mInputMethodPreferenceList.sort((lhs, rhs) -> lhs.compareTo(rhs, collator));
         getPreferenceScreen().removeAll();
-        for (int i = 0; i < N; ++i) {
+        for (int i = 0; i < numImis; ++i) {
             final InputMethodPreference pref = mInputMethodPreferenceList.get(i);
             pref.setOrder(i);
             getPreferenceScreen().addPreference(pref);
@@ -190,8 +184,6 @@
     static List<SearchIndexableRaw> buildSearchIndexOfInputMethods(final Context context,
             final List<InputMethodInfo> inputMethods, final String screenTitle) {
         final List<SearchIndexableRaw> indexes = new ArrayList<>();
-        final InputMethodManager imm = (InputMethodManager) context.getSystemService(
-                Context.INPUT_METHOD_SERVICE);
         for (int i = 0; i < inputMethods.size(); i++) {
             final InputMethodInfo imi = inputMethods.get(i);
             final ServiceInfo serviceInfo = imi.getServiceInfo();
@@ -207,7 +199,7 @@
         return indexes;
     }
 
-    public static Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
             new BaseSearchIndexProvider() {
         @Override
         public List<SearchIndexableRaw> getRawDataToIndex(Context context, boolean enabled) {
diff --git a/src/com/android/settings/inputmethod/InputMethodPreference.java b/src/com/android/settings/inputmethod/InputMethodPreference.java
deleted file mode 100755
index 463a043..0000000
--- a/src/com/android/settings/inputmethod/InputMethodPreference.java
+++ /dev/null
@@ -1,308 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.inputmethod;
-
-import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
-
-import android.app.AlertDialog;
-import android.content.ActivityNotFoundException;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.os.UserHandle;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.Preference.OnPreferenceChangeListener;
-import android.support.v7.preference.Preference.OnPreferenceClickListener;
-import android.text.TextUtils;
-import android.util.Log;
-import android.view.inputmethod.InputMethodInfo;
-import android.view.inputmethod.InputMethodManager;
-import android.view.inputmethod.InputMethodSubtype;
-import android.widget.Toast;
-
-import com.android.internal.inputmethod.InputMethodUtils;
-import com.android.settings.R;
-import com.android.settingslib.RestrictedLockUtils;
-import com.android.settingslib.RestrictedSwitchPreference;
-import com.android.settingslib.inputmethod.InputMethodAndSubtypeUtil;
-import com.android.settingslib.inputmethod.InputMethodSettingValuesWrapper;
-
-import java.text.Collator;
-import java.util.List;
-
-/**
- * Input method preference.
- *
- * This preference represents an IME. It is used for two purposes. 1) An instance with a switch
- * is used to enable or disable the IME. 2) An instance without a switch is used to invoke the
- * setting activity of the IME.
- */
-class InputMethodPreference extends RestrictedSwitchPreference implements OnPreferenceClickListener,
-        OnPreferenceChangeListener {
-    private static final String TAG = InputMethodPreference.class.getSimpleName();
-    private static final String EMPTY_TEXT = "";
-    private static final int NO_WIDGET = 0;
-
-    interface OnSavePreferenceListener {
-        /**
-         * Called when this preference needs to be saved its state.
-         *
-         * Note that this preference is non-persistent and needs explicitly to be saved its state.
-         * Because changing one IME state may change other IMEs' state, this is a place to update
-         * other IMEs' state as well.
-         *
-         * @param pref This preference.
-         */
-        public void onSaveInputMethodPreference(InputMethodPreference pref);
-    }
-
-    private final InputMethodInfo mImi;
-    private final boolean mHasPriorityInSorting;
-    private final OnSavePreferenceListener mOnSaveListener;
-    private final InputMethodSettingValuesWrapper mInputMethodSettingValues;
-    private final boolean mIsAllowedByOrganization;
-
-    private AlertDialog mDialog = null;
-
-    /**
-     * A preference entry of an input method.
-     *
-     * @param context The Context this is associated with.
-     * @param imi The {@link InputMethodInfo} of this preference.
-     * @param isImeEnabler true if this preference is the IME enabler that has enable/disable
-     *     switches for all available IMEs, not the list of enabled IMEs.
-     * @param isAllowedByOrganization false if the IME has been disabled by a device or profile
-     *     owner.
-     * @param onSaveListener The listener called when this preference has been changed and needs
-     *     to save the state to shared preference.
-     */
-    InputMethodPreference(final Context context, final InputMethodInfo imi,
-            final boolean isImeEnabler, final boolean isAllowedByOrganization,
-            final OnSavePreferenceListener onSaveListener) {
-        super(context);
-        setPersistent(false);
-        mImi = imi;
-        mIsAllowedByOrganization = isAllowedByOrganization;
-        mOnSaveListener = onSaveListener;
-        if (!isImeEnabler) {
-            // Remove switch widget.
-            setWidgetLayoutResource(NO_WIDGET);
-        }
-        // Disable on/off switch texts.
-        setSwitchTextOn(EMPTY_TEXT);
-        setSwitchTextOff(EMPTY_TEXT);
-        setKey(imi.getId());
-        setTitle(imi.loadLabel(context.getPackageManager()));
-        final String settingsActivity = imi.getSettingsActivity();
-        if (TextUtils.isEmpty(settingsActivity)) {
-            setIntent(null);
-        } else {
-            // Set an intent to invoke settings activity of an input method.
-            final Intent intent = new Intent(Intent.ACTION_MAIN);
-            intent.setClassName(imi.getPackageName(), settingsActivity);
-            setIntent(intent);
-        }
-        mInputMethodSettingValues = InputMethodSettingValuesWrapper.getInstance(context);
-        mHasPriorityInSorting = InputMethodUtils.isSystemIme(imi)
-                && mInputMethodSettingValues.isValidSystemNonAuxAsciiCapableIme(imi, context);
-        setOnPreferenceClickListener(this);
-        setOnPreferenceChangeListener(this);
-    }
-
-    public InputMethodInfo getInputMethodInfo() {
-        return mImi;
-    }
-
-    private boolean isImeEnabler() {
-        // If this {@link SwitchPreference} doesn't have a widget layout, we explicitly hide the
-        // switch widget at constructor.
-        return getWidgetLayoutResource() != NO_WIDGET;
-    }
-
-    @Override
-    public boolean onPreferenceChange(final Preference preference, final Object newValue) {
-        // Always returns false to prevent default behavior.
-        // See {@link TwoStatePreference#onClick()}.
-        if (!isImeEnabler()) {
-            // Prevent disabling an IME because this preference is for invoking a settings activity.
-            return false;
-        }
-        if (isChecked()) {
-            // Disable this IME.
-            setCheckedInternal(false);
-            return false;
-        }
-        if (InputMethodUtils.isSystemIme(mImi)) {
-            // Enable a system IME. No need to show a security warning dialog,
-            // but we might need to prompt if it's not Direct Boot aware.
-            if (mImi.getServiceInfo().directBootAware) {
-                setCheckedInternal(true);
-            } else {
-                showDirectBootWarnDialog();
-            }
-        } else {
-            // Once security is confirmed, we might prompt if the IME isn't
-            // Direct Boot aware.
-            showSecurityWarnDialog();
-        }
-        return false;
-    }
-
-    @Override
-    public boolean onPreferenceClick(final Preference preference) {
-        // Always returns true to prevent invoking an intent without catching exceptions.
-        // See {@link Preference#performClick(PreferenceScreen)}/
-        if (isImeEnabler()) {
-            // Prevent invoking a settings activity because this preference is for enabling and
-            // disabling an input method.
-            return true;
-        }
-        final Context context = getContext();
-        try {
-            final Intent intent = getIntent();
-            if (intent != null) {
-                // Invoke a settings activity of an input method.
-                context.startActivity(intent);
-            }
-        } catch (final ActivityNotFoundException e) {
-            Log.d(TAG, "IME's Settings Activity Not Found", e);
-            final String message = context.getString(
-                    R.string.failed_to_open_app_settings_toast,
-                    mImi.loadLabel(context.getPackageManager()));
-            Toast.makeText(context, message, Toast.LENGTH_LONG).show();
-        }
-        return true;
-    }
-
-    void updatePreferenceViews() {
-        final boolean isAlwaysChecked = mInputMethodSettingValues.isAlwaysCheckedIme(
-                mImi, getContext());
-        // When this preference has a switch and an input method should be always enabled,
-        // this preference should be disabled to prevent accidentally disabling an input method.
-        // This preference should also be disabled in case the admin does not allow this input
-        // method.
-        if (isAlwaysChecked && isImeEnabler()) {
-            setDisabledByAdmin(null);
-            setEnabled(false);
-        } else if (!mIsAllowedByOrganization) {
-            EnforcedAdmin admin =
-                    RestrictedLockUtils.checkIfInputMethodDisallowed(getContext(),
-                            mImi.getPackageName(), UserHandle.myUserId());
-            setDisabledByAdmin(admin);
-        } else {
-            setEnabled(true);
-        }
-        setChecked(mInputMethodSettingValues.isEnabledImi(mImi));
-        if (!isDisabledByAdmin()) {
-            setSummary(getSummaryString());
-        }
-    }
-
-    private InputMethodManager getInputMethodManager() {
-        return (InputMethodManager)getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
-    }
-
-    private String getSummaryString() {
-        final InputMethodManager imm = getInputMethodManager();
-        final List<InputMethodSubtype> subtypes = imm.getEnabledInputMethodSubtypeList(mImi, true);
-        return InputMethodAndSubtypeUtil.getSubtypeLocaleNameListAsSentence(
-                subtypes, getContext(), mImi);
-    }
-
-    private void setCheckedInternal(boolean checked) {
-        super.setChecked(checked);
-        mOnSaveListener.onSaveInputMethodPreference(InputMethodPreference.this);
-        notifyChanged();
-    }
-
-    private void showSecurityWarnDialog() {
-        if (mDialog != null && mDialog.isShowing()) {
-            mDialog.dismiss();
-        }
-        final Context context = getContext();
-        final AlertDialog.Builder builder = new AlertDialog.Builder(context);
-        builder.setCancelable(true /* cancelable */);
-        builder.setTitle(android.R.string.dialog_alert_title);
-        final CharSequence label = mImi.getServiceInfo().applicationInfo.loadLabel(
-                context.getPackageManager());
-        builder.setMessage(context.getString(R.string.ime_security_warning, label));
-        builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
-            @Override
-            public void onClick(final DialogInterface dialog, final int which) {
-                // The user confirmed to enable a 3rd party IME, but we might
-                // need to prompt if it's not Direct Boot aware.
-                if (mImi.getServiceInfo().directBootAware) {
-                    setCheckedInternal(true);
-                } else {
-                    showDirectBootWarnDialog();
-                }
-            }
-        });
-        builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
-            @Override
-            public void onClick(final DialogInterface dialog, final int which) {
-                // The user canceled to enable a 3rd party IME.
-                setCheckedInternal(false);
-            }
-        });
-        mDialog = builder.create();
-        mDialog.show();
-    }
-
-    private void showDirectBootWarnDialog() {
-        if (mDialog != null && mDialog.isShowing()) {
-            mDialog.dismiss();
-        }
-        final Context context = getContext();
-        final AlertDialog.Builder builder = new AlertDialog.Builder(context);
-        builder.setCancelable(true /* cancelable */);
-        builder.setMessage(context.getText(R.string.direct_boot_unaware_dialog_message));
-        builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
-            @Override
-            public void onClick(final DialogInterface dialog, final int which) {
-                setCheckedInternal(true);
-            }
-        });
-        builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
-            @Override
-            public void onClick(final DialogInterface dialog, final int which) {
-                setCheckedInternal(false);
-            }
-        });
-        mDialog = builder.create();
-        mDialog.show();
-    }
-
-    int compareTo(final InputMethodPreference rhs, final Collator collator) {
-        if (this == rhs) {
-            return 0;
-        }
-        if (mHasPriorityInSorting == rhs.mHasPriorityInSorting) {
-            final CharSequence t0 = getTitle();
-            final CharSequence t1 = rhs.getTitle();
-            if (TextUtils.isEmpty(t0)) {
-                return 1;
-            }
-            if (TextUtils.isEmpty(t1)) {
-                return -1;
-            }
-            return collator.compare(t0.toString(), t1.toString());
-        }
-        // Prefer always checked system IMEs
-        return mHasPriorityInSorting ? -1 : 1;
-    }
-}
diff --git a/src/com/android/settings/inputmethod/VirtualKeyboardFragment.java b/src/com/android/settings/inputmethod/VirtualKeyboardFragment.java
index c362389..7b7c599 100644
--- a/src/com/android/settings/inputmethod/VirtualKeyboardFragment.java
+++ b/src/com/android/settings/inputmethod/VirtualKeyboardFragment.java
@@ -35,6 +35,7 @@
 import com.android.settings.search.Indexable;
 import com.android.settings.search.SearchIndexableRaw;
 import com.android.settingslib.inputmethod.InputMethodAndSubtypeUtil;
+import com.android.settingslib.inputmethod.InputMethodPreference;
 
 import java.text.Collator;
 import java.util.ArrayList;
@@ -104,12 +105,7 @@
             mInputMethodPreferenceList.add(pref);
         }
         final Collator collator = Collator.getInstance();
-        Collections.sort(mInputMethodPreferenceList, new Comparator<InputMethodPreference>() {
-            @Override
-            public int compare(InputMethodPreference lhs, InputMethodPreference rhs) {
-                return lhs.compareTo(rhs, collator);
-            }
-        });
+        mInputMethodPreferenceList.sort((lhs, rhs) -> lhs.compareTo(rhs, collator));
         getPreferenceScreen().removeAll();
         for (int i = 0; i < N; ++i) {
             final InputMethodPreference pref = mInputMethodPreferenceList.get(i);
diff --git a/src/com/android/settings/print/PrintSettingsFragment.java b/src/com/android/settings/print/PrintSettingsFragment.java
index fad577c..a1c1660 100644
--- a/src/com/android/settings/print/PrintSettingsFragment.java
+++ b/src/com/android/settings/print/PrintSettingsFragment.java
@@ -529,7 +529,7 @@
             if (mPrintManager != null) {
                 if (isListening) {
                     List<PrintServiceInfo> services =
-                            mPrintManager.getPrintServices(PrintManager.ALL_SERVICES);
+                            mPrintManager.getPrintServices(PrintManager.ENABLED_SERVICES);
                     if (services == null || services.isEmpty()) {
                         mSummaryLoader.setSummary(this,
                                 mContext.getString(R.string.print_settings_summary_no_service));
diff --git a/src/com/android/settings/users/EditUserPhotoController.java b/src/com/android/settings/users/EditUserPhotoController.java
index 03b959a..c348b4aa 100644
--- a/src/com/android/settings/users/EditUserPhotoController.java
+++ b/src/com/android/settings/users/EditUserPhotoController.java
@@ -240,6 +240,7 @@
 
             @Override
             protected void onPostExecute(Void result) {
+                if (!mFragment.isAdded()) return;
                 cropPhoto();
             }
         }.execute();
diff --git a/src/com/android/settings/wifi/SavedAccessPointsWifiSettings.java b/src/com/android/settings/wifi/SavedAccessPointsWifiSettings.java
index 07495ee..1a60256 100644
--- a/src/com/android/settings/wifi/SavedAccessPointsWifiSettings.java
+++ b/src/com/android/settings/wifi/SavedAccessPointsWifiSettings.java
@@ -66,6 +66,18 @@
         }
     };
 
+    private final WifiManager.ActionListener mForgetListener = new WifiManager.ActionListener() {
+        @Override
+        public void onSuccess() {
+            initPreferences();
+        }
+
+        @Override
+        public void onFailure(int reason) {
+            initPreferences();
+        }
+    };
+
     private WifiDialog mDialog;
     private WifiManager mWifiManager;
     private AccessPoint mDlgAccessPoint;
@@ -229,11 +241,12 @@
                     Log.e(TAG, "Failed to remove Passpoint configuration for "
                             + mSelectedAccessPoint.getConfigName());
                 }
+                initPreferences();
             } else {
-                mWifiManager.forget(mSelectedAccessPoint.getConfig().networkId, null);
+                // mForgetListener will call initPreferences upon completion
+                mWifiManager.forget(mSelectedAccessPoint.getConfig().networkId, mForgetListener);
             }
             mSelectedAccessPoint = null;
-            initPreferences();
         }
     }
 
diff --git a/src/com/android/settings/wifi/WifiSettings.java b/src/com/android/settings/wifi/WifiSettings.java
index 8784d09..38f5a43 100644
--- a/src/com/android/settings/wifi/WifiSettings.java
+++ b/src/com/android/settings/wifi/WifiSettings.java
@@ -516,7 +516,10 @@
             if (mSelectedAccessPoint.isActive()) {
                 return super.onPreferenceTreeClick(preference);
             }
-            /** Bypass dialog and connect to unsecured or previously connected saved networks. */
+            /**
+             * Bypass dialog and connect to unsecured networks, or previously connected saved
+             * networks, or Passpoint provided networks.
+             */
             WifiConfiguration config = mSelectedAccessPoint.getConfig();
             if (mSelectedAccessPoint.getSecurity() == AccessPoint.SECURITY_NONE) {
                 mSelectedAccessPoint.generateOpenNetworkConfig();
@@ -525,6 +528,10 @@
                     && config.getNetworkSelectionStatus() != null
                     && config.getNetworkSelectionStatus().getHasEverConnected()) {
                 connect(config, true /* isSavedNetwork */);
+            } else if (mSelectedAccessPoint.isPasspoint()) {
+                // Access point provided by an installed Passpoint provider, connect using
+                // the associated config.
+                connect(config, true /* isSavedNetwork */);
             } else {
                 showDialog(mSelectedAccessPoint, WifiConfigUiBase.MODE_CONNECT);
             }
@@ -836,32 +843,24 @@
     }
 
     private void setOffMessage() {
-        final CharSequence briefText = getText(R.string.wifi_empty_list_wifi_off);
-
+        final CharSequence title = getText(R.string.wifi_empty_list_wifi_off);
         // Don't use WifiManager.isScanAlwaysAvailable() to check the Wi-Fi scanning mode. Instead,
         // read the system settings directly. Because when the device is in Airplane mode, even if
         // Wi-Fi scanning mode is on, WifiManager.isScanAlwaysAvailable() still returns "off".
-        final ContentResolver resolver = getActivity().getContentResolver();
-        final boolean wifiScanningMode = Settings.Global.getInt(
-                resolver, Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE, 0) == 1;
-
-        if (!wifiScanningMode) {
-            // Show only the brief text if the user is not allowed to configure scanning settings,
-            // or the scanning mode has been turned off.
-            mStatusMessagePreference.setTitle(briefText);
-        } else {
-            LinkifyUtils.OnClickListener clickListener = new LinkifyUtils.OnClickListener() {
-                @Override
-                public void onClick() {
-                    final SettingsActivity activity = (SettingsActivity) getActivity();
-                    activity.startPreferencePanel(WifiSettings.this,
-                            ScanningSettings.class.getName(),
-                            null, R.string.location_scanning_screen_title, null, null, 0);
-                }
-            };
-            mStatusMessagePreference.setText(
-                    briefText, getText(R.string.wifi_scan_notify_text), clickListener);
-        }
+        final boolean wifiScanningMode = Settings.Global.getInt(getActivity().getContentResolver(),
+                Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE, 0) == 1;
+        final CharSequence description = wifiScanningMode ? getText(R.string.wifi_scan_notify_text)
+                : getText(R.string.wifi_scan_notify_text_scanning_off);
+        final LinkifyUtils.OnClickListener clickListener = new LinkifyUtils.OnClickListener() {
+            @Override
+            public void onClick() {
+                final SettingsActivity activity = (SettingsActivity) getActivity();
+                activity.startPreferencePanel(WifiSettings.this,
+                        ScanningSettings.class.getName(),
+                        null, R.string.location_scanning_screen_title, null, null, 0);
+            }
+        };
+        mStatusMessagePreference.setText(title, description, clickListener);
         removeConnectedAccessPointPreference();
         mAccessPointsPreferenceCategory.removeAll();
         mAccessPointsPreferenceCategory.addPreference(mStatusMessagePreference);
diff --git a/src/com/android/settings/wifi/WifiSummaryUpdater.java b/src/com/android/settings/wifi/WifiSummaryUpdater.java
index c0d4468..2c56d08 100644
--- a/src/com/android/settings/wifi/WifiSummaryUpdater.java
+++ b/src/com/android/settings/wifi/WifiSummaryUpdater.java
@@ -75,7 +75,7 @@
     @Override
     public String getSummary() {
         if (!mWifiTracker.enabled) {
-            return mContext.getString(R.string.wifi_disabled_generic);
+            return mContext.getString(R.string.switch_off_text);
         }
         if (!mWifiTracker.connected) {
             return mContext.getString(R.string.disconnected);
diff --git a/tests/app/src/com/android/settings/wifi/WifiSettingsUiTest.java b/tests/app/src/com/android/settings/wifi/WifiSettingsUiTest.java
new file mode 100644
index 0000000..11a49fc
--- /dev/null
+++ b/tests/app/src/com/android/settings/wifi/WifiSettingsUiTest.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.settings.wifi;
+
+import static android.support.test.espresso.Espresso.onView;
+import static android.support.test.espresso.action.ViewActions.click;
+import static android.support.test.espresso.matcher.ViewMatchers.withText;
+
+import android.app.Instrumentation;
+import android.content.Context;
+import android.content.Intent;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.rule.ActivityTestRule;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.android.settings.R;
+import com.android.settings.Settings.WifiSettingsActivity;
+import com.android.settingslib.wifi.WifiTracker;
+import com.android.settingslib.wifi.WifiTrackerFactory;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@RunWith(AndroidJUnit4.class)
+public class WifiSettingsUiTest {
+
+    // TODO(sghuman): Investigate why resource ids are not resolving correctly in the test apk,
+    // then remove this manual string entry
+    private static final String WIFI_PREFERENCES = "Wi\\u2011Fi preferences";
+
+    @Mock private WifiTracker mockWifiTracker;
+
+    @Rule
+    public ActivityTestRule<WifiSettingsActivity> mActivityRule =
+            new ActivityTestRule<>(WifiSettingsActivity.class, true);
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        WifiTrackerFactory.setTestingWifiTracker(mockWifiTracker);
+    }
+
+    private void launchActivity() {
+        mActivityRule.launchActivity(new Intent("android.settings.WIFI_SETTINGS"));
+    }
+
+    @Test
+    public void launchActivityShouldSucceed() {
+        launchActivity();
+    }
+
+    @Test
+    public void shouldShowWifiPreferences() {
+        launchActivity();
+        onView(withText(WIFI_PREFERENCES)).perform(click());
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/applications/DrawOverlayDetailsTest.java b/tests/robotests/src/com/android/settings/applications/DrawOverlayDetailsTest.java
index a5306a2..ef6351a 100644
--- a/tests/robotests/src/com/android/settings/applications/DrawOverlayDetailsTest.java
+++ b/tests/robotests/src/com/android/settings/applications/DrawOverlayDetailsTest.java
@@ -19,10 +19,11 @@
 import android.content.Context;
 
 import com.android.internal.logging.nano.MetricsProto;
-import com.android.internal.telephony.SmsUsageMonitor;
 import com.android.settings.SettingsRobolectricTestRunner;
 import com.android.settings.TestConfig;
+import com.android.settings.core.TouchOverlayManager;
 import com.android.settings.testutils.FakeFeatureFactory;
+import com.android.settings.testutils.shadow.ShadowPreferenceFragment;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -32,6 +33,7 @@
 import org.mockito.MockitoAnnotations;
 import org.robolectric.annotation.Config;
 import org.robolectric.shadows.ShadowApplication;
+import org.robolectric.util.ReflectionHelpers;
 
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.eq;
@@ -47,17 +49,22 @@
     private FakeFeatureFactory mFeatureFactory;
     private DrawOverlayDetails mFragment;
 
+    @Mock
+    private TouchOverlayManager mTouchOverlayManager;
+
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         FakeFeatureFactory.setupForTest(mContext);
         mFeatureFactory = (FakeFeatureFactory) FakeFeatureFactory.getFactory(mContext);
+
         mFragment = new DrawOverlayDetails();
-        mFragment.onAttach(ShadowApplication.getInstance().getApplicationContext());
+        ReflectionHelpers.setField(mFragment, "mTouchOverlayManager", mTouchOverlayManager);
     }
 
     @Test
     public void logSpecialPermissionChange() {
+        mFragment.onAttach(ShadowApplication.getInstance().getApplicationContext());
         mFragment.logSpecialPermissionChange(true, "app");
         verify(mFeatureFactory.metricsFeatureProvider).action(any(Context.class),
                 eq(MetricsProto.MetricsEvent.APP_SPECIAL_PERMISSION_APPDRAW_ALLOW), eq("app"));
@@ -66,4 +73,18 @@
         verify(mFeatureFactory.metricsFeatureProvider).action(any(Context.class),
                 eq(MetricsProto.MetricsEvent.APP_SPECIAL_PERMISSION_APPDRAW_DENY), eq("app"));
     }
+
+    @Test
+    @Config(shadows = ShadowPreferenceFragment.class)
+    public void onStart_disableOverlay() {
+        mFragment.onStart();
+        verify(mTouchOverlayManager).setOverlayAllowed(false);
+    }
+
+    @Test
+    @Config(shadows = ShadowPreferenceFragment.class)
+    public void onStop_enableOverlay() {
+        mFragment.onStop();
+        verify(mTouchOverlayManager).setOverlayAllowed(true);
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/applications/InstalledAppDetailsTest.java b/tests/robotests/src/com/android/settings/applications/InstalledAppDetailsTest.java
index 209cdeb..a33a8c8 100644
--- a/tests/robotests/src/com/android/settings/applications/InstalledAppDetailsTest.java
+++ b/tests/robotests/src/com/android/settings/applications/InstalledAppDetailsTest.java
@@ -18,16 +18,21 @@
 
 
 import android.app.Activity;
+import android.app.AlertDialog;
 import android.app.admin.DevicePolicyManager;
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
+import android.os.BatteryStats;
 import android.os.UserManager;
 import android.support.v7.preference.Preference;
 import android.view.View;
 import android.widget.Button;
 
+import com.android.internal.os.BatterySipper;
+import com.android.internal.os.BatteryStatsHelper;
 import com.android.settings.R;
+import com.android.settings.SettingsActivity;
 import com.android.settings.SettingsRobolectricTestRunner;
 import com.android.settings.TestConfig;
 import com.android.settings.applications.instantapps.InstantAppButtonsController;
@@ -48,10 +53,14 @@
 import org.robolectric.util.ReflectionHelpers;
 
 import static com.google.common.truth.Truth.assertThat;
+
 import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyInt;
 import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -61,23 +70,37 @@
 public final class InstalledAppDetailsTest {
     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
     private Context mContext;
-
     @Mock
     ApplicationFeatureProvider mApplicationFeatureProvider;
-
     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
     private UserManager mUserManager;
     @Mock
-    private Activity mActivity;
+    private SettingsActivity mActivity;
     @Mock
     private DevicePolicyManager mDevicePolicyManager;
+    @Mock
+    private Preference mBatteryPreference;
+    @Mock
+    private BatterySipper mBatterySipper;
+    @Mock
+    private BatteryStatsHelper mBatteryStatsHelper;
+    @Mock
+    private BatteryStats.Uid mUid;
 
     private InstalledAppDetails mAppDetail;
+    private Context mShadowContext;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-        mAppDetail = new InstalledAppDetails();
+        mShadowContext = RuntimeEnvironment.application;
+
+        mAppDetail = spy(new InstalledAppDetails());
+
+        mBatterySipper.drainType = BatterySipper.DrainType.IDLE;
+        mBatterySipper.uidObj = mUid;
+        doReturn(mActivity).when(mAppDetail).getActivity();
+        doReturn(mShadowContext).when(mAppDetail).getContext();
 
         // Default to not considering any apps to be instant (individual tests can override this).
         ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider",
@@ -124,7 +147,7 @@
         when(stats.getTotalBytes()).thenReturn(1L);
 
         assertThat(InstalledAppDetails.getStorageSummary(context, stats, true))
-                .isEqualTo("1.00B used in External storage");
+                .isEqualTo("1.00B used in external storage");
     }
 
     @Test
@@ -134,7 +157,7 @@
         when(stats.getTotalBytes()).thenReturn(1L);
 
         assertThat(InstalledAppDetails.getStorageSummary(context, stats, false))
-                .isEqualTo("1.00B used in Internal storage");
+                .isEqualTo("1.00B used in internal storage");
     }
 
     @Test
@@ -154,6 +177,16 @@
         verify(mActivity, never()).finishAndRemoveTask();
     }
 
+    @Test
+    public void launchPowerUsageDetailFragment_shouldNotCrash() {
+        mAppDetail.mBatteryPreference = mBatteryPreference;
+        mAppDetail.mSipper = mBatterySipper;
+        mAppDetail.mBatteryHelper = mBatteryStatsHelper;
+
+        // Should not crash
+        mAppDetail.onPreferenceClick(mBatteryPreference);
+    }
+
     // Tests that we don't show the "uninstall for all users" button for instant apps.
     @Test
     public void instantApps_noUninstallForAllButton() {
@@ -181,7 +214,7 @@
     public void instantApps_noUninstallButton() {
         // Make this app appear to be instant.
         ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider",
-                                         (InstantAppDataProvider) (i -> true));
+                (InstantAppDataProvider) (i -> true));
         final ApplicationInfo info = new ApplicationInfo();
         info.flags = ApplicationInfo.FLAG_INSTALLED;
         info.enabled = true;
@@ -222,6 +255,20 @@
         verify(forceStopButton).setVisibility(View.GONE);
     }
 
+    @Test
+    public void instantApps_buttonControllerHandlesDialog() {
+        InstantAppButtonsController mockController = mock(InstantAppButtonsController.class);
+        ReflectionHelpers.setField(
+                mAppDetail, "mInstantAppButtonsController", mockController);
+        // Make sure first that button controller is not called for supported dialog id
+        AlertDialog mockDialog = mock(AlertDialog.class);
+        when(mockController.createDialog(InstantAppButtonsController.DLG_CLEAR_APP))
+                .thenReturn(mockDialog);
+        assertThat(mAppDetail.createDialog(InstantAppButtonsController.DLG_CLEAR_APP, 0))
+                .isEqualTo(mockDialog);
+        verify(mockController).createDialog(InstantAppButtonsController.DLG_CLEAR_APP);
+    }
+
     // A helper class for testing the InstantAppButtonsController - it lets us look up the
     // preference associated with a key for instant app buttons and get back a mock
     // LayoutPreference (to avoid a null pointer exception).
@@ -261,8 +308,8 @@
         FakeFeatureFactory.setupForTest(mContext);
         FakeFeatureFactory factory =
                 (FakeFeatureFactory) FakeFeatureFactory.getFactory(mContext);
-        when(factory.applicationFeatureProvider.newInstantAppButtonsController(any(),
-                any())).thenReturn(buttonsController);
+        when(factory.applicationFeatureProvider.newInstantAppButtonsController(
+                any(), any(), any())).thenReturn(buttonsController);
 
         fragment.maybeAddInstantAppButtons();
         verify(buttonsController).setPackageName(anyString());
diff --git a/tests/robotests/src/com/android/settings/applications/instantapps/InstantAppButtonsControllerTest.java b/tests/robotests/src/com/android/settings/applications/instantapps/InstantAppButtonsControllerTest.java
new file mode 100644
index 0000000..13040a2
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/applications/instantapps/InstantAppButtonsControllerTest.java
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.applications.instantapps;
+
+import static com.android.settings.applications.instantapps.InstantAppButtonsController
+        .ShowDialogDelegate;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Matchers.eq;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.isNull;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
+
+import android.annotation.SuppressLint;
+import android.app.Fragment;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.view.View;
+import android.widget.Button;
+
+import com.android.settings.R;
+import com.android.settings.SettingsRobolectricTestRunner;
+import com.android.settings.TestConfig;
+import com.android.settings.applications.PackageManagerWrapper;
+import com.android.settings.backup.BackupSettingsActivityTest;
+import com.android.settings.core.instrumentation.MetricsFeatureProvider;
+import com.android.settings.testutils.FakeFeatureFactory;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowUserManager;
+import org.robolectric.util.ReflectionHelpers;
+
+/** Tests for the InstantAppButtonsController. */
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = 23)
+public class InstantAppButtonsControllerTest {
+
+    private static final String TEST_INSTALLER_PACKAGE_NAME = "com.installer";
+    private static final String TEST_INSTALLER_ACTIVITY_NAME = "com.installer.InstallerActivity";
+    private static final ComponentName TEST_INSTALLER_COMPONENT =
+            new ComponentName(
+                    TEST_INSTALLER_PACKAGE_NAME,
+                    TEST_INSTALLER_ACTIVITY_NAME);
+    private static final String TEST_AIA_PACKAGE_NAME = "test.aia.package";
+
+    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+    Context mockContext;
+    @Mock
+    PackageManager mockPackageManager;
+    @Mock
+    PackageManagerWrapper mockPackageManagerWrapper;
+    @Mock
+    View mockView;
+    @Mock
+    ShowDialogDelegate mockShowDialogDelegate;
+    @Mock
+    Button mockInstallButton;
+    @Mock
+    Button mockClearButton;
+    @Mock
+    MetricsFeatureProvider mockMetricsFeatureProvider;
+    @Mock
+    ResolveInfo mockResolveInfo;
+    @Mock
+    ActivityInfo mockActivityInfo;
+
+    private PackageManager stubPackageManager;
+
+    private FakeFeatureFactory fakeFeatureFactory;
+    private TestFragment testFragment;
+    private InstantAppButtonsController controller;
+
+
+    private View.OnClickListener receivedListener;
+
+    @Before
+    public void init() {
+        MockitoAnnotations.initMocks(this);
+        testFragment = new TestFragment();
+        when(mockView.findViewById(R.id.install)).thenReturn(mockInstallButton);
+        when(mockView.findViewById(R.id.clear_data)).thenReturn(mockClearButton);
+        mockResolveInfo.activityInfo = mockActivityInfo;
+        mockActivityInfo.packageName = TEST_INSTALLER_PACKAGE_NAME;
+        mockActivityInfo.name = TEST_INSTALLER_ACTIVITY_NAME;
+        when(mockContext.getPackageManager()).thenReturn(mockPackageManager);
+        when(mockPackageManager.resolveActivity(any(), anyInt())).thenReturn(mockResolveInfo);
+        controller = new InstantAppButtonsController(
+                mockContext, testFragment, mockView, mockShowDialogDelegate);
+        controller.setPackageName(TEST_AIA_PACKAGE_NAME);
+        ReflectionHelpers.setField(
+                controller, "mPackageManagerWrapper", mockPackageManagerWrapper);
+        FakeFeatureFactory.setupForTest(mockContext);
+    }
+
+    @Test
+    public void testInstallListenerTriggersInstall() {
+        doAnswer(invocation -> {
+            receivedListener = (View.OnClickListener) invocation.getArguments()[0];
+            return null;
+        }).when(mockInstallButton).setOnClickListener(any());
+        controller.bindButtons();
+
+        assertThat(receivedListener).isNotNull();
+        receivedListener.onClick(mockInstallButton);
+        assertThat(testFragment.getStartActivityIntent()).isNotNull();
+        assertThat(testFragment.getStartActivityIntent().getComponent())
+                .isEqualTo(TEST_INSTALLER_COMPONENT);
+    }
+
+    @Test
+    public void testClearListenerShowsDialog() {
+        doAnswer(invocation -> {
+            receivedListener = (View.OnClickListener) invocation.getArguments()[0];
+            return null;
+        }).when(mockClearButton).setOnClickListener(any());
+        controller.bindButtons();
+        assertThat(receivedListener).isNotNull();
+        receivedListener.onClick(mockClearButton);
+        verify(mockShowDialogDelegate).showDialog(InstantAppButtonsController.DLG_CLEAR_APP);
+    }
+
+    @Test
+    public void testDialogInterfaceOnClick_positiveClearsApp() {
+        controller.onClick(mock(DialogInterface.class), DialogInterface.BUTTON_POSITIVE);
+        verify(mockPackageManagerWrapper)
+                .deletePackageAsUser(eq(TEST_AIA_PACKAGE_NAME), any(), anyInt(),anyInt());
+    }
+
+    @Test
+    public void testDialogInterfaceOnClick_nonPositiveDoesNothing() {
+        controller.onClick(mock(DialogInterface.class), DialogInterface.BUTTON_NEGATIVE);
+        controller.onClick(mock(DialogInterface.class), DialogInterface.BUTTON_NEUTRAL);
+        verifyZeroInteractions(mockPackageManagerWrapper);
+    }
+    @SuppressLint("ValidFragment")
+    private class TestFragment extends Fragment {
+
+        private Intent startActivityIntent;
+
+        public Intent getStartActivityIntent() {
+            return startActivityIntent;
+        }
+
+        @Override
+        public void startActivity(Intent intent) {
+            startActivityIntent = intent;
+        }
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/deviceinfo/StorageSettingsTest.java b/tests/robotests/src/com/android/settings/deviceinfo/StorageSettingsTest.java
index 84d3b98..95f9fbe 100644
--- a/tests/robotests/src/com/android/settings/deviceinfo/StorageSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/deviceinfo/StorageSettingsTest.java
@@ -18,6 +18,7 @@
 
 
 import android.app.Activity;
+import android.app.usage.StorageStatsManager;
 import android.icu.text.NumberFormat;
 import android.os.storage.VolumeInfo;
 import android.text.format.Formatter;
@@ -40,6 +41,7 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import static org.mockito.Matchers.any;
 import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
@@ -73,9 +75,14 @@
         final SummaryLoader.SummaryProvider provider =
                 StorageSettings.SUMMARY_PROVIDER_FACTORY.createSummaryProvider(mActivity, loader);
         final VolumeInfo volumeInfo = mVolumes.get(0);
+        when(volumeInfo.isMountedReadable()).thenReturn(true);
         when(volumeInfo.getType()).thenReturn(VolumeInfo.TYPE_PRIVATE);
-        when(volumeInfo.getPath().getTotalSpace()).thenReturn(500L);
-        when(volumeInfo.getPath().getFreeSpace()).thenReturn(0L);
+        when(mStorageManagerVolumeProvider.getTotalBytes(
+                        any(StorageStatsManager.class), any(VolumeInfo.class)))
+                .thenReturn(500L);
+        when(mStorageManagerVolumeProvider.getFreeBytes(
+                        any(StorageStatsManager.class), any(VolumeInfo.class)))
+                .thenReturn(0L);
 
         ReflectionHelpers.setField(
                 provider, "mStorageManagerVolumeProvider", mStorageManagerVolumeProvider);
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java b/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java
index a6e0943..5f2d54f 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java
@@ -15,19 +15,17 @@
  */
 package com.android.settings.fuelgauge;
 
-import android.app.Activity;
 import android.content.Context;
 import android.content.Intent;
 import android.os.PowerManager;
 import android.os.Process;
-import android.support.v7.preference.Preference;
 import android.text.TextUtils;
 import android.text.format.DateUtils;
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
-import android.view.View;
 import android.widget.TextView;
+
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.internal.os.BatterySipper;
 import com.android.internal.os.BatteryStatsHelper;
@@ -40,6 +38,7 @@
 import com.android.settings.applications.LayoutPreference;
 import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settingslib.BatteryInfo;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -53,13 +52,15 @@
 import java.util.ArrayList;
 import java.util.List;
 
-import static com.android.settings.fuelgauge.PowerUsageBase.MENU_STATS_REFRESH;
 import static com.android.settings.fuelgauge.PowerUsageSummary.MENU_ADDITIONAL_BATTERY_INFO;
 import static com.android.settings.fuelgauge.PowerUsageSummary.MENU_HIGH_POWER_APPS;
 import static com.android.settings.fuelgauge.PowerUsageSummary.MENU_TOGGLE_APPS;
+
 import static com.google.common.truth.Truth.assertThat;
+
 import static org.mockito.Matchers.anyInt;
 import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyLong;
 import static org.mockito.Matchers.anyString;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.doReturn;
@@ -77,9 +78,13 @@
 public class PowerUsageSummaryTest {
     private static final String[] PACKAGE_NAMES = {"com.app1", "com.app2"};
     private static final String TIME_LEFT = "2h30min";
+    private static final int BATTERY_LEVEL = 55;
     private static final int UID = 123;
     private static final int POWER_MAH = 100;
     private static final long REMAINING_TIME_US = 100000;
+    private static final long TIME_SINCE_LAST_FULL_CHARGE_MS = 25000;
+    private static final long TIME_SINCE_LAST_FULL_CHARGE_US =
+            TIME_SINCE_LAST_FULL_CHARGE_MS * 1000;
     private static final int DISCHARGE_AMOUNT = 100;
     private static final long USAGE_TIME_MS = 10000;
     private static final double TOTAL_POWER = 200;
@@ -117,20 +122,16 @@
     @Mock
     private BatteryMeterView mBatteryMeterView;
     @Mock
-    private TextView mTimeText;
+    private TextView mBatteryPercentText;
     @Mock
     private TextView mSummary1;
     @Mock
-    private TextView mSummary2;
-    @Mock
     private BatteryInfo mBatteryInfo;
     @Mock
-    private Preference mScreenUsagePref;
+    private PowerGaugePreference mScreenUsagePref;
     @Mock
-    private Preference mScreenConsumptionPref;
-    @Mock
-    private Preference mCellularNetworkPref;
-    @Mock
+    private PowerGaugePreference mLastFullChargePref;
+    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
     private BatteryStatsHelper mBatteryHelper;
     @Mock
     private PowerManager mPowerManager;
@@ -153,7 +154,7 @@
 
         mFragment = spy(new TestFragment(mContext));
         mFragment.initFeatureProvider();
-        
+
         when(mFragment.getActivity()).thenReturn(mSettingsActivity);
         when(mAdditionalBatteryInfoMenu.getItemId())
                 .thenReturn(MENU_ADDITIONAL_BATTERY_INFO);
@@ -162,6 +163,8 @@
         when(mFeatureFactory.powerUsageFeatureProvider.getAdditionalBatteryInfoIntent())
                 .thenReturn(ADDITIONAL_BATTERY_INFO_INTENT);
         when(mBatteryHelper.getTotalPower()).thenReturn(TOTAL_POWER);
+        when(mBatteryHelper.getStats().computeBatteryRealtime(anyLong(), anyInt())).thenReturn(
+                TIME_SINCE_LAST_FULL_CHARGE_US);
 
         when(mNormalBatterySipper.getPackages()).thenReturn(PACKAGE_NAMES);
         when(mNormalBatterySipper.getUid()).thenReturn(UID);
@@ -172,8 +175,7 @@
         mCellBatterySipper.totalPowerMah = POWER_MAH;
 
         when(mBatteryLayoutPref.findViewById(R.id.summary1)).thenReturn(mSummary1);
-        when(mBatteryLayoutPref.findViewById(R.id.summary2)).thenReturn(mSummary2);
-        when(mBatteryLayoutPref.findViewById(R.id.time)).thenReturn(mTimeText);
+        when(mBatteryLayoutPref.findViewById(R.id.battery_percent)).thenReturn(mBatteryPercentText);
         when(mBatteryLayoutPref.findViewById(R.id.battery_header_icon))
                 .thenReturn(mBatteryMeterView);
         mFragment.setBatteryLayoutPreference(mBatteryLayoutPref);
@@ -194,8 +196,9 @@
         mFragment.mStatsHelper = mBatteryHelper;
         when(mBatteryHelper.getUsageList()).thenReturn(mUsageList);
         mFragment.mScreenUsagePref = mScreenUsagePref;
-        mFragment.mScreenConsumptionPref = mScreenConsumptionPref;
-        mFragment.mCellularNetworkPref = mCellularNetworkPref;
+        mFragment.mLastFullChargePref = mLastFullChargePref;
+
+        mBatteryInfo.mBatteryLevel = BATTERY_LEVEL;
     }
 
     @Test
@@ -226,7 +229,7 @@
     }
 
     @Test
-    public void testOptionsMenu_MenuHighPower_MetricEventInvoked() {
+    public void testOptionsMenu_menuHighPower_metricEventInvoked() {
         mFragment.onOptionsItemSelected(mHighPowerMenu);
 
         verify(mFeatureFactory.metricsFeatureProvider).action(mContext,
@@ -234,7 +237,7 @@
     }
 
     @Test
-    public void testOptionsMenu_MenuAdditionalBattery_MetricEventInvoked() {
+    public void testOptionsMenu_menuAdditionalBattery_metricEventInvoked() {
         mFragment.onOptionsItemSelected(mAdditionalBatteryInfoMenu);
 
         verify(mFeatureFactory.metricsFeatureProvider).action(mContext,
@@ -242,7 +245,7 @@
     }
 
     @Test
-    public void testOptionsMenu_MenuAppToggle_MetricEventInvoked() {
+    public void testOptionsMenu_menuAppToggle_metricEventInvoked() {
         mFragment.onOptionsItemSelected(mToggleAppsMenu);
         mFragment.mShowAllApps = false;
 
@@ -251,7 +254,7 @@
     }
 
     @Test
-    public void testOptionsMenu_ToggleAppsEnabled() {
+    public void testOptionsMenu_toggleAppsEnabled() {
         when(mFeatureFactory.powerUsageFeatureProvider.isPowerAccountingToggleEnabled())
                 .thenReturn(true);
         mFragment.mShowAllApps = false;
@@ -262,13 +265,13 @@
     }
 
     @Test
-    public void testOptionsMenu_ClickToggleAppsMenu_DataChanged() {
+    public void testOptionsMenu_clickToggleAppsMenu_dataChanged() {
         testToggleAllApps(true);
         testToggleAllApps(false);
     }
 
     @Test
-    public void testExtractKeyFromSipper_TypeAPPUidObjectNull_ReturnPackageNames() {
+    public void testExtractKeyFromSipper_typeAPPUidObjectNull_returnPackageNames() {
         mNormalBatterySipper.uidObj = null;
         mNormalBatterySipper.drainType = BatterySipper.DrainType.APP;
 
@@ -277,7 +280,7 @@
     }
 
     @Test
-    public void testExtractKeyFromSipper_TypeOther_ReturnDrainType() {
+    public void testExtractKeyFromSipper_typeOther_returnDrainType() {
         mNormalBatterySipper.uidObj = null;
         mNormalBatterySipper.drainType = BatterySipper.DrainType.BLUETOOTH;
 
@@ -286,7 +289,7 @@
     }
 
     @Test
-    public void testExtractKeyFromSipper_TypeAPPUidObjectNotNull_ReturnUid() {
+    public void testExtractKeyFromSipper_typeAPPUidObjectNotNull_returnUid() {
         mNormalBatterySipper.uidObj = new BatteryStatsImpl.Uid(new BatteryStatsImpl(), UID);
         mNormalBatterySipper.drainType = BatterySipper.DrainType.APP;
 
@@ -295,7 +298,7 @@
     }
 
     @Test
-    public void testRemoveHiddenBatterySippers_ContainsHiddenSippers_RemoveAndReturnValue() {
+    public void testRemoveHiddenBatterySippers_containsHiddenSippers_removeAndReturnValue() {
         final List<BatterySipper> sippers = new ArrayList<>();
         sippers.add(mNormalBatterySipper);
         sippers.add(mScreenBatterySipper);
@@ -309,37 +312,37 @@
     }
 
     @Test
-    public void testShouldHideSipper_TypeIdle_ReturnTrue() {
+    public void testShouldHideSipper_typeIdle_returnTrue() {
         mNormalBatterySipper.drainType = BatterySipper.DrainType.IDLE;
         assertThat(mFragment.shouldHideSipper(mNormalBatterySipper)).isTrue();
     }
 
     @Test
-    public void testShouldHideSipper_TypeWifi_ReturnTrue() {
+    public void testShouldHideSipper_typeWifi_returnTrue() {
         mNormalBatterySipper.drainType = BatterySipper.DrainType.WIFI;
         assertThat(mFragment.shouldHideSipper(mNormalBatterySipper)).isTrue();
     }
 
     @Test
-    public void testShouldHideSipper_TypeCell_ReturnTrue() {
+    public void testShouldHideSipper_typeCell_returnTrue() {
         mNormalBatterySipper.drainType = BatterySipper.DrainType.CELL;
         assertThat(mFragment.shouldHideSipper(mNormalBatterySipper)).isTrue();
     }
 
     @Test
-    public void testShouldHideSipper_TypeScreen_ReturnTrue() {
+    public void testShouldHideSipper_typeScreen_returnTrue() {
         mNormalBatterySipper.drainType = BatterySipper.DrainType.SCREEN;
         assertThat(mFragment.shouldHideSipper(mNormalBatterySipper)).isTrue();
     }
 
     @Test
-    public void testShouldHideSipper_TypeBluetooth_ReturnTrue() {
+    public void testShouldHideSipper_typeBluetooth_returnTrue() {
         mNormalBatterySipper.drainType = BatterySipper.DrainType.BLUETOOTH;
         assertThat(mFragment.shouldHideSipper(mNormalBatterySipper)).isTrue();
     }
 
     @Test
-    public void testShouldHideSipper_TypeSystem_ReturnTrue() {
+    public void testShouldHideSipper_typeSystem_returnTrue() {
         mNormalBatterySipper.drainType = BatterySipper.DrainType.APP;
         when(mNormalBatterySipper.getUid()).thenReturn(Process.ROOT_UID);
         when(mFeatureFactory.powerUsageFeatureProvider.isTypeSystem(Matchers.<BatterySipper>any()))
@@ -348,14 +351,14 @@
     }
 
     @Test
-    public void testShouldHideSipper_UidNormal_ReturnFalse() {
+    public void testShouldHideSipper_uidNormal_returnFalse() {
         mNormalBatterySipper.drainType = BatterySipper.DrainType.APP;
         when(mNormalBatterySipper.getUid()).thenReturn(UID);
         assertThat(mFragment.shouldHideSipper(mNormalBatterySipper)).isFalse();
     }
 
     @Test
-    public void testShouldHideSipper_TypeService_ReturnTrue() {
+    public void testShouldHideSipper_typeService_returnTrue() {
         mNormalBatterySipper.drainType = BatterySipper.DrainType.APP;
         when(mNormalBatterySipper.getUid()).thenReturn(UID);
         when(mFeatureFactory.powerUsageFeatureProvider.isTypeService(Matchers.<BatterySipper>any()))
@@ -365,7 +368,7 @@
     }
 
     @Test
-    public void testSetUsageSummary_TimeLessThanOneMinute_DoNotSetSummary() {
+    public void testSetUsageSummary_timeLessThanOneMinute_doNotSetSummary() {
         final long usageTimeMs = 59 * DateUtils.SECOND_IN_MILLIS;
 
         mFragment.setUsageSummary(mPreference, "", usageTimeMs);
@@ -373,7 +376,7 @@
     }
 
     @Test
-    public void testSetUsageSummary_TimeMoreThanOneMinute_SetSummary() {
+    public void testSetUsageSummary_timeMoreThanOneMinute_setSummary() {
         final long usageTimeMs = 2 * DateUtils.MINUTE_IN_MILLIS;
 
         mFragment.setUsageSummary(mPreference, "", usageTimeMs);
@@ -381,45 +384,25 @@
     }
 
     @Test
-    public void testUpdatePreference_NoEstimatedTime_DoNotShowSummary() {
-        mBatteryInfo.remainingTimeUs = 0;
+    public void testUpdatePreference_hasRemainingTime_showRemainingLabel() {
         mBatteryInfo.remainingLabel = TIME_LEFT;
+
         mFragment.updateHeaderPreference(mBatteryInfo);
 
-        verify(mSummary1).setVisibility(View.INVISIBLE);
-        verify(mSummary2).setVisibility(View.INVISIBLE);
+        verify(mSummary1).setText(mBatteryInfo.remainingLabel);
     }
 
     @Test
-    public void testUpdatePreference_HasEstimatedTime_ShowSummary() {
-        mBatteryInfo.remainingTimeUs = REMAINING_TIME_US;
-        mBatteryInfo.remainingLabel = TIME_LEFT;
+    public void testUpdatePreference_noRemainingTime_showStatusLabel() {
+        mBatteryInfo.remainingLabel = null;
+
         mFragment.updateHeaderPreference(mBatteryInfo);
 
-        verify(mSummary1).setVisibility(View.VISIBLE);
-        verify(mSummary2).setVisibility(View.VISIBLE);
+        verify(mSummary1).setText(mBatteryInfo.statusLabel);
     }
 
     @Test
-    public void testUpdatePreference_Charging_ShowChargingTimeLeft() {
-        mBatteryInfo.remainingTimeUs = REMAINING_TIME_US;
-        mBatteryInfo.mDischarging = false;
-
-        mFragment.updateHeaderPreference(mBatteryInfo);
-        verify(mSummary1).setText(R.string.estimated_charging_time_left);
-    }
-
-    @Test
-    public void testUpdatePreference_NotCharging_ShowTimeLeft() {
-        mBatteryInfo.remainingTimeUs = REMAINING_TIME_US;
-        mBatteryInfo.mDischarging = true;
-
-        mFragment.updateHeaderPreference(mBatteryInfo);
-        verify(mSummary1).setText(R.string.estimated_time_left);
-    }
-
-    @Test
-    public void testUpdateHeaderPreference_AsyncUpdate_ShouldNotCrash() {
+    public void testUpdateHeaderPreference_asyncUpdate_shouldNotCrash() {
         when(mFragment.getContext()).thenReturn(null);
         mBatteryInfo.remainingTimeUs = REMAINING_TIME_US;
 
@@ -451,43 +434,36 @@
     }
 
     @Test
-    public void testUpdateCellularPreference_ShowCorrectSummary() {
-        final double percent = POWER_MAH / TOTAL_POWER * DISCHARGE_AMOUNT;
-        final String expectedSummary = mRealContext.getString(R.string.battery_overall_usage,
-                Utils.formatPercentage((int) percent));
-        doReturn(expectedSummary).when(mFragment)
-                .getString(eq(R.string.battery_overall_usage), anyInt());
-        mFragment.updateCellularPreference(DISCHARGE_AMOUNT);
+    public void testUpdateScreenPreference_showCorrectSummary() {
+        final String expectedUsedTime = Utils.formatElapsedTime(mRealContext, USAGE_TIME_MS, false);
+        doReturn(mScreenBatterySipper).when(mFragment).findBatterySipperByType(any(), any());
+        doReturn(mRealContext).when(mFragment).getContext();
 
-        verify(mCellularNetworkPref).setSummary(expectedSummary);
+        mFragment.updateScreenPreference();
+
+        verify(mScreenUsagePref).setSubtitle(expectedUsedTime);
     }
 
     @Test
-    public void testUpdateScreenPreference_ShowCorrectSummary() {
-        final String expectedUsedTime = mRealContext.getString(R.string.battery_used_for,
-                Utils.formatElapsedTime(mRealContext, USAGE_TIME_MS, false));
-        final double percent = BATTERY_SCREEN_USAGE / TOTAL_POWER * DISCHARGE_AMOUNT;
-        final String expectedOverallUsage = mRealContext.getString(R.string.battery_overall_usage,
-                Utils.formatPercentage((int) percent));
-        doReturn(expectedUsedTime).when(mFragment).getString(
-                eq(R.string.battery_used_for), anyInt());
-        doReturn(expectedOverallUsage).when(mFragment).getString(
-                eq(R.string.battery_overall_usage), anyInt());
+    public void testUpdateLastFullChargePreference_showCorrectSummary() {
+        doReturn(mRealContext).when(mFragment).getContext();
+        final String expected = mRealContext.getString(R.string.power_last_full_charge_summary,
+                Utils.formatElapsedTime(mRealContext, TIME_SINCE_LAST_FULL_CHARGE_MS, false));
+        doReturn(expected).when(mFragment).getString(eq(R.string.power_last_full_charge_summary),
+                any());
 
-        mFragment.updateScreenPreference(DISCHARGE_AMOUNT);
+        mFragment.updateLastFullChargePreference(TIME_SINCE_LAST_FULL_CHARGE_MS);
 
-        verify(mScreenUsagePref).setSummary(expectedUsedTime);
-        verify(mScreenConsumptionPref).setSummary(expectedOverallUsage);
+        verify(mLastFullChargePref).setSubtitle(expected);
     }
 
     @Test
-    public void testUpdatePreference_UsageListEmpty_ShouldNotCrash() {
+    public void testUpdatePreference_usageListEmpty_shouldNotCrash() {
         when(mBatteryHelper.getUsageList()).thenReturn(new ArrayList<BatterySipper>());
-        doReturn("").when(mFragment).getString(anyInt(), Matchers.anyObject());
+        doReturn("").when(mFragment).getString(anyInt(), any());
 
         // Should not crash when update
-        mFragment.updateScreenPreference(DISCHARGE_AMOUNT);
-        mFragment.updateCellularPreference(DISCHARGE_AMOUNT);
+        mFragment.updateScreenPreference();
     }
 
     @Test
@@ -496,6 +472,12 @@
         assertThat(percent).isWithin(PRECISION).of(POWER_USAGE_PERCENTAGE);
     }
 
+    @Test
+    public void testCalculateRunningTimeBasedOnStatsType() {
+        assertThat(mFragment.calculateRunningTimeBasedOnStatsType()).isEqualTo(
+                TIME_SINCE_LAST_FULL_CHARGE_MS);
+    }
+
     public static class TestFragment extends PowerUsageSummary {
 
         private Context mContext;
diff --git a/tests/robotests/src/com/android/settings/print/PrintSettingsFragmentTest.java b/tests/robotests/src/com/android/settings/print/PrintSettingsFragmentTest.java
index 265472e..0e2a2f6 100644
--- a/tests/robotests/src/com/android/settings/print/PrintSettingsFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/print/PrintSettingsFragmentTest.java
@@ -68,14 +68,15 @@
         when(printServices.isEmpty()).thenReturn(false);
         when(printServices.size()).thenReturn(2);
         // 2 services
-        when(mPrintManager.getPrintServices(PrintManager.ALL_SERVICES)).thenReturn(printServices);
+        when(mPrintManager.getPrintServices(PrintManager.ENABLED_SERVICES))
+            .thenReturn(printServices);
 
         mSummaryProvider.setListening(true);
 
         verify(mRes).getQuantityString(R.plurals.print_settings_summary, 2, 2);
 
         // No service
-        when(mPrintManager.getPrintServices(PrintManager.ALL_SERVICES)).thenReturn(null);
+        when(mPrintManager.getPrintServices(PrintManager.ENABLED_SERVICES)).thenReturn(null);
 
         mSummaryProvider.setListening(true);
 
diff --git a/tests/robotests/src/com/android/settings/suggestions/SettingsSuggestionsTest.java b/tests/robotests/src/com/android/settings/suggestions/SettingsSuggestionsTest.java
new file mode 100644
index 0000000..3780d35
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/suggestions/SettingsSuggestionsTest.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.suggestions;
+
+import static com.android.settings.TestConfig.MANIFEST_PATH;
+import static com.google.common.truth.Truth.assertThat;
+
+import android.annotation.StringRes;
+import android.content.Context;
+import com.android.settings.R;
+import com.android.settings.SettingsRobolectricTestRunner;
+import com.android.settings.TestConfig;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+import org.robolectric.manifest.ActivityData;
+import org.robolectric.manifest.AndroidManifest;
+import org.robolectric.manifest.IntentFilterData;
+import org.robolectric.shadows.ShadowApplication;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class SettingsSuggestionsTest {
+
+  @Test
+  public void zenModeAutomationSuggestion_isValid() {
+    assertSuggestionEquals("Settings$ZenModeAutomationSuggestionActivity",
+        R.string.zen_mode_automation_suggestion_title,
+        R.string.zen_mode_automation_suggestion_summary);
+  }
+
+  @Test
+  public void wallpaperSuggestion_isValid() {
+    assertSuggestionEquals("com.android.settings.wallpaper.WallpaperSuggestionActivity",
+        R.string.wallpaper_suggestion_title, R.string.wallpaper_suggestion_summary);
+  }
+
+  @Test
+  public void nightDisplaySettings_isValid() {
+    assertSuggestionEquals("Settings$NightDisplaySettingsActivity",
+        R.string.night_display_suggestion_title, R.string.night_display_suggestion_summary);
+  }
+
+  @Test
+  public void fingerprintSuggestion_isValid() {
+    assertSuggestionEquals("com.android.settings.Settings$FingerprintSuggestionActivity",
+        R.string.suggestion_additional_fingerprints,
+        R.string.suggestion_additional_fingerprints_summary);
+  }
+
+  @Test
+  public void wifiCallingSuggestion_isValid() {
+    assertSuggestionEquals("Settings$WifiCallingSuggestionActivity",
+        R.string.wifi_calling_suggestion_title, R.string.wifi_calling_suggestion_summary);
+  }
+
+  private void assertSuggestionEquals(String activityName, @StringRes int title,
+      @StringRes int summary) {
+    final AndroidManifest androidManifest = ShadowApplication.getInstance().getAppManifest();
+    final ActivityData activityData = androidManifest.getActivityData(activityName);
+    final Map<String, Object> metaData = activityData.getMetaData().getValueMap();
+    final Context context = RuntimeEnvironment.application;
+    final String expectedTitle = context.getString(title);
+    final String expectedSummary = context.getString(summary);
+
+    final String pName= context.getPackageName();
+    final String actualTitle = context.getString(context.getResources().getIdentifier(
+        ((String) metaData.get("com.android.settings.title")).substring(8), "string", pName));
+    final String actualSummary = context.getString(context.getResources().getIdentifier(
+        ((String) metaData.get("com.android.settings.summary")).substring(8), "string", pName));
+    assertThat(actualTitle).isEqualTo(expectedTitle);
+    assertThat(actualSummary).isEqualTo(expectedSummary);
+
+    final List<IntentFilterData> intentFilters = activityData.getIntentFilters();
+    final List<String> categories = new ArrayList<>();
+    for (IntentFilterData intentFilter : intentFilters) {
+      categories.addAll(intentFilter.getCategories());
+    }
+
+    assertThat(categories).contains("com.android.settings.suggested.category.SETTINGS_ONLY");
+  }
+}
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowPreferenceFragment.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowPreferenceFragment.java
new file mode 100644
index 0000000..cfd0ce9
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowPreferenceFragment.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.settings.testutils.shadow;
+
+import android.support.v14.preference.PreferenceFragment;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+
+@Implements(PreferenceFragment.class)
+public class ShadowPreferenceFragment {
+
+    @Implementation
+    public void onStart() {
+        // No-op.
+    }
+
+    @Implementation
+    public void onStop() {
+        // No-op.
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/wifi/WifiSummaryUpdaterTest.java b/tests/robotests/src/com/android/settings/wifi/WifiSummaryUpdaterTest.java
index df290b3..967da08 100644
--- a/tests/robotests/src/com/android/settings/wifi/WifiSummaryUpdaterTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/WifiSummaryUpdaterTest.java
@@ -103,7 +103,7 @@
         mWifiTracker.enabled = false;
 
         assertThat(mSummaryUpdater.getSummary()).isEqualTo(
-            mContext.getString(R.string.wifi_disabled_generic));
+            mContext.getString(R.string.switch_off_text));
     }
 
     @Test