Merge "Remove the old battery page" into pi-dev
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 6fbdbc0..100ac2c 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -985,7 +985,7 @@
         </activity>
 
         <activity android:name=".Settings$MyDeviceInfoActivity"
-                  android:label="@string/device_info_settings"
+                  android:label="@string/about_settings"
                   android:icon="@drawable/ic_settings_about"
                   android:taskAffinity="com.android.settings"
                   android:parentActivityName="Settings">
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index 8af69c7..8e1ab2b 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -1,3 +1,5 @@
 [Hook Scripts]
 checkcolor_hook = ${REPO_ROOT}/prebuilts/checkcolor/checkcolor.py -p .
 
+strings_lint_hook = ${REPO_ROOT}/frameworks/base/tools/stringslint/stringslint_sha.sh ${PREUPLOAD_COMMIT}
+
diff --git a/res/layout/choose_lock_pattern_common_footer.xml b/res/layout/choose_lock_pattern_common_footer.xml
index d80702e..fc36624 100644
--- a/res/layout/choose_lock_pattern_common_footer.xml
+++ b/res/layout/choose_lock_pattern_common_footer.xml
@@ -22,7 +22,15 @@
     android:layout_width="match_parent"
     android:layout_height="wrap_content">
 
-    <!-- left : cancel, or re-try -->
+    <!-- left : skip -->
+    <Button android:id="@+id/skip_button"
+        style="@style/SuwGlifButton.Secondary"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/skip_label"
+        android:visibility="gone" />
+
+    <!-- left : retry -->
     <Button android:id="@+id/footerLeftButton"
         style="@style/SuwGlifButton.Secondary"
         android:layout_width="wrap_content"
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 64a754b..2d530ee 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -393,8 +393,12 @@
     <string name="bluetooth_paired_device_title">Your devices</string>
     <!-- Title for pairing bluetooth device page [CHAR LIMIT=none] -->
     <string name="bluetooth_pairing_page_title">Pair new device</string>
-    <!-- Summary for bluetooth item in connection detail page -->
-    <string name="bluetooth_pref_summary">Allow device to pair and connect to bluetooth devices</string>
+    <!-- Summary for bluetooth item in connection detail page. (tablet)-->
+    <string name="bluetooth_pref_summary" product="tablet">Allow your tablet to communicate with nearby Bluetooth devices</string>
+    <!-- Summary for bluetooth item in connection detail page. (device)-->
+    <string name="bluetooth_pref_summary" product="device">Allow your device to communicate with nearby Bluetooth devices</string>
+    <!-- Summary for bluetooth item in connection detail page. (phone)-->
+    <string name="bluetooth_pref_summary" product="default">Allow your phone to communicate with nearby Bluetooth devices</string>
 
     <!-- Setting Checkbox title for disabling Bluetooth inband ringing in Development Settings -->
     <string name="bluetooth_disable_inband_ringing">Disable in-band ringing</string>
@@ -412,7 +416,7 @@
     <!-- Title for preference to add a device [CHAR LIMIT=none]-->
     <string name="connected_device_add_device_title">Add device</string>
     <!-- Summary for preference to add a device [CHAR LIMIT=none]-->
-    <string name="connected_device_add_device_summary">Bluetooth will turn on to enable pairing</string>
+    <string name="connected_device_add_device_summary">Bluetooth will turn on to pair</string>
     <!-- Title for other connection preferences [CHAR LIMIT=none]-->
     <string name="connected_device_connections_title">Connection preferences</string>
     <!-- Title for Bluetooth preference to open paired but no connection list [CHAR LIMIT=none]-->
@@ -754,10 +758,14 @@
     <string name="date_time_set_date_title">Date</string>
     <!-- Date & time setting screen setting option title -->
     <string name="date_time_set_date">Set date</string>
+    <!-- Text hint to search region in time zone setting screen -->
+    <string name="date_time_search_region">Search region</string>
     <!-- Setting option title to select region in time zone setting screen [CHAR LIMIT=30] -->
     <string name="date_time_select_region">Region</string>
     <!-- Setting option title to select time zone in time zone setting screen [CHAR LIMIT=30]-->
     <string name="date_time_select_zone">Time Zone</string>
+    <!-- Setting option title to select time zone in a region -->
+    <string name="date_time_set_timezone_in_region">Time zones in <xliff:g id="region" example="United States">%1$s</xliff:g></string>
     <!-- Setting option title in time zone setting screen [CHAR LIMIT=30] -->
     <string name="date_time_select_fixed_offset_time_zones">Select UTC offset</string>
     <!-- Menu item on Select time zone screen -->
@@ -1153,7 +1161,7 @@
     <string name="suggested_lock_settings_summary" product="default">Set screen lock to protect phone</string>
 
     <!-- Title for suggested actions for settings up a fingerprint lock [CHAR LIMIT=46] -->
-    <string name="suggested_fingerprint_lock_settings_title">Unlock with fingerprint</string>
+    <string name="suggested_fingerprint_lock_settings_title">Add fingerprint to unlock</string>
 
     <!-- Summary for suggested actions for settings up a fingerprint lock (tablet) [CHAR LIMIT=55] -->
     <string name="suggested_fingerprint_lock_settings_summary" product="tablet"></string>
@@ -2457,6 +2465,12 @@
     <string name="color_mode_option_boosted">Boosted</string>
     <!-- Display settings screen, Color mode option for "Saturated color"  [CHAR LIMIT=45] -->
     <string name="color_mode_option_saturated">Saturated</string>
+    <!-- Display settings screen, Color mode option for "Automatic color"  [CHAR LIMIT=45] -->
+    <string name="color_mode_option_automatic">Automatic</string>
+    <!-- Display settings screen, "natural(sRGB) color" setting option summary [CHAR LIMIT=NONE] -->
+    <string name="color_mode_summary_natural">Use accurate colors only</string>
+    <!-- Display settings screen, "Automatic color" setting option summary [CHAR LIMIT=NONE] -->
+    <string name="color_mode_summary_automatic">Adjust between vivid and accurate colors</string>
 
     <!-- Sound & display settings screen, accelerometer-based rotation summary text when check box is selected -->
     <string name="accelerometer_summary_on" product="tablet">Switch orientation automatically when rotating tablet</string>
@@ -3088,10 +3102,10 @@
     <!-- Next button text of wizard step prompting user to format a storage device [CHAR LIMIT=32] -->
     <string name="storage_wizard_format_confirm_next">Erase &amp; format</string>
 
-    <!-- Title of wizard step showing formatting progress [CHAR LIMIT=32] -->
+    <!-- In-progress title. This string lets the user know the SD card is being formatted. The user won't be able to proceed with setup until this step is finished. The placeholder is for the name of the device (e.g. brand name of the SD card). [CHAR LIMIT=32] -->
     <string name="storage_wizard_format_progress_title">Formatting <xliff:g id="name" example="SD card">^1</xliff:g>\u2026</string>
-    <!-- Body of wizard step showing formatting progress [CHAR LIMIT=NONE] -->
-    <string name="storage_wizard_format_progress_body">Don\u2019t remove the <xliff:g id="name" example="SD card">^1</xliff:g> while it\u2019s formatting.</string>
+    <!-- Subtext for a full-screen title. This string lets the user know that the SD card can't be removed during this process. The user won't be able to proceed with setup until this step is finished. The placeholder is for the specific device (e.g. SD card, USB drive, etc.). [CHAR LIMIT=NONE] -->
+    <string name="storage_wizard_format_progress_body">Don\u2019t remove the <xliff:g id="name" example="SD card">^1</xliff:g> while it\u2019s being formatting.</string>
 
     <!-- Title of wizard step prompting user to migrate data to new storage [CHAR LIMIT=32] -->
     <string name="storage_wizard_migrate_title">Move data to new storage</string>
@@ -3122,12 +3136,10 @@
 \n\u2022 Keep the device charged.
     </string>
 
-    <!-- Title of wizard step indicating that storage is ready [CHAR LIMIT=32] -->
-    <string name="storage_wizard_ready_title"><xliff:g id="name" example="SD card">^1</xliff:g> is ready</string>
+    <!-- Title of a full-screen message. This string lets the user know that their storage device is ready to use. They can tap a button at the bottom of the screen to complete the setup process. The placeholder is for the specific device (e.g. SD card, USB drive, etc.). [CHAR LIMIT=32] -->
+    <string name="storage_wizard_ready_title">Your <xliff:g id="name" example="SD card">^1</xliff:g> is ready to use</string>
     <!-- Body of wizard step indicating that external storage is ready [CHAR LIMIT=NONE] -->
-    <string name="storage_wizard_ready_external_body">
-        Your <xliff:g id="name" example="SD card">^1</xliff:g> is all set to use with photos and other media.
-    </string>
+    <string name="storage_wizard_ready_external_body">Your <xliff:g id="name" example="SD card">^1</xliff:g> is all set to use with photos and other media.</string>
     <!-- Body of wizard step indicating that internal storage is ready [CHAR LIMIT=NONE] -->
     <string name="storage_wizard_ready_internal_body">Your new <xliff:g id="name" example="SD card">^1</xliff:g> is working.
 \n\nTo move photos, files, and app data to this device, go to Settings > Storage.
@@ -3158,6 +3170,85 @@
 \n\nConsider using a faster <xliff:g id="name" example="SD card">^1</xliff:g> for better performance.
 </string>
 
+    <!-- This is the title of a full-screen message. After this question, the user will get to choose how they want to use the storage device that they have in their phone. The placeholder is for the specific device (e.g. SD card, USB drive, etc.). [CHAR LIMIT=32] -->
+    <string name="storage_wizard_init_v2_title">How will you use this <xliff:g id="name" example="SD card">^1</xliff:g>?</string>
+
+    <!-- Title of a line item. Below this title, a user can tap a button to select this option if they want to use their SD card as extra device storage. [CHAR LIMIT=32] -->
+    <string name="storage_wizard_init_v2_internal_title" product="tablet">Use for extra tablet storage</string>
+    <!-- Subtext for a line item. Below this subtext, a user can tap a button to select this option if they want to use their SD card as extra device storage. [CHAR LIMIT=64] -->
+    <string name="storage_wizard_init_v2_internal_summary" product="tablet">For apps, files, and media on this tablet only</string>
+    <!-- Button text. A user can tap this button if they want to use their SD card as extra device storage. [CHAR LIMIT=32] -->
+    <string name="storage_wizard_init_v2_internal_action" product="tablet">Tablet storage</string>
+    <!-- Title of a line item. Below this title, a user can tap a button to select this option if they want to use their SD card as extra device storage. [CHAR LIMIT=32] -->
+    <string name="storage_wizard_init_v2_internal_title" product="default">Use for extra phone storage</string>
+    <!-- Subtext for a line item. Below this subtext, a user can tap a button to select this option if they want to use their SD card as extra device storage. [CHAR LIMIT=64] -->
+    <string name="storage_wizard_init_v2_internal_summary" product="default">For apps, files, and media on this phone only</string>
+    <!-- Button text. A user can tap this button if they want to use their SD card as extra device storage. [CHAR LIMIT=32] -->
+    <string name="storage_wizard_init_v2_internal_action" product="default">Phone storage</string>
+    <!-- This text separates two options in a full-screen message. It's used to indicate a user can choose one option or the other. [CHAR LIMIT=16] -->
+    <string name="storage_wizard_init_v2_or">Or</string>
+    <!-- Title of a line item. Below this title, a user can tap a button to select this option if they want to use their SD card as portable device storage. [CHAR LIMIT=32] -->
+    <string name="storage_wizard_init_v2_external_title">Use for portable storage</string>
+    <!-- Subtext for a line item. Below this subtext, a user can tap a button to select this option if they want to use their SD card as portable device storage. [CHAR LIMIT=64] -->
+    <string name="storage_wizard_init_v2_external_summary">For transferring files and media between devices</string>
+    <!-- Button text. A user can tap this button if they want to use their SD card as portable device storage. [CHAR LIMIT=32] -->
+    <string name="storage_wizard_init_v2_external_action">Portable storage</string>
+    <!-- Button text. A user can tap this button if they want to delay setting up their SD card until a later time. [CHAR LIMIT=32] -->
+    <string name="storage_wizard_init_v2_later">Set up later</string>
+
+    <!-- Title of a dialog. This string is asking users if they want to format their SD card or USB drive in order to use it as extra phone storage. The placeholder is for the specific device (e.g. SD card, USB drive, etc.). [CHAR LIMIT=32] -->
+    <string name="storage_wizard_format_confirm_v2_title">Format this <xliff:g id="name" example="SD card">^1</xliff:g>?</string>
+    <!-- Body of a dialog. This text is confirming that the user wants to use their SD card as extra phone storage, but the formatting process will erase existing content on the card. The first placeholder is for the name of the device (e.g. a brand name of the SD card or USB drive). The second and third placeholders are for the general references (e.g. SD card, USB drive). [CHAR LIMIT=NONE] -->
+    <string name="storage_wizard_format_confirm_v2_body">This <xliff:g id="name" example="SanDisk SD card">^1</xliff:g> needs to be formatted to store apps, files, and media.
+\n\nFormatting will erase existing content on the <xliff:g id="name" example="SD card">^2</xliff:g>. To avoid losing content, back it up to another <xliff:g id="name" example="SD card">^3</xliff:g> or device.</string>
+    <!-- Button text. If a user taps this button, their SD card or USB device will be formatted and used as extra phone storage. The placeholder is for the specific device (e.g. SD card, USB drive, etc.). [CHAR LIMIT=16] -->
+    <string name="storage_wizard_format_confirm_v2_action">Format <xliff:g id="name" example="SD card">^1</xliff:g></string>
+
+    <!-- Title of a full-screen message. This string is confirming that a user wants to move their content to the storage device. They can press a button at the bottom of the screen to move their content. The placeholder is for the specific device (e.g. SD card, USB drive, etc.). [CHAR LIMIT=32] -->
+    <string name="storage_wizard_migrate_v2_title">Move content to <xliff:g id="name" example="SD card">^1</xliff:g>?</string>
+    <!-- Main text for a full-screen message. These strings let the user know what they can move to the storage device, how much space will be made in their phone's storage, and how long the move will take. The first placeholder is for the amount of space (e.g. 1.4 GB) that will become available ("free up" is the phrasal verb used for this case). The second placeholder is for the amount of time (e.g. 6 minutes) it'll take to move their content to the storage device. The third placeholder is the name of the storage device (e.g. brand name of the SD card). [CHAR LIMIT=NONE] -->
+    <string name="storage_wizard_migrate_v2_body" product="tablet">You can move files, media, and certain apps to this <xliff:g id="name" example="SanDisk SD card">^1</xliff:g>.
+\n\nThis move will free up <xliff:g id="size" example="3 GB">^2</xliff:g> of your tablet\u2019s storage and should take around <xliff:g id="duration" example="3 minutes">^3</xliff:g>.</string>
+    <!-- Main text for a full-screen message. These strings let the user know what they can move to the storage device, how much space will be made in their device's storage, and how long the move will take. The first placeholder is for the amount of space (e.g. 1.4 GB) that will become available ("free up" is the phrasal verb used for this case). The second placeholder is for the amount of time (e.g. 6 minutes) it'll take to move their content to the storage device. The third placeholder is the name of the storage device (e.g. brand name of the SD card). [CHAR LIMIT=NONE] -->
+    <string name="storage_wizard_migrate_v2_body" product="default">You can move files, media, and certain apps to this <xliff:g id="name" example="SanDisk SD card">^1</xliff:g>.
+\n\nThis move will free up <xliff:g id="size" example="3 GB">^2</xliff:g> of your phone\u2019s storage and should take around <xliff:g id="duration" example="3 minutes">^3</xliff:g>.</string>
+
+    <!-- Title of a section of main text that shows a checklist of items a user should be aware of while moving their content to the SD card. [CHAR LIMIT=64] -->
+    <string name="storage_wizard_migrate_v2_checklist">During the move:</string>
+    <!-- Item that a user should be aware of while moving their content to the storage device. The string tells them not to remove the storage device while the move is happening. The placeholder is for the specific device (e.g. SD card, USB device, etc.). [CHAR LIMIT=64] -->
+    <string name="storage_wizard_migrate_v2_checklist_media">Don\u2019t remove the <xliff:g id="name" example="SD card">^1</xliff:g></string>
+    <!-- Item that a user should be aware of while moving their content to the SD card. Tells them that apps may have trouble working while the move is happening. [CHAR LIMIT=64] -->
+    <string name="storage_wizard_migrate_v2_checklist_apps">Some apps won\u2019t work</string>
+    <!-- Item that a user should be aware of while moving their content to the SD card. Tells them to keep the tablet charged while the move is happening. [CHAR LIMIT=64] -->
+    <string name="storage_wizard_migrate_v2_checklist_battery" product="tablet">Keep this tablet charged</string>
+    <!-- Item that a user should be aware of while moving their content to the SD card. Tells them to keep the phone charged while the move is happening. [CHAR LIMIT=64] -->
+    <string name="storage_wizard_migrate_v2_checklist_battery" product="default">Keep this phone charged</string>
+
+    <!-- Button text. If a user taps this button, they'll start moving their content to the SD card. Move is a verb. [CHAR LIMIT=32] -->
+    <string name="storage_wizard_migrate_v2_now">Move content</string>
+    <!-- Button text. If a user taps this button, they'll be able to move their content later. Move is a verb. [CHAR LIMIT=32] -->
+    <string name="storage_wizard_migrate_v2_later">Move content later</string>
+
+    <!-- In-progress title. This string lets the user know that their content is being moved to the SD card. They won't be able to proceed until the move is complete. [CHAR LIMIT=32] -->
+    <string name="storage_wizard_migrate_progress_v2_title">Moving content\u2026</string>
+
+    <!-- Title of a dialog. This string is telling users that their storage device is performing slowly. The placeholder is for the specific device (e.g. SD card, USB drive, etc.). [CHAR LIMIT=32] -->
+    <string name="storage_wizard_slow_v2_title">Slow <xliff:g id="name" example="SD card">^1</xliff:g></string>
+    <!-- Strings that are part of a full-screen message. These strings let the user know that their storage device is slow, and include some options they can try. The first placeholder is for the name of the storage device (e.g. brand name of the SD card), and the second and third placeholders are for the general references (e.g. SD card, USB drive, etc.). [CHAR LIMIT=NONE] -->
+    <string name="storage_wizard_slow_v2_body">You can still use this <xliff:g id="name" example="SanDisk SD card">^1</xliff:g>, but it may be slow.
+\n\nApps stored on this <xliff:g id="name" example="SD card">^2</xliff:g> may not work properly, and content transfers could take a long time.
+\n\nTry using a faster <xliff:g id="name" example="SD card">^3</xliff:g>, or use this <xliff:g id="name" example="SD card">^4</xliff:g> for portable storage instead.</string>
+    <!-- Action of a dialog. This action will start the wizard from the beginning, letting the user make an alternative choice. [CHAR LIMIT=32] -->
+    <string name="storage_wizard_slow_v2_start_over">Start over</string>
+    <!-- Action of a dialog. This action will continue the wizard, meaning the user acknowledges their card is slow. [CHAR LIMIT=32] -->
+    <string name="storage_wizard_slow_v2_continue">Continue</string>
+
+    <!-- Title of a full-screen message. This text lets the user know how to manage the storage device moving forward. The placeholder is for the name of the device (e.g. brand name of the SD card). [CHAR LIMIT=NONE] -->
+    <string name="storage_wizard_ready_v2_external_body">To move content to <xliff:g id="name" example="SanDisk SD card">^1</xliff:g>, go to <b>Settings > Storage</b></string>
+    <!-- Title of a full-screen message. This text lets the user know that their content was moved to their storage device and how to manage the storage device moving forward. The placeholder is for the name of the device (e.g. brand name of the SD card). [CHAR LIMIT=NONE] -->
+    <string name="storage_wizard_ready_v2_internal_body">Your content was moved to <xliff:g id="name" example="SanDisk SD card">^1</xliff:g>.
+\n\nTo manage this <xliff:g id="name" example="SD card">^2</xliff:g>, go to <b>Settings > Storage</b>.</string>
+
     <!-- Phone info screen, section titles: -->
     <string name="battery_status_title">Battery status</string>
     <!-- Phone info screen, section titles: -->
@@ -4472,6 +4563,24 @@
     <!-- Used in the Captions settings screen to control turning on/off the feature entirely -->
     <string name="accessibility_caption_master_switch_title">Use captions</string>
 
+    <!-- Title for the accessibility preference for hearing aid. [CHAR LIMIT=35] -->
+    <string name="accessibility_hearingaid_title">Hearing aids</string>
+    <!-- Summary for the accessibility preference for hearing aid when not connected. [CHAR LIMIT=50] -->
+    <string name="accessibility_hearingaid_not_connected_summary">No hearing aids connected</string>
+    <!-- Summary for the accessibility preference for hearing aid when adding new devices. [CHAR LIMIT=50] -->
+    <string name="accessibility_hearingaid_adding_summary">Add hearing aid</string>
+    <!-- Message to ask the user that if they want to pair the hearing aid, then they should find and tap the hearing aid device from the list on the next screen. [CHAR LIMIT=NONE] -->
+    <string name="accessibility_hearingaid_pair_instructions_first_message">To pair your hearing aids, find and tap your device on the next screen.</string>
+    <!-- Message to ask the user to make sure that their hearing aid devices are in pairing mode. [CHAR LIMIT=NONE] -->
+    <string name="accessibility_hearingaid_pair_instructions_second_message">Make sure your hearing aids are in pairing mode.</string>
+    <!-- Summary for the accessibility preference for hearing aid when there is an active device. [CHAR LIMIT=50] -->
+    <string name="accessibility_hearingaid_active_device_summary"><xliff:g id="device_name">%1$s</xliff:g> currently active</string>
+    <!-- Summary for the accessibility preference for hearing aid when there are saved devices. [CHAR LIMIT=50] -->
+    <plurals name="show_number_hearingaid_count">
+        <item quantity="one"><xliff:g id="number_device_count">%1$d</xliff:g> saved hearing aid</item>
+        <item quantity="other"><xliff:g id="number_device_count">%1$d</xliff:g> saved hearing aids</item>
+    </plurals>
+
     <!-- Preference's state when enabled. -->
     <string name="accessibility_summary_state_enabled">On</string>
     <!-- Preference's state when disabled. -->
@@ -6506,7 +6615,7 @@
     <string name="help_url_bluetooth" translatable="false"></string>
     <!-- Help URL, Data usage [DO NOT TRANSLATE] -->
     <string name="help_url_data_usage" translatable="false"></string>
-    <!-- Help URL, Data saver [DO NOT TRANSLATE] -->
+    <!-- Help URL, Data Saver [DO NOT TRANSLATE] -->
     <string name="help_url_data_saver" translatable="false"></string>
     <!-- Help URL, Unrestricted data access [DO NOT TRANSLATE] -->
     <string name="help_url_unrestricted_data_access" translatable="false"></string>
@@ -7245,7 +7354,7 @@
     <string name="recent_notifications">Recently sent</string>
 
     <!-- Preference title for showing all apps on device [CHAR_LIMIT=50]-->
-    <string name="recent_notifications_see_all_title">See all apps</string>
+    <string name="recent_notifications_see_all_title">See all from last 7 days</string>
 
     <!-- Configure Notifications: Advanced section header [CHAR LIMIT=30] -->
     <string name="advanced_section_header">Advanced</string>
@@ -7948,11 +8057,13 @@
     <string name="change_storage">Change storage</string>
 
     <!-- Label for notification settings for an specific app [CHAR LIMIT=40] -->
-    <string name="notifications_label">App notifications</string>
+    <string name="notifications_label">Notifications</string>
     <!-- App notification summary with notifications enabled [CHAR LIMIT=40] -->
     <string name="notifications_enabled">On</string>
+    <!-- App notification summary with notifications enabled [CHAR LIMIT=40] -->
+    <string name="notifications_enabled_with_info">On / <xliff:g id="notifications_categories_off" example="3 categories turned off">%1$s</xliff:g> </string>
     <!-- Label for showing apps with blocked notifications in list [CHAR LIMIT=30] -->
-    <string name="notifications_disabled">Everything turned off</string>
+    <string name="notifications_disabled">Off</string>
     <!-- Label for showing apps with some blocked notifications in list [CHAR LIMIT=30] -->
     <string name="notifications_partly_blocked"><xliff:g id="count" example="1">%1$d</xliff:g> of <xliff:g id="count" example="10">%2$d</xliff:g> categories turned off</string>
     <!-- App notification summary with notifications silenced [CHAR LIMIT=40] -->
@@ -7970,6 +8081,11 @@
     <!-- App notification summary channel divider-->
     <string name="notification_summary_channel"><xliff:g id="channel_name">%1$s</xliff:g> \u2022 <xliff:g id="group_name">%2$s</xliff:g></string>
 
+    <!-- Permissions preference summary [CHAR LIMIT=40] -->
+    <plurals name="notifications_categories_off">
+        <item quantity="one"><xliff:g id="count" example="1">%d</xliff:g> category turned off</item>
+        <item quantity="other"><xliff:g id="count" example="10">%d</xliff:g> categories turned off</item>
+    </plurals>
 
     <!-- Permissions preference summary [CHAR LIMIT=40] -->
     <plurals name="permissions_summary">
@@ -8641,8 +8757,8 @@
     <!-- Summary of Android version info (when there is a pending upgrade available) [CHAR LIMIT=NONE] -->
     <string name="android_version_pending_update_summary">Update available</string>
 
-    <!-- Title for dialog displayed when user clicks on a setting locked by an admin [CHAR LIMIT=30] -->
-    <string name="disabled_by_policy_title">Action not allowed</string>
+    <!-- Title for dialog displayed when user selects on a setting locked by an admin [CHAR LIMIT=30] -->
+    <string name="disabled_by_policy_title">Can\'t change this setting</string>
     <!-- Title for dialog displayed to tell user that changing volume was disallowed by an admin [CHAR LIMIT=50] -->
     <string name="disabled_by_policy_title_adjust_volume">Can\'t change volume</string>
     <!-- Title for dialog displayed to tell user that outgoing calls were disabled by an admin [CHAR LIMIT=50] -->
@@ -8656,8 +8772,7 @@
     <!-- Title for dialog displayed to tell user that turning off backups is disallowed by an admin [CHAR LIMIT=50] -->
     <string name="disabled_by_policy_title_turn_off_backups">Can\'t turn off backups</string>
     <!-- Shown when the user tries to change a settings locked by an admin [CHAR LIMIT=200] -->
-    <string name="default_admin_support_msg">This action is disabled. To learn more, contact your
-        organization\'s admin.</string>
+    <string name="default_admin_support_msg">If you have questions, contact your IT admin</string>
     <!-- Shown in dialog to allow user to see more information about the device admin [CHAR LIMIT=30] -->
     <string name="admin_support_more_info">More details</string>
     <!-- Shown in admin details page to warn user about policies the admin can set in a work profile. [CHAR LIMIT=NONE] -->
@@ -8724,6 +8839,9 @@
     <!-- Summary of condition that work mode is off [CHAR LIMIT=NONE] -->
     <string name="condition_work_summary">Apps, background sync, and other features related to your work profile are turned off.</string>
 
+    <!-- Action label on device muted card - clicking action will turn on ringtone sound [CHAR LIMIT=50] -->
+    <string name="condition_device_muted_action_turn_on_sound">Turn on sound</string>
+
     <!-- Title of condition that indicates device is muted [CHAR LIMIT=50] -->
     <string name="condition_device_muted_title" product="tablet">Device is muted</string>
 
@@ -8957,7 +9075,7 @@
     <string name="launch_mdp_app_text">View plan</string>
 
     <!-- Name of Data Saver screens [CHAR LIMIT=30] -->
-    <string name="data_saver_title">Data saver</string>
+    <string name="data_saver_title">Data Saver</string>
 
     <!-- Button that leads to list of apps with unrestricted data access [CHAR LIMIT=60] -->
     <string name="unrestricted_data_saver">Unrestricted data</string>
@@ -8971,6 +9089,9 @@
     <!-- Summary for the Data Saver feature being off [CHAR LIMIT=NONE] -->
     <string name="data_saver_off">Off</string>
 
+    <!-- Switch label to enable the Data Saver feature [CHAR LIMIT=NONE] -->
+    <string name="data_saver_switch_title">Use Data Saver</string>
+
     <!-- Title for switch to allow app unrestricted data usage [CHAR LIMIT=30] -->
     <string name="unrestricted_app_title">Unrestricted data usage</string>
 
@@ -9623,6 +9744,27 @@
          show both names, with the directory name wrapped in parenthesis -->
     <string name="directory_on_volume"><xliff:g id="volume" example="SD Card">%1$s</xliff:g> (<xliff:g id="directory" example="Movies">%2$s</xliff:g>)</string>
 
+    <!-- Slices Strings -->
+
+    <!-- Summary text on a card explaining that a setting does not exist / is not supported on the device [CHAR_LIMIT=NONE]-->
+    <string name="unsupported_setting_summary" product="default">Setting isn’t supported on this phone</string>
+
+    <!-- Summary text on a card explaining that a setting does not exist / is not supported on the device [CHAR_LIMIT=NONE]-->
+    <string name="unsupported_setting_summary" product="tablet">Setting isn’t supported on this tablet</string>
+
+    <!-- Summary text on a card explaining that a setting does not exist / is not supported on the device [CHAR_LIMIT=NONE]-->
+    <string name="unsupported_setting_summary" product="device">Setting isn’t supported on this device</string>
+
+    <!-- Summary text on a card explaining that a setting cannot be changed by the current user. [CHAR_LIMIT=NONE] -->
+    <string name="disabled_for_user_setting_summary">Setting can’t be changed by current user</string>
+
+    <!-- Summary text on a card explaining a setting cannot be changed right now because it needs another setting to be changed. [CHAR_LIMIT=NONE] -->
+    <string name="disabled_dependent_setting_summary">Depends on another setting</string>
+
+    <!-- Summary text on a card explaining a setting cannot be changed right now, but we don't know the reason. [CHAR_LIMIT=NONE] -->
+    <string name="unknown_unavailability_setting_summary">Setting unavailable</string>
+
+
     <!-- Account type associated with the backup account. Empty for AOSP. [DO NOT TRANSLATE] -->
     <string name="account_type" translatable="false"></string>
     <!-- Package to target for Account credential confirmation. This will allow users to
@@ -9634,12 +9776,6 @@
          [DO NOT TRANSLATE] -->
     <string name="account_confirmation_class" translatable="false"></string>
 
-    <!-- Title for the new About Phone screen [CHAR LIMIT=40] -->
-    <string name="my_device_info_title" product="default">My Phone</string>
-    <!-- Title for the new About Phone screen [CHAR LIMIT=40] -->
-    <string name="my_device_info_title" product="tablet">My Tablet</string>
-    <!-- Title for the new About Phone screen [CHAR LIMIT=40] -->
-    <string name="my_device_info_title" product="device">My Device</string>
     <!-- Title for preference showing the primary account on the device [CHAR LIMIT=60]-->
     <string name="my_device_info_account_preference_title">Account</string>
     <!-- Title for preference showing the name of the device. [CHAR LIMIT=60]-->
@@ -9709,4 +9845,7 @@
     <!-- Title for detail page of wifi network [CHAR LIMIT=30] -->
     <string name="pref_title_network_details">Network details</string>
 
+    <!--  Warning text about the visibility of device name. [CHAR LIMIT=NONE] -->
+    <string name="about_phone_device_name_warning">Your device name is visible to apps on your phone. It may also be seen by other people when you connect to Bluetooth devices or set up a Wi-Fi hotspot.</string>
+
 </resources>
diff --git a/res/xml/app_info_settings.xml b/res/xml/app_info_settings.xml
index 99c76b8..4695b44 100644
--- a/res/xml/app_info_settings.xml
+++ b/res/xml/app_info_settings.xml
@@ -25,13 +25,13 @@
         android:key="header_view"
         android:layout="@layout/settings_entity_header"
         android:selectable="false"
-        android:order="-10000"/>
+        android:order="-10000" />
 
     <com.android.settings.applications.LayoutPreference
         android:key="instant_app_buttons"
         android:layout="@layout/instant_app_buttons"
         android:selectable="false"
-        android:order="-9999"/>
+        android:order="-9999" />
 
     <com.android.settings.widget.ActionButtonPreference
         android:key="action_buttons"
@@ -39,7 +39,7 @@
 
     <Preference
         android:key="notification_settings"
-        android:title="@string/notifications_label"/>
+        android:title="@string/notifications_label" />
 
     <com.android.settings.widget.FixedLineSummaryPreference
         android:key="permission_settings"
@@ -50,7 +50,7 @@
     <Preference
         android:key="storage_settings"
         android:title="@string/storage_settings"
-        android:summary="@string/summary_placeholder"/>
+        android:summary="@string/summary_placeholder" />
 
     <com.android.settings.applications.AppDomainsPreference
         android:key="instant_app_launch_supported_domain_urls"
@@ -60,24 +60,29 @@
     <Preference
         android:key="data_settings"
         android:title="@string/data_usage_summary_title"
-        android:summary="@string/summary_placeholder"/>
+        android:summary="@string/summary_placeholder" />
+
+    <Preference
+        android:key="time_spent_in_app"
+        android:title="@string/time_spent_in_app_pref_title"
+        app:controller="com.android.settings.applications.appinfo.TimeSpentInAppPreferenceController" />
 
     <Preference
         android:key="battery"
         android:title="@string/power_usage_summary_title"
-        android:summary="@string/summary_placeholder"/>
+        android:summary="@string/summary_placeholder" />
 
     <Preference
         android:key="preferred_settings"
         android:title="@string/launch_by_default"
         android:summary="@string/summary_placeholder"
-        android:selectable="true"/>
+        android:selectable="true" />
 
     <Preference
         android:key="memory"
         android:title="@string/memory_settings_title"
         android:summary="@string/summary_placeholder"
-        android:enabled="false"/>
+        android:enabled="false" />
 
     <!-- Default apps shortcuts -->
     <Preference
@@ -146,6 +151,6 @@
     <Preference
         android:key="app_version"
         android:selectable="false"
-        android:order="9999"/>
+        android:order="9999" />
 
 </PreferenceScreen>
\ No newline at end of file
diff --git a/res/xml/date_time_prefs.xml b/res/xml/date_time_prefs.xml
index 3249189..511b39f 100644
--- a/res/xml/date_time_prefs.xml
+++ b/res/xml/date_time_prefs.xml
@@ -30,7 +30,6 @@
             android:summaryOn="@string/date_time_auto_summaryOn"
             android:summaryOff="@string/date_time_auto_summaryOff"
             settings:useAdditionalSummary="true"
-            settings:restrictedSwitchSummary="@string/enabled_by_admin"
             settings:userRestriction="no_config_date_time" />
 
         <com.android.settingslib.RestrictedPreference
diff --git a/res/xml/my_device_info.xml b/res/xml/my_device_info.xml
index 8c93f97..619bd66 100644
--- a/res/xml/my_device_info.xml
+++ b/res/xml/my_device_info.xml
@@ -19,7 +19,7 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:settings="http://schemas.android.com/apk/res-auto"
     android:key="my_device_info_pref_screen"
-    android:title="@string/my_device_info_title"
+    android:title="@string/about_settings"
     settings:initialExpandedChildrenCount="7">
 
     <com.android.settings.applications.LayoutPreference
diff --git a/res/xml/zen_mode_block_settings.xml b/res/xml/zen_mode_block_settings.xml
index ce33e97..595e2ca 100644
--- a/res/xml/zen_mode_block_settings.xml
+++ b/res/xml/zen_mode_block_settings.xml
@@ -17,7 +17,8 @@
 
 <PreferenceScreen
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:key="zen_mode_block_settings_page">
+    android:key="zen_mode_block_settings_page"
+    android:title="@string/zen_mode_behavior_settings_title">
 
     <!-- sound vibration -->
     <CheckBoxPreference
diff --git a/src/com/android/settings/accounts/RemoveAccountPreferenceController.java b/src/com/android/settings/accounts/RemoveAccountPreferenceController.java
index 068847f..98ab504 100644
--- a/src/com/android/settings/accounts/RemoveAccountPreferenceController.java
+++ b/src/com/android/settings/accounts/RemoveAccountPreferenceController.java
@@ -21,11 +21,11 @@
 import android.accounts.AccountManagerFuture;
 import android.accounts.AuthenticatorException;
 import android.accounts.OperationCanceledException;
-import android.app.admin.DevicePolicyManager;
 import android.app.Activity;
 import android.app.AlertDialog;
 import android.app.Dialog;
 import android.app.Fragment;
+import android.app.admin.DevicePolicyManager;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
@@ -44,6 +44,8 @@
 import com.android.settings.core.PreferenceControllerMixin;
 import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
 import com.android.settings.wrapper.DevicePolicyManagerWrapper;
+import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
 import com.android.settingslib.core.AbstractPreferenceController;
 
 import java.io.IOException;
@@ -92,12 +94,15 @@
 
     @Override
     public void onClick(View v) {
-        final Intent intent = mDpm.createAdminSupportIntent(UserManager.DISALLOW_MODIFY_ACCOUNTS);
-        if (intent != null) {
-            // DISALLOW_MODIFY_ACCOUNTS is active, show admin support dialog
-            mContext.startActivity(intent);
-            return;
+        if (mUserHandle != null) {
+            final EnforcedAdmin admin = RestrictedLockUtils.checkIfRestrictionEnforced(mContext,
+                UserManager.DISALLOW_MODIFY_ACCOUNTS, mUserHandle.getIdentifier());
+            if (admin != null) {
+                RestrictedLockUtils.sendShowAdminSupportDetailsIntent(mContext, admin);
+                return;
+            }
         }
+
         ConfirmRemoveAccountDialog.show(mParentFragment, mAccount, mUserHandle);
     }
 
diff --git a/src/com/android/settings/applications/appinfo/AppActionButtonPreferenceController.java b/src/com/android/settings/applications/appinfo/AppActionButtonPreferenceController.java
index 130138c..6e978dc 100644
--- a/src/com/android/settings/applications/appinfo/AppActionButtonPreferenceController.java
+++ b/src/com/android/settings/applications/appinfo/AppActionButtonPreferenceController.java
@@ -283,6 +283,10 @@
             // User can't force stop device admin.
             Log.w(TAG, "User can't force stop device admin");
             updateForceStopButton(false);
+        } else if (mPm.isPackageStateProtected(packageInfo.packageName,
+            UserHandle.getUserId(appEntry.info.uid))) {
+            Log.w(TAG, "User can't force stop protected packages");
+            updateForceStopButton(false);
         } else if (AppUtils.isInstant(packageInfo.applicationInfo)) {
             updateForceStopButton(false);
             mActionButtons.setButton2Visible(false);
diff --git a/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java b/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java
index 7428e53..daed1e1 100755
--- a/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java
+++ b/src/com/android/settings/applications/appinfo/AppInfoDashboardFragment.java
@@ -45,20 +45,16 @@
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
-import android.view.View;
 
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settings.DeviceAdminAdd;
 import com.android.settings.R;
 import com.android.settings.SettingsActivity;
 import com.android.settings.SettingsPreferenceFragment;
-import com.android.settings.Utils;
-import com.android.settings.applications.LayoutPreference;
 import com.android.settings.applications.manageapplications.ManageApplications;
 import com.android.settings.core.SubSettingLauncher;
 import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
 import com.android.settings.dashboard.DashboardFragment;
-import com.android.settings.widget.EntityHeaderController;
 import com.android.settings.widget.PreferenceCategoryController;
 import com.android.settings.wrapper.DevicePolicyManagerWrapper;
 import com.android.settingslib.RestrictedLockUtils;
@@ -157,7 +153,12 @@
                 == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
     }
 
-    /** Called when the activity is first created. */
+    @Override
+    public void onAttach(Context context) {
+        super.onAttach(context);
+        use(TimeSpentInAppPreferenceController.class).setPackageName(getPackageName());
+    }
+
     @Override
     public void onCreate(Bundle icicle) {
         super.onCreate(icicle);
@@ -191,9 +192,10 @@
     @Override
     public void onResume() {
         super.onResume();
-        mAppsControlDisallowedAdmin = RestrictedLockUtils.checkIfRestrictionEnforced(getActivity(),
+        final Activity activity = getActivity();
+        mAppsControlDisallowedAdmin = RestrictedLockUtils.checkIfRestrictionEnforced(activity,
                 UserManager.DISALLOW_APPS_CONTROL, mUserId);
-        mAppsControlDisallowedBySystem = RestrictedLockUtils.hasBaseUserRestriction(getActivity(),
+        mAppsControlDisallowedBySystem = RestrictedLockUtils.hasBaseUserRestriction(activity,
                 UserManager.DISALLOW_APPS_CONTROL, mUserId);
 
         if (!refreshUi()) {
@@ -300,7 +302,7 @@
      *
      * @return true if packageInfo is available.
      */
-    @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+    @VisibleForTesting
     boolean ensurePackageInfoAvailable(Activity activity) {
         if (mPackageInfo == null) {
             mFinishing = true;
diff --git a/src/com/android/settings/applications/appinfo/TimeSpentInAppPreferenceController.java b/src/com/android/settings/applications/appinfo/TimeSpentInAppPreferenceController.java
new file mode 100644
index 0000000..047d38e
--- /dev/null
+++ b/src/com/android/settings/applications/appinfo/TimeSpentInAppPreferenceController.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2018 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.appinfo;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.support.annotation.VisibleForTesting;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+import android.text.TextUtils;
+
+import com.android.settings.core.BasePreferenceController;
+
+import java.util.List;
+
+public class TimeSpentInAppPreferenceController extends BasePreferenceController {
+
+    @VisibleForTesting
+    static final Intent SEE_TIME_IN_APP_TEMPLATE =
+            new Intent("com.android.settings.action.TIME_SPENT_IN_APP");
+
+    private final PackageManager mPackageManager;
+
+    private Intent mIntent;
+    private String mPackageName;
+
+    public TimeSpentInAppPreferenceController(Context context, String preferenceKey) {
+        super(context, preferenceKey);
+        mPackageManager = context.getPackageManager();
+    }
+
+    public void setPackageName(String packageName) {
+        mPackageName = packageName;
+        mIntent = new Intent(SEE_TIME_IN_APP_TEMPLATE)
+                .putExtra(Intent.EXTRA_PACKAGE_NAME, mPackageName);
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        if (TextUtils.isEmpty(mPackageName)) {
+            return DISABLED_UNSUPPORTED;
+        }
+        final List<ResolveInfo> resolved = mPackageManager.queryIntentActivities(mIntent,
+                0 /* flags */);
+        if (resolved == null || resolved.isEmpty()) {
+            return DISABLED_UNSUPPORTED;
+        }
+        return AVAILABLE;
+    }
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        super.displayPreference(screen);
+        final Preference pref = screen.findPreference(getPreferenceKey());
+        if (pref != null) {
+            pref.setIntent(mIntent);
+        }
+    }
+}
diff --git a/src/com/android/settings/applications/manageapplications/ManageApplications.java b/src/com/android/settings/applications/manageapplications/ManageApplications.java
index d144169..6521056 100644
--- a/src/com/android/settings/applications/manageapplications/ManageApplications.java
+++ b/src/com/android/settings/applications/manageapplications/ManageApplications.java
@@ -16,6 +16,7 @@
 
 package com.android.settings.applications.manageapplications;
 
+import static android.support.v7.widget.RecyclerView.SCROLL_STATE_IDLE;
 import static com.android.settings.applications.manageapplications.AppFilterRegistry
         .FILTER_APPS_ALL;
 import static com.android.settings.applications.manageapplications.AppFilterRegistry
@@ -50,6 +51,7 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.preference.PreferenceFrameLayout;
+import android.support.annotation.NonNull;
 import android.support.annotation.VisibleForTesting;
 import android.support.v7.widget.LinearLayoutManager;
 import android.support.v7.widget.RecyclerView;
@@ -844,11 +846,16 @@
         private boolean mHasReceivedBridgeCallback;
         private FileViewHolderController mExtraViewController;
 
-        // These two variables are used to remember and restore the last scroll position when this
+        // This is to remember and restore the last scroll position when this
         // fragment is paused. We need this special handling because app entries are added gradually
         // when we rebuild the list after the user made some changes, like uninstalling an app.
         private int mLastIndex = -1;
 
+        @VisibleForTesting
+        OnScrollListener mOnScrollListener;
+        private RecyclerView mRecyclerView;
+
+
         public ApplicationsAdapter(ApplicationsState state, ManageApplications manageApplications,
                 AppFilterItem appFilter, Bundle savedInstanceState) {
             setHasStableIds(true);
@@ -886,6 +893,22 @@
             }
         }
 
+        @Override
+        public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) {
+            super.onAttachedToRecyclerView(recyclerView);
+            mRecyclerView = recyclerView;
+            mOnScrollListener = new OnScrollListener(this);
+            mRecyclerView.addOnScrollListener(mOnScrollListener);
+        }
+
+        @Override
+        public void onDetachedFromRecyclerView(@NonNull RecyclerView recyclerView) {
+            super.onDetachedFromRecyclerView(recyclerView);
+            mRecyclerView.removeOnScrollListener(mOnScrollListener);
+            mOnScrollListener = null;
+            mRecyclerView = null;
+        }
+
         public void setCompositeFilter(AppFilter compositeFilter) {
             mCompositeFilter = compositeFilter;
             rebuild();
@@ -1180,9 +1203,8 @@
                     rebuild();
                     return;
                 } else {
-                    notifyItemChanged(i);
+                    mOnScrollListener.postNotifyItemChange(i);
                 }
-
             }
         }
 
@@ -1310,13 +1332,39 @@
             return mExtraViewController != null
                     && mExtraViewController.shouldShow();
         }
+
+        public static class OnScrollListener extends RecyclerView.OnScrollListener {
+            private int mScrollState = SCROLL_STATE_IDLE;
+            private boolean mDelayNotifyDataChange;
+            private ApplicationsAdapter mAdapter;
+
+            public OnScrollListener(ApplicationsAdapter adapter) {
+                mAdapter = adapter;
+            }
+
+            @Override
+            public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
+                mScrollState = newState;
+                if (mScrollState == SCROLL_STATE_IDLE && mDelayNotifyDataChange) {
+                    mDelayNotifyDataChange = false;
+                    mAdapter.notifyDataSetChanged();
+                }
+            }
+
+            public void postNotifyItemChange(int index) {
+                if (mScrollState == SCROLL_STATE_IDLE) {
+                    mAdapter.notifyItemChanged(index);
+                } else {
+                    mDelayNotifyDataChange = true;
+                }
+            }
+        }
     }
 
     private static class SummaryProvider implements SummaryLoader.SummaryProvider {
 
         private final Context mContext;
         private final SummaryLoader mLoader;
-        private ApplicationsState.Session mSession;
 
         private SummaryProvider(Context context, SummaryLoader loader) {
             mContext = context;
diff --git a/src/com/android/settings/core/PreferenceControllerListHelper.java b/src/com/android/settings/core/PreferenceControllerListHelper.java
index a4808a1..738a695 100644
--- a/src/com/android/settings/core/PreferenceControllerListHelper.java
+++ b/src/com/android/settings/core/PreferenceControllerListHelper.java
@@ -56,7 +56,7 @@
             preferenceMetadata = PreferenceXmlParserUtils.extractMetadata(context, xmlResId,
                     MetadataFlag.FLAG_NEED_KEY | MetadataFlag.FLAG_NEED_PREF_CONTROLLER);
         } catch (IOException | XmlPullParserException e) {
-            Log.e(TAG, "Failed to parse preference xml for getting controllers");
+            Log.e(TAG, "Failed to parse preference xml for getting controllers", e);
             return controllers;
         }
 
diff --git a/src/com/android/settings/dashboard/DashboardAdapter.java b/src/com/android/settings/dashboard/DashboardAdapter.java
index 879a4b8..937e6db 100644
--- a/src/com/android/settings/dashboard/DashboardAdapter.java
+++ b/src/com/android/settings/dashboard/DashboardAdapter.java
@@ -18,7 +18,6 @@
 import android.app.Activity;
 import android.content.Context;
 import android.graphics.drawable.Drawable;
-import android.graphics.drawable.Icon;
 import android.os.Bundle;
 import android.service.settings.suggestions.Suggestion;
 import android.support.annotation.VisibleForTesting;
@@ -262,7 +261,7 @@
 
     @VisibleForTesting
     void onBindConditionHeader(final ConditionHeaderHolder holder, ConditionHeaderData data) {
-        holder.icon.setImageIcon(data.conditionIcons.get(0));
+        holder.icon.setImageDrawable(data.conditionIcons.get(0));
         if (data.conditionCount == 1) {
             holder.title.setText(data.title);
             holder.summary.setText(null);
@@ -338,7 +337,7 @@
         outState.putBoolean(STATE_CONDITION_EXPANDED, mDashboardData.isConditionExpanded());
     }
 
-    private void updateConditionIcons(List<Icon> icons, ViewGroup parent) {
+    private void updateConditionIcons(List<Drawable> icons, ViewGroup parent) {
         if (icons == null || icons.size() < 2) {
             parent.setVisibility(View.INVISIBLE);
             return;
@@ -348,7 +347,7 @@
         for (int i = 1, size = icons.size(); i < size; i++) {
             ImageView icon = (ImageView) inflater.inflate(
                     R.layout.condition_header_icon, parent, false);
-            icon.setImageIcon(icons.get(i));
+            icon.setImageDrawable(icons.get(i));
             parent.addView(icon);
         }
         parent.setVisibility(View.VISIBLE);
diff --git a/src/com/android/settings/dashboard/DashboardData.java b/src/com/android/settings/dashboard/DashboardData.java
index 113caba..b180dd7 100644
--- a/src/com/android/settings/dashboard/DashboardData.java
+++ b/src/com/android/settings/dashboard/DashboardData.java
@@ -16,7 +16,7 @@
 package com.android.settings.dashboard;
 
 import android.annotation.IntDef;
-import android.graphics.drawable.Icon;
+import android.graphics.drawable.Drawable;
 import android.service.settings.suggestions.Suggestion;
 import android.support.annotation.VisibleForTesting;
 import android.support.v7.util.DiffUtil;
@@ -432,7 +432,7 @@
      * also be used to check the diff in DiffUtil.Callback
      */
     public static class ConditionHeaderData {
-        public final List<Icon> conditionIcons;
+        public final List<Drawable> conditionIcons;
         public final CharSequence title;
         public final int conditionCount;
 
diff --git a/src/com/android/settings/dashboard/conditional/AirplaneModeCondition.java b/src/com/android/settings/dashboard/conditional/AirplaneModeCondition.java
index c6002bd..448510f 100644
--- a/src/com/android/settings/dashboard/conditional/AirplaneModeCondition.java
+++ b/src/com/android/settings/dashboard/conditional/AirplaneModeCondition.java
@@ -19,6 +19,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.graphics.drawable.Drawable;
 import android.graphics.drawable.Icon;
 import android.net.ConnectivityManager;
 import android.provider.Settings;
@@ -58,8 +59,8 @@
     }
 
     @Override
-    public Icon getIcon() {
-        return Icon.createWithResource(mManager.getContext(), R.drawable.ic_airplane);
+    public Drawable getIcon() {
+        return mManager.getContext().getDrawable(R.drawable.ic_airplane);
     }
 
     @Override
diff --git a/src/com/android/settings/dashboard/conditional/BackgroundDataCondition.java b/src/com/android/settings/dashboard/conditional/BackgroundDataCondition.java
index 34172c2..a7e160f 100644
--- a/src/com/android/settings/dashboard/conditional/BackgroundDataCondition.java
+++ b/src/com/android/settings/dashboard/conditional/BackgroundDataCondition.java
@@ -16,7 +16,7 @@
 package com.android.settings.dashboard.conditional;
 
 import android.content.Intent;
-import android.graphics.drawable.Icon;
+import android.graphics.drawable.Drawable;
 import android.net.NetworkPolicyManager;
 import android.util.FeatureFlagUtils;
 
@@ -37,8 +37,8 @@
     }
 
     @Override
-    public Icon getIcon() {
-        return Icon.createWithResource(mManager.getContext(), R.drawable.ic_data_saver);
+    public Drawable getIcon() {
+        return mManager.getContext().getDrawable(R.drawable.ic_data_saver);
     }
 
     @Override
@@ -53,7 +53,7 @@
 
     @Override
     public CharSequence[] getActions() {
-        return new CharSequence[] { mManager.getContext().getString(R.string.condition_turn_off) };
+        return new CharSequence[] {mManager.getContext().getString(R.string.condition_turn_off)};
     }
 
     @Override
diff --git a/src/com/android/settings/dashboard/conditional/BatterySaverCondition.java b/src/com/android/settings/dashboard/conditional/BatterySaverCondition.java
index d113578..f1962ef 100644
--- a/src/com/android/settings/dashboard/conditional/BatterySaverCondition.java
+++ b/src/com/android/settings/dashboard/conditional/BatterySaverCondition.java
@@ -16,12 +16,13 @@
 package com.android.settings.dashboard.conditional;
 
 import android.content.Intent;
-import android.graphics.drawable.Icon;
+import android.graphics.drawable.Drawable;
 import android.os.PowerManager;
 
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settings.R;
 import com.android.settings.core.SubSettingLauncher;
+import com.android.settings.fuelgauge.BatterySaverDrawable;
 import com.android.settings.fuelgauge.batterysaver.BatterySaverSettings;
 import com.android.settingslib.fuelgauge.BatterySaverUtils;
 
@@ -37,8 +38,8 @@
     }
 
     @Override
-    public Icon getIcon() {
-        return Icon.createWithResource(mManager.getContext(), R.drawable.ic_settings_battery);
+    public Drawable getIcon() {
+        return new BatterySaverDrawable(mManager.getContext(), 0);
     }
 
     @Override
@@ -53,7 +54,7 @@
 
     @Override
     public CharSequence[] getActions() {
-        return new CharSequence[] { mManager.getContext().getString(R.string.condition_turn_off) };
+        return new CharSequence[] {mManager.getContext().getString(R.string.condition_turn_off)};
     }
 
     @Override
diff --git a/src/com/android/settings/dashboard/conditional/CellularDataCondition.java b/src/com/android/settings/dashboard/conditional/CellularDataCondition.java
index 112248c..bc0cbd5 100644
--- a/src/com/android/settings/dashboard/conditional/CellularDataCondition.java
+++ b/src/com/android/settings/dashboard/conditional/CellularDataCondition.java
@@ -14,9 +14,10 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.graphics.drawable.Icon;
+import android.graphics.drawable.Drawable;
 import android.net.ConnectivityManager;
 import android.telephony.TelephonyManager;
+
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.telephony.TelephonyIntents;
 import com.android.settings.R;
@@ -58,8 +59,8 @@
     }
 
     @Override
-    public Icon getIcon() {
-        return Icon.createWithResource(mManager.getContext(), R.drawable.ic_cellular_off);
+    public Drawable getIcon() {
+        return mManager.getContext().getDrawable(R.drawable.ic_cellular_off);
     }
 
     @Override
diff --git a/src/com/android/settings/dashboard/conditional/Condition.java b/src/com/android/settings/dashboard/conditional/Condition.java
index d66440e..f2905b9 100644
--- a/src/com/android/settings/dashboard/conditional/Condition.java
+++ b/src/com/android/settings/dashboard/conditional/Condition.java
@@ -19,10 +19,10 @@
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.IntentFilter;
-import android.graphics.drawable.Icon;
+import android.graphics.drawable.Drawable;
 import android.os.PersistableBundle;
-
 import android.support.annotation.VisibleForTesting;
+
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
@@ -151,7 +151,7 @@
     public abstract int getMetricsConstant();
 
     // UI.
-    public abstract Icon getIcon();
+    public abstract Drawable getIcon();
     public abstract CharSequence getTitle();
     public abstract CharSequence getSummary();
     public abstract CharSequence[] getActions();
diff --git a/src/com/android/settings/dashboard/conditional/ConditionAdapter.java b/src/com/android/settings/dashboard/conditional/ConditionAdapter.java
index a540b3f..a656cc7 100644
--- a/src/com/android/settings/dashboard/conditional/ConditionAdapter.java
+++ b/src/com/android/settings/dashboard/conditional/ConditionAdapter.java
@@ -50,8 +50,8 @@
             //TODO: get rid of setTag/getTag
             Condition condition = (Condition) v.getTag();
             mMetricsFeatureProvider.action(mContext,
-                MetricsEvent.ACTION_SETTINGS_CONDITION_CLICK,
-                condition.getMetricsConstant());
+                    MetricsEvent.ACTION_SETTINGS_CONDITION_CLICK,
+                    condition.getMetricsConstant());
             condition.onPrimaryClick();
         }
     };
@@ -108,7 +108,7 @@
     @Override
     public void onBindViewHolder(DashboardItemHolder holder, int position) {
         bindViews(mConditions.get(position), holder,
-            position == mConditions.size() - 1, mConditionClickListener);
+                position == mConditions.size() - 1, mConditionClickListener);
     }
 
     @Override
@@ -145,7 +145,7 @@
         View card = view.itemView.findViewById(R.id.content);
         card.setTag(condition);
         card.setOnClickListener(onClickListener);
-        view.icon.setImageIcon(condition.getIcon());
+        view.icon.setImageDrawable(condition.getIcon());
         view.title.setText(condition.getTitle());
 
         CharSequence[] actions = condition.getActions();
diff --git a/src/com/android/settings/dashboard/conditional/DndCondition.java b/src/com/android/settings/dashboard/conditional/DndCondition.java
index 673dccc..3112d48 100644
--- a/src/com/android/settings/dashboard/conditional/DndCondition.java
+++ b/src/com/android/settings/dashboard/conditional/DndCondition.java
@@ -20,7 +20,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.graphics.drawable.Icon;
+import android.graphics.drawable.Drawable;
 import android.os.PersistableBundle;
 import android.provider.Settings;
 import android.provider.Settings.Global;
@@ -81,8 +81,8 @@
     }
 
     @Override
-    public Icon getIcon() {
-        return Icon.createWithResource(mManager.getContext(), R.drawable.ic_zen);
+    public Drawable getIcon() {
+        return mManager.getContext().getDrawable(R.drawable.ic_zen);
     }
 
     @Override
diff --git a/src/com/android/settings/dashboard/conditional/HotspotCondition.java b/src/com/android/settings/dashboard/conditional/HotspotCondition.java
index c62b0a4..53e0c07 100644
--- a/src/com/android/settings/dashboard/conditional/HotspotCondition.java
+++ b/src/com/android/settings/dashboard/conditional/HotspotCondition.java
@@ -19,7 +19,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.graphics.drawable.Icon;
+import android.graphics.drawable.Drawable;
 import android.net.ConnectivityManager;
 import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiManager;
@@ -64,8 +64,8 @@
     }
 
     @Override
-    public Icon getIcon() {
-        return Icon.createWithResource(mManager.getContext(), R.drawable.ic_hotspot);
+    public Drawable getIcon() {
+        return mManager.getContext().getDrawable(R.drawable.ic_hotspot);
     }
 
     private String getSsid() {
diff --git a/src/com/android/settings/dashboard/conditional/NightDisplayCondition.java b/src/com/android/settings/dashboard/conditional/NightDisplayCondition.java
index 9cb8605..78278b5 100644
--- a/src/com/android/settings/dashboard/conditional/NightDisplayCondition.java
+++ b/src/com/android/settings/dashboard/conditional/NightDisplayCondition.java
@@ -17,7 +17,7 @@
 package com.android.settings.dashboard.conditional;
 
 import android.content.Intent;
-import android.graphics.drawable.Icon;
+import android.graphics.drawable.Drawable;
 
 import com.android.internal.app.ColorDisplayController;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -42,8 +42,8 @@
     }
 
     @Override
-    public Icon getIcon() {
-        return Icon.createWithResource(mManager.getContext(), R.drawable.ic_settings_night_display);
+    public Drawable getIcon() {
+        return mManager.getContext().getDrawable(R.drawable.ic_settings_night_display);
     }
 
     @Override
@@ -58,7 +58,7 @@
 
     @Override
     public CharSequence[] getActions() {
-        return new CharSequence[] { mManager.getContext().getString(R.string.condition_turn_off) };
+        return new CharSequence[] {mManager.getContext().getString(R.string.condition_turn_off)};
     }
 
     @Override
diff --git a/src/com/android/settings/dashboard/conditional/WorkModeCondition.java b/src/com/android/settings/dashboard/conditional/WorkModeCondition.java
index cb1b60a..941d5b0 100644
--- a/src/com/android/settings/dashboard/conditional/WorkModeCondition.java
+++ b/src/com/android/settings/dashboard/conditional/WorkModeCondition.java
@@ -19,7 +19,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.UserInfo;
-import android.graphics.drawable.Icon;
+import android.graphics.drawable.Drawable;
 import android.os.UserHandle;
 import android.os.UserManager;
 
@@ -60,9 +60,8 @@
     }
 
     @Override
-    public Icon getIcon() {
-        return Icon.createWithResource(mManager.getContext(),
-                R.drawable.ic_signal_workmode_enable);
+    public Drawable getIcon() {
+        return mManager.getContext().getDrawable(R.drawable.ic_signal_workmode_enable);
     }
 
     @Override
diff --git a/src/com/android/settings/datausage/DataUsageSummary.java b/src/com/android/settings/datausage/DataUsageSummary.java
index 25ab330..ccfcff1 100644
--- a/src/com/android/settings/datausage/DataUsageSummary.java
+++ b/src/com/android/settings/datausage/DataUsageSummary.java
@@ -20,7 +20,6 @@
 import android.content.Intent;
 import android.net.NetworkTemplate;
 import android.os.Bundle;
-import android.os.UserManager;
 import android.provider.SearchIndexableResource;
 import android.support.annotation.VisibleForTesting;
 import android.support.v7.preference.Preference;
@@ -35,21 +34,16 @@
 import android.text.TextUtils;
 import android.text.format.Formatter;
 import android.text.style.RelativeSizeSpan;
-import android.view.Menu;
-import android.view.MenuInflater;
 import android.view.MenuItem;
 
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settings.R;
-import com.android.settings.SettingsActivity;
 import com.android.settings.Utils;
 import com.android.settings.dashboard.SummaryLoader;
 import com.android.settings.search.BaseSearchIndexProvider;
 import com.android.settings.search.Indexable;
-import com.android.settings.widget.EntityHeaderController;
 import com.android.settingslib.NetworkPolicyEditor;
 import com.android.settingslib.core.AbstractPreferenceController;
-import com.android.settingslib.core.lifecycle.Lifecycle;
 import com.android.settingslib.net.DataUsageController;
 
 import java.util.ArrayList;
diff --git a/src/com/android/settings/datetime/timezone/BaseTimeZoneAdapter.java b/src/com/android/settings/datetime/timezone/BaseTimeZoneAdapter.java
index effa948..5a614a3 100644
--- a/src/com/android/settings/datetime/timezone/BaseTimeZoneAdapter.java
+++ b/src/com/android/settings/datetime/timezone/BaseTimeZoneAdapter.java
@@ -18,6 +18,7 @@
 
 import android.icu.text.BreakIterator;
 import android.support.annotation.NonNull;
+import android.support.annotation.VisibleForTesting;
 import android.support.annotation.WorkerThread;
 import android.support.v7.widget.RecyclerView;
 import android.text.TextUtils;
@@ -42,14 +43,14 @@
         extends RecyclerView.Adapter<BaseTimeZoneAdapter.ItemViewHolder> {
 
     private final List<T> mOriginalItems;
-    private final OnListItemClickListener mOnListItemClickListener;
+    private final OnListItemClickListener<T> mOnListItemClickListener;
     private final Locale mLocale;
     private final boolean mShowItemSummary;
 
     private List<T> mItems;
     private ArrayFilter mFilter;
 
-    public BaseTimeZoneAdapter(List<T> items, OnListItemClickListener
+    public BaseTimeZoneAdapter(List<T> items, OnListItemClickListener<T>
             onListItemClickListener, Locale locale, boolean showItemSummary) {
         mOriginalItems = items;
         mItems = items;
@@ -69,14 +70,8 @@
 
     @Override
     public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) {
-        final AdapterItem item = mItems.get(position);
-        holder.mSummaryFrame.setVisibility(
-                mShowItemSummary ? View.VISIBLE : View.GONE);
-        holder.mTitleView.setText(item.getTitle());
-        holder.mIconTextView.setText(item.getIconText());
-        holder.mSummaryView.setText(item.getSummary());
-        holder.mTimeView.setText(item.getCurrentTime());
-        holder.setPosition(position);
+        holder.setAdapterItem(mItems.get(position));
+        holder.mSummaryFrame.setVisibility(mShowItemSummary ? View.VISIBLE : View.GONE);
     }
 
     @Override
@@ -89,8 +84,7 @@
         return mItems.size();
     }
 
-    public  @NonNull
-    Filter getFilter() {
+    public @NonNull ArrayFilter getFilter() {
         if (mFilter == null) {
             mFilter = new ArrayFilter();
         }
@@ -110,18 +104,18 @@
         String[] getSearchKeys();
     }
 
-    public static class ItemViewHolder extends RecyclerView.ViewHolder
-            implements View.OnClickListener{
+    public static class ItemViewHolder<T extends BaseTimeZoneAdapter.AdapterItem>
+            extends RecyclerView.ViewHolder implements View.OnClickListener {
 
-        final OnListItemClickListener mOnListItemClickListener;
+        final OnListItemClickListener<T> mOnListItemClickListener;
         final View mSummaryFrame;
         final TextView mTitleView;
         final TextView mIconTextView;
         final TextView mSummaryView;
         final TextView mTimeView;
-        private int mPosition;
+        private T mItem;
 
-        public ItemViewHolder(View itemView, OnListItemClickListener onListItemClickListener) {
+        public ItemViewHolder(View itemView, OnListItemClickListener<T> onListItemClickListener) {
             super(itemView);
             itemView.setOnClickListener(this);
             mSummaryFrame = itemView.findViewById(R.id.summary_frame);
@@ -132,13 +126,17 @@
             mOnListItemClickListener = onListItemClickListener;
         }
 
-        public void setPosition(int position) {
-            mPosition = position;
+        public void setAdapterItem(T item) {
+            mItem = item;
+            mTitleView.setText(item.getTitle());
+            mIconTextView.setText(item.getIconText());
+            mSummaryView.setText(item.getSummary());
+            mTimeView.setText(item.getCurrentTime());
         }
 
         @Override
         public void onClick(View v) {
-            mOnListItemClickListener.onListItemClick(mPosition);
+            mOnListItemClickListener.onListItemClick(mItem);
         }
     }
 
@@ -151,7 +149,8 @@
      * require additional pre-processing. Potentially, a trie structure can be used to match
      * prefixes of the search keys.
      */
-    private class ArrayFilter extends Filter {
+    @VisibleForTesting
+    public class ArrayFilter extends Filter {
 
         private BreakIterator mBreakIterator = BreakIterator.getWordInstance(mLocale);
 
@@ -197,8 +196,9 @@
             return results;
         }
 
+        @VisibleForTesting
         @Override
-        protected void publishResults(CharSequence constraint, FilterResults results) {
+        public void publishResults(CharSequence constraint, FilterResults results) {
             mItems = (List<T>) results.values;
             notifyDataSetChanged();
         }
diff --git a/src/com/android/settings/datetime/timezone/BaseTimeZoneInfoPicker.java b/src/com/android/settings/datetime/timezone/BaseTimeZoneInfoPicker.java
index c1a3f8b..d734542 100644
--- a/src/com/android/settings/datetime/timezone/BaseTimeZoneInfoPicker.java
+++ b/src/com/android/settings/datetime/timezone/BaseTimeZoneInfoPicker.java
@@ -31,7 +31,6 @@
 import java.util.Date;
 import java.util.List;
 import java.util.Locale;
-import java.util.Objects;
 
 /**
  * Render a list of {@class TimeZoneInfo} into the list view in {@class BaseTimeZonePicker}
@@ -52,8 +51,8 @@
         return mAdapter;
     }
 
-    private void onListItemClick(int position) {
-        final TimeZoneInfo timeZoneInfo = mAdapter.getItem(position).mTimeZoneInfo;
+    private void onListItemClick(TimeZoneInfoItem item) {
+        final TimeZoneInfo timeZoneInfo = item.mTimeZoneInfo;
         getActivity().setResult(Activity.RESULT_OK, prepareResultData(timeZoneInfo));
         getActivity().finish();
     }
@@ -67,7 +66,7 @@
     protected static class ZoneAdapter extends BaseTimeZoneAdapter<TimeZoneInfoItem> {
 
         public ZoneAdapter(Context context, List<TimeZoneInfo> timeZones,
-                OnListItemClickListener onListItemClickListener, Locale locale) {
+                OnListItemClickListener<TimeZoneInfoItem> onListItemClickListener, Locale locale) {
             super(createTimeZoneInfoItems(context, timeZones, locale),
                     onListItemClickListener, locale,  true /* showItemSummary */);
         }
diff --git a/src/com/android/settings/datetime/timezone/BaseTimeZonePicker.java b/src/com/android/settings/datetime/timezone/BaseTimeZonePicker.java
index 032e2d2..5150045 100644
--- a/src/com/android/settings/datetime/timezone/BaseTimeZonePicker.java
+++ b/src/com/android/settings/datetime/timezone/BaseTimeZonePicker.java
@@ -17,6 +17,7 @@
 package com.android.settings.datetime.timezone;
 
 import android.os.Bundle;
+import android.support.annotation.VisibleForTesting;
 import android.support.v7.widget.LinearLayoutManager;
 import android.support.v7.widget.RecyclerView;
 import android.view.LayoutInflater;
@@ -161,8 +162,8 @@
         return false;
     }
 
-    public interface OnListItemClickListener {
-        void onListItemClick(int position);
+    public interface OnListItemClickListener<T extends BaseTimeZoneAdapter.AdapterItem> {
+        void onListItemClick(T item);
     }
 
 }
diff --git a/src/com/android/settings/datetime/timezone/RegionSearchPicker.java b/src/com/android/settings/datetime/timezone/RegionSearchPicker.java
index bb87e85..ca4e0bc 100644
--- a/src/com/android/settings/datetime/timezone/RegionSearchPicker.java
+++ b/src/com/android/settings/datetime/timezone/RegionSearchPicker.java
@@ -18,15 +18,16 @@
 
 import android.app.Activity;
 import android.content.Intent;
-import android.graphics.Paint;
 import android.icu.text.Collator;
 import android.icu.text.LocaleDisplayNames;
 import android.os.Bundle;
+import android.support.annotation.VisibleForTesting;
 import android.util.Log;
 
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.settings.R;
 import com.android.settings.core.SubSettingLauncher;
+import com.android.settings.datetime.timezone.BaseTimeZoneAdapter.AdapterItem;
 import com.android.settings.datetime.timezone.model.FilteredCountryTimeZones;
 import com.android.settings.datetime.timezone.model.TimeZoneData;
 
@@ -63,8 +64,8 @@
         return mAdapter;
     }
 
-    private void onListItemClick(int position) {
-        final String regionId = mAdapter.getItem(position).getId();
+    private void onListItemClick(RegionItem item) {
+        final String regionId = item.getId();
         final FilteredCountryTimeZones countryTimeZones = mTimeZoneData.lookupCountryTimeZones(
                 regionId);
         final Activity activity = getActivity();
@@ -119,7 +120,8 @@
         return new ArrayList<>(items);
     }
 
-    private static class RegionItem implements BaseTimeZoneAdapter.AdapterItem {
+    @VisibleForTesting
+    static class RegionItem implements AdapterItem {
 
         private final String mId;
         private final String mName;
diff --git a/src/com/android/settings/display/ColorModePreferenceFragment.java b/src/com/android/settings/display/ColorModePreferenceFragment.java
index f1bb6e1..5f5445b 100644
--- a/src/com/android/settings/display/ColorModePreferenceFragment.java
+++ b/src/com/android/settings/display/ColorModePreferenceFragment.java
@@ -38,6 +38,9 @@
     static final String KEY_COLOR_MODE_BOOSTED = "color_mode_boosted";
     @VisibleForTesting
     static final String KEY_COLOR_MODE_SATURATED = "color_mode_saturated";
+    // TODO have a real key for "automatic" rather than just re-using "saturated"
+    @VisibleForTesting
+    static final String KEY_COLOR_MODE_AUTOMATIC = "color_mode_saturated";
 
     private ColorDisplayController mController;
 
@@ -74,7 +77,9 @@
             new ColorModeCandidateInfo(c.getString(R.string.color_mode_option_boosted),
                     KEY_COLOR_MODE_BOOSTED),
             new ColorModeCandidateInfo(c.getString(R.string.color_mode_option_saturated),
-                    KEY_COLOR_MODE_SATURATED)
+                    KEY_COLOR_MODE_SATURATED),
+            new ColorModeCandidateInfo(c.getString(R.string.color_mode_option_automatic),
+                    KEY_COLOR_MODE_AUTOMATIC)
         );
     }
 
diff --git a/src/com/android/settings/fingerprint/FingerprintUiHelper.java b/src/com/android/settings/fingerprint/FingerprintUiHelper.java
index 655ce26..4a67ecd 100644
--- a/src/com/android/settings/fingerprint/FingerprintUiHelper.java
+++ b/src/com/android/settings/fingerprint/FingerprintUiHelper.java
@@ -79,6 +79,10 @@
 
     @Override
     public void onAuthenticationError(int errMsgId, CharSequence errString) {
+        if (errMsgId == FingerprintManager.FINGERPRINT_ERROR_CANCELED) {
+            // Only happens if we get preempted by another activity. Ignored.
+            return;
+        }
         showError(errString);
         setFingerprintIconVisibility(false);
     }
diff --git a/src/com/android/settings/fuelgauge/BatteryEntry.java b/src/com/android/settings/fuelgauge/BatteryEntry.java
index 7a18cd0..1733a6e 100644
--- a/src/com/android/settings/fuelgauge/BatteryEntry.java
+++ b/src/com/android/settings/fuelgauge/BatteryEntry.java
@@ -38,6 +38,7 @@
 
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.Locale;
 
 /**
  * Wraps the power usage data of a BatterySipper with information about package name
@@ -55,6 +56,8 @@
     static final ArrayList<BatteryEntry> mRequestQueue = new ArrayList<BatteryEntry>();
     static Handler sHandler;
 
+    static Locale sCurrentLocale = null;
+
     static private class NameAndIconLoader extends Thread {
         private boolean mAbort = false;
 
@@ -227,6 +230,13 @@
     }
 
     void getQuickNameIconForUid(final int uid) {
+        // Locale sync to system config in Settings
+        final Locale locale = Locale.getDefault();
+        if (sCurrentLocale != locale) {
+            clearUidCache();
+            sCurrentLocale = locale;
+        }
+
         final String uidString = Integer.toString(uid);
         if (sUidCache.containsKey(uidString)) {
             UidToDetail utd = sUidCache.get(uidString);
diff --git a/src/com/android/settings/fuelgauge/BatterySaverDrawable.java b/src/com/android/settings/fuelgauge/BatterySaverDrawable.java
new file mode 100644
index 0000000..0d3008a
--- /dev/null
+++ b/src/com/android/settings/fuelgauge/BatterySaverDrawable.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2018 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.fuelgauge;
+
+import android.content.Context;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffColorFilter;
+
+import com.android.settingslib.Utils;
+import com.android.settingslib.graph.BatteryMeterDrawableBase;
+
+/**
+ * Drawable that shows a static battery saver icon - a full battery symbol and a plus sign.
+ */
+public class BatterySaverDrawable extends BatteryMeterDrawableBase {
+
+    private static final int MAX_BATTERY = 100;
+
+    public BatterySaverDrawable(Context context, int frameColor) {
+        super(context, frameColor);
+        // Show as full so it's always uniform color
+        setBatteryLevel(MAX_BATTERY);
+        setPowerSave(true);
+        setCharging(false);
+        setPowerSaveAsColorError(false);
+        final int tintColor = Utils.getColorAttr(context, android.R.attr.colorAccent);
+        setColorFilter(new PorterDuffColorFilter(tintColor, PorterDuff.Mode.SRC_IN));
+    }
+}
\ No newline at end of file
diff --git a/src/com/android/settings/fuelgauge/batterytip/tips/RestrictAppTip.java b/src/com/android/settings/fuelgauge/batterytip/tips/RestrictAppTip.java
index d4e950c..ed2f6b6 100644
--- a/src/com/android/settings/fuelgauge/batterytip/tips/RestrictAppTip.java
+++ b/src/com/android/settings/fuelgauge/batterytip/tips/RestrictAppTip.java
@@ -112,7 +112,7 @@
                     metricsFeatureProvider.action(context,
                             MetricsProto.MetricsEvent.ACTION_APP_RESTRICTION_TIP_LIST,
                             appInfo.packageName,
-                            Pair.create(MetricsProto.MetricsEvent.FIELD_CONTEXT, anomalyType));
+                            Pair.create(MetricsProto.MetricsEvent.FIELD_ANOMALY_TYPE, anomalyType));
                 }
 
             }
diff --git a/src/com/android/settings/notification/NotificationAppPreference.java b/src/com/android/settings/notification/NotificationAppPreference.java
index a6bcdd6..e43c52b 100644
--- a/src/com/android/settings/notification/NotificationAppPreference.java
+++ b/src/com/android/settings/notification/NotificationAppPreference.java
@@ -17,35 +17,38 @@
 
 import android.content.Context;
 import android.support.v7.preference.PreferenceViewHolder;
-import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.view.View;
-import android.widget.ProgressBar;
 import android.widget.Switch;
 
 import com.android.settings.R;
+import com.android.settings.widget.MasterSwitchPreference;
 import com.android.settingslib.RestrictedLockUtils;
-import com.android.settingslib.TwoTargetPreference;
 
 /**
  * Shows an app icon, title and summary. Has a second switch touch target.
  */
-public class NotificationAppPreference extends TwoTargetPreference {
+public class NotificationAppPreference extends MasterSwitchPreference {
 
-    private int mProgress;
-    private boolean mProgressVisible;
     private Switch mSwitch;
     private boolean mChecked;
     private boolean mEnableSwitch = true;
 
     public NotificationAppPreference(Context context) {
         super(context);
-        setLayoutResource(R.layout.preference_app);
     }
 
     public NotificationAppPreference(Context context, AttributeSet attrs) {
         super(context, attrs);
-        setLayoutResource(R.layout.preference_app);
+    }
+
+    public NotificationAppPreference(Context context, AttributeSet attrs,
+            int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+    }
+
+    public NotificationAppPreference(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
     }
 
     @Override
@@ -53,26 +56,10 @@
         return R.layout.preference_widget_master_switch;
     }
 
-    public void setProgress(int amount) {
-        mProgress = amount;
-        mProgressVisible = true;
-        notifyChanged();
-    }
-
     @Override
     public void onBindViewHolder(PreferenceViewHolder view) {
         super.onBindViewHolder(view);
 
-        view.findViewById(R.id.summary_container)
-                .setVisibility(TextUtils.isEmpty(getSummary()) ? View.GONE : View.VISIBLE);
-        final ProgressBar progress = (ProgressBar) view.findViewById(android.R.id.progress);
-        if (mProgressVisible) {
-            progress.setProgress(mProgress);
-            progress.setVisibility(View.VISIBLE);
-        } else {
-            progress.setVisibility(View.GONE);
-        }
-
         final View widgetView = view.findViewById(android.R.id.widget_frame);
         if (widgetView != null) {
             widgetView.setOnClickListener(new View.OnClickListener() {
diff --git a/src/com/android/settings/notification/RecentNotifyingAppsPreferenceController.java b/src/com/android/settings/notification/RecentNotifyingAppsPreferenceController.java
index 6cc99f7..3867640 100644
--- a/src/com/android/settings/notification/RecentNotifyingAppsPreferenceController.java
+++ b/src/com/android/settings/notification/RecentNotifyingAppsPreferenceController.java
@@ -81,7 +81,6 @@
     private PreferenceCategory mCategory;
     private Preference mSeeAllPref;
     private Preference mDivider;
-    private boolean mHasRecentApps;
 
     static {
         SKIP_SYSTEM_PACKAGES.addAll(Arrays.asList(
@@ -142,20 +141,7 @@
     public void updateState(Preference preference) {
         super.updateState(preference);
         refreshUi(mCategory.getContext());
-        // Show total number of installed apps as See all's summary.
-        new InstalledAppCounter(mContext, InstalledAppCounter.IGNORE_INSTALL_REASON,
-                new PackageManagerWrapper(mContext.getPackageManager())) {
-            @Override
-            protected void onCountComplete(int num) {
-                if (mHasRecentApps) {
-                    mSeeAllPref.setTitle(
-                            mContext.getString(R.string.recent_notifications_see_all_title));
-                } else {
-                    mSeeAllPref.setSummary(mContext.getString(R.string.apps_summary, num));
-                }
-            }
-        }.execute();
-
+        mSeeAllPref.setTitle(mContext.getString(R.string.recent_notifications_see_all_title));
     }
 
     @VisibleForTesting
@@ -163,10 +149,8 @@
         reloadData();
         final List<NotifyingApp> recentApps = getDisplayableRecentAppList();
         if (recentApps != null && !recentApps.isEmpty()) {
-            mHasRecentApps = true;
             displayRecentApps(prefContext, recentApps);
         } else {
-            mHasRecentApps = false;
             displayOnlyAllAppsLink();
         }
     }
@@ -228,7 +212,7 @@
             pref.setTitle(appEntry.label);
             pref.setIcon(mIconDrawableFactory.getBadgedIcon(appEntry.info));
             pref.setSummary(StringUtil.formatRelativeTime(mContext,
-                    System.currentTimeMillis() - app.getLastNotified(), false));
+                    System.currentTimeMillis() - app.getLastNotified(), true));
             pref.setOrder(i);
             Bundle args = new Bundle();
             args.putString(AppInfoBase.ARG_PACKAGE_NAME, pkgName);
diff --git a/src/com/android/settings/password/ChooseLockPassword.java b/src/com/android/settings/password/ChooseLockPassword.java
index 38fdbce..50cb40a 100644
--- a/src/com/android/settings/password/ChooseLockPassword.java
+++ b/src/com/android/settings/password/ChooseLockPassword.java
@@ -636,13 +636,15 @@
         }
 
         /**
-         * Validates PIN and returns the validation result.
+         * Validates PIN/Password and returns the validation result.
          *
          * @param password the raw password the user typed in
          * @return the validation result.
          */
         private int validatePassword(String password) {
             int errorCode = NO_ERROR;
+            final PasswordMetrics metrics = PasswordMetrics.computeForPassword(password);
+
 
             if (password.length() < mPasswordMinLength) {
                 if (mPasswordMinLength > mPasswordMinLengthToFulfillAllPolicies) {
@@ -652,8 +654,14 @@
                 errorCode |= TOO_LONG;
             } else {
                 // The length requirements are fulfilled.
-                if (mRequestedQuality == PASSWORD_QUALITY_NUMERIC_COMPLEX) {
+                final int dpmQuality = mLockPatternUtils.getRequestedPasswordQuality(mUserId);
+                if (dpmQuality == PASSWORD_QUALITY_NUMERIC_COMPLEX &&
+                        metrics.numeric == password.length()) {
                     // Check for repeated characters or sequences (e.g. '1234', '0000', '2468')
+                    // if DevicePolicyManager requires a complex numeric password. There can be
+                    // two cases in the UI: 1. User chooses to enroll a PIN, 2. User chooses to
+                    // enroll a password but enters a numeric-only pin. We should carry out the
+                    // sequence check in both cases.
                     final int sequence = PasswordMetrics.maxLengthSequence(password);
                     if (sequence > PasswordMetrics.MAX_ALLOWED_SEQUENCE) {
                         errorCode |= CONTAIN_SEQUENTIAL_DIGITS;
@@ -674,8 +682,6 @@
                 }
             }
 
-            final PasswordMetrics metrics = PasswordMetrics.computeForPassword(password);
-
             // Ensure no non-digits if we are requesting numbers. This shouldn't be possible unless
             // user finds some way to bring up soft keyboard.
             if (mRequestedQuality == PASSWORD_QUALITY_NUMERIC
diff --git a/src/com/android/settings/password/SetupChooseLockPattern.java b/src/com/android/settings/password/SetupChooseLockPattern.java
index 8853950..c9858b8 100644
--- a/src/com/android/settings/password/SetupChooseLockPattern.java
+++ b/src/com/android/settings/password/SetupChooseLockPattern.java
@@ -25,7 +25,6 @@
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.Button;
-import android.widget.TextView;
 
 import com.android.settings.R;
 import com.android.settings.SetupRedactionInterstitial;
@@ -70,6 +69,17 @@
                         ChooseLockTypeDialogFragment.newInstance(mUserId)
                                 .show(getChildFragmentManager(), null));
             }
+            // enable skip button only during setup wizard and not with fingerprint flow.
+            if (!mForFingerprint) {
+                Button skipButton = view.findViewById(R.id.skip_button);
+                skipButton.setVisibility(View.VISIBLE);
+                skipButton.setOnClickListener(v -> {
+                    SetupSkipDialog dialog = SetupSkipDialog.newInstance(
+                            getActivity().getIntent()
+                                    .getBooleanExtra(SetupSkipDialog.EXTRA_FRP_SUPPORTED, false));
+                    dialog.show(getFragmentManager());
+                });
+            }
             return view;
         }
 
@@ -82,16 +92,6 @@
         }
 
         @Override
-        protected void updateFooterLeftButton(Stage stage, TextView footerLeftButton) {
-            super.updateFooterLeftButton(stage, footerLeftButton);
-            // enable skip button only during setupwizard and not with fingerprint flow.
-            if (!mForFingerprint) {
-                footerLeftButton.setVisibility(View.VISIBLE);
-                footerLeftButton.setText(R.string.skip_label);
-            }
-        }
-
-        @Override
         protected void updateStage(Stage stage) {
             super.updateStage(stage);
             if (!getResources().getBoolean(R.bool.config_lock_pattern_minimal_ui)
@@ -102,14 +102,6 @@
         }
 
         @Override
-        public void handleLeftButton() {
-            SetupSkipDialog dialog = SetupSkipDialog.newInstance(
-                    getActivity().getIntent()
-                            .getBooleanExtra(SetupSkipDialog.EXTRA_FRP_SUPPORTED, false));
-            dialog.show(getFragmentManager());
-        }
-
-        @Override
         protected Intent getRedactionInterstitialIntent(Context context) {
             // Setup wizard's redaction interstitial is deferred to optional step. Enable that
             // optional step if the lock screen was set up.
diff --git a/src/com/android/settings/slices/SettingsSliceProvider.java b/src/com/android/settings/slices/SettingsSliceProvider.java
index 8b3bdbd..b07bcb0 100644
--- a/src/com/android/settings/slices/SettingsSliceProvider.java
+++ b/src/com/android/settings/slices/SettingsSliceProvider.java
@@ -90,6 +90,12 @@
      */
     public static final String EXTRA_SLICE_KEY = "com.android.settings.slice.extra.key";
 
+    /**
+     * Boolean extra to indicate if the Slice is platform-defined.
+     */
+    public static final String EXTRA_SLICE_PLATFORM_DEFINED =
+            "com.android.settings.slice.extra.platform";
+
     // TODO -- Associate slice URI with search result instead of separate hardcoded thing
 
     @VisibleForTesting
diff --git a/src/com/android/settings/slices/SliceBroadcastReceiver.java b/src/com/android/settings/slices/SliceBroadcastReceiver.java
index c455640..f47aeb2 100644
--- a/src/com/android/settings/slices/SliceBroadcastReceiver.java
+++ b/src/com/android/settings/slices/SliceBroadcastReceiver.java
@@ -20,6 +20,7 @@
 import static com.android.settings.slices.SettingsSliceProvider.ACTION_TOGGLE_CHANGED;
 import static com.android.settings.slices.SettingsSliceProvider.ACTION_WIFI_CHANGED;
 import static com.android.settings.slices.SettingsSliceProvider.EXTRA_SLICE_KEY;
+import static com.android.settings.slices.SettingsSliceProvider.EXTRA_SLICE_PLATFORM_DEFINED;
 
 import android.content.BroadcastReceiver;
 import android.content.Context;
@@ -27,7 +28,9 @@
 import android.net.Uri;
 import android.net.wifi.WifiManager;
 import android.os.Handler;
+import android.provider.SettingsSlicesContract;
 import android.text.TextUtils;
+import android.util.Log;
 
 import com.android.settings.core.BasePreferenceController;
 import com.android.settings.core.SliderPreferenceController;
@@ -49,12 +52,14 @@
      */
     @Override
     public void onReceive(Context context, Intent intent) {
-        String action = intent.getAction();
-        String key = intent.getStringExtra(EXTRA_SLICE_KEY);
+        final String action = intent.getAction();
+        final String key = intent.getStringExtra(EXTRA_SLICE_KEY);
+        final boolean isPlatformDefined = intent.getBooleanExtra(EXTRA_SLICE_PLATFORM_DEFINED,
+                false /* default */);
 
         switch (action) {
             case ACTION_TOGGLE_CHANGED:
-                handleToggleAction(context, key);
+                handleToggleAction(context, key, isPlatformDefined);
                 break;
             case ACTION_SLIDER_CHANGED:
                 int newPosition = intent.getIntExtra(SliceHints.EXTRA_RANGE_VALUE, -1);
@@ -76,7 +81,7 @@
         }
     }
 
-    private void handleToggleAction(Context context, String key) {
+    private void handleToggleAction(Context context, String key, boolean isPlatformSlice) {
         if (TextUtils.isEmpty(key)) {
             throw new IllegalStateException("No key passed to Intent for toggle controller");
         }
@@ -87,11 +92,17 @@
             throw new IllegalStateException("Toggle action passed for a non-toggle key: " + key);
         }
 
+        if (!controller.isAvailable()) {
+            Log.d(TAG, "Can't update " + key + " since the setting is unavailable");
+            updateUri(context, key, isPlatformSlice);
+        }
+
         // TODO post context.getContentResolver().notifyChanged(uri, null) in the Toggle controller
         // so that it's automatically broadcast to any slice.
         final TogglePreferenceController toggleController = (TogglePreferenceController) controller;
         final boolean currentValue = toggleController.isChecked();
         toggleController.setChecked(!currentValue);
+        updateUri(context, key, isPlatformSlice);
     }
 
     private void handleSliderAction(Context context, String key, int newPosition) {
@@ -126,4 +137,10 @@
         final SliceData sliceData = accessor.getSliceDataFromKey(key);
         return SliceBuilderUtils.getPreferenceController(context, sliceData);
     }
+
+    private void updateUri(Context context, String key, boolean isPlatformDefined) {
+        final String path = SettingsSlicesContract.PATH_SETTING_ACTION + "/" + key;
+        final Uri uri = SliceBuilderUtils.getUri(path, isPlatformDefined);
+        context.getContentResolver().notifyChange(uri, null /* observer */);
+    }
 }
diff --git a/src/com/android/settings/slices/SliceBuilderUtils.java b/src/com/android/settings/slices/SliceBuilderUtils.java
index 43cba73..af9a336 100644
--- a/src/com/android/settings/slices/SliceBuilderUtils.java
+++ b/src/com/android/settings/slices/SliceBuilderUtils.java
@@ -16,7 +16,12 @@
 
 package com.android.settings.slices;
 
+import static com.android.settings.core.BasePreferenceController.DISABLED_DEPENDENT_SETTING;
+import static com.android.settings.core.BasePreferenceController.DISABLED_FOR_USER;
+import static com.android.settings.core.BasePreferenceController.DISABLED_UNSUPPORTED;
+import static com.android.settings.core.BasePreferenceController.UNAVAILABLE_UNKNOWN;
 import static com.android.settings.slices.SettingsSliceProvider.EXTRA_SLICE_KEY;
+import static com.android.settings.slices.SettingsSliceProvider.EXTRA_SLICE_PLATFORM_DEFINED;
 
 import static androidx.slice.builders.ListBuilder.ICON_IMAGE;
 
@@ -24,6 +29,7 @@
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.PackageManager;
 import android.graphics.drawable.Icon;
 import android.net.Uri;
 import android.provider.SettingsSlicesContract;
@@ -42,7 +48,6 @@
 import androidx.slice.Slice;
 import androidx.slice.builders.SliceAction;
 import androidx.slice.builders.ListBuilder;
-import androidx.slice.builders.ListBuilder.RowBuilder;
 
 
 /**
@@ -61,8 +66,12 @@
      * {@param sliceData} is an inline controller.
      */
     public static Slice buildSlice(Context context, SliceData sliceData) {
-        // TODO (b/71640747) Respect setting availability.
         final BasePreferenceController controller = getPreferenceController(context, sliceData);
+
+        if (!controller.isAvailable()) {
+            return buildUnavailableSlice(context, sliceData, controller);
+        }
+
         switch (sliceData.getSliceType()) {
             case SliceData.SliceType.INTENT:
                 return buildIntentSlice(context, sliceData, controller);
@@ -120,8 +129,8 @@
     }
 
     /**
-     * Looks at the {@link SliceData#preferenceController} from {@param sliceData} and attempts to
-     * build an {@link AbstractPreferenceController}.
+     * Looks at the controller classname in in {@link SliceData} from {@param sliceData}
+     * and attempts to build an {@link AbstractPreferenceController}.
      */
     public static BasePreferenceController getPreferenceController(Context context,
             SliceData sliceData) {
@@ -147,7 +156,7 @@
         final CharSequence subtitleText = getSubtitleText(context, controller, sliceData);
         final TogglePreferenceController toggleController =
                 (TogglePreferenceController) controller;
-        final SliceAction sliceAction = getToggleAction(context, sliceData.getKey(),
+        final SliceAction sliceAction = getToggleAction(context, sliceData,
                 toggleController.isChecked());
 
         return new ListBuilder(context, sliceData.getUri())
@@ -179,7 +188,7 @@
             BasePreferenceController controller) {
         final SliderPreferenceController sliderController =
                 (SliderPreferenceController) controller;
-        final PendingIntent actionIntent = getSliderAction(context, sliceData.getKey());
+        final PendingIntent actionIntent = getSliderAction(context, sliceData);
         return new ListBuilder(context, sliceData.getUri())
                 .addInputRange(builder -> builder
                         .setTitle(sliceData.getTitle())
@@ -200,20 +209,22 @@
         return BasePreferenceController.createInstance(context, controllerClassName, controllerKey);
     }
 
-    private static SliceAction getToggleAction(Context context, String key, boolean isChecked) {
+    private static SliceAction getToggleAction(Context context, SliceData sliceData,
+            boolean isChecked) {
         PendingIntent actionIntent = getActionIntent(context,
-                SettingsSliceProvider.ACTION_TOGGLE_CHANGED, key);
+                SettingsSliceProvider.ACTION_TOGGLE_CHANGED, sliceData);
         return new SliceAction(actionIntent, null, isChecked);
     }
 
-    private static PendingIntent getSliderAction(Context context, String key) {
-        return getActionIntent(context, SettingsSliceProvider.ACTION_SLIDER_CHANGED, key);
+    private static PendingIntent getSliderAction(Context context, SliceData sliceData) {
+        return getActionIntent(context, SettingsSliceProvider.ACTION_SLIDER_CHANGED, sliceData);
     }
 
-    private static PendingIntent getActionIntent(Context context, String action, String key) {
+    private static PendingIntent getActionIntent(Context context, String action, SliceData data) {
         Intent intent = new Intent(action);
         intent.setClass(context, SliceBroadcastReceiver.class);
-        intent.putExtra(EXTRA_SLICE_KEY, key);
+        intent.putExtra(EXTRA_SLICE_KEY, data.getKey());
+        intent.putExtra(EXTRA_SLICE_PLATFORM_DEFINED, data.isPlatformDefined());
         return PendingIntent.getBroadcast(context, 0 /* requestCode */, intent,
                 PendingIntent.FLAG_CANCEL_CURRENT);
     }
@@ -226,6 +237,12 @@
         return PendingIntent.getActivity(context, 0 /* requestCode */, intent, 0 /* flags */);
     }
 
+    private static PendingIntent getSettingsIntent(Context context) {
+        final PackageManager manager = context.getPackageManager();
+        final Intent intent = manager.getLaunchIntentForPackage(context.getPackageName());
+        return PendingIntent.getActivity(context, 0 /* requestCode */, intent, 0 /* flags */);
+    }
+
     @VisibleForTesting
     static CharSequence getSubtitleText(Context context, AbstractPreferenceController controller,
             SliceData sliceData) {
@@ -257,4 +274,41 @@
         return !(TextUtils.equals(summary, placeHolder)
                 || TextUtils.equals(summary, doublePlaceHolder));
     }
+
+    private static Slice buildUnavailableSlice(Context context, SliceData data,
+            BasePreferenceController controller) {
+        final String title = data.getTitle();
+        final String summary;
+        final SliceAction primaryAction;
+
+        switch (controller.getAvailabilityStatus()) {
+            case DISABLED_UNSUPPORTED:
+                summary = context.getString(R.string.unsupported_setting_summary);
+                primaryAction = new SliceAction(getSettingsIntent(context), null /* actionIcon */,
+                        null /* actionTitle */);
+                break;
+            case DISABLED_FOR_USER:
+                summary = context.getString(R.string.disabled_for_user_setting_summary);
+                primaryAction = new SliceAction(getContentIntent(context, data),
+                        null /* actionIcon */, null /* actionTitle */);
+                break;
+            case DISABLED_DEPENDENT_SETTING:
+                summary = context.getString(R.string.disabled_dependent_setting_summary);
+                primaryAction = new SliceAction(getContentIntent(context, data),
+                        null /* actionIcon */, null /* actionTitle */);
+                break;
+            case UNAVAILABLE_UNKNOWN:
+            default:
+                summary = context.getString(R.string.unknown_unavailability_setting_summary);
+                primaryAction = new SliceAction(getSettingsIntent(context),
+                        null /* actionIcon */, null /* actionTitle */);
+        }
+
+        return new ListBuilder(context, data.getUri())
+                .addRow(builder -> builder
+                        .setTitle(title)
+                        .setSubtitle(summary)
+                        .setPrimaryAction(primaryAction))
+                .build();
+    }
 }
diff --git a/src/com/android/settings/wifi/CaptivePortalNetworkCallback.java b/src/com/android/settings/wifi/CaptivePortalNetworkCallback.java
new file mode 100644
index 0000000..9bcfba0
--- /dev/null
+++ b/src/com/android/settings/wifi/CaptivePortalNetworkCallback.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2018 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 android.net.ConnectivityManager.NetworkCallback;
+import android.net.Network;
+import android.net.NetworkCapabilities;
+
+import com.android.internal.util.Preconditions;
+
+/** Listens for changes to NetworkCapabilities to update the ConnectedAccessPointPreference. */
+final class CaptivePortalNetworkCallback extends NetworkCallback {
+
+    private final ConnectedAccessPointPreference mConnectedApPreference;
+    private final Network mNetwork;
+
+    private boolean mIsCaptivePortal;
+
+    CaptivePortalNetworkCallback(
+            Network network, ConnectedAccessPointPreference connectedApPreference) {
+        mNetwork = Preconditions.checkNotNull(network);
+        mConnectedApPreference = Preconditions.checkNotNull(connectedApPreference);
+    }
+
+    @Override
+    public void onLost(Network network) {
+        if (mNetwork.equals(network)) {
+            mIsCaptivePortal = false;
+        }
+    }
+
+    @Override
+    public void onCapabilitiesChanged(Network network, NetworkCapabilities networkCapabilities) {
+        if (mNetwork.equals(network)) {
+            mIsCaptivePortal = WifiUtils.canSignIntoNetwork(networkCapabilities);
+            mConnectedApPreference.setCaptivePortal(mIsCaptivePortal);
+        }
+    }
+
+    /**
+     * Returns true if the supplied network and preference are not null and are the same as the
+     * originally supplied values.
+     */
+    public boolean isSameNetworkAndPreference(
+            Network network, ConnectedAccessPointPreference connectedApPreference) {
+        return mNetwork.equals(network) && mConnectedApPreference == connectedApPreference;
+    }
+
+    /**
+     * Returns true if the most recent update to the NetworkCapabilities indicates a captive portal
+     * network and the Network was not lost in the interim.
+     */
+    public boolean isCaptivePortal() {
+        return mIsCaptivePortal;
+    }
+
+    /** Returns the currently associated network. */
+    public Network getNetwork() {
+        return mNetwork;
+    }
+}
diff --git a/src/com/android/settings/wifi/ConnectedAccessPointPreference.java b/src/com/android/settings/wifi/ConnectedAccessPointPreference.java
index e9e1560..def48e0 100644
--- a/src/com/android/settings/wifi/ConnectedAccessPointPreference.java
+++ b/src/com/android/settings/wifi/ConnectedAccessPointPreference.java
@@ -31,15 +31,12 @@
 public class ConnectedAccessPointPreference extends AccessPointPreference implements
         View.OnClickListener {
 
-    private final CaptivePortalStatus mCaptivePortalStatus;
     private OnGearClickListener mOnGearClickListener;
-    private boolean mCaptivePortalNetwork;
+    private boolean mIsCaptivePortal;
 
     public ConnectedAccessPointPreference(AccessPoint accessPoint, Context context,
-            UserBadgeCache cache, @DrawableRes int iconResId, boolean forSavedNetworks,
-            CaptivePortalStatus captivePortalStatus) {
+            UserBadgeCache cache, @DrawableRes int iconResId, boolean forSavedNetworks) {
         super(accessPoint, context, cache, iconResId, forSavedNetworks);
-        mCaptivePortalStatus = captivePortalStatus;
     }
 
     @Override
@@ -51,9 +48,8 @@
     public void refresh() {
         super.refresh();
 
-        mCaptivePortalNetwork = mCaptivePortalStatus.isCaptivePortalNetwork();
-        setShowDivider(mCaptivePortalNetwork);
-        if (mCaptivePortalNetwork) {
+        setShowDivider(mIsCaptivePortal);
+        if (mIsCaptivePortal) {
             setSummary(R.string.wifi_tap_to_sign_in);
         }
     }
@@ -71,8 +67,8 @@
         gear.setOnClickListener(this);
 
         final View gearNoBg = holder.findViewById(R.id.settings_button_no_background);
-        gearNoBg.setVisibility(mCaptivePortalNetwork ? View.INVISIBLE : View.VISIBLE);
-        gear.setVisibility(mCaptivePortalNetwork ? View.VISIBLE : View.INVISIBLE);
+        gearNoBg.setVisibility(mIsCaptivePortal ? View.INVISIBLE : View.VISIBLE);
+        gear.setVisibility(mIsCaptivePortal ? View.VISIBLE : View.INVISIBLE);
     }
 
     @Override
@@ -84,11 +80,15 @@
         }
     }
 
+    public void setCaptivePortal(boolean isCaptivePortal) {
+        if (mIsCaptivePortal != isCaptivePortal) {
+            mIsCaptivePortal = isCaptivePortal;
+            refresh();
+        }
+    }
+
     public interface OnGearClickListener {
         void onGearClick(ConnectedAccessPointPreference p);
     }
 
-    public interface CaptivePortalStatus {
-        boolean isCaptivePortalNetwork();
-    }
 }
diff --git a/src/com/android/settings/wifi/WifiSettings.java b/src/com/android/settings/wifi/WifiSettings.java
index 7c1b725..0f6a0bb 100644
--- a/src/com/android/settings/wifi/WifiSettings.java
+++ b/src/com/android/settings/wifi/WifiSettings.java
@@ -16,6 +16,7 @@
 
 package com.android.settings.wifi;
 
+import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
 import static android.os.UserManager.DISALLOW_CONFIG_WIFI;
 
 import android.annotation.NonNull;
@@ -27,14 +28,15 @@
 import android.content.res.Resources;
 import android.net.ConnectivityManager;
 import android.net.Network;
-import android.net.NetworkCapabilities;
 import android.net.NetworkInfo;
 import android.net.NetworkInfo.State;
+import android.net.NetworkRequest;
 import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiManager;
 import android.nfc.NfcAdapter;
 import android.os.Bundle;
 import android.os.Handler;
+import android.os.Looper;
 import android.os.PowerManager;
 import android.provider.Settings;
 import android.support.annotation.VisibleForTesting;
@@ -124,6 +126,7 @@
     private WifiManager.ActionListener mConnectListener;
     private WifiManager.ActionListener mSaveListener;
     private WifiManager.ActionListener mForgetListener;
+    private CaptivePortalNetworkCallback mCaptivePortalNetworkCallback;
 
     /**
      * The state of {@link #isUiRestricted()} at {@link #onCreate(Bundle)}}. This is neccesary to
@@ -400,6 +403,7 @@
     public void onStop() {
         getView().removeCallbacks(mUpdateAccessPointsRunnable);
         getView().removeCallbacks(mHideProgressBarRunnable);
+        unregisterCaptivePortalNetworkCallback();
         super.onStop();
     }
 
@@ -786,11 +790,9 @@
 
     @NonNull
     private ConnectedAccessPointPreference createConnectedAccessPointPreference(
-            AccessPoint accessPoint,
-            ConnectedAccessPointPreference.CaptivePortalStatus captivePortalStatus) {
+            AccessPoint accessPoint) {
         return new ConnectedAccessPointPreference(accessPoint, getPrefContext(), mUserBadgeCache,
-                R.drawable.ic_wifi_signal_0, false /* forSavedNetworks */,
-                captivePortalStatus);
+                R.drawable.ic_wifi_signal_0, false /* forSavedNetworks */);
     }
 
     /**
@@ -817,8 +819,9 @@
         }
 
         // Is the previous currently connected SSID different from the new one?
-        AccessPointPreference preference = (AccessPointPreference)
-            (mConnectedAccessPointPreferenceCategory.getPreference(0));
+        ConnectedAccessPointPreference preference =
+                (ConnectedAccessPointPreference)
+                        (mConnectedAccessPointPreferenceCategory.getPreference(0));
         // The AccessPoints need to be the same reference to ensure that updates are reflected
         // in the UI.
         if (preference.getAccessPoint() != connectedAp) {
@@ -829,8 +832,10 @@
 
         // Else same AP is connected, simply refresh the connected access point preference
         // (first and only access point in this category).
-        ((AccessPointPreference) mConnectedAccessPointPreferenceCategory.getPreference(0))
-                .refresh();
+        preference.refresh();
+        // Update any potential changes to the connected network and ensure that the callback is
+        // registered after an onStop lifecycle event.
+        registerCaptivePortalNetworkCallback(getCurrentWifiNetwork(), preference);
         return true;
     }
 
@@ -840,18 +845,19 @@
      */
     private void addConnectedAccessPointPreference(AccessPoint connectedAp) {
         final ConnectedAccessPointPreference pref =
-                createConnectedAccessPointPreference(
-                        connectedAp, this::isConnectedToCaptivePortalNetwork);
+                createConnectedAccessPointPreference(connectedAp);
+        registerCaptivePortalNetworkCallback(getCurrentWifiNetwork(), pref);
 
         // Launch details page or captive portal on click.
         pref.setOnPreferenceClickListener(
                 preference -> {
                     pref.getAccessPoint().saveWifiState(pref.getExtras());
-                    Network network = getConnectedWifiNetwork();
-                    if (isConnectedToCaptivePortalNetwork(network)) {
+                    if (mCaptivePortalNetworkCallback != null
+                            && mCaptivePortalNetworkCallback.isCaptivePortal()) {
                         ConnectivityManagerWrapper connectivityManagerWrapper =
                                 new ConnectivityManagerWrapper(mConnectivityManager);
-                        connectivityManagerWrapper.startCaptivePortalApp(network);
+                        connectivityManagerWrapper.startCaptivePortalApp(
+                                mCaptivePortalNetworkCallback.getNetwork());
                     } else {
                         launchNetworkDetailsFragment(pref);
                     }
@@ -874,6 +880,41 @@
         }
     }
 
+    private void registerCaptivePortalNetworkCallback(
+            Network wifiNetwork, ConnectedAccessPointPreference pref) {
+        if (wifiNetwork == null || pref == null) {
+            Log.w(TAG, "Network or Preference were null when registering callback.");
+            return;
+        }
+
+        if (mCaptivePortalNetworkCallback != null
+                && mCaptivePortalNetworkCallback.isSameNetworkAndPreference(wifiNetwork, pref)) {
+            return;
+        }
+
+        unregisterCaptivePortalNetworkCallback();
+
+        mCaptivePortalNetworkCallback = new CaptivePortalNetworkCallback(wifiNetwork, pref);
+        mConnectivityManager.registerNetworkCallback(
+                new NetworkRequest.Builder()
+                        .clearCapabilities()
+                        .addTransportType(TRANSPORT_WIFI)
+                        .build(),
+                mCaptivePortalNetworkCallback,
+                new Handler(Looper.getMainLooper()));
+    }
+
+    private void unregisterCaptivePortalNetworkCallback() {
+        if (mCaptivePortalNetworkCallback != null) {
+            try {
+                mConnectivityManager.unregisterNetworkCallback(mCaptivePortalNetworkCallback);
+            } catch (RuntimeException e) {
+                Log.e(TAG, "Unregistering CaptivePortalNetworkCallback failed.", e);
+            }
+            mCaptivePortalNetworkCallback = null;
+        }
+    }
+
     private void launchNetworkDetailsFragment(ConnectedAccessPointPreference pref) {
         new SubSettingLauncher(getContext())
                 .setTitle(getContext().getString(R.string.pref_title_network_details))
@@ -883,38 +924,15 @@
                 .launch();
     }
 
-    private boolean isConnectedToCaptivePortalNetwork() {
-        return isConnectedToCaptivePortalNetwork(getConnectedWifiNetwork());
-    }
-
-    private boolean isConnectedToCaptivePortalNetwork(Network network) {
-        if (mConnectivityManager == null || network == null) {
-            return false;
-        }
-        return WifiUtils.canSignIntoNetwork(mConnectivityManager.getNetworkCapabilities(network));
-    }
-
-    private Network getConnectedWifiNetwork() {
-        if (mConnectivityManager != null) {
-            Network networks[] = mConnectivityManager.getAllNetworks();
-            if (networks != null) {
-                for (Network network : networks) {
-                    NetworkCapabilities capabilities =
-                            mConnectivityManager.getNetworkCapabilities(network);
-                    if (capabilities != null
-                            && capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
-                        return network;
-                    }
-                }
-            }
-        }
-        return null;
+    private Network getCurrentWifiNetwork() {
+        return mWifiManager != null ? mWifiManager.getCurrentNetwork() : null;
     }
 
     /** Removes all preferences and hide the {@link #mConnectedAccessPointPreferenceCategory}. */
     private void removeConnectedAccessPointPreference() {
         mConnectedAccessPointPreferenceCategory.removeAll();
         mConnectedAccessPointPreferenceCategory.setVisible(false);
+        unregisterCaptivePortalNetworkCallback();
     }
 
     private void setAdditionalSettingsSummaries() {
diff --git a/src/com/android/settings/wifi/WifiSummaryUpdater.java b/src/com/android/settings/wifi/WifiSummaryUpdater.java
index 2c56d08..81c531b 100644
--- a/src/com/android/settings/wifi/WifiSummaryUpdater.java
+++ b/src/com/android/settings/wifi/WifiSummaryUpdater.java
@@ -20,14 +20,17 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.net.ConnectivityManager;
+import android.net.NetworkScoreManager;
+import android.net.wifi.WifiInfo;
 import android.net.wifi.WifiManager;
 import android.support.annotation.VisibleForTesting;
+import android.text.TextUtils;
+
 import com.android.settings.R;
 import com.android.settings.widget.SummaryUpdater;
 import com.android.settingslib.wifi.WifiStatusTracker;
 
-import static android.net.wifi.WifiInfo.removeDoubleQuotes;
-
 /**
  * Helper class that listeners to wifi callback and notify client when there is update in
  * wifi summary info.
@@ -46,14 +49,18 @@
     }
 
     public WifiSummaryUpdater(Context context, OnSummaryChangeListener listener) {
-        this(context, listener, new WifiStatusTracker(context.getSystemService(WifiManager.class)));
+        this(context, listener, null);
     }
 
     @VisibleForTesting
     public WifiSummaryUpdater(Context context, OnSummaryChangeListener listener,
         WifiStatusTracker wifiTracker) {
         super(context, listener);
-        mWifiTracker = wifiTracker;
+        mWifiTracker = wifiTracker != null ? wifiTracker :
+                new WifiStatusTracker(context, context.getSystemService(WifiManager.class),
+                context.getSystemService(NetworkScoreManager.class),
+                context.getSystemService(ConnectivityManager.class),
+                        this::notifyChangeIfNeeded);
         mReceiver = new BroadcastReceiver() {
             @Override
             public void onReceive(Context context, Intent intent) {
@@ -70,6 +77,7 @@
         } else {
             mContext.unregisterReceiver(mReceiver);
         }
+        mWifiTracker.setListening(register);
     }
 
     @Override
@@ -80,7 +88,12 @@
         if (!mWifiTracker.connected) {
             return mContext.getString(R.string.disconnected);
         }
-        return removeDoubleQuotes(mWifiTracker.ssid);
+        String ssid = WifiInfo.removeDoubleQuotes(mWifiTracker.ssid);
+        if (TextUtils.isEmpty(mWifiTracker.statusLabel)) {
+            return ssid;
+        }
+        return mContext.getResources().getString(
+                com.android.settingslib.R.string.preference_summary_default_combination,
+                ssid, mWifiTracker.statusLabel);
     }
-
 }
diff --git a/src/com/android/settings/wifi/tether/WifiTetherSwitchBarController.java b/src/com/android/settings/wifi/tether/WifiTetherSwitchBarController.java
index dc6c6c9..bdad9e6 100644
--- a/src/com/android/settings/wifi/tether/WifiTetherSwitchBarController.java
+++ b/src/com/android/settings/wifi/tether/WifiTetherSwitchBarController.java
@@ -27,6 +27,7 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.provider.Settings;
+import android.support.annotation.VisibleForTesting;
 
 import com.android.settings.datausage.DataSaverBackend;
 import com.android.settings.widget.SwitchWidgetController;
@@ -44,6 +45,16 @@
     private final ConnectivityManager mConnectivityManager;
     private final DataSaverBackend mDataSaverBackend;
     private final WifiManager mWifiManager;
+    @VisibleForTesting
+    final ConnectivityManager.OnStartTetheringCallback mOnStartTetheringCallback =
+            new ConnectivityManager.OnStartTetheringCallback() {
+                @Override
+                public void onTetheringFailed() {
+                    super.onTetheringFailed();
+                    mSwitchBar.setChecked(false);
+                    updateWifiSwitch();
+                }
+            };
 
     static {
         WIFI_INTENT_FILTER = new IntentFilter(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
@@ -92,7 +103,7 @@
     void startTether() {
         mSwitchBar.setEnabled(false);
         mConnectivityManager.startTethering(TETHERING_WIFI, true /* showProvisioningUi */,
-                NoOpOnStartTetheringCallback.newInstance(), new Handler(Looper.getMainLooper()));
+                mOnStartTetheringCallback, new Handler(Looper.getMainLooper()));
     }
 
     private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
diff --git a/tests/robotests/src/com/android/settings/accounts/RemoveAccountPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accounts/RemoveAccountPreferenceControllerTest.java
index 6020277..3df7c9d 100644
--- a/tests/robotests/src/com/android/settings/accounts/RemoveAccountPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accounts/RemoveAccountPreferenceControllerTest.java
@@ -32,8 +32,8 @@
 import android.app.Activity;
 import android.app.FragmentManager;
 import android.app.FragmentTransaction;
+import android.content.ComponentName;
 import android.content.Context;
-import android.content.Intent;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.UserHandle;
@@ -48,8 +48,13 @@
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.testutils.shadow.ShadowAccountManager;
 import com.android.settings.testutils.shadow.ShadowContentResolver;
+import com.android.settings.testutils.shadow.ShadowDevicePolicyManager;
+import com.android.settings.testutils.shadow.ShadowUserManager;
 import com.android.settings.wrapper.DevicePolicyManagerWrapper;
 
+import java.util.ArrayList;
+import java.util.List;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -60,6 +65,11 @@
 import org.robolectric.shadows.ShadowApplication;
 
 @RunWith(SettingsRobolectricTestRunner.class)
+@Config(
+    shadows = {
+        ShadowUserManager.class,
+        ShadowDevicePolicyManager.class
+    })
 public class RemoveAccountPreferenceControllerTest {
 
     private static final String KEY_REMOVE_ACCOUNT = "remove_account";
@@ -125,8 +135,21 @@
     @Test
     public void onClick_shouldNotStartConfirmDialogWhenModifyAccountsIsDisallowed() {
         when(mFragment.isAdded()).thenReturn(true);
-        when(mDevicePolicyManager.createAdminSupportIntent(UserManager.DISALLOW_MODIFY_ACCOUNTS))
-            .thenReturn(new Intent());
+
+        final int userId = UserHandle.myUserId();
+        mController.init(new Account("test", "test"), UserHandle.of(userId));
+
+        List<UserManager.EnforcingUser> enforcingUsers = new ArrayList<>();
+        enforcingUsers.add(new UserManager.EnforcingUser(userId,
+            UserManager.RESTRICTION_SOURCE_DEVICE_OWNER));
+        ComponentName componentName = new ComponentName("test", "test");
+        // Ensure that RestrictedLockUtils.checkIfRestrictionEnforced doesn't return null.
+        ShadowUserManager.getShadow().setUserRestrictionSources(
+            UserManager.DISALLOW_MODIFY_ACCOUNTS,
+            UserHandle.of(userId),
+            enforcingUsers);
+        ShadowDevicePolicyManager.getShadow().setDeviceOwnerComponentOnAnyUser(componentName);
+
         mController.onClick(null);
 
         verify(mFragmentTransaction, never()).add(
diff --git a/tests/robotests/src/com/android/settings/applications/appinfo/AppActionButtonPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/appinfo/AppActionButtonPreferenceControllerTest.java
index d7c2964..e571521 100644
--- a/tests/robotests/src/com/android/settings/applications/appinfo/AppActionButtonPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/applications/appinfo/AppActionButtonPreferenceControllerTest.java
@@ -79,6 +79,8 @@
     private AppInfoDashboardFragment mFragment;
     @Mock
     private ApplicationInfo mAppInfo;
+    @Mock
+    private PackageManager mPackageManager;
 
     private Context mContext;
     private AppActionButtonPreferenceController mController;
@@ -95,7 +97,9 @@
         ReflectionHelpers.setField(mController, "mDpm", mDevicePolicyManager);
         ReflectionHelpers.setField(mController, "mApplicationFeatureProvider",
                 mFeatureFactory.applicationFeatureProvider);
+        ReflectionHelpers.setField(mController, "mPm", mPackageManager);
         when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
+        when(mContext.getPackageManager()).thenReturn(mPackageManager);
         final PackageInfo packageInfo = mock(PackageInfo.class);
         packageInfo.applicationInfo = mAppInfo;
         when(mFragment.getPackageInfo()).thenReturn(packageInfo);
@@ -214,6 +218,25 @@
     }
 
     @Test
+    public void checkForceStop_isStateProtected_shouldDisableForceStop() {
+        ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider",
+            (InstantAppDataProvider) (i -> false));
+        final String packageName = "Package1";
+        final PackageInfo packageInfo = new PackageInfo();
+        packageInfo.packageName = packageName;
+        final ApplicationInfo appInfo = new ApplicationInfo();
+        appInfo.uid = 42;
+        appInfo.sourceDir = "source";
+        final ApplicationsState.AppEntry appEntry = new ApplicationsState.AppEntry(
+            mContext, appInfo, 0);
+        when(mPackageManager.isPackageStateProtected(packageName, 0)).thenReturn(true);
+
+        mController.checkForceStop(appEntry, packageInfo);
+
+        verify(mController.mActionButtons).setButton2Enabled(false);
+    }
+
+    @Test
     public void checkForceStop_hasActiveAdmin_shouldDisableForceStop() {
         ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider",
                 (InstantAppDataProvider) (i -> false));
diff --git a/tests/robotests/src/com/android/settings/applications/appinfo/TimeSpentInAppPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/appinfo/TimeSpentInAppPreferenceControllerTest.java
new file mode 100644
index 0000000..ab3e066
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/applications/appinfo/TimeSpentInAppPreferenceControllerTest.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2018 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.appinfo;
+
+import static android.content.Intent.EXTRA_PACKAGE_NAME;
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ResolveInfo;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settings.core.BasePreferenceController;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.Shadows;
+import org.robolectric.shadows.ShadowPackageManager;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class TimeSpentInAppPreferenceControllerTest {
+
+    private static final String TEST_KEY = "test_tey";
+    private static final Intent TEST_INTENT = new Intent(
+            TimeSpentInAppPreferenceController.SEE_TIME_IN_APP_TEMPLATE)
+            .putExtra(EXTRA_PACKAGE_NAME, "com.android.settings");
+
+    @Mock
+    private PreferenceScreen mScreen;
+
+    private Context mContext;
+    private ShadowPackageManager mPackageManager;
+    private TimeSpentInAppPreferenceController mController;
+    private Preference mPreference;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = RuntimeEnvironment.application;
+        mPackageManager = Shadows.shadowOf(mContext.getPackageManager());
+        mController = new TimeSpentInAppPreferenceController(mContext, TEST_KEY);
+        mPreference = new Preference(mContext);
+        when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
+    }
+
+    @Test
+    public void noPackageName_shouldBeDisabled() {
+        mController.setPackageName(null);
+
+        assertThat(mController.getAvailabilityStatus())
+                .isEqualTo(BasePreferenceController.DISABLED_UNSUPPORTED);
+    }
+
+    @Test
+    public void noIntentHandler_shouldBeDisabled() {
+        mController.setPackageName(TEST_INTENT.getStringExtra(EXTRA_PACKAGE_NAME));
+
+        assertThat(mController.getAvailabilityStatus())
+                .isEqualTo(BasePreferenceController.DISABLED_UNSUPPORTED);
+    }
+
+    @Test
+    public void hasIntentHandler_shouldBeAvailable() {
+        mPackageManager.addResolveInfoForIntent(TEST_INTENT, new ResolveInfo());
+        mController.setPackageName(TEST_INTENT.getStringExtra(EXTRA_PACKAGE_NAME));
+
+        assertThat(mController.getAvailabilityStatus())
+                .isEqualTo(BasePreferenceController.AVAILABLE);
+
+        mController.displayPreference(mScreen);
+
+        final Intent intent = mPreference.getIntent();
+        assertThat(intent.getAction()).isEqualTo(TEST_INTENT.getAction());
+        assertThat(intent.getStringExtra(EXTRA_PACKAGE_NAME))
+                .isEqualTo(TEST_INTENT.getStringExtra(EXTRA_PACKAGE_NAME));
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/applications/manageapplications/ManageApplicationsTest.java b/tests/robotests/src/com/android/settings/applications/manageapplications/ManageApplicationsTest.java
index f60c7b0..fb7b59d 100644
--- a/tests/robotests/src/com/android/settings/applications/manageapplications/ManageApplicationsTest.java
+++ b/tests/robotests/src/com/android/settings/applications/manageapplications/ManageApplicationsTest.java
@@ -16,6 +16,8 @@
 
 package com.android.settings.applications.manageapplications;
 
+import static android.support.v7.widget.RecyclerView.SCROLL_STATE_DRAGGING;
+import static android.support.v7.widget.RecyclerView.SCROLL_STATE_IDLE;
 import static com.android.settings.applications.manageapplications.AppFilterRegistry.FILTER_APPS_ALL;
 import static com.android.settings.applications.manageapplications.ManageApplications.LIST_TYPE_MAIN;
 import static com.android.settings.applications.manageapplications.ManageApplications.LIST_TYPE_NOTIFICATION;
@@ -229,6 +231,40 @@
         verify(loadingViewController).showContent(true /* animate */);
     }
 
+    @Test
+    public void notifyItemChange_recyclerViewIdle_shouldNotify() {
+        final RecyclerView recyclerView = mock(RecyclerView.class);
+        final ManageApplications.ApplicationsAdapter adapter =
+                spy(new ManageApplications.ApplicationsAdapter(mState,
+                        mock(ManageApplications.class),
+                        AppFilterRegistry.getInstance().get(FILTER_APPS_ALL), new Bundle()));
+
+        adapter.onAttachedToRecyclerView(recyclerView);
+        adapter.mOnScrollListener.onScrollStateChanged(recyclerView, SCROLL_STATE_IDLE);
+        adapter.mOnScrollListener.postNotifyItemChange(0 /* index */);
+
+        verify(adapter).notifyItemChanged(0);
+    }
+
+    @Test
+    public void notifyItemChange_recyclerViewScrolling_shouldNotifyWhenIdle() {
+        final RecyclerView recyclerView = mock(RecyclerView.class);
+        final ManageApplications.ApplicationsAdapter adapter =
+                spy(new ManageApplications.ApplicationsAdapter(mState,
+                        mock(ManageApplications.class),
+                        AppFilterRegistry.getInstance().get(FILTER_APPS_ALL), new Bundle()));
+
+        adapter.onAttachedToRecyclerView(recyclerView);
+        adapter.mOnScrollListener.onScrollStateChanged(recyclerView, SCROLL_STATE_DRAGGING);
+        adapter.mOnScrollListener.postNotifyItemChange(0 /* index */);
+
+        verify(adapter, never()).notifyItemChanged(0);
+        verify(adapter, never()).notifyDataSetChanged();
+
+        adapter.mOnScrollListener.onScrollStateChanged(recyclerView, SCROLL_STATE_IDLE);
+        verify(adapter).notifyDataSetChanged();
+    }
+
     private void setUpOptionMenus() {
         when(mMenu.findItem(anyInt())).thenAnswer(invocation -> {
             final Object[] args = invocation.getArguments();
diff --git a/tests/robotests/src/com/android/settings/dashboard/conditional/ConditionTest.java b/tests/robotests/src/com/android/settings/dashboard/conditional/ConditionTest.java
index 0333ae0..6d56731 100644
--- a/tests/robotests/src/com/android/settings/dashboard/conditional/ConditionTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/conditional/ConditionTest.java
@@ -27,7 +27,7 @@
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.IntentFilter;
-import android.graphics.drawable.Icon;
+import android.graphics.drawable.Drawable;
 
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
@@ -120,7 +120,7 @@
         }
 
         @Override
-        public Icon getIcon() {
+        public Drawable getIcon() {
             return null;
         }
 
diff --git a/tests/robotests/src/com/android/settings/datetime/timezone/RegionSearchPickerTest.java b/tests/robotests/src/com/android/settings/datetime/timezone/RegionSearchPickerTest.java
index b2c7f03..8da9cbf 100644
--- a/tests/robotests/src/com/android/settings/datetime/timezone/RegionSearchPickerTest.java
+++ b/tests/robotests/src/com/android/settings/datetime/timezone/RegionSearchPickerTest.java
@@ -16,7 +16,20 @@
 
 package com.android.settings.datetime.timezone;
 
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import android.app.Activity;
+import android.app.Fragment;
+import android.widget.Filter;
+import android.widget.LinearLayout;
+
 import com.android.settings.datetime.timezone.BaseTimeZoneAdapter.AdapterItem;
+import com.android.settings.datetime.timezone.BaseTimeZoneAdapter.ItemViewHolder;
+import com.android.settings.datetime.timezone.RegionSearchPicker.RegionItem;
 import com.android.settings.datetime.timezone.model.TimeZoneData;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 
@@ -24,17 +37,23 @@
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.robolectric.Robolectric;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Locale;
 
-import static com.google.common.truth.Truth.assertThat;
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
 @RunWith(SettingsRobolectricTestRunner.class)
+@Config(shadows = {
+        RegionSearchPickerTest.ShadowBaseTimeZonePicker.class,
+        RegionSearchPickerTest.ShadowFragment.class,
+    }
+)
 public class RegionSearchPickerTest {
 
     @Test
@@ -44,16 +63,90 @@
         CountryZonesFinder finder = mock(CountryZonesFinder.class);
         when(finder.lookupAllCountryIsoCodes()).thenReturn(regionList);
 
-        RegionSearchPicker picker = new RegionSearchPicker() {
-            @Override
-            protected Locale getLocale() {
-                return Locale.US;
-            }
-        };
+        RegionSearchPicker picker = new RegionSearchPicker();
         BaseTimeZoneAdapter adapter = picker.createAdapter(new TimeZoneData(finder));
         assertEquals(1, adapter.getItemCount());
         AdapterItem item = adapter.getItem(0);
         assertEquals("United States", item.getTitle().toString());
         assertThat(Arrays.asList(item.getSearchKeys())).contains("United States");
     }
+
+    // Test RegionSearchPicker does not crash due to the wrong assumption that no view is clicked
+    // before all views are updated and after internal data structure is updated for text filtering.
+    // This test mocks the text filtering event and emit click event immediately
+    // http://b/75322108
+    @Test
+    public void clickItemView_duringRegionSearch_shouldNotCrash() {
+        List regionList = new ArrayList();
+        regionList.add("US");
+        CountryZonesFinder finder = mock(CountryZonesFinder.class);
+        when(finder.lookupAllCountryIsoCodes()).thenReturn(regionList);
+
+        // Prepare the picker and adapter
+        RegionSearchPicker picker = new RegionSearchPicker();
+        BaseTimeZoneAdapter<RegionItem> adapter = picker.createAdapter(new TimeZoneData(finder));
+        // Prepare and bind a new ItemViewHolder with United States
+        ItemViewHolder viewHolder = adapter.onCreateViewHolder(
+                new LinearLayout(RuntimeEnvironment.application), 0);
+        adapter.onBindViewHolder(viewHolder, 0);
+        assertEquals(1, adapter.getItemCount());
+
+        // Pretend to search for a unknown region and no result is found.
+        FilterWrapper filterWrapper = new FilterWrapper(adapter.getFilter());
+        filterWrapper.publishEmptyResult("Unknown region 1");
+
+        // Assert that the adapter should have been updated with no item
+        assertEquals(0, adapter.getItemCount());
+        viewHolder.itemView.performClick(); // This should not crash
+    }
+
+    // FilterResults is a protected inner class. Use FilterWrapper to create an empty FilterResults
+    // instance.
+    private static class FilterWrapper extends Filter {
+
+        private final BaseTimeZoneAdapter.ArrayFilter mFilter;
+
+        private FilterWrapper(BaseTimeZoneAdapter.ArrayFilter filter) {
+            mFilter = filter;
+        }
+
+        @Override
+        protected FilterResults performFiltering(CharSequence charSequence) {
+            return null;
+        }
+
+        private void publishEmptyResult(CharSequence charSequence) {
+            FilterResults filterResults = new FilterResults();
+            filterResults.count = 0;
+            filterResults.values = new ArrayList<>();
+            publishResults(charSequence, filterResults);
+        }
+
+        @Override
+        protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
+            mFilter.publishResults(charSequence, filterResults);
+        }
+    }
+
+    // Robolectric can't start android.app.Fragment with support library v4 resources. Pretend
+    // the fragment has started, and provide the objects in context here.
+    @Implements(BaseTimeZonePicker.class)
+    public static class ShadowBaseTimeZonePicker extends ShadowFragment {
+
+        @Implementation
+        protected Locale getLocale() {
+            return Locale.US;
+        }
+    }
+
+    @Implements(Fragment.class)
+    public static class ShadowFragment {
+
+        private Activity mActivity = Robolectric.setupActivity(Activity.class);
+
+        @Implementation
+        public final Activity getActivity() {
+            return mActivity;
+        }
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/display/ColorModePreferenceFragmentTest.java b/tests/robotests/src/com/android/settings/display/ColorModePreferenceFragmentTest.java
index 4352e1c..e962441 100644
--- a/tests/robotests/src/com/android/settings/display/ColorModePreferenceFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/display/ColorModePreferenceFragmentTest.java
@@ -73,13 +73,15 @@
         when(mFragment.getContext()).thenReturn(RuntimeEnvironment.application);
         List<? extends CandidateInfo> candidates = mFragment.getCandidates();
 
-        assertThat(candidates.size()).isEqualTo(3);
+        assertThat(candidates.size()).isEqualTo(4);
         assertThat(candidates.get(0).getKey())
                 .isEqualTo(ColorModePreferenceFragment.KEY_COLOR_MODE_NATURAL);
         assertThat(candidates.get(1).getKey())
                 .isEqualTo(ColorModePreferenceFragment.KEY_COLOR_MODE_BOOSTED);
         assertThat(candidates.get(2).getKey())
                 .isEqualTo(ColorModePreferenceFragment.KEY_COLOR_MODE_SATURATED);
+        assertThat(candidates.get(3).getKey())
+                .isEqualTo(ColorModePreferenceFragment.KEY_COLOR_MODE_AUTOMATIC);
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryEntryTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryEntryTest.java
index 21b1d29..b6be9ee 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryEntryTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryEntryTest.java
@@ -39,6 +39,8 @@
 import org.mockito.junit.MockitoRule;
 import org.robolectric.RobolectricTestRunner;
 
+import java.util.Locale;
+
 @RunWith(RobolectricTestRunner.class)
 public class BatteryEntryTest {
 
@@ -148,4 +150,17 @@
 
         assertThat(entry.extractPackagesFromSipper(entry.sipper)).isEqualTo(entry.sipper.mPackages);
     }
+
+    @Test
+    public void testUidCache_switchLocale_shouldCleanCache() {
+        BatteryEntry.stopRequestQueue();
+
+        Locale.setDefault(new Locale("en_US"));
+        BatteryEntry.sUidCache.put(Integer.toString(APP_UID), null);
+        assertThat(BatteryEntry.sUidCache).isNotEmpty();
+
+        Locale.setDefault(new Locale("zh_TW"));
+        createBatteryEntryForApp();
+        assertThat(BatteryEntry.sUidCache).isEmpty(); // check if cache is clear
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/tips/RestrictAppTipTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/tips/RestrictAppTipTest.java
index 7fe617e..c23311b 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/tips/RestrictAppTipTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/tips/RestrictAppTipTest.java
@@ -172,11 +172,11 @@
         verify(mMetricsFeatureProvider).action(mContext,
                 MetricsProto.MetricsEvent.ACTION_APP_RESTRICTION_TIP_LIST,
                 PACKAGE_NAME,
-                Pair.create(MetricsProto.MetricsEvent.FIELD_CONTEXT, ANOMALY_WAKEUP));
+                Pair.create(MetricsProto.MetricsEvent.FIELD_ANOMALY_TYPE, ANOMALY_WAKEUP));
         verify(mMetricsFeatureProvider).action(mContext,
                 MetricsProto.MetricsEvent.ACTION_APP_RESTRICTION_TIP_LIST,
                 PACKAGE_NAME,
-                Pair.create(MetricsProto.MetricsEvent.FIELD_CONTEXT, ANOMALY_WAKELOCK));
+                Pair.create(MetricsProto.MetricsEvent.FIELD_ANOMALY_TYPE, ANOMALY_WAKELOCK));
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/notification/NotificationAppPreferenceTest.java b/tests/robotests/src/com/android/settings/notification/NotificationAppPreferenceTest.java
index 4ac7527..80780ac 100644
--- a/tests/robotests/src/com/android/settings/notification/NotificationAppPreferenceTest.java
+++ b/tests/robotests/src/com/android/settings/notification/NotificationAppPreferenceTest.java
@@ -211,28 +211,4 @@
 
         assertThat(toggle.getContentDescription()).isEqualTo(label);
     }
-
-    @Test
-    public void setSummary_showSummaryContainer() {
-        final NotificationAppPreference preference = new NotificationAppPreference(mContext);
-        View rootView = View.inflate(mContext, R.layout.preference_app, null /* parent */);
-        PreferenceViewHolder holder = PreferenceViewHolder.createInstanceForTests(rootView);
-        preference.setSummary("test");
-        preference.onBindViewHolder(holder);
-
-        assertThat(holder.findViewById(R.id.summary_container).getVisibility())
-                .isEqualTo(View.VISIBLE);
-    }
-
-    @Test
-    public void noSummary_hideSummaryContainer() {
-        final NotificationAppPreference preference = new NotificationAppPreference(mContext);
-        View rootView = View.inflate(mContext, R.layout.preference_app, null /* parent */);
-        PreferenceViewHolder holder = PreferenceViewHolder.createInstanceForTests(rootView);
-        preference.setSummary(null);
-        preference.onBindViewHolder(holder);
-
-        assertThat(holder.findViewById(R.id.summary_container).getVisibility())
-                .isEqualTo(View.GONE);
-    }
 }
diff --git a/tests/robotests/src/com/android/settings/notification/RecentNotifyingAppsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/RecentNotifyingAppsPreferenceControllerTest.java
index 13826b2..3447703 100644
--- a/tests/robotests/src/com/android/settings/notification/RecentNotifyingAppsPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/RecentNotifyingAppsPreferenceControllerTest.java
@@ -290,7 +290,7 @@
 
         mController.displayPreference(mScreen);
 
-        verify(mCategory).addPreference(argThat(summaryMatches("0 minutes ago")));
+        verify(mCategory).addPreference(argThat(summaryMatches("Just now")));
     }
 
     private static ArgumentMatcher<Preference> summaryMatches(String expected) {
diff --git a/tests/robotests/src/com/android/settings/password/SetupChooseLockPatternTest.java b/tests/robotests/src/com/android/settings/password/SetupChooseLockPatternTest.java
index a98db11..63bf711 100644
--- a/tests/robotests/src/com/android/settings/password/SetupChooseLockPatternTest.java
+++ b/tests/robotests/src/com/android/settings/password/SetupChooseLockPatternTest.java
@@ -29,6 +29,8 @@
 import android.widget.Button;
 
 import com.android.internal.widget.LockPatternView;
+import com.android.internal.widget.LockPatternView.Cell;
+import com.android.internal.widget.LockPatternView.DisplayMode;
 import com.android.settings.R;
 import com.android.settings.SetupRedactionInterstitial;
 import com.android.settings.password.ChooseLockPattern.ChooseLockPatternFragment;
@@ -47,6 +49,9 @@
 import org.robolectric.shadows.ShadowAlertDialog;
 import org.robolectric.shadows.ShadowPackageManager;
 import org.robolectric.util.ReflectionHelpers;
+import org.robolectric.util.ReflectionHelpers.ClassParameter;
+
+import java.util.Arrays;
 
 @RunWith(SettingsRobolectricTestRunner.class)
 @Config(shadows = {
@@ -120,16 +125,28 @@
 
     @Test
     public void skipButton_shouldBeVisible_duringNonFingerprintFlow() {
-        Button button = mActivity.findViewById(R.id.footerLeftButton);
-        assertThat(button).isNotNull();
-        assertThat(button.getVisibility()).isEqualTo(View.VISIBLE);
+        Button skipButton = mActivity.findViewById(R.id.skip_button);
+        assertThat(skipButton).isNotNull();
+        assertThat(skipButton.getVisibility()).isEqualTo(View.VISIBLE);
 
-        button.performClick();
+        skipButton.performClick();
         AlertDialog chooserDialog = ShadowAlertDialog.getLatestAlertDialog();
         assertThat(chooserDialog).isNotNull();
     }
 
     @Test
+    public void clearButton_shouldBeVisible_duringRetryStage() {
+        enterPattern();
+
+        Button clearButton = mActivity.findViewById(R.id.footerLeftButton);
+        assertThat(clearButton.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(clearButton.isEnabled()).isTrue();
+
+        clearButton.performClick();
+        assertThat(findFragment(mActivity).mChosenPattern).isNull();
+    }
+
+    @Test
     public void skipButton_shouldNotBeVisible_duringFingerprintFlow() {
         mActivity = Robolectric.buildActivity(
                 SetupChooseLockPattern.class,
@@ -140,13 +157,32 @@
                                 .setForFingerprint(true)
                                 .build()))
                 .setup().get();
-        Button button = mActivity.findViewById(R.id.footerLeftButton);
-        assertThat(button).isNotNull();
-        assertThat(button.getVisibility()).isEqualTo(View.GONE);
+        Button skipButton = mActivity.findViewById(R.id.skip_button);
+        assertThat(skipButton).isNotNull();
+        assertThat(skipButton.getVisibility()).isEqualTo(View.GONE);
     }
 
     private ChooseLockPatternFragment findFragment(Activity activity) {
         return (ChooseLockPatternFragment)
                 activity.getFragmentManager().findFragmentById(R.id.main_content);
     }
+
+    private void enterPattern() {
+        LockPatternView lockPatternView = mActivity.findViewById(R.id.lockPattern);
+        lockPatternView.setPattern(
+                DisplayMode.Animate,
+                Arrays.asList(
+                        createCell(0, 0),
+                        createCell(0, 1),
+                        createCell(1, 1),
+                        createCell(1, 0)));
+        ReflectionHelpers.callInstanceMethod(lockPatternView, "notifyPatternDetected");
+    }
+
+    private Cell createCell(int row, int column) {
+        return ReflectionHelpers.callConstructor(
+                Cell.class,
+                ClassParameter.from(int.class, row),
+                ClassParameter.from(int.class, column));
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/slices/FakeUnavailablePreferenceController.java b/tests/robotests/src/com/android/settings/slices/FakeUnavailablePreferenceController.java
new file mode 100644
index 0000000..a7e5d75
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/slices/FakeUnavailablePreferenceController.java
@@ -0,0 +1,21 @@
+package com.android.settings.slices;
+
+import android.content.Context;
+import android.provider.Settings;
+
+import com.android.settings.core.BasePreferenceController;
+
+public class FakeUnavailablePreferenceController extends BasePreferenceController {
+
+    public static final String AVAILABILITY_KEY = "fake_availability_key";
+
+    public FakeUnavailablePreferenceController(Context context) {
+        super(context, "key");
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        return Settings.System.getInt(mContext.getContentResolver(),
+                AVAILABILITY_KEY, 0);
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/slices/SliceBuilderUtilsTest.java b/tests/robotests/src/com/android/settings/slices/SliceBuilderUtilsTest.java
index d0c0326..d21fc05 100644
--- a/tests/robotests/src/com/android/settings/slices/SliceBuilderUtilsTest.java
+++ b/tests/robotests/src/com/android/settings/slices/SliceBuilderUtilsTest.java
@@ -17,12 +17,14 @@
 package com.android.settings.slices;
 
 import static com.google.common.truth.Truth.assertThat;
+
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.spy;
 
 import android.content.ContentResolver;
 import android.content.Context;
 import android.net.Uri;
+import android.provider.Settings;
 import android.provider.SettingsSlicesContract;
 import android.util.Pair;
 
@@ -132,7 +134,7 @@
     @Test
     public void testGetPreferenceController_buildsMatchingController() {
         BasePreferenceController controller =
-            SliceBuilderUtils.getPreferenceController(mContext, getDummyData());
+                SliceBuilderUtils.getPreferenceController(mContext, getDummyData());
 
         assertThat(controller).isInstanceOf(FakeToggleController.class);
     }
@@ -140,7 +142,7 @@
     @Test
     public void testGetPreferenceController_contextOnly_buildsMatchingController() {
         BasePreferenceController controller =
-            SliceBuilderUtils.getPreferenceController(mContext, getDummyData(PREF_CONTROLLER2));
+                SliceBuilderUtils.getPreferenceController(mContext, getDummyData(PREF_CONTROLLER2));
 
         assertThat(controller).isInstanceOf(FakeContextOnlyPreferenceController.class);
     }
@@ -251,6 +253,54 @@
         assertThat(pathPair.second).isEqualTo(KEY + "/" + KEY);
     }
 
+    @Test
+    public void testUnsupportedSlice_validTitleSummary() {
+        SliceData data = getDummyData(FakeUnavailablePreferenceController.class.getName());
+        Settings.System.putInt(mContext.getContentResolver(),
+                FakeUnavailablePreferenceController.AVAILABILITY_KEY,
+                BasePreferenceController.DISABLED_UNSUPPORTED);
+
+        Slice slice = SliceBuilderUtils.buildSlice(mContext, data);
+
+        assertThat(slice).isNotNull();
+    }
+
+    @Test
+    public void testDisabledForUserSlice_validTitleSummary() {
+        SliceData data = getDummyData(FakeUnavailablePreferenceController.class.getName());
+        Settings.System.putInt(mContext.getContentResolver(),
+                FakeUnavailablePreferenceController.AVAILABILITY_KEY,
+                BasePreferenceController.DISABLED_FOR_USER);
+
+        Slice slice = SliceBuilderUtils.buildSlice(mContext, data);
+
+        assertThat(slice).isNotNull();
+    }
+
+    @Test
+    public void testDisabledDependententSettingSlice_validTitleSummary() {
+        SliceData data = getDummyData(FakeUnavailablePreferenceController.class.getName());
+        Settings.System.putInt(mContext.getContentResolver(),
+                FakeUnavailablePreferenceController.AVAILABILITY_KEY,
+                BasePreferenceController.DISABLED_DEPENDENT_SETTING);
+
+        Slice slice = SliceBuilderUtils.buildSlice(mContext, data);
+
+        assertThat(slice).isNotNull();
+    }
+
+    @Test
+    public void testUnavailableUnknownSlice_validTitleSummary() {
+        SliceData data = getDummyData(FakeUnavailablePreferenceController.class.getName());
+        Settings.System.putInt(mContext.getContentResolver(),
+                FakeUnavailablePreferenceController.AVAILABILITY_KEY,
+                BasePreferenceController.UNAVAILABLE_UNKNOWN);
+
+        Slice slice = SliceBuilderUtils.buildSlice(mContext, data);
+
+        assertThat(slice).isNotNull();
+    }
+
     private SliceData getDummyData() {
         return getDummyData(PREF_CONTROLLER, SUMMARY);
     }
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowDevicePolicyManager.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowDevicePolicyManager.java
index 77daae0..7e2c3cc 100644
--- a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowDevicePolicyManager.java
+++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowDevicePolicyManager.java
@@ -5,12 +5,14 @@
 import android.app.admin.DevicePolicyManager;
 import android.content.ComponentName;
 
+import org.robolectric.RuntimeEnvironment;
 import org.robolectric.annotation.Implementation;
 import org.robolectric.annotation.Implements;
 
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Objects;
+import org.robolectric.shadow.api.Shadow;
 
 /**
  * This shadow if using {@link ShadowDevicePolicyManagerWrapper} is not possible.
@@ -19,6 +21,7 @@
 public class ShadowDevicePolicyManager extends org.robolectric.shadows.ShadowDevicePolicyManager {
     private Map<Integer, CharSequence> mSupportMessagesMap = new HashMap<>();
     private boolean mIsAdminActiveAsUser = false;
+    ComponentName mDeviceOwnerComponentName;
 
     public void setShortSupportMessageForUser(ComponentName admin, int userHandle, String message) {
         mSupportMessagesMap.put(Objects.hash(admin, userHandle), message);
@@ -38,4 +41,17 @@
     public void setIsAdminActiveAsUser(boolean active) {
         mIsAdminActiveAsUser = active;
     }
+
+    public static ShadowDevicePolicyManager getShadow() {
+        return (ShadowDevicePolicyManager) Shadow.extract(
+            RuntimeEnvironment.application.getSystemService(DevicePolicyManager.class));
+    }
+
+    public ComponentName getDeviceOwnerComponentOnAnyUser() {
+        return mDeviceOwnerComponentName;
+    }
+
+    public void setDeviceOwnerComponentOnAnyUser(ComponentName admin) {
+        mDeviceOwnerComponentName = admin;
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/wifi/ConnectedAccessPointPreferenceTest.java b/tests/robotests/src/com/android/settings/wifi/ConnectedAccessPointPreferenceTest.java
index b9b29d2..452fe03 100644
--- a/tests/robotests/src/com/android/settings/wifi/ConnectedAccessPointPreferenceTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/ConnectedAccessPointPreferenceTest.java
@@ -17,6 +17,7 @@
 package com.android.settings.wifi;
 
 import static com.google.common.truth.Truth.assertThat;
+
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -32,7 +33,6 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
-import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
 import org.robolectric.RuntimeEnvironment;
 
@@ -45,8 +45,6 @@
     private View mView;
     @Mock
     private ConnectedAccessPointPreference.OnGearClickListener mOnGearClickListener;
-    @Mock
-    private ConnectedAccessPointPreference.CaptivePortalStatus mCaptivePortalStatus;
     private Context mContext;
     private ConnectedAccessPointPreference mConnectedAccessPointPreference;
 
@@ -56,7 +54,7 @@
 
         mContext = RuntimeEnvironment.application;
         mConnectedAccessPointPreference = new ConnectedAccessPointPreference(mAccessPoint, mContext,
-                null, 0 /* iconResId */, false /* forSavedNetworks */, mCaptivePortalStatus);
+                null, 0 /* iconResId */, false /* forSavedNetworks */);
         mConnectedAccessPointPreference.setOnGearClickListener(mOnGearClickListener);
     }
 
@@ -78,15 +76,13 @@
 
     @Test
     public void testCaptivePortalStatus_isCaptivePortal_dividerDrawn() {
-        Mockito.when(mCaptivePortalStatus.isCaptivePortalNetwork()).thenReturn(true);
-        mConnectedAccessPointPreference.refresh();
+        mConnectedAccessPointPreference.setCaptivePortal(true);
         assertThat(mConnectedAccessPointPreference.shouldShowDivider()).isTrue();
     }
 
     @Test
     public void testCaptivePortalStatus_isNotCaptivePortal_dividerNotDrawn() {
-        Mockito.when(mCaptivePortalStatus.isCaptivePortalNetwork()).thenReturn(false);
-        mConnectedAccessPointPreference.refresh();
+        mConnectedAccessPointPreference.setCaptivePortal(false);
         assertThat(mConnectedAccessPointPreference.shouldShowDivider()).isFalse();
     }
 
diff --git a/tests/robotests/src/com/android/settings/wifi/WifiMasterSwitchPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/wifi/WifiMasterSwitchPreferenceControllerTest.java
index f6acafd..69cfb10 100644
--- a/tests/robotests/src/com/android/settings/wifi/WifiMasterSwitchPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/WifiMasterSwitchPreferenceControllerTest.java
@@ -17,6 +17,7 @@
 package com.android.settings.wifi;
 
 import static com.google.common.truth.Truth.assertThat;
+
 import static org.mockito.Matchers.any;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
@@ -25,6 +26,7 @@
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.IntentFilter;
+import android.net.NetworkScoreManager;
 import android.net.wifi.WifiManager;
 import android.support.v7.preference.Preference.OnPreferenceChangeListener;
 import android.support.v7.preference.PreferenceScreen;
@@ -51,6 +53,8 @@
     private PreferenceScreen mScreen;
     @Mock
     private MasterSwitchPreference mPreference;
+    @Mock
+    private NetworkScoreManager mNetworkScoreManager;
 
     private Context mContext;
     private WifiMasterSwitchPreferenceController mController;
@@ -61,6 +65,7 @@
         MockitoAnnotations.initMocks(this);
         mMetricsFeatureProvider = FakeFeatureFactory.setupForTest().getMetricsFeatureProvider();
         mContext = spy(RuntimeEnvironment.application.getApplicationContext());
+        when(mContext.getSystemService(NetworkScoreManager.class)).thenReturn(mNetworkScoreManager);
         mController = new WifiMasterSwitchPreferenceController(mContext, mMetricsFeatureProvider);
         when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
         when(mContext.getSystemService(Context.WIFI_SERVICE)).thenReturn(mWifiManager);
diff --git a/tests/robotests/src/com/android/settings/wifi/WifiSummaryUpdaterTest.java b/tests/robotests/src/com/android/settings/wifi/WifiSummaryUpdaterTest.java
index fcfadda..f55c57f 100644
--- a/tests/robotests/src/com/android/settings/wifi/WifiSummaryUpdaterTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/WifiSummaryUpdaterTest.java
@@ -36,45 +36,41 @@
 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.RuntimeEnvironment;
 
 @RunWith(SettingsRobolectricTestRunner.class)
 public class WifiSummaryUpdaterTest {
-
-    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
-    private WifiManager mWifiManager;
-    @Mock
-    private SummaryListener mListener;
+    @Mock private WifiStatusTracker mWifiTracker;
+    @Mock private SummaryListener mListener;
 
     private Context mContext;
     private WifiSummaryUpdater mSummaryUpdater;
-    private WifiStatusTracker mWifiTracker;
+
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-        mWifiTracker = new WifiStatusTracker(mWifiManager);
-
         mContext = spy(RuntimeEnvironment.application.getApplicationContext());
         mSummaryUpdater = new WifiSummaryUpdater(mContext, mListener, mWifiTracker);
     }
 
     @Test
-    public void register_true_shouldRegisterListener() {
+    public void register_true_shouldRegisterListenerAndTracker() {
         mSummaryUpdater.register(true);
 
         verify(mContext).registerReceiver(any(BroadcastReceiver.class), any(IntentFilter.class));
+        verify(mWifiTracker).setListening(true);
     }
 
     @Test
-    public void register_false_shouldUnregisterListener() {
+    public void register_false_shouldUnregisterListenerAndTracker() {
         mSummaryUpdater.register(true);
         mSummaryUpdater.register(false);
 
         verify(mContext).unregisterReceiver(any(BroadcastReceiver.class));
+        verify(mWifiTracker).setListening(false);
     }
 
     @Test
@@ -82,7 +78,6 @@
         mSummaryUpdater.register(true);
         mContext.sendBroadcast(new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION));
 
-
         verify(mListener).onSummaryChanged(anyString());
     }
 
@@ -91,7 +86,6 @@
         mSummaryUpdater.register(true);
         mContext.sendBroadcast(new Intent(WifiManager.RSSI_CHANGED_ACTION));
 
-
         verify(mListener).onSummaryChanged(anyString());
     }
 
@@ -121,6 +115,16 @@
         assertThat(mSummaryUpdater.getSummary()).isEqualTo("Test Ssid");
     }
 
+    @Test
+    public void getSummary_wifiConnected_withSpeedLabel_shouldReturnSsid_withSpeedLabel() {
+        mWifiTracker.enabled = true;
+        mWifiTracker.connected = true;
+        mWifiTracker.ssid = "Test Ssid";
+        mWifiTracker.statusLabel = "Very Fast";
+
+        assertThat(mSummaryUpdater.getSummary()).isEqualTo("Test Ssid / Very Fast");
+    }
+
     private class SummaryListener implements OnSummaryChangeListener {
         String summary;
 
diff --git a/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherSwitchBarControllerTest.java b/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherSwitchBarControllerTest.java
index 660f335..db8baab 100644
--- a/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherSwitchBarControllerTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherSwitchBarControllerTest.java
@@ -22,6 +22,8 @@
 import static org.mockito.Mockito.when;
 
 import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.NetworkPolicyManager;
 import android.net.wifi.WifiManager;
 import android.provider.Settings;
 
@@ -40,9 +42,14 @@
 public class WifiTetherSwitchBarControllerTest {
     @Mock
     private WifiManager mWifiManager;
+    @Mock
+    private ConnectivityManager mConnectivityManager;
+    @Mock
+    private NetworkPolicyManager mNetworkPolicyManager;
 
     private Context mContext;
     private SwitchBar mSwitchBar;
+    private WifiTetherSwitchBarController mController;
 
     @Before
     public void setUp() {
@@ -51,6 +58,13 @@
         mContext = spy(RuntimeEnvironment.application);
         mSwitchBar = new SwitchBar(mContext);
         when(mContext.getSystemService(Context.WIFI_SERVICE)).thenReturn(mWifiManager);
+        when(mContext.getSystemService(Context.CONNECTIVITY_SERVICE)).thenReturn(
+                mConnectivityManager);
+        when(mContext.getSystemService(Context.NETWORK_POLICY_SERVICE)).thenReturn(
+                mNetworkPolicyManager);
+
+        mController = new WifiTetherSwitchBarController(mContext,
+                new SwitchBarController(mSwitchBar));
     }
 
     @Test
@@ -63,4 +77,15 @@
 
         assertThat(mSwitchBar.isEnabled()).isFalse();
     }
+
+    @Test
+    public void testStartTether_fail_resetSwitchBar() {
+        when(mNetworkPolicyManager.getRestrictBackground()).thenReturn(false);
+
+        mController.startTether();
+        mController.mOnStartTetheringCallback.onTetheringFailed();
+
+        assertThat(mSwitchBar.isChecked()).isFalse();
+        assertThat(mSwitchBar.isEnabled()).isTrue();
+    }
 }