Merge "Adding strings for heap dump dev options."
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index b708471..4166d6f 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -901,8 +901,7 @@
<activity android:name=".Settings$MyDeviceInfoActivity"
android:label="@string/about_settings"
- android:icon="@drawable/ic_homepage_about"
- android:parentActivityName="Settings">
+ android:icon="@drawable/ic_homepage_about">
<intent-filter android:priority="1">
<action android:name="android.settings.DEVICE_INFO_SETTINGS" />
<action android:name="android.settings.DEVICE_NAME" />
@@ -1633,8 +1632,9 @@
android:icon="@drawable/ic_suggestion_security">
<intent-filter android:priority="1">
<action android:name="android.intent.action.MAIN" />
- <category android:name="com.android.settings.suggested.category.DEFAULT" />
+ <category android:name="com.android.settings.suggested.category.FIRST_IMPRESSION" />
</intent-filter>
+ <meta-data android:name="com.android.settings.dismiss" android:value="14" />
<meta-data android:name="com.android.settings.title"
android:resource="@string/suggested_lock_settings_title" />
<meta-data android:name="com.android.settings.summary"
@@ -2553,7 +2553,7 @@
<receiver android:name=".sim.SimSelectNotification">
<intent-filter>
- <action android:name="android.intent.action.SIM_STATE_CHANGED"/>
+ <action android:name="android.intent.action.PRIMARY_SUBSCRIPTION_LIST_CHANGED"/>
</intent-filter>
</receiver>
@@ -2622,6 +2622,8 @@
android:name=".wifi.NetworkRequestDialogActivity"
android:theme="@style/Transparent"
android:excludeFromRecents="true"
+ android:launchMode="singleTop"
+ android:taskAffinity=".wifi.NetworkRequestDialogActivity"
android:exported="true"
android:permission="android.permission.NETWORK_SETTINGS">
<intent-filter>
@@ -2971,6 +2973,17 @@
</intent-filter>
</service>
+ <service
+ android:name=".development.qstile.DevelopmentTiles$SensorsOff"
+ android:label="@string/sensors_off_quick_settings_title"
+ android:icon="@drawable/tile_icon_sensors_off"
+ android:permission="android.permission.BIND_QUICK_SETTINGS_TILE"
+ android:enabled="false">
+ <intent-filter>
+ <action android:name="android.service.quicksettings.action.QS_TILE" />
+ </intent-filter>
+ </service>
+
<activity
android:name=".HelpTrampoline"
android:exported="true"
@@ -3149,6 +3162,17 @@
<meta-data android:name="com.android.settings.FRAGMENT_CLASS"
android:value="com.android.settings.wifi.calling.WifiCallingDisclaimerFragment" />
</activity>
+
+ <activity android:name="Settings$BatterySaverScheduleSettingsActivity"
+ android:label="@string/battery_saver_schedule_settings_title"
+ android:parentActivityName="Settings">
+ <intent-filter>
+ <action android:name="com.android.settings.BATTERY_SAVER_SCHEDULE_SETTINGS" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
+ android:value="com.android.settings.fuelgauge.batterysaver.BatterySaverScheduleSettings" />
+ </activity>
<!-- This is the longest AndroidManifest.xml ever. -->
</application>
</manifest>
diff --git a/color-check-baseline.xml b/color-check-baseline.xml
index 7ab18a4..3424e76 100644
--- a/color-check-baseline.xml
+++ b/color-check-baseline.xml
@@ -1541,6 +1541,22 @@
priority="4"
summary="Using hardcoded color"
explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
+ errorLine1=" <color name="bt_outline_color">#1f000000</color> <!-- icon outline color -->"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/values/colors.xml"
+ line="160"
+ column="5"/>
+ </issue>
+
+ <issue
+ id="HardCodedColor"
+ severity="Error"
+ message="Avoid using hardcoded color"
+ category="Correctness"
+ priority="4"
+ summary="Using hardcoded color"
+ explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
errorLine1=" android:background="@color/lock_pattern_background" />"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
diff --git a/res/drawable/tile_icon_sensors_off.xml b/res/drawable/tile_icon_sensors_off.xml
new file mode 100644
index 0000000..890fa83
--- /dev/null
+++ b/res/drawable/tile_icon_sensors_off.xml
@@ -0,0 +1,39 @@
+<!--
+ Copyright (C) 2019 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.
+-->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:pathData="M21.966,2 L2,22"
+ android:strokeLineCap="round"
+ android:strokeColor="#000000"
+ android:fillColor="#00000000"
+ android:strokeWidth="1.6521436"
+ android:strokeLineJoin="miter"
+ android:strokeAlpha="1"/>
+ <path
+ android:pathData="M0.752,12L4.496,12l2.496,-6.25 2.496,12.5 2.496,-15 2.496,12.5 2.496,-7.5 1.248,3.75h4.992"
+ android:strokeLineCap="round"
+ android:strokeColor="#000000"
+ android:fillColor="#00000000"
+ android:strokeWidth="1.25090861"
+ android:strokeLineJoin="round"
+ android:strokeAlpha="1"/>
+</vector>
+
diff --git a/res/layout-land/wifi_dpp_qrcode_scanner_fragment.xml b/res/layout-land/wifi_dpp_qrcode_scanner_fragment.xml
index 3a0e659..c408a97 100644
--- a/res/layout-land/wifi_dpp_qrcode_scanner_fragment.xml
+++ b/res/layout-land/wifi_dpp_qrcode_scanner_fragment.xml
@@ -60,10 +60,10 @@
android:id="@+id/error_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:layout_marginTop="16dp"
android:textAlignment="center"
- android:layout_marginTop="8dp"
- android:visibility="invisible"
- android:textColor="?android:attr/colorError"/>
+ android:textColor="?android:attr/colorError"
+ android:visibility="invisible"/>
</LinearLayout>
diff --git a/res/layout/manage_applications_apps.xml b/res/layout/manage_applications_apps.xml
index 87db820..9c90f02 100644
--- a/res/layout/manage_applications_apps.xml
+++ b/res/layout/manage_applications_apps.xml
@@ -26,41 +26,34 @@
android:layout_height="match_parent"
settings:layout_behavior="com.android.settings.widget.FloatingAppBarScrollingViewBehavior">
- <LinearLayout
+ <FrameLayout
android:id="@+id/list_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:orientation="vertical"
android:visibility="gone">
- <FrameLayout
+ <androidx.recyclerview.widget.RecyclerView
+ android:id="@+id/apps_list"
android:layout_width="match_parent"
- android:layout_height="match_parent">
+ android:layout_height="match_parent"
+ android:clipToPadding="false"
+ settings:fastScrollEnabled="true"
+ settings:fastScrollHorizontalThumbDrawable="@drawable/thumb_drawable"
+ settings:fastScrollHorizontalTrackDrawable="@drawable/line_drawable"
+ settings:fastScrollVerticalThumbDrawable="@drawable/thumb_drawable"
+ settings:fastScrollVerticalTrackDrawable="@drawable/line_drawable"/>
- <androidx.recyclerview.widget.RecyclerView
- android:id="@+id/apps_list"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:clipToPadding="false"
- settings:fastScrollEnabled="true"
- settings:fastScrollHorizontalThumbDrawable="@drawable/thumb_drawable"
- settings:fastScrollHorizontalTrackDrawable="@drawable/line_drawable"
- settings:fastScrollVerticalThumbDrawable="@drawable/thumb_drawable"
- settings:fastScrollVerticalTrackDrawable="@drawable/line_drawable"/>
+ <TextView
+ android:id="@android:id/empty"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:gravity="center"
+ android:layout_gravity="center"
+ android:text="@string/no_applications"
+ android:textAppearance="?android:attr/textAppearanceLarge"
+ android:visibility="invisible"/>
- <TextView
- android:id="@android:id/empty"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:gravity="center"
- android:layout_gravity="center"
- android:text="@string/no_applications"
- android:textAppearance="?android:attr/textAppearanceLarge"
- android:visibility="invisible"/>
-
- </FrameLayout>
-
- </LinearLayout>
+ </FrameLayout>
<include layout="@layout/loading_container"/>
diff --git a/res/layout/preference.xml b/res/layout/preference.xml
index db96139..195671b 100644
--- a/res/layout/preference.xml
+++ b/res/layout/preference.xml
@@ -54,10 +54,6 @@
</RelativeLayout>
- <include
- layout="@layout/preference_two_target_divider"
- android:visibility="gone"/>
-
<LinearLayout
android:id="@android:id/widget_frame"
android:layout_width="wrap_content"
diff --git a/res/layout/settings_homepage.xml b/res/layout/settings_homepage.xml
index e04b372..6e2b302 100644
--- a/res/layout/settings_homepage.xml
+++ b/res/layout/settings_homepage.xml
@@ -21,7 +21,7 @@
android:layout_height="wrap_content"
android:orientation="vertical">
- <androidx.recyclerview.widget.RecyclerView
+ <com.android.settings.homepage.contextualcards.FocusRecyclerView
android:id="@+id/card_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
diff --git a/res/layout/wifi_dpp_qrcode_generator_fragment.xml b/res/layout/wifi_dpp_qrcode_generator_fragment.xml
index 2617aea..31bf7cc 100644
--- a/res/layout/wifi_dpp_qrcode_generator_fragment.xml
+++ b/res/layout/wifi_dpp_qrcode_generator_fragment.xml
@@ -40,6 +40,14 @@
android:layout_height="@dimen/qrcode_size"
android:src="@android:color/transparent"/>
+ <TextView
+ android:id="@+id/password"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="16dp"
+ android:textAlignment="center"
+ android:textAppearance="@android:style/TextAppearance.Material.Body1"
+ android:textColor="?android:attr/textColorSecondary"/>
</LinearLayout>
</ScrollView>
diff --git a/res/layout/wifi_dpp_qrcode_scanner_fragment.xml b/res/layout/wifi_dpp_qrcode_scanner_fragment.xml
index 4fa8e8b..9bd742a 100644
--- a/res/layout/wifi_dpp_qrcode_scanner_fragment.xml
+++ b/res/layout/wifi_dpp_qrcode_scanner_fragment.xml
@@ -60,10 +60,10 @@
android:id="@+id/error_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:layout_marginTop="16dp"
android:textAlignment="center"
- android:layout_marginTop="8dp"
- android:visibility="invisible"
- android:textColor="?android:attr/colorError"/>
+ android:textColor="?android:attr/colorError"
+ android:visibility="invisible"/>
</LinearLayout>
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 59ed4c4..c333edb 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -156,4 +156,6 @@
<color name="bt_color_bg_5">#fdcfe8</color> <!-- Material Pink 100 -->
<color name="bt_color_bg_6">#e9d2fd</color> <!-- Material Purple 100 -->
<color name="bt_color_bg_7">#cbf0f8</color> <!-- Material Cyan 100 -->
+
+ <color name="bt_outline_color">#1f000000</color> <!-- icon outline color -->
</resources>
\ No newline at end of file
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 248fb81..4a65bc9 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -404,4 +404,13 @@
<!-- Wi-Fi DPP fragment icon size -->
<dimen name="wifi_dpp_fragment_icon_width_height">48dp</dimen>
+
+ <!-- Size of nearby icon -->
+ <dimen name="bt_nearby_icon_size">24dp</dimen>
+
+ <!-- Stroke size of adaptive outline -->
+ <dimen name="adaptive_outline_stroke">1dp</dimen>
+
+ <!-- Elevation of bluetooth icon -->
+ <dimen name="bt_icon_elevation">4dp</dimen>
</resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 9a954d4..4f99dab 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1584,6 +1584,9 @@
<!-- Label for ChoosePassword/PIN Clear button that clears all text entered by the user so far. -->
<string name="lockpassword_clear_label">Clear</string>
+ <!-- Toast for a failed password change attempt when the old credential has been changed. [CHAR LIMIT=120]-->
+ <string name="lockpassword_credential_changed">Screen lock was already changed. Try again with the new screen lock.</string>
+
<!-- Label for LockPatternTutorial Cancel button -->
<string name="lockpattern_tutorial_cancel_label">Cancel</string>
@@ -2129,7 +2132,9 @@
<!-- Title for the fragment to share Wi-Fi [CHAR LIMIT=50] -->
<string name="wifi_dpp_share_wifi">Share Wi\u2011Fi</string>
<!-- Hint for the user to use another device to scan QR code on screen to join Wi-Fi [CHAR LIMIT=NONE] -->
- <string name="wifi_dpp_scan_qr_code_with_another_device">Scan this QR code with another device to join \u201c<xliff:g id="ssid" example="OfficeWifi">%1$s</xliff:g>\u201d</string>
+ <string name="wifi_dpp_scan_qr_code_with_another_device">Scan this QR code to connect to \u201c<xliff:g id="ssid" example="OfficeWifi">%1$s</xliff:g>\u201d and share the password</string>
+ <!-- Hint for the user to use another device to scan QR code on screen to join a open Wi-Fi [CHAR LIMIT=NONE] -->
+ <string name="wifi_dpp_scan_open_network_qr_code_with_another_device">Scan this QR code to connect to \u201c<xliff:g id="ssid" example="OfficeWifi">%1$s</xliff:g>\u201d</string>
<!-- Hint for QR code detection [CHAR LIMIT=NONE] -->
<string name="wifi_dpp_could_not_detect_valid_qr_code">Couldn\u2019t read QR code. Re-center code and try again</string>
<!-- Hint for Wi-Fi DPP handshake failure [CHAR LIMIT=NONE] -->
@@ -2166,8 +2171,16 @@
<string name="wifi_dpp_connecting">Connecting\u2026</string>
<!-- Title for the fragment to show that the QR code is for sharing Wi-Fi hotspot network [CHAR LIMIT=50] -->
<string name="wifi_dpp_share_hotspot">Share hotspot</string>
- <!-- Hint for the user to share Wi-Fi hotspot network [CHAR LIMIT=NONE] -->
- <string name="wifi_dpp_scan_qr_code_to_share_hotspot">Scan this QR code with another device to join hotspot \u201c<xliff:g id="ssid" example="OfficeWifi">%1$s</xliff:g>\u201d</string>
+ <!-- Title for Wi-Fi DPP lockscreen title [CHAR LIMIT=50] -->
+ <string name="wifi_dpp_lockscreen_title">Verify it\u0027s you</string>
+ <!-- Hint for Wi-Fi password [CHAR LIMIT=50] -->
+ <string name="wifi_dpp_wifi_password">Wi\u2011Fi password: <xliff:g id="password" example="my password">%1$s</xliff:g></string>
+ <!-- Hint for Wi-Fi hotspot password [CHAR LIMIT=50] -->
+ <string name="wifi_dpp_hotspot_password">Hotspot password: <xliff:g id="password" example="my password">%1$s</xliff:g></string>
+ <!-- Label for "Connect to this network using a QR code" [CHAR LIMIT=50] -->
+ <string name="wifi_dpp_add_device">Add device</string>
+ <!-- Hint for "Add device" [CHAR LIMIT=NONE] -->
+ <string name="wifi_dpp_connect_network_using_qr_code">Connect to this network using a QR code</string>
<!-- Label for the try again button [CHAR LIMIT=20]-->
<string name="retry">Retry</string>
<!-- Label for the check box to share a network with other users on the same device -->
@@ -2997,6 +3010,8 @@
<string name="device_status_summary" product="default">Phone number, signal, etc.</string>
<!-- Main settings screen item's title to go into the storage settings screen [CHAR LIMIT=25] -->
<string name="storage_settings" >Storage</string>
+ <!-- Settings title that shows user how much storage and cache space an App is taking [CHAR LIMIT=50] -->
+ <string name="storage_settings_for_app" >Storage & cache</string>
<!-- Main settings screen item's title to go into the storage & USB settings screen [CHAR LIMIT=25] -->
<string name="storage_usb_settings" >Storage</string>
<!-- Storage settings screen title -->
@@ -3943,8 +3958,6 @@
<string name="lockpassword_choose_your_pattern_header_for_face">To use face authentication, set pattern</string>
<!-- Header on first screen of choose password/PIN as backup for face authentication flow. If this string cannot be translated in under 40 characters, please translate "Set face authentication backup" [CHAR LIMIT=40] -->
<string name="lockpassword_choose_your_pin_header_for_face">To use face authentication, set PIN</string>
- <!-- Message on Wi-Fi Sharing screen [CHAR LIMIT=NONE] -->
- <string name="wifi_sharing_message">Your Wi\u2011Fi name and password for \"<xliff:g id="SSID" example="GoogleGuest">%1$s</xliff:g>\" will be shared.</string>
<!-- Message to be used to explain the user that he needs to enter his pattern to continue a
particular operation. [CHAR LIMIT=70]-->
@@ -5266,11 +5279,13 @@
<!-- Summary for the battery high usage tip, which presents battery may run out earlier [CHAR LIMIT=NONE] -->
<string name="battery_tip_high_usage_summary">Battery may run out earlier than usual</string>
<!-- Message for battery tip dialog to show the status about the battery [CHAR LIMIT=NONE] -->
- <string name="battery_tip_dialog_message" product="default">Your phone has been used more than usual. Your battery may run out sooner than expected.\n\nTop <xliff:g id="number">%1$d</xliff:g> apps you used since full charge:</string>
+ <string name="battery_tip_dialog_message" product="default">Your phone has been used more than usual. Your battery may run out sooner than expected.\n\nMost used apps since full charge:</string>
<!-- Message for battery tip dialog to show the status about the battery [CHAR LIMIT=NONE] -->
- <string name="battery_tip_dialog_message" product="tablet">Your tablet has been used more than usual. Your battery may run out sooner than expected.\n\nTop <xliff:g id="number">%1$d</xliff:g> apps you used since full charge:</string>
+ <string name="battery_tip_dialog_message" product="tablet">Your tablet has been used more than usual. Your battery may run out sooner than expected.\n\nMost used apps since full charge:</string>
<!-- Message for battery tip dialog to show the status about the battery [CHAR LIMIT=NONE] -->
- <string name="battery_tip_dialog_message" product="device">Your device has been used more than usual. Your battery may run out sooner than expected.\n\nTop <xliff:g id="number">%1$d</xliff:g> apps you used since full charge:</string>
+ <string name="battery_tip_dialog_message" product="device">Your device has been used more than usual. Your battery may run out sooner than expected.\n\nMost used apps since full charge:</string>
+ <!-- Footer message for battery tip dialog to show the status about the battery [CHAR LIMIT=NONE] -->
+ <string name="battery_tip_dialog_message_footer">Includes high-power background activity</string>
<!-- Title for restricted app preference, showing how many app need to be restricted [CHAR LIMIT=NONE] -->
<plurals name="battery_tip_restrict_title">
<item quantity="one">Restrict %1$d app</item>
@@ -5634,6 +5649,16 @@
<!-- Battery Saver: Description for sticky battery saver preference [CHAR_LIMIT=NONE] -->
<string name="battery_saver_sticky_description">Battery saver will stay on even after device is fully charged</string>
+ <!-- Battery Saver: Title for sticky battery saver preference [CHAR_LIMIT=60] -->
+ <string name="battery_saver_sticky_title_new">Turn off when fully charged</string>
+
+ <!-- Battery Saver: Description for sticky battery saver preference [CHAR_LIMIT=NONE] -->
+ <string name="battery_saver_sticky_description_new" product="default">Battery Saver turns off when your phone is at <xliff:g id="percent" example="90%">%1$s</xliff:g></string>
+ <!-- Battery Saver: Description for sticky battery saver preference [CHAR_LIMIT=NONE] -->
+ <string name="battery_saver_sticky_description_new" product="tablet">Battery Saver turns off when your tablet is at <xliff:g id="percent" example="90%">%1$s</xliff:g></string>
+ <!-- Battery Saver: Description for sticky battery saver preference [CHAR_LIMIT=NONE] -->
+ <string name="battery_saver_sticky_description_new" product="device">Battery Saver turns off when your device is at <xliff:g id="percent" example="90%">%1$s</xliff:g></string>
+
<!-- Battery saver: Label for seekbar to change battery saver threshold [CHAR_LIMIT=40] -->
<string name="battery_saver_seekbar_title"><xliff:g id="percent">%1$s</xliff:g></string>
@@ -7165,7 +7190,7 @@
<string name="keywords_screen_timeout">screen, lock time, timeout, lockscreen</string>
<!-- List of synonyms for Storage settings (everything related to storage on the device), used to match in settings search [CHAR LIMIT=NONE] -->
- <string name="keywords_storage_settings">memory, data, delete, clear, free, space</string>
+ <string name="keywords_storage_settings">memory, cache, data, delete, clear, free, space</string>
<!-- List of synonyms for the Bluetooth setting, used to match in settings search [CHAR LIMIT=NONE] -->
<string name="keywords_bluetooth_settings">connected, device, headphones, headset, speaker, wireless, pair, earbuds, music, media </string>
@@ -7706,6 +7731,20 @@
<string name="notification_bubbles_title">Allow bubbles</string>
<!-- Configure Notifications: Summary for the notification bubbles option. [CHAR LIMIT=NONE] -->
<string name="notification_bubbles_summary">Allow apps to show some notifications as bubbles</string>
+ <!-- Feature education for bubbles. [CHAR LIMIT=NONE] -->
+ <string name="bubbles_feature_education">Some notifications and other content can appear as bubbles on the screen. To open a bubble, tap it. To dismiss it, drag it down the screen.</string>
+ <!-- Title for the toggle shown on the app-level bubbles page [CHAR LIMIT=60] -->
+ <string name="bubbles_app_toggle_title">Bubbles</string>
+ <!-- Description for the toggle shown on the app-level bubbles page [CHAR LIMIT=NONE] -->
+ <string name="bubbles_app_toggle_summary">Allow <xliff:g id="app_name" example="YouTube">%1$s</xliff:g> to show some notifications as bubbles</string>
+ <!-- Title of the dialog shown when the user has disabled bubbles at the feature level but tries to enable it for an app. [CHAR LIMIT=NONE] -->
+ <string name="bubbles_feature_disabled_dialog_title">Turn on bubbles</string>
+ <!-- Description of the dialog shown when the user has disabled bubbles at the feature level but tries to enable it for an app. [CHAR LIMIT=NONE] -->
+ <string name="bubbles_feature_disabled_dialog_text">Before you can turn on bubbles for this app, you need to turn on bubbles for your device</string>
+ <!-- Button of the dialog shown when the user has disabled bubbles at the feature level but tries to enable it for an app. [CHAR LIMIT=60]-->
+ <string name="bubbles_feature_disabled_button_go_to_bubbles">Go to Bubbles</string>
+ <!-- Button to cancel out of the dialog shown when the user has disabled bubbles at the feature level but tries to enable it for an app. [CHAR LIMIT=60] -->
+ <string name="bubbles_feature_disabled_button_cancel">Cancel</string>
<!-- Configure notifications: title for swipe direction [CHAR LIMIT=60] -->
<string name="swipe_direction_title">Swipe actions</string>
@@ -9799,16 +9838,21 @@
<!-- [CHAR LIMIT=25] Title of developer tile to toggle winscope trace -->
<string name="winscope_trace_quick_settings_title">Winscope Trace</string>
+ <!-- [CHAR LIMIT=25] Title of developer tile to toggle sensors -->
+ <string name="sensors_off_quick_settings_title">Sensors Off</string>
+
<!-- [CHAR LIMIT=60] Title of work profile setting page -->
<string name="managed_profile_settings_title">Work profile settings</string>
<!-- [CHAR LIMIT=60] The preference title for enabling cross-profile remote contact search -->
<string name="managed_profile_contact_search_title">Contact search</string>
<!-- [CHAR LIMIT=NONE] The preference summary for enabling cross-profile remote contact search -->
<string name="managed_profile_contact_search_summary">Allow contact searches by your organization to identify callers and contacts</string>
- <!-- [CHAR LIMIT=60] The preference title for enabling cross profile calendar sync -->
+ <!-- [CHAR LIMIT=NONE] Settings label. This setting lets the user show their work events on their personal calendar. The adjective 'Cross-profile' is referring to the work and personal profiles a user has on their phone. -->
<string name="cross_profile_calendar_title">Cross-profile calendar</string>
- <!-- [CHAR LIMIT=NONE] The preference summary for enabling cross profile calendar sync -->
- <string name="cross_profile_calendar_summary">Show work events on personal calendar</string>
+ <!-- [CHAR LIMIT=NONE] Setting description. If the user turns on this setting, they can see their work events on their personal calendar. -->
+ <string name="cross_profile_calendar_summary">Show work events on your personal calendar</string>
+ <!-- [CHAR LIMIT=NONE] The preference summary when cross-profile calendar is restricted. -->
+ <string name="cross_profile_calendar_restricted_summary">Your organization doesn\u2019t allow personal apps to access your work calendar</string>
<!-- Time in hours -->
@@ -10614,20 +10658,20 @@
<string name="mobile_network_list_add_more">Add more</string>
<!-- Summary for an item in the page listing multiple mobile service subscriptions, indicating
that service is active and is tied to a physical SIM card [CHAR LIMIT=40] -->
- <string name="mobile_network_active_sim">Active SIM</string>
+ <string name="mobile_network_active_sim">Active / SIM</string>
<!-- Summary for an item in the page listing multiple mobile service subscriptions, indicating
that service is inactive and is tied to a physical SIM card [CHAR LIMIT=40] -->
- <string name="mobile_network_inactive_sim">Inactive SIM</string>
+ <string name="mobile_network_inactive_sim">Inactive / SIM</string>
<!-- Summary for an item in the page listing multiple mobile service subscriptions, indicating
that service is active and is tied to an eSIM profile [CHAR LIMIT=40] -->
- <string name="mobile_network_active_esim">Active eSIM</string>
+ <string name="mobile_network_active_esim">Active / Downloaded SIM</string>
<!-- Summary for an item in the page listing multiple mobile service subscriptions, indicating
that service is inactive and is tied to an eSIM profile [CHAR LIMIT=40] -->
- <string name="mobile_network_inactive_esim">Inactive eSIM</string>
+ <string name="mobile_network_inactive_esim">Inactive / Downloaded SIM</string>
<!-- Title of a dialog that lets a user modify the display name used for a mobile network
subscription in various places in the Settings app. The default name is typically just the
- carrier name, but especially in multi-SIM configurations users may want to use a different
- name. [CHAR LIMIT=40] -->
+ carrier name, but especially in multi-SIM configurations users may want to use a different
+ name. [CHAR LIMIT=40] -->
<string name="mobile_network_sim_name">SIM name</string>
<!-- Label on the confirmation button of a dialog that lets a user set the display name of a
mobile network subscription [CHAR LIMIT=20] -->
@@ -10639,6 +10683,35 @@
disabling/enabling a SIM. The SIM is disabled in this state. [CHAR LIMIT=40] -->
<string name="mobile_network_use_sim_off">Off</string>
+ <!-- Mobile network details page. Label for an option that lets the user delete an eSIM from
+ the device. [CHAR LIMIT=60] -->
+ <string name="mobile_network_erase_sim">Erase SIM</string>
+ <!-- Title of a confirmation dialog for deleting an eSIM from the device.
+ [CHAR LIMIT=60] -->
+ <string name="mobile_network_erase_sim_dialog_title">Erase this downloaded SIM?</string>
+ <!-- Body text of of a confirmation dialog for deleting an eSIM from the device.
+ [CHAR LIMIT=NONE] -->
+ <string name="mobile_network_erase_sim_dialog_body">
+ Erasing this SIM removes <xliff:g id="carrier" example="Verizon">%1$s</xliff:g> service
+ from this device.\n\nService for <xliff:g id="carrier" example="Verizon">%2$s</xliff:g>
+ won\u2019t be canceled.
+ </string>
+ <!-- OK button on a confirmation dialog for deleting an eSIM from the device.
+ [CHAR LIMIT=30] -->
+ <string name="mobile_network_erase_sim_dialog_ok">Erase</string>
+ <!-- Body text of the progress dialog we show while deleting an eSIM from the device.
+ [CHAR LIMIT=NONE] -->
+ <string name="mobile_network_erase_sim_dialog_progress">Erasing SIM\u2026</string>
+
+ <!-- Title of a dialog indicating that an error ocurred when deleting an eSIM from the device
+ [CHAR LIMIT=60] -->
+ <string name="mobile_network_erase_sim_error_dialog_title">Can\u2019t erase SIM</string>
+ <!-- Body of a dialog indicating that an error ocurred when deleting an eSIM from the device
+ [CHAR LIMIT=NONE] -->
+ <string name="mobile_network_erase_sim_error_dialog_body">
+ This SIM can\u2019t be erased due to an error.\n\nRestart your device and try again.
+ </string>
+
<!-- Title for preferred network type [CHAR LIMIT=NONE] -->
<string name="preferred_network_mode_title">Preferred network type</string>
<!-- Summary for preferred network type [CHAR LIMIT=NONE] -->
@@ -10761,6 +10834,10 @@
<string name="contextual_card_dismiss_keep">Keep</string>
<!-- String for contextual card dismissal [CHAR LIMIT=NONE] -->
<string name="contextual_card_dismiss_confirm_message">Remove this suggestion?</string>
+ <!-- String for snack bar message when users swipe to dismiss a contextual card [CHAR LIMIT=60]-->
+ <string name="contextual_card_removed_message">Suggestion removed</string>
+ <!-- Label for snack bar action allowing users to undo contextual card dismissal [CHAR LIMIT=30]-->
+ <string name="contextual_card_undo_dismissal_text">Undo</string>
<!-- Summary for low storage slice. [CHAR LIMIT=NONE] -->
<string name="low_storage_summary">Storage is low. <xliff:g id="percentage" example="54%">%1$s</xliff:g> used - <xliff:g id="free_space" example="32GB">%2$s</xliff:g> free</string>
diff --git a/res/xml/app_info_settings.xml b/res/xml/app_info_settings.xml
index 506686a..435a7ef 100644
--- a/res/xml/app_info_settings.xml
+++ b/res/xml/app_info_settings.xml
@@ -55,7 +55,7 @@
<Preference
android:key="storage_settings"
- android:title="@string/storage_settings"
+ android:title="@string/storage_settings_for_app"
android:summary="@string/summary_placeholder"
settings:controller="com.android.settings.applications.appinfo.AppStoragePreferenceController" />
diff --git a/res/xml/development_settings.xml b/res/xml/development_settings.xml
index 032f622..a9af2d4 100644
--- a/res/xml/development_settings.xml
+++ b/res/xml/development_settings.xml
@@ -113,7 +113,8 @@
<Preference
android:key="quick_settings_tiles"
android:title="@string/quick_settings_developer_tiles"
- android:fragment="com.android.settings.development.qstile.DevelopmentTileConfigFragment" />
+ android:fragment="com.android.settings.development.qstile.DevelopmentTileConfigFragment"
+ settings:searchable="false" />
<!-- Configure trust agent behavior -->
<SwitchPreference
diff --git a/res/xml/privacy_dashboard_settings.xml b/res/xml/privacy_dashboard_settings.xml
index d2d9e35..f39880c 100644
--- a/res/xml/privacy_dashboard_settings.xml
+++ b/res/xml/privacy_dashboard_settings.xml
@@ -63,12 +63,25 @@
settings:searchable="false"/>
<!-- Content Capture -->
+
+ <!-- NOTE: content capture has a different preference, depending whether or not the
+ ContentCaptureService implementations defines a custom settings activitiy on its manifest.
+ Hence, we show both here, but the controller itself will decide if it's available or not.
+ -->
+
<SwitchPreference
android:key="content_capture"
android:title="@string/content_capture"
android:summary="@string/content_capture_summary"
settings:controller="com.android.settings.privacy.EnableContentCapturePreferenceController"/>
+ <com.android.settings.widget.MasterSwitchPreference
+ android:key="content_capture_custom_settings"
+ android:title="@string/content_capture"
+ android:summary="@string/content_capture_summary"
+ settings:controller="com.android.settings.privacy.EnableContentCaptureWithServiceSettingsPreferenceController">
+ </com.android.settings.widget.MasterSwitchPreference>
+
<!-- Privacy Service -->
<PreferenceCategory
android:key="privacy_services"/>
diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java
index ead0d6a..7595657 100644
--- a/src/com/android/settings/Settings.java
+++ b/src/com/android/settings/Settings.java
@@ -77,6 +77,7 @@
public static class FactoryResetActivity extends SettingsActivity { /* empty */ }
public static class RunningServicesActivity extends SettingsActivity { /* empty */ }
public static class BatterySaverSettingsActivity extends SettingsActivity { /* empty */ }
+ public static class BatterySaverScheduleSettingsActivity extends SettingsActivity { /* empty */ }
public static class AccountSyncSettingsActivity extends SettingsActivity { /* empty */ }
public static class AccountSyncSettingsInAddAccountActivity extends SettingsActivity { /* empty */ }
public static class CryptKeeperSettingsActivity extends SettingsActivity { /* empty */ }
diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java
index a93fb76..36230d1 100644
--- a/src/com/android/settings/Utils.java
+++ b/src/com/android/settings/Utils.java
@@ -22,6 +22,8 @@
import static android.text.format.DateUtils.FORMAT_SHOW_DATE;
import android.annotation.Nullable;
+import android.app.ActionBar;
+import android.app.Activity;
import android.app.ActivityManager;
import android.app.AppGlobals;
import android.app.IActivityManager;
@@ -92,6 +94,7 @@
import androidx.annotation.StringRes;
import androidx.core.graphics.drawable.IconCompat;
import androidx.fragment.app.Fragment;
+import androidx.lifecycle.Lifecycle;
import androidx.preference.Preference;
import androidx.preference.PreferenceGroup;
@@ -101,6 +104,7 @@
import com.android.settings.core.FeatureFlags;
import com.android.settings.development.featureflags.FeatureFlagPersistent;
import com.android.settings.password.ChooseLockSettingsHelper;
+import com.android.settingslib.widget.ActionBarShadowController;
import java.net.InetAddress;
import java.util.Iterator;
@@ -1023,4 +1027,28 @@
ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
return !(am.isLowRamDevice() && (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q));
}
+
+ /**
+ * Adds a shadow appear/disappear animation to action bar scroll.
+ *
+ * <p/>
+ * This method must be called after {@link Fragment#onCreate(Bundle)}.
+ */
+ public static void setActionBarShadowAnimation(Activity activity, Lifecycle lifecycle,
+ View scrollView) {
+ if (activity == null) {
+ Log.w(TAG, "No activity, cannot style actionbar.");
+ return;
+ }
+ final ActionBar actionBar = activity.getActionBar();
+ if (actionBar == null) {
+ Log.w(TAG, "No actionbar, cannot style actionbar.");
+ return;
+ }
+ actionBar.setElevation(0);
+
+ if (lifecycle != null && scrollView != null) {
+ ActionBarShadowController.attachToView(activity, lifecycle, scrollView);
+ }
+ }
}
diff --git a/src/com/android/settings/applications/AppAndNotificationDashboardFragment.java b/src/com/android/settings/applications/AppAndNotificationDashboardFragment.java
index 7aaf80d..c32a33d 100644
--- a/src/com/android/settings/applications/AppAndNotificationDashboardFragment.java
+++ b/src/com/android/settings/applications/AppAndNotificationDashboardFragment.java
@@ -21,6 +21,7 @@
import android.provider.SearchIndexableResource;
import com.android.settings.R;
+import com.android.settings.Utils;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.notification.EmergencyBroadcastPreferenceController;
import com.android.settings.search.BaseSearchIndexProvider;
@@ -85,6 +86,10 @@
super.onResume();
mIsFirstLaunch = false;
+
+ if (mRecentAppsPreferenceController.isAvailable()) {
+ Utils.setActionBarShadowAnimation(getActivity(), getSettingsLifecycle(), getListView());
+ }
}
@Override
diff --git a/src/com/android/settings/applications/manageapplications/ApplicationViewHolder.java b/src/com/android/settings/applications/manageapplications/ApplicationViewHolder.java
index e46f294..bd08236 100644
--- a/src/com/android/settings/applications/manageapplications/ApplicationViewHolder.java
+++ b/src/com/android/settings/applications/manageapplications/ApplicationViewHolder.java
@@ -19,7 +19,6 @@
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
-import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
@@ -41,10 +40,6 @@
private final TextView mAppName;
private final ImageView mAppIcon;
- private final boolean mKeepStableHeight;
-
- @VisibleForTesting
- View mSummaryContainer;
@VisibleForTesting
final TextView mSummary;
@VisibleForTesting
@@ -54,20 +49,18 @@
@VisibleForTesting
final Switch mSwitch;
- ApplicationViewHolder(View itemView, boolean keepStableHeight) {
+ ApplicationViewHolder(View itemView) {
super(itemView);
mAppName = itemView.findViewById(android.R.id.title);
mAppIcon = itemView.findViewById(android.R.id.icon);
- mSummaryContainer = itemView.findViewById(R.id.summary_container);
mSummary = itemView.findViewById(android.R.id.summary);
mDisabled = itemView.findViewById(R.id.appendix);
- mKeepStableHeight = keepStableHeight;
mSwitch = itemView.findViewById(R.id.switchWidget);
mWidgetContainer = itemView.findViewById(android.R.id.widget_frame);
}
static View newView(ViewGroup parent) {
- return newView(parent, false);
+ return newView(parent, false /* twoTarget */);
}
static View newView(ViewGroup parent, boolean twoTarget) {
@@ -76,13 +69,13 @@
final ViewGroup widgetFrame = view.findViewById(android.R.id.widget_frame);
if (twoTarget) {
if (widgetFrame != null) {
- LayoutInflater.from(parent.getContext())
- .inflate(R.layout.preference_widget_master_switch, widgetFrame, true);
+ LayoutInflater.from(parent.getContext())
+ .inflate(R.layout.preference_widget_master_switch, widgetFrame, true);
- View divider = LayoutInflater.from(parent.getContext()).inflate(
- R.layout.preference_two_target_divider, view, false);
- // second to last, before widget frame
- view.addView(divider, view.getChildCount() - 1);
+ View divider = LayoutInflater.from(parent.getContext()).inflate(
+ R.layout.preference_two_target_divider, view, false);
+ // second to last, before widget frame
+ view.addView(divider, view.getChildCount() - 1);
}
} else if (widgetFrame != null) {
widgetFrame.setVisibility(View.GONE);
@@ -92,12 +85,10 @@
void setSummary(CharSequence summary) {
mSummary.setText(summary);
- updateSummaryContainer();
}
void setSummary(@StringRes int summary) {
mSummary.setText(summary);
- updateSummaryContainer();
}
void setEnabled(boolean isEnabled) {
@@ -133,17 +124,6 @@
} else {
mDisabled.setVisibility(View.GONE);
}
- updateSummaryContainer();
- }
-
- void updateSummaryContainer() {
- if (mKeepStableHeight) {
- mSummaryContainer.setVisibility(View.VISIBLE);
- return;
- }
- final boolean hasContent =
- !TextUtils.isEmpty(mDisabled.getText()) || !TextUtils.isEmpty(mSummary.getText());
- mSummaryContainer.setVisibility(hasContent ? View.VISIBLE : View.GONE);
}
void updateSizeText(AppEntry entry, CharSequence invalidSizeStr, int whichSize) {
diff --git a/src/com/android/settings/applications/manageapplications/ManageApplications.java b/src/com/android/settings/applications/manageapplications/ManageApplications.java
index 9586be0..9839934 100644
--- a/src/com/android/settings/applications/manageapplications/ManageApplications.java
+++ b/src/com/android/settings/applications/manageapplications/ManageApplications.java
@@ -33,7 +33,6 @@
import android.annotation.Nullable;
import android.annotation.StringRes;
import android.app.Activity;
-import android.app.ActivityManager;
import android.app.settings.SettingsEnums;
import android.app.usage.IUsageStatsManager;
import android.content.Context;
@@ -50,22 +49,18 @@
import android.util.ArraySet;
import android.util.IconDrawableFactory;
import android.util.Log;
-import android.util.TypedValue;
-import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
-import android.view.ViewGroup.LayoutParams;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.Filter;
import android.widget.FrameLayout;
import android.widget.SearchView;
import android.widget.Spinner;
-import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
@@ -1059,14 +1054,13 @@
@Override
public ApplicationViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
- View view;
+ final View view;
if (mManageApplications.mListType == LIST_TYPE_NOTIFICATION) {
view = ApplicationViewHolder.newView(parent, true /* twoTarget */);
} else {
view = ApplicationViewHolder.newView(parent, false /* twoTarget */);
}
- return new ApplicationViewHolder(view,
- shouldUseStableItemHeight(mManageApplications.mListType));
+ return new ApplicationViewHolder(view);
}
@Override
@@ -1153,11 +1147,6 @@
mSearchFilter.filter(query);
}
- @VisibleForTesting
- static boolean shouldUseStableItemHeight(int listType) {
- return true;
- }
-
private static boolean packageNameEquals(PackageItemInfo info1, PackageItemInfo info2) {
if (info1 == null || info2 == null) {
return false;
diff --git a/src/com/android/settings/applications/managedomainurls/DomainAppPreference.java b/src/com/android/settings/applications/managedomainurls/DomainAppPreference.java
index 94d2818..bc7b855 100644
--- a/src/com/android/settings/applications/managedomainurls/DomainAppPreference.java
+++ b/src/com/android/settings/applications/managedomainurls/DomainAppPreference.java
@@ -47,12 +47,6 @@
setState();
}
- @Override
- public void onBindViewHolder(PreferenceViewHolder holder) {
- super.onBindViewHolder(holder);
- holder.itemView.findViewById(R.id.appendix).setVisibility(View.GONE);
- }
-
public void reuse() {
setState();
notifyChanged();
diff --git a/src/com/android/settings/biometrics/BiometricEnrollIntroduction.java b/src/com/android/settings/biometrics/BiometricEnrollIntroduction.java
index 097ffe2..81b70b5 100644
--- a/src/com/android/settings/biometrics/BiometricEnrollIntroduction.java
+++ b/src/com/android/settings/biometrics/BiometricEnrollIntroduction.java
@@ -140,7 +140,7 @@
if (!mHasPassword) {
// No password registered, launch into enrollment wizard.
launchChooseLock();
- } else {
+ } else if (!mLaunchedConfirmLock || mToken == null) {
launchConfirmLock(getConfirmLockTitleResId(), getChallenge());
}
}
diff --git a/src/com/android/settings/bluetooth/BluetoothDetailsHeaderController.java b/src/com/android/settings/bluetooth/BluetoothDetailsHeaderController.java
index 3860352..fe73a2e 100644
--- a/src/com/android/settings/bluetooth/BluetoothDetailsHeaderController.java
+++ b/src/com/android/settings/bluetooth/BluetoothDetailsHeaderController.java
@@ -80,8 +80,10 @@
@Override
protected void refresh() {
- setHeaderProperties();
- mHeaderController.done(mFragment.getActivity(), true /* rebindActions */);
+ if (isAvailable()) {
+ setHeaderProperties();
+ mHeaderController.done(mFragment.getActivity(), true /* rebindActions */);
+ }
}
@Override
diff --git a/src/com/android/settings/bluetooth/BluetoothDevicePreference.java b/src/com/android/settings/bluetooth/BluetoothDevicePreference.java
index 8d727eb..4a7ca27 100644
--- a/src/com/android/settings/bluetooth/BluetoothDevicePreference.java
+++ b/src/com/android/settings/bluetooth/BluetoothDevicePreference.java
@@ -164,6 +164,8 @@
final ImageView imageView = (ImageView) view.findViewById(android.R.id.icon);
if (imageView != null) {
imageView.setContentDescription(contentDescription);
+ imageView.setElevation(
+ getContext().getResources().getDimension(R.dimen.bt_icon_elevation));
}
super.onBindViewHolder(view);
}
diff --git a/src/com/android/settings/bluetooth/Utils.java b/src/com/android/settings/bluetooth/Utils.java
index e02ddc4..ecf40b6 100755
--- a/src/com/android/settings/bluetooth/Utils.java
+++ b/src/com/android/settings/bluetooth/Utils.java
@@ -22,8 +22,11 @@
import android.content.Context;
import android.content.DialogInterface;
import android.content.res.Resources;
+import android.graphics.Bitmap;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.provider.MediaStore;
import android.provider.Settings;
import android.util.Log;
import android.util.Pair;
@@ -33,14 +36,18 @@
import androidx.appcompat.app.AlertDialog;
import com.android.settings.R;
+import com.android.settings.homepage.AdaptiveIconShapeDrawable;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.widget.AdaptiveIcon;
+import com.android.settings.widget.AdaptiveOutlineDrawable;
import com.android.settingslib.bluetooth.BluetoothUtils;
import com.android.settingslib.bluetooth.BluetoothUtils.ErrorListener;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.bluetooth.LocalBluetoothManager.BluetoothManagerCallback;
+import java.io.IOException;
+
/**
* Utils is a helper class that contains constants for various
* Android resource IDs, debug logging flags, and static methods
@@ -165,6 +172,7 @@
if (bluetoothDevice == null) {
return false;
}
+
return Boolean.parseBoolean(bluetoothDevice.getMetadata(key));
}
@@ -193,7 +201,36 @@
CachedBluetoothDevice cachedDevice) {
final Pair<Drawable, String> pair = BluetoothUtils.getBtClassDrawableWithDescription(
context, cachedDevice);
+ final boolean untetheredHeadset = Utils.getBooleanMetaData(cachedDevice.getDevice(),
+ BluetoothDevice.METADATA_IS_UNTHETHERED_HEADSET);
+ final int iconSize = context.getResources().getDimensionPixelSize(
+ R.dimen.bt_nearby_icon_size);
final Resources resources = context.getResources();
+
+ // Deal with untethered headset
+ if (untetheredHeadset) {
+ final String uriString = Utils.getStringMetaData(cachedDevice.getDevice(),
+ BluetoothDevice.METADATA_MAIN_ICON);
+ final Uri iconUri = uriString != null ? Uri.parse(uriString) : null;
+ if (iconUri != null) {
+ try {
+ final Bitmap bitmap = MediaStore.Images.Media.getBitmap(
+ context.getContentResolver(), iconUri);
+ if (bitmap != null) {
+ final Bitmap resizedBitmap = Bitmap.createScaledBitmap(bitmap, iconSize,
+ iconSize, false);
+ bitmap.recycle();
+ final AdaptiveOutlineDrawable drawable = new AdaptiveOutlineDrawable(
+ resources, resizedBitmap);
+ return new Pair<>(drawable, pair.second);
+ }
+ } catch (IOException e) {
+ Log.e(TAG, "Failed to get drawable for: " + iconUri, e);
+ }
+ }
+ }
+
+ // Deal with normal headset
final int[] iconFgColors = resources.getIntArray(R.array.bt_icon_fg_colors);
final int[] iconBgColors = resources.getIntArray(R.array.bt_icon_bg_colors);
diff --git a/src/com/android/settings/core/gateway/SettingsGateway.java b/src/com/android/settings/core/gateway/SettingsGateway.java
index d522918..10eec4e 100644
--- a/src/com/android/settings/core/gateway/SettingsGateway.java
+++ b/src/com/android/settings/core/gateway/SettingsGateway.java
@@ -76,6 +76,7 @@
import com.android.settings.enterprise.EnterprisePrivacySettings;
import com.android.settings.fuelgauge.AdvancedPowerUsageDetail;
import com.android.settings.fuelgauge.PowerUsageSummary;
+import com.android.settings.fuelgauge.batterysaver.BatterySaverScheduleSettings;
import com.android.settings.fuelgauge.batterysaver.BatterySaverSettings;
import com.android.settings.gestures.AssistGestureSettings;
import com.android.settings.gestures.DoubleTapPowerSettings;
@@ -272,6 +273,7 @@
DataUsageList.class.getName(),
ToggleBackupSettingFragment.class.getName(),
PreviouslyConnectedDeviceDashboardFragment.class.getName(),
+ BatterySaverScheduleSettings.class.getName()
};
public static final String[] SETTINGS_FOR_RESTRICTED = {
diff --git a/src/com/android/settings/development/qstile/DevelopmentTiles.java b/src/com/android/settings/development/qstile/DevelopmentTiles.java
index 5edbc70..bb791ab 100644
--- a/src/com/android/settings/development/qstile/DevelopmentTiles.java
+++ b/src/com/android/settings/development/qstile/DevelopmentTiles.java
@@ -16,9 +16,12 @@
package com.android.settings.development.qstile;
+import android.app.settings.SettingsEnums;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.PackageManager;
+import android.hardware.SensorPrivacyManager;
+import android.app.KeyguardManager;
import android.os.IBinder;
import android.os.Parcel;
import android.os.RemoteException;
@@ -38,6 +41,8 @@
import com.android.internal.app.LocalePicker;
import com.android.internal.statusbar.IStatusBarService;
+import com.android.settings.overlay.FeatureFactory;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
import com.android.settingslib.development.DevelopmentSettingsEnabler;
import com.android.settingslib.development.SystemPropPoker;
@@ -273,4 +278,45 @@
}
}
}
-}
\ No newline at end of file
+
+ /**
+ * Tile to toggle sensors off to control camera, mic, and sensors managed by the SensorManager.
+ */
+ public static class SensorsOff extends DevelopmentTiles {
+ private Context mContext;
+ private SensorPrivacyManager mSensorPrivacyManager;
+ private KeyguardManager mKeyguardManager;
+ private MetricsFeatureProvider mMetricsFeatureProvider;
+ private boolean mIsEnabled;
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ mContext = getApplicationContext();
+ mSensorPrivacyManager = (SensorPrivacyManager) mContext.getSystemService(
+ Context.SENSOR_PRIVACY_SERVICE);
+ mIsEnabled = mSensorPrivacyManager.isSensorPrivacyEnabled();
+ mMetricsFeatureProvider = FeatureFactory.getFactory(
+ mContext).getMetricsFeatureProvider();
+ mKeyguardManager = (KeyguardManager) mContext.getSystemService(
+ Context.KEYGUARD_SERVICE);
+ }
+
+ @Override
+ protected boolean isEnabled() {
+ return mIsEnabled;
+ }
+
+ @Override
+ public void setIsEnabled(boolean isEnabled) {
+ // Don't allow sensors to be reenabled from the lock screen.
+ if (mIsEnabled && mKeyguardManager.isKeyguardLocked()) {
+ return;
+ }
+ mMetricsFeatureProvider.action(getApplicationContext(), SettingsEnums.QS_SENSOR_PRIVACY,
+ isEnabled);
+ mIsEnabled = isEnabled;
+ mSensorPrivacyManager.setSensorPrivacy(isEnabled);
+ }
+ }
+}
diff --git a/src/com/android/settings/fuelgauge/BatterySaverController.java b/src/com/android/settings/fuelgauge/BatterySaverController.java
index c4ed88b..acb5e32 100644
--- a/src/com/android/settings/fuelgauge/BatterySaverController.java
+++ b/src/com/android/settings/fuelgauge/BatterySaverController.java
@@ -90,10 +90,10 @@
final int percent = Settings.Global.getInt(resolver,
Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, 0);
final int mode = Settings.Global.getInt(resolver,
- Global.AUTOMATIC_POWER_SAVER_MODE, PowerManager.POWER_SAVER_MODE_PERCENTAGE);
+ Global.AUTOMATIC_POWER_SAVE_MODE, PowerManager.POWER_SAVE_MODE_TRIGGER_PERCENTAGE);
if (isPowerSaveOn) {
return mContext.getString(R.string.battery_saver_on_summary);
- } else if (mode == PowerManager.POWER_SAVER_MODE_PERCENTAGE) {
+ } else if (mode == PowerManager.POWER_SAVE_MODE_TRIGGER_PERCENTAGE) {
if (percent != 0) {
return mContext.getString(R.string.battery_saver_off_scheduled_summary,
Utils.formatPercentage(percent));
diff --git a/src/com/android/settings/fuelgauge/batterysaver/BatterySaverSchedulePreferenceController.java b/src/com/android/settings/fuelgauge/batterysaver/BatterySaverSchedulePreferenceController.java
index 2cc73d1..0b129ef 100644
--- a/src/com/android/settings/fuelgauge/batterysaver/BatterySaverSchedulePreferenceController.java
+++ b/src/com/android/settings/fuelgauge/batterysaver/BatterySaverSchedulePreferenceController.java
@@ -61,9 +61,9 @@
@Override
public CharSequence getSummary() {
final ContentResolver resolver = mContext.getContentResolver();
- final int mode = Settings.Global.getInt(resolver, Global.AUTOMATIC_POWER_SAVER_MODE,
- PowerManager.POWER_SAVER_MODE_PERCENTAGE);
- if (mode == PowerManager.POWER_SAVER_MODE_PERCENTAGE) {
+ final int mode = Settings.Global.getInt(resolver, Global.AUTOMATIC_POWER_SAVE_MODE,
+ PowerManager.POWER_SAVE_MODE_TRIGGER_PERCENTAGE);
+ if (mode == PowerManager.POWER_SAVE_MODE_TRIGGER_PERCENTAGE) {
final int threshold =
Settings.Global.getInt(resolver, Global.LOW_POWER_MODE_TRIGGER_LEVEL, 0);
if (threshold <= 0) {
diff --git a/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleRadioButtonsController.java b/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleRadioButtonsController.java
index d49eb0a..796df46 100644
--- a/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleRadioButtonsController.java
+++ b/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleRadioButtonsController.java
@@ -29,7 +29,7 @@
*
* Will call the appropriate power manager APIs and modify the correct settings to enable
* users to control their automatic battery saver toggling preferences.
- * See {@link Settings.Global#AUTOMATIC_POWER_SAVER_MODE} for more details.
+ * See {@link Settings.Global#AUTOMATIC_POWER_SAVE_MODE} for more details.
*/
public class BatterySaverScheduleRadioButtonsController {
@@ -48,12 +48,12 @@
public String getDefaultKey() {
final ContentResolver resolver = mContext.getContentResolver();
- // Note: this can also be obtained via PowerManager.getPowerSaveMode()
- final int mode = Settings.Global.getInt(resolver, Global.AUTOMATIC_POWER_SAVER_MODE,
- PowerManager.POWER_SAVER_MODE_PERCENTAGE);
+ // Note: this can also be obtained via PowerManager.getPowerSaveModeTrigger()
+ final int mode = Settings.Global.getInt(resolver, Global.AUTOMATIC_POWER_SAVE_MODE,
+ PowerManager.POWER_SAVE_MODE_TRIGGER_PERCENTAGE);
// if mode is "dynamic" we are in routine mode, percentage with non-zero threshold is
// percentage mode, otherwise it is no schedule mode
- if (mode == PowerManager.POWER_SAVER_MODE_PERCENTAGE) {
+ if (mode == PowerManager.POWER_SAVE_MODE_TRIGGER_PERCENTAGE) {
final int threshold =
Settings.Global.getInt(resolver, Global.LOW_POWER_MODE_TRIGGER_LEVEL, 0);
if (threshold <= 0) {
@@ -68,18 +68,18 @@
final ContentResolver resolver = mContext.getContentResolver();
switch(key) {
case KEY_NO_SCHEDULE:
- Settings.Global.putInt(resolver, Global.AUTOMATIC_POWER_SAVER_MODE,
- PowerManager.POWER_SAVER_MODE_PERCENTAGE);
+ Settings.Global.putInt(resolver, Global.AUTOMATIC_POWER_SAVE_MODE,
+ PowerManager.POWER_SAVE_MODE_TRIGGER_PERCENTAGE);
Settings.Global.putInt(resolver, Global.LOW_POWER_MODE_TRIGGER_LEVEL, 0);
break;
case KEY_PERCENTAGE:
- Settings.Global.putInt(resolver, Global.AUTOMATIC_POWER_SAVER_MODE,
- PowerManager.POWER_SAVER_MODE_PERCENTAGE);
+ Settings.Global.putInt(resolver, Global.AUTOMATIC_POWER_SAVE_MODE,
+ PowerManager.POWER_SAVE_MODE_TRIGGER_PERCENTAGE);
Settings.Global.putInt(resolver, Global.LOW_POWER_MODE_TRIGGER_LEVEL, 5);
break;
case KEY_ROUTINE:
- Settings.Global.putInt(resolver, Global.AUTOMATIC_POWER_SAVER_MODE,
- PowerManager.POWER_SAVER_MODE_DYNAMIC);
+ Settings.Global.putInt(resolver, Global.AUTOMATIC_POWER_SAVE_MODE,
+ PowerManager.POWER_SAVE_MODE_TRIGGER_DYNAMIC);
break;
default:
throw new IllegalStateException(
diff --git a/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleSeekBarController.java b/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleSeekBarController.java
index 6253947..b704fde 100644
--- a/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleSeekBarController.java
+++ b/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleSeekBarController.java
@@ -39,7 +39,7 @@
*
* Will call the appropriate power manager APIs and modify the correct settings to enable
* users to control their automatic battery saver toggling preferences.
- * See {@link Settings.Global#AUTOMATIC_POWER_SAVER_MODE} for more details.
+ * See {@link Settings.Global#AUTOMATIC_POWER_SAVE_MODE} for more details.
*/
public class BatterySaverScheduleSeekBarController implements
OnPreferenceChangeListener {
@@ -76,12 +76,12 @@
public void updateSeekBar() {
final ContentResolver resolver = mContext.getContentResolver();
- // Note: this can also be obtained via PowerManager.getPowerSaveMode()
- final int mode = Settings.Global.getInt(resolver, Global.AUTOMATIC_POWER_SAVER_MODE,
- PowerManager.POWER_SAVER_MODE_PERCENTAGE);
+ // Note: this can also be obtained via PowerManager.getPowerSaveModeTrigger()
+ final int mode = Settings.Global.getInt(resolver, Global.AUTOMATIC_POWER_SAVE_MODE,
+ PowerManager.POWER_SAVE_MODE_TRIGGER_PERCENTAGE);
// if mode is "dynamic" we are in routine mode, percentage with non-zero threshold is
// percentage mode, otherwise it is no schedule mode
- if (mode == PowerManager.POWER_SAVER_MODE_PERCENTAGE) {
+ if (mode == PowerManager.POWER_SAVE_MODE_TRIGGER_PERCENTAGE) {
final int threshold =
Settings.Global.getInt(resolver, Global.LOW_POWER_MODE_TRIGGER_LEVEL, 0);
if (threshold <= 0) {
diff --git a/src/com/android/settings/gestures/WakeScreenGesturePreferenceController.java b/src/com/android/settings/gestures/WakeScreenGesturePreferenceController.java
deleted file mode 100644
index e9d03d7..0000000
--- a/src/com/android/settings/gestures/WakeScreenGesturePreferenceController.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * 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.gestures;
-
-import static android.provider.Settings.Secure.DOZE_WAKE_SCREEN_GESTURE;
-
-import android.annotation.UserIdInt;
-import android.content.Context;
-import android.hardware.display.AmbientDisplayConfiguration;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.text.TextUtils;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.settings.aware.AwareFeatureProvider;
-import com.android.settings.overlay.FeatureFactory;
-
-public class WakeScreenGesturePreferenceController extends GesturePreferenceController {
-
- private static final int ON = 1;
- private static final int OFF = 0;
-
- private static final String PREF_KEY_VIDEO = "gesture_wake_screen_video";
-
- private final AwareFeatureProvider mFeatureProvider;
- private AmbientDisplayConfiguration mAmbientConfig;
- @UserIdInt
- private final int mUserId;
-
- public WakeScreenGesturePreferenceController(Context context, String key) {
- super(context, key);
- mUserId = UserHandle.myUserId();
- mFeatureProvider = FeatureFactory.getFactory(context).getAwareFeatureProvider();
- }
-
- @Override
- public int getAvailabilityStatus() {
- if (!getAmbientConfig().wakeScreenGestureAvailable()
- || !mFeatureProvider.isSupported(mContext)) {
- return UNSUPPORTED_ON_DEVICE;
- }
-
- if (!mFeatureProvider.isEnabled(mContext)) {
- return CONDITIONALLY_UNAVAILABLE;
- }
-
- return getAmbientConfig().alwaysOnEnabled(mUserId)
- ? AVAILABLE : DISABLED_DEPENDENT_SETTING;
- }
-
- @Override
- protected boolean canHandleClicks() {
- return getAmbientConfig().alwaysOnEnabled(mUserId);
- }
-
- @Override
- public boolean isSliceable() {
- return TextUtils.equals(getPreferenceKey(), "gesture_wake_screen");
- }
-
- @Override
- protected String getVideoPrefKey() {
- return PREF_KEY_VIDEO;
- }
-
- @Override
- public boolean isChecked() {
- return getAmbientConfig().wakeScreenGestureEnabled(mUserId);
- }
-
- @Override
- public boolean setChecked(boolean isChecked) {
- return Settings.Secure.putInt(mContext.getContentResolver(), DOZE_WAKE_SCREEN_GESTURE,
- isChecked ? ON : OFF);
- }
-
- private AmbientDisplayConfiguration getAmbientConfig() {
- if (mAmbientConfig == null) {
- mAmbientConfig = new AmbientDisplayConfiguration(mContext);
- }
-
- return mAmbientConfig;
- }
-
- @VisibleForTesting
- public void setConfig(AmbientDisplayConfiguration config) {
- mAmbientConfig = config;
- }
-}
diff --git a/src/com/android/settings/homepage/contextualcards/ContextualCardManager.java b/src/com/android/settings/homepage/contextualcards/ContextualCardManager.java
index 7df322d..92108f0 100644
--- a/src/com/android/settings/homepage/contextualcards/ContextualCardManager.java
+++ b/src/com/android/settings/homepage/contextualcards/ContextualCardManager.java
@@ -43,6 +43,8 @@
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnSaveInstanceState;
+import com.android.settingslib.core.lifecycle.events.OnStart;
+import com.android.settingslib.core.lifecycle.events.OnStop;
import java.util.ArrayList;
import java.util.List;
@@ -98,7 +100,6 @@
mLifecycleObservers = new ArrayList<>();
mControllerRendererPool = new ControllerRendererPool();
mLifecycle.addObserver(this);
-
if (savedInstanceState == null) {
mIsFirstLaunch = true;
mSavedCards = null;
@@ -240,6 +241,21 @@
outState.putStringArrayList(KEY_CONTEXTUAL_CARDS, cards);
}
+ public void onWindowFocusChanged(boolean hasWindowFocus) {
+ // Duplicate a list to avoid java.util.ConcurrentModificationException.
+ final List<ContextualCard> cards = new ArrayList<>(mContextualCards);
+ for (ContextualCard card : cards) {
+ final ContextualCardController controller = mControllerRendererPool
+ .getController(mContext, card.getCardType());
+ if (hasWindowFocus && controller instanceof OnStart) {
+ ((OnStart) controller).onStart();
+ }
+ if (!hasWindowFocus && controller instanceof OnStop) {
+ ((OnStop) controller).onStop();
+ }
+ }
+ }
+
public ControllerRendererPool getControllerRendererPool() {
return mControllerRendererPool;
}
diff --git a/src/com/android/settings/homepage/contextualcards/ContextualCardsFragment.java b/src/com/android/settings/homepage/contextualcards/ContextualCardsFragment.java
index 72ddb50..bd25866 100644
--- a/src/com/android/settings/homepage/contextualcards/ContextualCardsFragment.java
+++ b/src/com/android/settings/homepage/contextualcards/ContextualCardsFragment.java
@@ -27,17 +27,17 @@
import androidx.loader.app.LoaderManager;
import androidx.recyclerview.widget.GridLayoutManager;
-import androidx.recyclerview.widget.RecyclerView;
import com.android.settings.R;
import com.android.settings.core.InstrumentedFragment;
import com.android.settings.overlay.FeatureFactory;
-public class ContextualCardsFragment extends InstrumentedFragment {
+public class ContextualCardsFragment extends InstrumentedFragment implements
+ FocusRecyclerView.FocusListener {
private static final String TAG = "ContextualCardsFragment";
- private RecyclerView mCardsContainer;
+ private FocusRecyclerView mCardsContainer;
private GridLayoutManager mLayoutManager;
private ContextualCardsAdapter mContextualCardsAdapter;
private ContextualCardManager mContextualCardManager;
@@ -72,11 +72,17 @@
this /* lifecycleOwner */, mContextualCardManager);
mCardsContainer.setAdapter(mContextualCardsAdapter);
mContextualCardManager.setListener(mContextualCardsAdapter);
+ mCardsContainer.setListener(this);
return rootView;
}
@Override
+ public void onWindowFocusChanged(boolean hasWindowFocus) {
+ mContextualCardManager.onWindowFocusChanged(hasWindowFocus);
+ }
+
+ @Override
public int getMetricsCategory() {
return SettingsEnums.SETTINGS_HOMEPAGE;
}
diff --git a/src/com/android/settings/homepage/contextualcards/FocusRecyclerView.java b/src/com/android/settings/homepage/contextualcards/FocusRecyclerView.java
new file mode 100644
index 0000000..a2ec9af
--- /dev/null
+++ b/src/com/android/settings/homepage/contextualcards/FocusRecyclerView.java
@@ -0,0 +1,36 @@
+package com.android.settings.homepage.contextualcards;
+
+import android.content.Context;
+import android.util.AttributeSet;
+
+import androidx.annotation.Nullable;
+import androidx.recyclerview.widget.RecyclerView;
+
+public class FocusRecyclerView extends RecyclerView {
+
+ private FocusListener mListener;
+
+ public FocusRecyclerView(Context context) {
+ super(context);
+ }
+
+ public FocusRecyclerView(Context context, @Nullable AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ @Override
+ public void onWindowFocusChanged(boolean hasWindowFocus) {
+ super.onWindowFocusChanged(hasWindowFocus);
+ if (mListener != null) {
+ mListener.onWindowFocusChanged(hasWindowFocus);
+ }
+ }
+
+ public void setListener(FocusListener listener) {
+ mListener = listener;
+ }
+
+ public interface FocusListener {
+ void onWindowFocusChanged(boolean hasWindowFocus);
+ }
+}
diff --git a/src/com/android/settings/password/ChooseLockPassword.java b/src/com/android/settings/password/ChooseLockPassword.java
index c9d1af3..16cecc8 100644
--- a/src/com/android/settings/password/ChooseLockPassword.java
+++ b/src/com/android/settings/password/ChooseLockPassword.java
@@ -45,10 +45,10 @@
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.Log;
+import android.util.Pair;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
-import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import android.widget.LinearLayout;
@@ -1100,12 +1100,11 @@
}
@Override
- protected Intent saveAndVerifyInBackground() {
+ protected Pair<Boolean, Intent> saveAndVerifyInBackground() {
+ final boolean success = mUtils.saveLockPassword(
+ mChosenPassword, mCurrentPassword, mRequestedQuality, mUserId);
Intent result = null;
- mUtils.saveLockPassword(mChosenPassword, mCurrentPassword, mRequestedQuality,
- mUserId);
-
- if (mHasChallenge) {
+ if (success && mHasChallenge) {
byte[] token;
try {
token = mUtils.verifyPassword(mChosenPassword, mChallenge, mUserId);
@@ -1120,8 +1119,7 @@
result = new Intent();
result.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, token);
}
-
- return result;
+ return Pair.create(success, result);
}
}
}
diff --git a/src/com/android/settings/password/ChooseLockPattern.java b/src/com/android/settings/password/ChooseLockPattern.java
index d5ad1ab..d89ad30 100644
--- a/src/com/android/settings/password/ChooseLockPattern.java
+++ b/src/com/android/settings/password/ChooseLockPattern.java
@@ -24,6 +24,7 @@
import android.content.res.Resources.Theme;
import android.os.Bundle;
import android.util.Log;
+import android.util.Pair;
import android.util.TypedValue;
import android.view.KeyEvent;
import android.view.LayoutInflater;
@@ -854,12 +855,11 @@
}
@Override
- protected Intent saveAndVerifyInBackground() {
- Intent result = null;
+ protected Pair<Boolean, Intent> saveAndVerifyInBackground() {
final int userId = mUserId;
- mUtils.saveLockPattern(mChosenPattern, mCurrentPattern, userId);
-
- if (mHasChallenge) {
+ final boolean success = mUtils.saveLockPattern(mChosenPattern, mCurrentPattern, userId);
+ Intent result = null;
+ if (success && mHasChallenge) {
byte[] token;
try {
token = mUtils.verifyPattern(mChosenPattern, mChallenge, userId);
@@ -874,8 +874,7 @@
result = new Intent();
result.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, token);
}
-
- return result;
+ return Pair.create(success, result);
}
@Override
diff --git a/src/com/android/settings/password/SaveChosenLockWorkerBase.java b/src/com/android/settings/password/SaveChosenLockWorkerBase.java
index 5b6a812..2798b3d 100644
--- a/src/com/android/settings/password/SaveChosenLockWorkerBase.java
+++ b/src/com/android/settings/password/SaveChosenLockWorkerBase.java
@@ -21,10 +21,13 @@
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.UserManager;
+import android.util.Pair;
+import android.widget.Toast;
import androidx.fragment.app.Fragment;
import com.android.internal.widget.LockPatternUtils;
+import com.android.settings.R;
/**
* An invisible retained worker fragment to track the AsyncWork that saves (and optionally
@@ -84,7 +87,7 @@
protected void start() {
if (mBlocking) {
- finish(saveAndVerifyInBackground());
+ finish(saveAndVerifyInBackground().second);
} else {
new Task().execute();
}
@@ -92,9 +95,10 @@
/**
* Executes the save and verify work in background.
- * @return Intent with challenge token or null.
+ * @return pair where the first is a boolean confirming whether the change was successful or not
+ * and second is the Intent which has the challenge token or is null.
*/
- protected abstract Intent saveAndVerifyInBackground();
+ protected abstract Pair<Boolean, Intent> saveAndVerifyInBackground();
protected void finish(Intent resultData) {
mFinished = true;
@@ -108,19 +112,24 @@
mBlocking = blocking;
}
- private class Task extends AsyncTask<Void, Void, Intent> {
+ private class Task extends AsyncTask<Void, Void, Pair<Boolean, Intent>> {
+
@Override
- protected Intent doInBackground(Void... params){
+ protected Pair<Boolean, Intent> doInBackground(Void... params){
return saveAndVerifyInBackground();
}
@Override
- protected void onPostExecute(Intent resultData) {
- finish(resultData);
+ protected void onPostExecute(Pair<Boolean, Intent> resultData) {
+ if (!resultData.first) {
+ Toast.makeText(getContext(), R.string.lockpassword_credential_changed,
+ Toast.LENGTH_LONG).show();
+ }
+ finish(resultData.second);
}
}
interface Listener {
- public void onChosenLockSaveFinished(boolean wasSecureBefore, Intent resultData);
+ void onChosenLockSaveFinished(boolean wasSecureBefore, Intent resultData);
}
}
diff --git a/src/com/android/settings/privacy/EnableContentCapturePreferenceController.java b/src/com/android/settings/privacy/EnableContentCapturePreferenceController.java
index b3ea9a7..47610aa 100644
--- a/src/com/android/settings/privacy/EnableContentCapturePreferenceController.java
+++ b/src/com/android/settings/privacy/EnableContentCapturePreferenceController.java
@@ -16,43 +16,34 @@
package com.android.settings.privacy;
+import android.annotation.NonNull;
import android.content.Context;
-import android.os.IBinder;
-import android.os.ServiceManager;
-import android.os.UserHandle;
import android.provider.Settings;
-import android.view.contentcapture.ContentCaptureManager;
import com.android.settings.core.TogglePreferenceController;
+import com.android.settings.utils.ContentCaptureUtils;
-public class EnableContentCapturePreferenceController extends TogglePreferenceController {
+public final class EnableContentCapturePreferenceController extends TogglePreferenceController {
- private static final String KEY_SHOW_PASSWORD = "content_capture";
- private static final int MY_USER_ID = UserHandle.myUserId();
-
- public EnableContentCapturePreferenceController(Context context) {
- super(context, KEY_SHOW_PASSWORD);
+ public EnableContentCapturePreferenceController(@NonNull Context context, @NonNull String key) {
+ super(context, key);
}
@Override
public boolean isChecked() {
- boolean enabled = Settings.Secure.getIntForUser(mContext.getContentResolver(),
- Settings.Secure.CONTENT_CAPTURE_ENABLED, 1, MY_USER_ID) == 1;
- return enabled;
+ return ContentCaptureUtils.isEnabledForUser(mContext);
}
@Override
public boolean setChecked(boolean isChecked) {
- Settings.Secure.putIntForUser(mContext.getContentResolver(),
- Settings.Secure.CONTENT_CAPTURE_ENABLED, isChecked ? 1 : 0, MY_USER_ID);
+ ContentCaptureUtils.setEnabledForUser(mContext, isChecked);
return true;
}
@Override
public int getAvailabilityStatus() {
- // We cannot look for ContentCaptureManager, because it's not available if the service
- // didn't whitelist Settings
- IBinder service = ServiceManager.checkService(Context.CONTENT_CAPTURE_MANAGER_SERVICE);
- return service != null ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
+ boolean available = ContentCaptureUtils.isFeatureAvailable()
+ && ContentCaptureUtils.getServiceSettingsComponentName() == null;
+ return available ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
}
}
diff --git a/src/com/android/settings/privacy/EnableContentCaptureWithServiceSettingsPreferenceController.java b/src/com/android/settings/privacy/EnableContentCaptureWithServiceSettingsPreferenceController.java
new file mode 100644
index 0000000..1456c2d
--- /dev/null
+++ b/src/com/android/settings/privacy/EnableContentCaptureWithServiceSettingsPreferenceController.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2019 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.privacy;
+
+import android.annotation.NonNull;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.util.Log;
+
+import androidx.preference.Preference;
+
+import com.android.settings.core.TogglePreferenceController;
+import com.android.settings.utils.ContentCaptureUtils;
+import com.android.settings.widget.MasterSwitchPreference;
+
+public final class EnableContentCaptureWithServiceSettingsPreferenceController
+ extends TogglePreferenceController {
+
+ private static final String TAG = "ContentCaptureController";
+
+ public EnableContentCaptureWithServiceSettingsPreferenceController(@NonNull Context context,
+ @NonNull String key) {
+ super(context, key);
+ }
+
+ @Override
+ public boolean isChecked() {
+ return ContentCaptureUtils.isEnabledForUser(mContext);
+ }
+
+ @Override
+ public boolean setChecked(boolean isChecked) {
+ ContentCaptureUtils.setEnabledForUser(mContext, isChecked);
+ return true;
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ super.updateState(preference);
+
+ ComponentName componentName = ContentCaptureUtils.getServiceSettingsComponentName();
+ if (componentName != null) {
+ preference.setIntent(new Intent(Intent.ACTION_MAIN).setComponent(componentName));
+ } else {
+ // Should not happen - preference should be disabled by controller
+ Log.w(TAG, "No component name for custom service settings");
+ preference.setSelectable(false);
+ }
+ }
+
+ @Override
+ public int getAvailabilityStatus() {
+ boolean available = ContentCaptureUtils.isFeatureAvailable()
+ && ContentCaptureUtils.getServiceSettingsComponentName() != null;
+ return available ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
+ }
+}
diff --git a/src/com/android/settings/privacy/PrivacyDashboardFragment.java b/src/com/android/settings/privacy/PrivacyDashboardFragment.java
index be6701e..fa21f9d 100644
--- a/src/com/android/settings/privacy/PrivacyDashboardFragment.java
+++ b/src/com/android/settings/privacy/PrivacyDashboardFragment.java
@@ -16,25 +16,22 @@
package com.android.settings.privacy;
-import android.app.ActionBar;
-import android.app.Activity;
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.os.Bundle;
import android.provider.SearchIndexableResource;
-import android.util.Log;
import android.view.View;
import androidx.annotation.VisibleForTesting;
import com.android.settings.R;
+import com.android.settings.Utils;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.notification.LockScreenNotificationPreferenceController;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.search.SearchIndexable;
-import com.android.settingslib.widget.ActionBarShadowController;
import java.util.ArrayList;
import java.util.List;
@@ -87,29 +84,11 @@
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
- styleActionBar();
+ Utils.setActionBarShadowAnimation(getActivity(), getSettingsLifecycle(), getListView());
initLoadingBar();
}
@VisibleForTesting
- void styleActionBar() {
- final Activity activity = getActivity();
- final ActionBar actionBar = activity.getActionBar();
- final Lifecycle lifecycle = getSettingsLifecycle();
- final View scrollView = getListView();
-
- if (actionBar == null) {
- Log.w(TAG, "No actionbar, cannot style actionbar.");
- return;
- }
-
- actionBar.setElevation(0);
- if (lifecycle != null && scrollView != null) {
- ActionBarShadowController.attachToView(activity, lifecycle, scrollView);
- }
- }
-
- @VisibleForTesting
void initLoadingBar() {
mProgressHeader = setPinnedHeaderView(R.layout.progress_header);
mProgressAnimation = mProgressHeader.findViewById(R.id.progress_bar_animation);
diff --git a/src/com/android/settings/sim/SimSelectNotification.java b/src/com/android/settings/sim/SimSelectNotification.java
index cf67f5e..891d171 100644
--- a/src/com/android/settings/sim/SimSelectNotification.java
+++ b/src/com/android/settings/sim/SimSelectNotification.java
@@ -16,6 +16,12 @@
package com.android.settings.sim;
+import static android.telephony.TelephonyManager.EXTRA_DEFAULT_SUBSCRIPTION_ID;
+import static android.telephony.TelephonyManager.EXTRA_DEFAULT_SUBSCRIPTION_SELECT_FOR_ALL_TYPES;
+import static android.telephony.TelephonyManager.EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE;
+import static android.telephony.TelephonyManager.EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_DATA;
+import static android.telephony.TelephonyManager.EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_NONE;
+
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
@@ -23,19 +29,12 @@
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
-import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyManager;
-import android.util.Log;
-import androidx.core.app.NotificationCompat;
-
-import com.android.internal.telephony.IccCardConstants;
import com.android.settings.R;
import com.android.settings.Settings.SimSettingsActivity;
-import com.android.settings.Utils;
-import java.util.List;
+import androidx.core.app.NotificationCompat;
public class SimSelectNotification extends BroadcastReceiver {
private static final String TAG = "SimSelectNotification";
@@ -46,71 +45,24 @@
@Override
public void onReceive(Context context, Intent intent) {
- final TelephonyManager telephonyManager = (TelephonyManager)
- context.getSystemService(Context.TELEPHONY_SERVICE);
- final SubscriptionManager subscriptionManager = SubscriptionManager.from(context);
- final int numSlots = telephonyManager.getSimCount();
-
- // Do not create notifications on single SIM devices or when provisioning i.e. Setup Wizard.
- if (numSlots < 2 || !Utils.isDeviceProvisioned(context)) {
- return;
- }
-
// Cancel any previous notifications
cancelNotification(context);
-
- // If sim state is not ABSENT or LOADED then ignore
- String simStatus = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE);
- if (!(IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(simStatus) ||
- IccCardConstants.INTENT_VALUE_ICC_LOADED.equals(simStatus))) {
- Log.d(TAG, "sim state is not Absent or Loaded");
- return;
- } else {
- Log.d(TAG, "simstatus = " + simStatus);
- }
-
- int state;
- for (int i = 0; i < numSlots; i++) {
- state = telephonyManager.getSimState(i);
- if (!(state == TelephonyManager.SIM_STATE_ABSENT
- || state == TelephonyManager.SIM_STATE_READY
- || state == TelephonyManager.SIM_STATE_UNKNOWN)) {
- Log.d(TAG, "All sims not in valid state yet");
- return;
- }
- }
-
- List<SubscriptionInfo> sil = subscriptionManager.getActiveSubscriptionInfoList(true);
- if (sil == null || sil.size() < 1) {
- Log.d(TAG, "Subscription list is empty");
- return;
- }
-
- // Clear defaults for any subscriptions which no longer exist
- subscriptionManager.clearDefaultsForInactiveSubIds();
-
- boolean dataSelected = SubscriptionManager.isUsableSubIdValue(
- SubscriptionManager.getDefaultDataSubscriptionId());
- boolean smsSelected = SubscriptionManager.isUsableSubIdValue(
- SubscriptionManager.getDefaultSmsSubscriptionId());
-
- // If data and sms defaults are selected, dont show notification (Calls default is optional)
- if (dataSelected && smsSelected) {
- Log.d(TAG, "Data & SMS default sims are selected. No notification");
- return;
- }
-
// Create a notification to tell the user that some defaults are missing
createNotification(context);
- if (sil.size() == 1) {
+ int dialogType = intent.getIntExtra(EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE,
+ EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_NONE);
+ if (dialogType == EXTRA_DEFAULT_SUBSCRIPTION_SELECT_FOR_ALL_TYPES) {
+ int subId = intent.getIntExtra(EXTRA_DEFAULT_SUBSCRIPTION_ID,
+ SubscriptionManager.DEFAULT_SUBSCRIPTION_ID);
+ int slotIndex = SubscriptionManager.getSlotIndex(subId);
// If there is only one subscription, ask if user wants to use if for everything
Intent newIntent = new Intent(context, SimDialogActivity.class);
newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
newIntent.putExtra(SimDialogActivity.DIALOG_TYPE_KEY, SimDialogActivity.PREFERRED_PICK);
- newIntent.putExtra(SimDialogActivity.PREFERRED_SIM, sil.get(0).getSimSlotIndex());
+ newIntent.putExtra(SimDialogActivity.PREFERRED_SIM, slotIndex);
context.startActivity(newIntent);
- } else if (!dataSelected) {
+ } else if (dialogType == EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_DATA) {
// If there are mulitple, ensure they pick default data
Intent newIntent = new Intent(context, SimDialogActivity.class);
newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
diff --git a/src/com/android/settings/slices/SettingsSliceProvider.java b/src/com/android/settings/slices/SettingsSliceProvider.java
index 3187d10..3bdcb13 100644
--- a/src/com/android/settings/slices/SettingsSliceProvider.java
+++ b/src/com/android/settings/slices/SettingsSliceProvider.java
@@ -28,12 +28,12 @@
import android.provider.SettingsSlicesContract;
import android.text.TextUtils;
import android.util.ArrayMap;
-import android.util.ArraySet;
import android.util.KeyValueListParser;
import android.util.Log;
import android.util.Pair;
import androidx.annotation.VisibleForTesting;
+import androidx.collection.ArraySet;
import androidx.slice.Slice;
import androidx.slice.SliceProvider;
@@ -53,7 +53,6 @@
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;
-import java.util.concurrent.ConcurrentHashMap;
/**
* A {@link SliceProvider} for Settings to enabled inline results in system apps.
@@ -123,9 +122,6 @@
@VisibleForTesting
Map<Uri, SliceData> mSliceWeakDataCache;
- @VisibleForTesting
- Map<Uri, SliceData> mSliceDataCache;
-
final Map<Uri, SliceBackgroundWorker> mPinnedWorkers = new ArrayMap<>();
public SettingsSliceProvider() {
@@ -135,7 +131,6 @@
@Override
public boolean onCreateSliceProvider() {
mSlicesDatabaseAccessor = new SlicesDatabaseAccessor(getContext());
- mSliceDataCache = new ConcurrentHashMap<>();
mSliceWeakDataCache = new WeakHashMap<>();
return true;
}
@@ -170,7 +165,6 @@
public void onSliceUnpinned(Uri sliceUri) {
SliceBroadcastRelay.unregisterReceivers(getContext(), sliceUri);
ThreadUtils.postOnMainThread(() -> stopBackgroundWorker(sliceUri));
- mSliceDataCache.remove(sliceUri);
}
@Override
@@ -226,7 +220,7 @@
}
// Remove the SliceData from the cache after it has been used to prevent a memory-leak.
- if (!mSliceDataCache.containsKey(sliceUri)) {
+ if (!getPinnedSlices().contains(sliceUri)) {
mSliceWeakDataCache.remove(sliceUri);
}
return SliceBuilderUtils.buildSlice(getContext(), cachedSliceData);
@@ -396,11 +390,6 @@
ThreadUtils.postOnMainThread(() -> startBackgroundWorker(controller, uri));
- final List<Uri> pinnedSlices = getContext().getSystemService(
- SliceManager.class).getPinnedSlices();
- if (pinnedSlices.contains(uri)) {
- mSliceDataCache.put(uri, sliceData);
- }
mSliceWeakDataCache.put(uri, sliceData);
getContext().getContentResolver().notifyChange(uri, null /* content observer */);
diff --git a/src/com/android/settings/utils/ContentCaptureUtils.java b/src/com/android/settings/utils/ContentCaptureUtils.java
new file mode 100644
index 0000000..a92651f
--- /dev/null
+++ b/src/com/android/settings/utils/ContentCaptureUtils.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2019 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.utils;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.ComponentName;
+import android.content.Context;
+import android.os.IBinder;
+import android.os.ServiceManager;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.util.Log;
+import android.view.contentcapture.ContentCaptureManager;
+
+public final class ContentCaptureUtils {
+
+ private static final String TAG = ContentCaptureUtils.class.getSimpleName();
+ private static final int MY_USER_ID = UserHandle.myUserId();
+
+ public static boolean isEnabledForUser(@NonNull Context context) {
+ boolean enabled = Settings.Secure.getIntForUser(context.getContentResolver(),
+ Settings.Secure.CONTENT_CAPTURE_ENABLED, 1, MY_USER_ID) == 1;
+ return enabled;
+ }
+
+ public static void setEnabledForUser(@NonNull Context context, boolean enabled) {
+ Settings.Secure.putIntForUser(context.getContentResolver(),
+ Settings.Secure.CONTENT_CAPTURE_ENABLED, enabled ? 1 : 0, MY_USER_ID);
+ }
+
+ public static boolean isFeatureAvailable() {
+ // We cannot look for ContentCaptureManager, because it's not available if the service
+ // didn't whitelist Settings
+ IBinder service = ServiceManager.checkService(Context.CONTENT_CAPTURE_MANAGER_SERVICE);
+ return service != null;
+ }
+
+ @Nullable
+ public static ComponentName getServiceSettingsComponentName() {
+ try {
+ return ContentCaptureManager.getServiceSettingsComponentName();
+ } catch (RuntimeException e) {
+ Log.w(TAG, "Could not get service settings: " + e);
+ return null;
+ }
+ }
+
+ private ContentCaptureUtils() {
+ throw new UnsupportedOperationException("contains only static methods");
+ }
+}
diff --git a/src/com/android/settings/widget/AdaptiveOutlineDrawable.java b/src/com/android/settings/widget/AdaptiveOutlineDrawable.java
new file mode 100644
index 0000000..84c4e2f
--- /dev/null
+++ b/src/com/android/settings/widget/AdaptiveOutlineDrawable.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2019 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.widget;
+
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.graphics.Rect;
+import android.graphics.drawable.AdaptiveIconDrawable;
+import android.graphics.drawable.DrawableWrapper;
+import android.util.PathParser;
+
+import androidx.annotation.VisibleForTesting;
+
+import com.android.settings.R;
+import com.android.settings.homepage.AdaptiveIconShapeDrawable;
+
+/**
+ * Adaptive outline drawable with white plain background color and black outline
+ */
+public class AdaptiveOutlineDrawable extends DrawableWrapper {
+ @VisibleForTesting
+ final Paint mOutlinePaint;
+ private Path mPath;
+ private final int mInsetPx;
+ private final Bitmap mBitmap;
+
+ public AdaptiveOutlineDrawable(Resources resources, Bitmap bitmap) {
+ super(new AdaptiveIconShapeDrawable(resources));
+
+ getDrawable().setTint(Color.WHITE);
+ mPath = new Path(PathParser.createPathFromPathData(
+ resources.getString(com.android.internal.R.string.config_icon_mask)));
+ mOutlinePaint = new Paint();
+ mOutlinePaint.setColor(resources.getColor(R.color.bt_outline_color, null));
+ mOutlinePaint.setStyle(Paint.Style.STROKE);
+ mOutlinePaint.setStrokeWidth(resources.getDimension(R.dimen.adaptive_outline_stroke));
+ mOutlinePaint.setAntiAlias(true);
+
+ mInsetPx = resources
+ .getDimensionPixelSize(R.dimen.dashboard_tile_foreground_image_inset);
+ mBitmap = bitmap;
+ }
+
+ @Override
+ public void draw(Canvas canvas) {
+ super.draw(canvas);
+ final Rect bounds = getBounds();
+ final float pathSize = AdaptiveIconDrawable.MASK_SIZE;
+
+ final float scaleX = (bounds.right - bounds.left) / pathSize;
+ final float scaleY = (bounds.bottom - bounds.top) / pathSize;
+
+ final int count = canvas.save();
+ canvas.scale(scaleX, scaleY);
+ // Draw outline
+ canvas.drawPath(mPath, mOutlinePaint);
+ canvas.restoreToCount(count);
+
+ // Draw the foreground icon
+ canvas.drawBitmap(mBitmap, bounds.left + mInsetPx, bounds.top + mInsetPx, null);
+ }
+
+ @Override
+ public int getIntrinsicHeight() {
+ return mBitmap.getHeight() + 2 * mInsetPx;
+ }
+
+ @Override
+ public int getIntrinsicWidth() {
+ return mBitmap.getWidth() + 2 * mInsetPx;
+ }
+}
diff --git a/src/com/android/settings/widget/AppCheckBoxPreference.java b/src/com/android/settings/widget/AppCheckBoxPreference.java
index e56efd9..3ce67eb 100644
--- a/src/com/android/settings/widget/AppCheckBoxPreference.java
+++ b/src/com/android/settings/widget/AppCheckBoxPreference.java
@@ -21,7 +21,6 @@
import android.util.AttributeSet;
import android.view.View;
import android.widget.LinearLayout;
-import android.widget.TextView;
import androidx.preference.CheckBoxPreference;
import androidx.preference.PreferenceViewHolder;
@@ -46,11 +45,6 @@
public void onBindViewHolder(PreferenceViewHolder holder) {
super.onBindViewHolder(holder);
- final TextView appendix = (TextView) holder.findViewById(R.id.appendix);
- if (appendix != null) {
- appendix.setVisibility(View.GONE);
- }
-
final LinearLayout layout = (LinearLayout) holder.findViewById(R.id.summary_container);
if (layout != null) {
// If summary doesn't exist, make it gone
diff --git a/src/com/android/settings/widget/AppSwitchPreference.java b/src/com/android/settings/widget/AppSwitchPreference.java
index 288096e..506ab76 100644
--- a/src/com/android/settings/widget/AppSwitchPreference.java
+++ b/src/com/android/settings/widget/AppSwitchPreference.java
@@ -17,10 +17,7 @@
package com.android.settings.widget;
import android.content.Context;
-import android.text.TextUtils;
-import android.view.View;
-import androidx.preference.PreferenceViewHolder;
import androidx.preference.SwitchPreference;
import com.android.settings.R;
@@ -31,12 +28,4 @@
super(context);
setLayoutResource(R.layout.preference_app);
}
-
- @Override
- public void onBindViewHolder(PreferenceViewHolder view) {
- super.onBindViewHolder(view);
-
- view.findViewById(R.id.summary_container)
- .setVisibility(TextUtils.isEmpty(getSummary()) ? View.GONE : View.VISIBLE);
- }
}
diff --git a/src/com/android/settings/wifi/AddWifiNetworkPreference.java b/src/com/android/settings/wifi/AddWifiNetworkPreference.java
index e49f2ab..cd2e4a8 100644
--- a/src/com/android/settings/wifi/AddWifiNetworkPreference.java
+++ b/src/com/android/settings/wifi/AddWifiNetworkPreference.java
@@ -20,6 +20,7 @@
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.util.Log;
+import android.view.View;
import android.widget.ImageButton;
import androidx.annotation.DrawableRes;
@@ -62,6 +63,10 @@
getContext().startActivity(
WifiDppUtils.getEnrolleeQrCodeScannerIntent(/* ssid */ null));
});
+
+ final View divider = (View) holder.findViewById(
+ com.android.settingslib.R.id.two_target_divider);
+ divider.setVisibility(View.INVISIBLE);
}
}
diff --git a/src/com/android/settings/wifi/NetworkRequestDialogFragment.java b/src/com/android/settings/wifi/NetworkRequestDialogFragment.java
index 28c6cb7..e9057e6 100644
--- a/src/com/android/settings/wifi/NetworkRequestDialogFragment.java
+++ b/src/com/android/settings/wifi/NetworkRequestDialogFragment.java
@@ -138,6 +138,10 @@
.setOnItemClickListener(
(parent, view, position, id) -> this.onClick(dialog, position));
+ // Don't dismiss dialog when touching outside. User report it is easy to touch outside.
+ // This causes dialog to close. Which is concerned as a bad UX (b/128877712).
+ dialog.setCanceledOnTouchOutside(false);
+
dialog.setOnShowListener((dialogInterface) -> {
// Replace NeutralButton onClickListener to avoid closing dialog
final Button neutralBtn = dialog.getButton(AlertDialog.BUTTON_NEUTRAL);
diff --git a/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java b/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java
index f328dba..cf59dbd 100644
--- a/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java
+++ b/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java
@@ -771,14 +771,7 @@
* Share the wifi network with QR code.
*/
private void shareNetwork() {
- final String title = mContext.getString(
- R.string.lockpassword_confirm_your_pattern_header);
- final String description = String.format(
- mContext.getString(R.string.wifi_sharing_message),
- mAccessPoint.getSsidStr());
-
- WifiDppUtils.showLockScreen(mContext, title, description,
- () -> launchWifiDppConfiguratorActivity());
+ WifiDppUtils.showLockScreen(mContext, () -> launchWifiDppConfiguratorActivity());
}
/**
diff --git a/src/com/android/settings/wifi/dpp/WifiDppQrCodeGeneratorFragment.java b/src/com/android/settings/wifi/dpp/WifiDppQrCodeGeneratorFragment.java
index 2cd5e23..4e6a0d6 100644
--- a/src/com/android/settings/wifi/dpp/WifiDppQrCodeGeneratorFragment.java
+++ b/src/com/android/settings/wifi/dpp/WifiDppQrCodeGeneratorFragment.java
@@ -21,6 +21,7 @@
import android.content.Context;
import android.graphics.Bitmap;
import android.os.Bundle;
+import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
@@ -29,6 +30,7 @@
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
+import android.widget.TextView;
import com.android.settings.R;
import com.android.settings.wifi.qrcode.QrCodeGenerator;
@@ -43,6 +45,7 @@
private static final String TAG = "WifiDppQrCodeGeneratorFragment";
private ImageView mQrCodeView;
+ private TextView mPasswordView;
private String mQrCode;
@Override
@@ -138,12 +141,27 @@
final WifiNetworkConfig wifiNetworkConfig = getWifiNetworkConfigFromHostActivity();
if (wifiNetworkConfig.isHotspot()) {
mTitle.setText(R.string.wifi_dpp_share_hotspot);
- mSummary.setText(getString(R.string.wifi_dpp_scan_qr_code_to_share_hotspot,
- wifiNetworkConfig.getSsid()));
} else {
mTitle.setText(R.string.wifi_dpp_share_wifi);
+ }
+
+ final String password = wifiNetworkConfig.getPreSharedKey();
+ mPasswordView = view.findViewById(R.id.password);
+ if (TextUtils.isEmpty(password)) {
+ mSummary.setText(getString(
+ R.string.wifi_dpp_scan_open_network_qr_code_with_another_device,
+ wifiNetworkConfig.getSsid()));
+
+ mPasswordView.setVisibility(View.GONE);
+ } else {
mSummary.setText(getString(R.string.wifi_dpp_scan_qr_code_with_another_device,
wifiNetworkConfig.getSsid()));
+
+ if (wifiNetworkConfig.isHotspot()) {
+ mPasswordView.setText(getString(R.string.wifi_dpp_hotspot_password, password));
+ } else {
+ mPasswordView.setText(getString(R.string.wifi_dpp_wifi_password, password));
+ }
}
mQrCode = wifiNetworkConfig.getQrCode();
diff --git a/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java b/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java
index 4535599..905d3a0 100644
--- a/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java
+++ b/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java
@@ -45,6 +45,7 @@
import android.widget.ProgressBar;
import android.widget.TextView;
+import androidx.annotation.StringRes;
import androidx.lifecycle.ViewModelProviders;
import com.android.settings.R;
@@ -52,12 +53,17 @@
import com.android.settings.wifi.qrcode.QrCamera;
import com.android.settings.wifi.qrcode.QrDecorateView;
+import com.android.settingslib.wifi.AccessPoint;
+import com.android.settingslib.wifi.WifiTracker;
+import com.android.settingslib.wifi.WifiTrackerFactory;
+
import java.util.List;
public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment implements
SurfaceTextureListener,
QrCamera.ScannerCallback,
- WifiManager.ActionListener {
+ WifiManager.ActionListener,
+ WifiTracker.WifiListener {
private static final String TAG = "WifiDppQrCodeScannerFragment";
/** Message sent to hide error message */
@@ -80,6 +86,8 @@
private static final String KEY_LATEST_ERROR_CODE = "key_latest_error_code";
private static final String KEY_WIFI_CONFIGURATION = "key_wifi_configuration";
+ private static final int ARG_RESTART_CAMERA = 1;
+
private ProgressBar mProgressBar;
private QrCamera mCamera;
private TextureView mTextureView;
@@ -100,6 +108,68 @@
private int mLatestStatusCode = WifiDppUtils.EASY_CONNECT_EVENT_FAILURE_NONE;
+ private WifiTracker mWifiTracker;
+
+ private final Handler mHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MESSAGE_HIDE_ERROR_MESSAGE:
+ mErrorMessage.setVisibility(View.INVISIBLE);
+ break;
+
+ case MESSAGE_SHOW_ERROR_MESSAGE:
+ final String errorMessage = (String) msg.obj;
+
+ mErrorMessage.setVisibility(View.VISIBLE);
+ mErrorMessage.setText(errorMessage);
+ mErrorMessage.sendAccessibilityEvent(
+ AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
+
+ // Cancel any pending messages to hide error view and requeue the message so
+ // user has time to see error
+ removeMessages(MESSAGE_HIDE_ERROR_MESSAGE);
+ sendEmptyMessageDelayed(MESSAGE_HIDE_ERROR_MESSAGE,
+ SHOW_ERROR_MESSAGE_INTERVAL);
+
+ if (msg.arg1 == ARG_RESTART_CAMERA) {
+ mProgressBar.setVisibility(View.INVISIBLE);
+ restartCamera();
+ }
+ break;
+
+ case MESSAGE_SCAN_WIFI_DPP_SUCCESS:
+ mErrorMessage.setVisibility(View.INVISIBLE);
+
+ if (mScanWifiDppSuccessListener == null) {
+ return;
+ }
+ mScanWifiDppSuccessListener.onScanWifiDppSuccess((WifiQrCode)msg.obj);
+
+ if (!mIsConfiguratorMode) {
+ mProgressBar.setVisibility(View.VISIBLE);
+ startWifiDppEnrolleeInitiator((WifiQrCode)msg.obj);
+ updateEnrolleeSummary();
+ mSummary.sendAccessibilityEvent(
+ AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
+ }
+ break;
+
+ case MESSAGE_SCAN_ZXING_WIFI_FORMAT_SUCCESS:
+ mErrorMessage.setVisibility(View.INVISIBLE);
+
+ final WifiNetworkConfig wifiNetworkConfig = (WifiNetworkConfig)msg.obj;
+ mWifiConfiguration = wifiNetworkConfig.getWifiConfigurationOrNull();
+ wifiNetworkConfig.connect(getContext(),
+ /* listener */ WifiDppQrCodeScannerFragment.this);
+ break;
+
+ default:
+ return;
+ }
+ }
+ };
+
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -175,6 +245,9 @@
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
+ mWifiTracker = WifiTrackerFactory.create(getActivity(), /* wifiListener */ this,
+ getSettingsLifecycle(), /* includeSaved */ false, /* includeScans */ true);
+
// setTitle for Talkback
if (mIsConfiguratorMode) {
getActivity().setTitle(R.string.wifi_dpp_add_device_to_network);
@@ -291,7 +364,7 @@
try {
mWifiQrCode = new WifiQrCode(qrCode);
} catch (IllegalArgumentException e) {
- mHandler.sendEmptyMessage(MESSAGE_SHOW_ERROR_MESSAGE);
+ showErrorMessage(R.string.wifi_dpp_could_not_detect_valid_qr_code);
return false;
}
@@ -301,14 +374,14 @@
if (!mIsConfiguratorMode && WifiQrCode.SCHEME_ZXING_WIFI_NETWORK_CONFIG.equals(scheme)) {
final String ssidQrCode = mWifiQrCode.getWifiNetworkConfig().getSsid();
if (!TextUtils.isEmpty(mSsid) && !mSsid.equals(ssidQrCode)) {
- mHandler.sendEmptyMessage(MESSAGE_SHOW_ERROR_MESSAGE);
+ showErrorMessage(R.string.wifi_dpp_could_not_detect_valid_qr_code);
return false;
}
}
// It's impossible to provision other device with ZXing Wi-Fi Network config format
if (mIsConfiguratorMode && WifiQrCode.SCHEME_ZXING_WIFI_NETWORK_CONFIG.equals(scheme)) {
- mHandler.sendEmptyMessage(MESSAGE_SHOW_ERROR_MESSAGE);
+ showErrorMessage(R.string.wifi_dpp_could_not_detect_valid_qr_code);
return false;
}
@@ -385,59 +458,18 @@
}
}
- public void showErrorMessage(String message) {
- mErrorMessage.setVisibility(View.VISIBLE);
- mErrorMessage.setText(message);
- mErrorMessage.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
-
- mHandler.removeMessages(MESSAGE_HIDE_ERROR_MESSAGE);
- mHandler.sendEmptyMessageDelayed(MESSAGE_HIDE_ERROR_MESSAGE,
- SHOW_ERROR_MESSAGE_INTERVAL);
+ private void showErrorMessage(@StringRes int messageResId) {
+ final Message message = mHandler.obtainMessage(MESSAGE_SHOW_ERROR_MESSAGE,
+ getString(messageResId));
+ message.sendToTarget();
}
- private final Handler mHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case MESSAGE_HIDE_ERROR_MESSAGE:
- mErrorMessage.setVisibility(View.INVISIBLE);
- break;
-
- case MESSAGE_SHOW_ERROR_MESSAGE:
- showErrorMessage(getString(R.string.wifi_dpp_could_not_detect_valid_qr_code));
- break;
-
- case MESSAGE_SCAN_WIFI_DPP_SUCCESS:
- mErrorMessage.setVisibility(View.INVISIBLE);
-
- if (mScanWifiDppSuccessListener == null) {
- return;
- }
- mScanWifiDppSuccessListener.onScanWifiDppSuccess((WifiQrCode)msg.obj);
-
- if (!mIsConfiguratorMode) {
- mProgressBar.setVisibility(View.VISIBLE);
- startWifiDppEnrolleeInitiator((WifiQrCode)msg.obj);
- updateEnrolleeSummary();
- mSummary.sendAccessibilityEvent(
- AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
- }
- break;
-
- case MESSAGE_SCAN_ZXING_WIFI_FORMAT_SUCCESS:
- mErrorMessage.setVisibility(View.INVISIBLE);
-
- final WifiNetworkConfig wifiNetworkConfig = (WifiNetworkConfig)msg.obj;
- mWifiConfiguration = wifiNetworkConfig.getWifiConfigurationOrNull();
- wifiNetworkConfig.connect(getContext(),
- /* listener */ WifiDppQrCodeScannerFragment.this);
- break;
-
- default:
- return;
- }
- }
- };
+ private void showErrorMessageAndRestartCamera(@StringRes int messageResId) {
+ final Message message = mHandler.obtainMessage(MESSAGE_SHOW_ERROR_MESSAGE,
+ getString(messageResId));
+ message.arg1 = ARG_RESTART_CAMERA;
+ message.sendToTarget();
+ }
@Override
public void onSaveInstanceState(Bundle outState) {
@@ -468,9 +500,7 @@
Log.e(TAG, "Invalid networkId " + newNetworkId);
mLatestStatusCode = EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_GENERIC;
updateEnrolleeSummary();
- mProgressBar.setVisibility(View.INVISIBLE);
- showErrorMessage(getString(R.string.wifi_dpp_check_connection_try_again));
- restartCamera();
+ showErrorMessageAndRestartCamera(R.string.wifi_dpp_check_connection_try_again);
}
@Override
@@ -482,23 +512,22 @@
public void onFailure(int code) {
Log.d(TAG, "EasyConnectEnrolleeStatusCallback.onFailure " + code);
+ int errorMessageResId = 0;
switch (code) {
case EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_INVALID_URI:
- showErrorMessage(getString(R.string.wifi_dpp_could_not_detect_valid_qr_code));
+ errorMessageResId = R.string.wifi_dpp_could_not_detect_valid_qr_code;
break;
case EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_AUTHENTICATION:
- showErrorMessage(
- getString(R.string.wifi_dpp_failure_authentication_or_configuration));
+ errorMessageResId = R.string.wifi_dpp_failure_authentication_or_configuration;
break;
case EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_NOT_COMPATIBLE:
- showErrorMessage(getString(R.string.wifi_dpp_failure_not_compatible));
+ errorMessageResId = R.string.wifi_dpp_failure_not_compatible;
break;
case EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_CONFIGURATION:
- showErrorMessage(
- getString(R.string.wifi_dpp_failure_authentication_or_configuration));
+ errorMessageResId = R.string.wifi_dpp_failure_authentication_or_configuration;
break;
case EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_BUSY:
@@ -515,11 +544,11 @@
return;
case EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_TIMEOUT:
- showErrorMessage(getString(R.string.wifi_dpp_failure_timeout));
+ errorMessageResId = R.string.wifi_dpp_failure_timeout;
break;
case EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_GENERIC:
- showErrorMessage(getString(R.string.wifi_dpp_failure_generic));
+ errorMessageResId = R.string.wifi_dpp_failure_generic;
break;
case EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_NOT_SUPPORTED:
@@ -536,8 +565,7 @@
mLatestStatusCode = code;
updateEnrolleeSummary();
- mProgressBar.setVisibility(View.INVISIBLE);
- restartCamera();
+ showErrorMessageAndRestartCamera(errorMessageResId);
}
@Override
@@ -555,21 +583,39 @@
@Override
public void onSuccess() {
- final Intent resultIntent = new Intent();
- resultIntent.putExtra(WifiDialogActivity.KEY_WIFI_CONFIGURATION, mWifiConfiguration);
+ if (isEnrollingWifiNetworkReachable()) {
+ final Intent resultIntent = new Intent();
+ resultIntent.putExtra(WifiDialogActivity.KEY_WIFI_CONFIGURATION, mWifiConfiguration);
- final Activity hostActivity = getActivity();
- hostActivity.setResult(Activity.RESULT_OK, resultIntent);
- hostActivity.finish();
+ final Activity hostActivity = getActivity();
+ hostActivity.setResult(Activity.RESULT_OK, resultIntent);
+ hostActivity.finish();
+ } else {
+ Log.d(TAG, "Enroll Wi-Fi network succeeded but it's not reachable");
+ showErrorMessageAndRestartCamera(R.string.wifi_dpp_check_connection_try_again);
+ }
}
@Override
public void onFailure(int reason) {
Log.d(TAG, "Wi-Fi connect onFailure reason - " + reason);
+ showErrorMessageAndRestartCamera(R.string.wifi_dpp_check_connection_try_again);
+ }
- mProgressBar.setVisibility(View.INVISIBLE);
- showErrorMessage(getString(R.string.wifi_dpp_check_connection_try_again));
- restartCamera();
+ private boolean isEnrollingWifiNetworkReachable() {
+ if (mWifiConfiguration == null) {
+ Log.e(TAG, "Connect succeeded but lost WifiConfiguration");
+ return false;
+ }
+
+ final List<AccessPoint> scannedAccessPoints = mWifiTracker.getAccessPoints();
+ for (AccessPoint accessPoint : scannedAccessPoints) {
+ if (accessPoint.matches(mWifiConfiguration) &&
+ accessPoint.isReachable()) {
+ return true;
+ }
+ }
+ return false;
}
// Check is Easy Connect handshaking or not
@@ -610,4 +656,25 @@
mSummary.setText(description);
}
}
+
+ /** Called when the state of Wifi has changed. */
+ @Override
+ public void onWifiStateChanged(int state) {
+ // Do nothing.
+ }
+
+ /** Called when the connection state of wifi has changed. */
+ @Override
+ public void onConnectedChanged() {
+ // Do nothing.
+ }
+
+ /**
+ * Called to indicate the list of AccessPoints has been updated and
+ * getAccessPoints should be called to get the latest information.
+ */
+ @Override
+ public void onAccessPointsChanged() {
+ // Do nothing.
+ }
}
diff --git a/src/com/android/settings/wifi/dpp/WifiDppUtils.java b/src/com/android/settings/wifi/dpp/WifiDppUtils.java
index fe7af27..bf78b3f 100644
--- a/src/com/android/settings/wifi/dpp/WifiDppUtils.java
+++ b/src/com/android/settings/wifi/dpp/WifiDppUtils.java
@@ -29,6 +29,8 @@
import android.text.TextUtils;
import android.util.FeatureFlagUtils;
+import com.android.settings.R;
+
import com.android.settingslib.wifi.AccessPoint;
import java.util.List;
@@ -273,13 +275,10 @@
* user of the device.
*
* @param context The {@code Context} used to get {@code KeyguardManager} service
- * @param title The title on lock screen
- * @param description The description on lock screen
* @param successRunnable The {@code Runnable} which will be executed if the user does not setup
* device security or if lock screen is unlocked
*/
- public static void showLockScreen(Context context, String title, String description,
- Runnable successRunnable) {
+ public static void showLockScreen(Context context, Runnable successRunnable) {
final KeyguardManager keyguardManager = (KeyguardManager) context.getSystemService(
Context.KEYGUARD_SERVICE);
@@ -299,8 +298,7 @@
};
final BiometricPrompt.Builder builder = new BiometricPrompt.Builder(context)
- .setTitle(title)
- .setDescription(description);
+ .setTitle(context.getText(R.string.wifi_dpp_lockscreen_title));
if (keyguardManager.isDeviceSecure()) {
builder.setDeviceCredentialAllowed(true);
diff --git a/src/com/android/settings/wifi/slice/WifiSlice.java b/src/com/android/settings/wifi/slice/WifiSlice.java
index 0c95a23..f2c919b 100644
--- a/src/com/android/settings/wifi/slice/WifiSlice.java
+++ b/src/com/android/settings/wifi/slice/WifiSlice.java
@@ -65,7 +65,10 @@
import com.android.settingslib.wifi.WifiTracker;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
/**
* {@link CustomSliceable} for Wi-Fi, used by generic clients.
@@ -150,6 +153,7 @@
return new ListBuilder(mContext, getUri(), ListBuilder.INFINITY)
.setAccentColor(COLOR_NOT_TINTED)
+ .setKeywords(getKeywords())
.addRow(new ListBuilder.RowBuilder()
.setTitle(title)
.setSubtitle(summary)
@@ -346,6 +350,14 @@
intent, 0 /* flags */);
}
+ private Set<String> getKeywords() {
+ final String keywords = mContext.getString(R.string.keywords_wifi);
+ return Arrays.asList(TextUtils.split(keywords, ","))
+ .stream()
+ .map(String::trim)
+ .collect(Collectors.toSet());
+ }
+
@Override
public Class getBackgroundWorkerClass() {
return WifiScanWorker.class;
diff --git a/src/com/android/settings/wifi/tether/WifiTetherSSIDPreferenceController.java b/src/com/android/settings/wifi/tether/WifiTetherSSIDPreferenceController.java
index 10f3e56..b7ddcae 100644
--- a/src/com/android/settings/wifi/tether/WifiTetherSSIDPreferenceController.java
+++ b/src/com/android/settings/wifi/tether/WifiTetherSSIDPreferenceController.java
@@ -104,13 +104,7 @@
}
private void shareHotspotNetwork(Intent intent) {
- final String title = mContext.getString(
- R.string.lockpassword_confirm_your_pattern_header);
- final String description = String.format(
- mContext.getString(R.string.wifi_sharing_message), mSSID);
-
- WifiDppUtils.showLockScreen(mContext, title, description,
- () -> mContext.startActivity(intent));
+ WifiDppUtils.showLockScreen(mContext, () -> mContext.startActivity(intent));
}
@VisibleForTesting
diff --git a/src/com/android/settings/wifi/tether/WifiTetherSsidPreference.java b/src/com/android/settings/wifi/tether/WifiTetherSsidPreference.java
index e2566d0..64014d9 100644
--- a/src/com/android/settings/wifi/tether/WifiTetherSsidPreference.java
+++ b/src/com/android/settings/wifi/tether/WifiTetherSsidPreference.java
@@ -39,7 +39,6 @@
private ImageButton mImageButton;
private Drawable mButtonIcon;
- private View mDivider;
private View.OnClickListener mClickListener;
private boolean mVisible;
@@ -69,8 +68,6 @@
}
private void initialize() {
- // TODO(b/129019971): use methods of divider line in parent object
- setLayoutResource(R.layout.preference);
setWidgetLayoutResource(R.layout.wifi_button_preference_widget);
}
@@ -85,17 +82,13 @@
getContext().getString(R.string.wifi_dpp_share_hotspot));
setButtonIcon(R.drawable.ic_qrcode_24dp);
mImageButton.setImageDrawable(mButtonIcon);
-
- mDivider = holder.findViewById(R.id.two_target_divider);
}
if (mVisible) {
mImageButton.setOnClickListener(mClickListener);
mImageButton.setVisibility(View.VISIBLE);
- mDivider.setVisibility(View.VISIBLE);
} else {
mImageButton.setVisibility(View.GONE);
- mDivider.setVisibility(View.GONE);
}
}
diff --git a/tests/robotests/src/com/android/settings/UtilsTest.java b/tests/robotests/src/com/android/settings/UtilsTest.java
index 37186ca..3d3aff4 100644
--- a/tests/robotests/src/com/android/settings/UtilsTest.java
+++ b/tests/robotests/src/com/android/settings/UtilsTest.java
@@ -28,6 +28,8 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.app.ActionBar;
+import android.app.Activity;
import android.app.admin.DevicePolicyManager;
import android.content.ComponentName;
import android.content.Context;
@@ -51,15 +53,18 @@
import android.os.storage.VolumeInfo;
import android.util.IconDrawableFactory;
import android.widget.EditText;
+import android.widget.ScrollView;
import android.widget.TextView;
import androidx.core.graphics.drawable.IconCompat;
+import androidx.fragment.app.FragmentActivity;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
@@ -259,4 +264,21 @@
public void isPackageEnabled_noApp_returnFalse() {
assertThat(Utils.isPackageEnabled(mContext, PACKAGE_NAME)).isFalse();
}
+
+ @Test
+ public void setActionBarShadowAnimation_nullParameters_shouldNotCrash() {
+ // no crash here
+ Utils.setActionBarShadowAnimation(null, null, null);
+ }
+
+ @Test
+ public void setActionBarShadowAnimation_shouldSetElevationToZero() {
+ final FragmentActivity activity = Robolectric.setupActivity(FragmentActivity.class);
+ final ActionBar actionBar = activity.getActionBar();
+
+ Utils.setActionBarShadowAnimation(activity, activity.getLifecycle(),
+ new ScrollView(mContext));
+
+ assertThat(actionBar.getElevation()).isEqualTo(0.f);
+ }
}
diff --git a/tests/robotests/src/com/android/settings/applications/manageapplications/ApplicationViewHolderTest.java b/tests/robotests/src/com/android/settings/applications/manageapplications/ApplicationViewHolderTest.java
index b8d0f20..c3ae904 100644
--- a/tests/robotests/src/com/android/settings/applications/manageapplications/ApplicationViewHolderTest.java
+++ b/tests/robotests/src/com/android/settings/applications/manageapplications/ApplicationViewHolderTest.java
@@ -46,7 +46,7 @@
public void seUp() {
mContext = RuntimeEnvironment.application;
mView = ApplicationViewHolder.newView(new FrameLayout(mContext));
- mHolder = new ApplicationViewHolder(mView, false /* useStableHeight */);
+ mHolder = new ApplicationViewHolder(mView);
}
@Test
@@ -67,10 +67,6 @@
mHolder.setSummary(R.string.disabled);
assertThat(mHolder.mSummary.getText()).isEqualTo(mContext.getText(R.string.disabled));
- assertThat(mHolder.mSummaryContainer.getVisibility()).isEqualTo(View.VISIBLE);
-
- mHolder.setSummary(null);
- assertThat(mHolder.mSummaryContainer.getVisibility()).isEqualTo(View.GONE);
}
@Test
@@ -104,7 +100,7 @@
@Test
public void twoTouchTarget() {
mView = ApplicationViewHolder.newView(new FrameLayout(mContext), true);
- mHolder = new ApplicationViewHolder(mView, false /* useStableHeight */);
+ mHolder = new ApplicationViewHolder(mView);
assertThat(mHolder.mSwitch).isNotNull();
assertThat(mHolder.mWidgetContainer.getChildCount()).isEqualTo(1);
}
@@ -112,8 +108,9 @@
@Test
public void updateSwitch() {
mView = ApplicationViewHolder.newView(new FrameLayout(mContext), true);
- mHolder = new ApplicationViewHolder(mView, false /* useStableHeight */);
- mHolder.updateSwitch(v -> {}, true, true);
+ mHolder = new ApplicationViewHolder(mView);
+ mHolder.updateSwitch(v -> {
+ } /* listener */, true, true);
assertThat(mHolder.mSwitch.isChecked()).isTrue();
assertThat(mHolder.mSwitch.isEnabled()).isTrue();
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 419fc49..27c3e7d 100644
--- a/tests/robotests/src/com/android/settings/applications/manageapplications/ManageApplicationsTest.java
+++ b/tests/robotests/src/com/android/settings/applications/manageapplications/ManageApplicationsTest.java
@@ -235,16 +235,6 @@
}
@Test
- public void shouldUseStableItemHeight() {
- assertThat(ManageApplications.ApplicationsAdapter.shouldUseStableItemHeight(
- LIST_TYPE_MAIN))
- .isTrue();
- assertThat(ManageApplications.ApplicationsAdapter.shouldUseStableItemHeight(
- LIST_TYPE_NOTIFICATION))
- .isTrue();
- }
-
- @Test
public void onRebuildComplete_shouldHideLoadingView() {
final Context context = RuntimeEnvironment.application;
final RecyclerView recyclerView = mock(RecyclerView.class);
diff --git a/tests/robotests/src/com/android/settings/applications/manageapplications/MusicViewHolderControllerTest.java b/tests/robotests/src/com/android/settings/applications/manageapplications/MusicViewHolderControllerTest.java
index 8f5b0ab..74fb98f 100644
--- a/tests/robotests/src/com/android/settings/applications/manageapplications/MusicViewHolderControllerTest.java
+++ b/tests/robotests/src/com/android/settings/applications/manageapplications/MusicViewHolderControllerTest.java
@@ -64,7 +64,7 @@
mController = new MusicViewHolderController(mContext, mSource, fsUuid, new UserHandle(0));
View view = ApplicationViewHolder.newView(new FrameLayout(mContext));
- mHolder = new ApplicationViewHolder(view, false /* useStableHeight */);
+ mHolder = new ApplicationViewHolder(view);
}
@Test
diff --git a/tests/robotests/src/com/android/settings/applications/manageapplications/PhotosViewHolderControllerTest.java b/tests/robotests/src/com/android/settings/applications/manageapplications/PhotosViewHolderControllerTest.java
index c453474..5475b9c 100644
--- a/tests/robotests/src/com/android/settings/applications/manageapplications/PhotosViewHolderControllerTest.java
+++ b/tests/robotests/src/com/android/settings/applications/manageapplications/PhotosViewHolderControllerTest.java
@@ -63,7 +63,7 @@
mController = new PhotosViewHolderController(mContext, mSource, fsUuid, new UserHandle(0));
final View view = ApplicationViewHolder.newView(new FrameLayout(mContext));
- mHolder = new ApplicationViewHolder(view, false /* useStableHeight */);
+ mHolder = new ApplicationViewHolder(view);
}
@Test
@@ -71,19 +71,19 @@
mController.setupView(mHolder);
assertThat(mHolder.mSummary.getText().toString())
- .isEqualTo(Formatter.formatFileSize(mContext, 0));
+ .isEqualTo(Formatter.formatFileSize(mContext, 0));
}
@Test
public void storageShouldRepresentStorageStatsQuery() throws Exception {
when(mSource.getExternalStorageStats(nullable(String.class), nullable(UserHandle.class)))
- .thenReturn(new StorageStatsSource.ExternalStorageStats(1, 0, 1, 10, 0));
+ .thenReturn(new StorageStatsSource.ExternalStorageStats(1, 0, 1, 10, 0));
mController.queryStats();
mController.setupView(mHolder);
assertThat(mHolder.mSummary.getText().toString())
- .isEqualTo(Formatter.formatFileSize(mContext, 11));
+ .isEqualTo(Formatter.formatFileSize(mContext, 11));
}
@Test
diff --git a/tests/robotests/src/com/android/settings/bluetooth/UtilsTest.java b/tests/robotests/src/com/android/settings/bluetooth/UtilsTest.java
index 51e559f..a956518 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/UtilsTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/UtilsTest.java
@@ -29,6 +29,8 @@
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.testutils.FakeFeatureFactory;
+import com.android.settings.widget.AdaptiveIcon;
+import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
@@ -39,6 +41,7 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
@RunWith(RobolectricTestRunner.class)
public class UtilsTest {
@@ -51,6 +54,8 @@
private Context mContext;
@Mock
private BluetoothDevice mBluetoothDevice;
+ @Mock
+ private CachedBluetoothDevice mCachedBluetoothDevice;
private MetricsFeatureProvider mMetricsFeatureProvider;
@@ -107,4 +112,16 @@
BluetoothDevice.METADATA_IS_UNTHETHERED_HEADSET)).isEqualTo(true);
}
+ @Test
+ public void getBtRainbowDrawableWithDescription_normalHeadset_returnAdaptiveIcon() {
+ when(mBluetoothDevice.getMetadata(
+ BluetoothDevice.METADATA_IS_UNTHETHERED_HEADSET)).thenReturn("false");
+ when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice);
+ when(mCachedBluetoothDevice.getAddress()).thenReturn("1f:aa:bb");
+
+ assertThat(Utils.getBtRainbowDrawableWithDescription(RuntimeEnvironment.application,
+ mCachedBluetoothDevice).first).isInstanceOf(
+ AdaptiveIcon.class);
+ }
+
}
diff --git a/tests/robotests/src/com/android/settings/development/OverlayCategoryPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/OverlayCategoryPreferenceControllerTest.java
index 8a90b20..b2e8013 100644
--- a/tests/robotests/src/com/android/settings/development/OverlayCategoryPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/development/OverlayCategoryPreferenceControllerTest.java
@@ -221,6 +221,7 @@
return new OverlayInfo(pkg /* packageName */,
"android" /* targetPackageName */,
+ null /* targetOverlayableName */,
TEST_CATEGORY/* category */,
pkg + ".baseCodePath" /* baseCodePath */,
state /* state */,
diff --git a/tests/robotests/src/com/android/settings/display/ThemePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/display/ThemePreferenceControllerTest.java
index 41947a0..5133ae6 100644
--- a/tests/robotests/src/com/android/settings/display/ThemePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/display/ThemePreferenceControllerTest.java
@@ -84,7 +84,7 @@
when(mPackageManager.getPackageInfo(anyString(), anyInt())).thenReturn(
new PackageInfo());
when(mOverlayManager.getOverlayInfosForTarget(any(), anyInt()))
- .thenReturn(Arrays.asList(new OverlayInfo("", "", "", "", 0, 0, 0, false)));
+ .thenReturn(Arrays.asList(new OverlayInfo("", "", "", "", "", 0, 0, 0, false)));
assertThat(mController.isAvailable()).isFalse();
}
@@ -94,8 +94,9 @@
new PackageInfo());
when(mOverlayManager.getOverlayInfosForTarget(any(), anyInt()))
.thenReturn(Arrays.asList(
- new OverlayInfo("", "", OverlayInfo.CATEGORY_THEME, "", 0, 0, 0, true),
- new OverlayInfo("", "", OverlayInfo.CATEGORY_THEME, "", 0, 0, 0, true)));
+ new OverlayInfo("", "", "", OverlayInfo.CATEGORY_THEME, "", 0, 0, 0, true),
+ new OverlayInfo("", "", "", OverlayInfo.CATEGORY_THEME, "", 0, 0, 0,
+ true)));
assertThat(mController.isAvailable()).isTrue();
}
@@ -140,9 +141,9 @@
@Test
public void getCurrentTheme_withEnabledState() throws Exception {
- OverlayInfo info1 = new OverlayInfo("com.android.Theme1", "android",
+ OverlayInfo info1 = new OverlayInfo("com.android.Theme1", "android", "",
OverlayInfo.CATEGORY_THEME, "", OverlayInfo.STATE_ENABLED, 0, 0, true);
- OverlayInfo info2 = new OverlayInfo("com.android.Theme2", "android",
+ OverlayInfo info2 = new OverlayInfo("com.android.Theme2", "android", "",
OverlayInfo.CATEGORY_THEME, "", 0, 0, 0, true);
when(mOverlayManager.getOverlayInfosForTarget(any(), anyInt())).thenReturn(
Arrays.asList(info1, info2));
@@ -154,9 +155,9 @@
@Test
public void testGetCurrentTheme_withoutEnabledState() throws Exception {
- OverlayInfo info1 = new OverlayInfo("com.android.Theme1", "android",
+ OverlayInfo info1 = new OverlayInfo("com.android.Theme1", "android", "",
OverlayInfo.CATEGORY_THEME, "", OverlayInfo.STATE_DISABLED, 0, 0, true);
- OverlayInfo info2 = new OverlayInfo("com.android.Theme2", "android",
+ OverlayInfo info2 = new OverlayInfo("com.android.Theme2", "android", "",
OverlayInfo.CATEGORY_THEME, "", 0, 0, 0, true);
when(mOverlayManager.getOverlayInfosForTarget(any(), anyInt())).thenReturn(
Arrays.asList(info1, info2));
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverSchedulePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverSchedulePreferenceControllerTest.java
index d1d21f3..a6c8534 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverSchedulePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverSchedulePreferenceControllerTest.java
@@ -62,7 +62,7 @@
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, 0);
Settings.Global.putInt(mContext.getContentResolver(),
- Global.AUTOMATIC_POWER_SAVER_MODE, PowerManager.POWER_SAVER_MODE_PERCENTAGE);
+ Global.AUTOMATIC_POWER_SAVE_MODE, PowerManager.POWER_SAVE_MODE_TRIGGER_PERCENTAGE);
mController.updateState(mPreference);
@@ -74,7 +74,7 @@
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, TRIGGER_LEVEL);
Settings.Global.putInt(mContext.getContentResolver(),
- Global.AUTOMATIC_POWER_SAVER_MODE, PowerManager.POWER_SAVER_MODE_PERCENTAGE);
+ Global.AUTOMATIC_POWER_SAVE_MODE, PowerManager.POWER_SAVE_MODE_TRIGGER_PERCENTAGE);
mController.updateState(mPreference);
@@ -87,7 +87,7 @@
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, TRIGGER_LEVEL);
Settings.Global.putInt(mContext.getContentResolver(),
- Global.AUTOMATIC_POWER_SAVER_MODE, PowerManager.POWER_SAVER_MODE_DYNAMIC);
+ Global.AUTOMATIC_POWER_SAVE_MODE, PowerManager.POWER_SAVE_MODE_TRIGGER_DYNAMIC);
mController.updateState(mPreference);
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleRadioButtonsControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleRadioButtonsControllerTest.java
index 6d412ee..6012dbb 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleRadioButtonsControllerTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleRadioButtonsControllerTest.java
@@ -31,16 +31,16 @@
@Test
public void getDefaultKey_routine_returnsCorrectValue() {
- Settings.Global.putInt(mResolver, Global.AUTOMATIC_POWER_SAVER_MODE,
- PowerManager.POWER_SAVER_MODE_DYNAMIC);
+ Settings.Global.putInt(mResolver, Global.AUTOMATIC_POWER_SAVE_MODE,
+ PowerManager.POWER_SAVE_MODE_TRIGGER_DYNAMIC);
assertThat(mController.getDefaultKey())
.isEqualTo(BatterySaverScheduleRadioButtonsController.KEY_ROUTINE);
}
@Test
public void getDefaultKey_automatic_returnsCorrectValue() {
- Settings.Global.putInt(mResolver, Global.AUTOMATIC_POWER_SAVER_MODE,
- PowerManager.POWER_SAVER_MODE_PERCENTAGE);
+ Settings.Global.putInt(mResolver, Global.AUTOMATIC_POWER_SAVE_MODE,
+ PowerManager.POWER_SAVE_MODE_TRIGGER_PERCENTAGE);
Settings.Global.putInt(mResolver, Global.LOW_POWER_MODE_TRIGGER_LEVEL, 5);
assertThat(mController.getDefaultKey())
.isEqualTo(BatterySaverScheduleRadioButtonsController.KEY_PERCENTAGE);
@@ -48,8 +48,8 @@
@Test
public void getDefaultKey_none_returnsCorrectValue() {
- Settings.Global.putInt(mResolver, Global.AUTOMATIC_POWER_SAVER_MODE,
- PowerManager.POWER_SAVER_MODE_PERCENTAGE);
+ Settings.Global.putInt(mResolver, Global.AUTOMATIC_POWER_SAVE_MODE,
+ PowerManager.POWER_SAVE_MODE_TRIGGER_PERCENTAGE);
Settings.Global.putInt(mResolver, Global.LOW_POWER_MODE_TRIGGER_LEVEL, 0);
assertThat(mController.getDefaultKey())
.isEqualTo(BatterySaverScheduleRadioButtonsController.KEY_NO_SCHEDULE);
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleSeekBarControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleSeekBarControllerTest.java
index 8aac9d8..03c9b0a 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleSeekBarControllerTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleSeekBarControllerTest.java
@@ -39,16 +39,16 @@
@Test
public void updateSeekBar_routineMode_hasCorrectProperties() {
- Settings.Global.putInt(mResolver, Global.AUTOMATIC_POWER_SAVER_MODE,
- PowerManager.POWER_SAVER_MODE_DYNAMIC);
+ Settings.Global.putInt(mResolver, Global.AUTOMATIC_POWER_SAVE_MODE,
+ PowerManager.POWER_SAVE_MODE_TRIGGER_DYNAMIC);
mController.updateSeekBar();
assertThat(mController.mSeekBarPreference.isVisible()).isFalse();
}
@Test
public void updateSeekBar_percentageMode_hasCorrectProperties() {
- Settings.Global.putInt(mResolver, Global.AUTOMATIC_POWER_SAVER_MODE,
- PowerManager.POWER_SAVER_MODE_PERCENTAGE);
+ Settings.Global.putInt(mResolver, Global.AUTOMATIC_POWER_SAVE_MODE,
+ PowerManager.POWER_SAVE_MODE_TRIGGER_PERCENTAGE);
Settings.Global.putInt(mResolver, Global.LOW_POWER_MODE_TRIGGER_LEVEL, 5);
mController.updateSeekBar();
assertThat(mController.mSeekBarPreference.isVisible()).isTrue();
@@ -56,8 +56,8 @@
@Test
public void updateSeekBar_noneMode_hasCorrectProperties() {
- Settings.Global.putInt(mResolver, Global.AUTOMATIC_POWER_SAVER_MODE,
- PowerManager.POWER_SAVER_MODE_PERCENTAGE);
+ Settings.Global.putInt(mResolver, Global.AUTOMATIC_POWER_SAVE_MODE,
+ PowerManager.POWER_SAVE_MODE_TRIGGER_PERCENTAGE);
Settings.Global.putInt(mResolver, Global.LOW_POWER_MODE_TRIGGER_LEVEL, 0);
mController.updateSeekBar();
assertThat(mController.mSeekBarPreference.isVisible()).isFalse();
diff --git a/tests/robotests/src/com/android/settings/gestures/WakeScreenGesturePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/WakeScreenGesturePreferenceControllerTest.java
deleted file mode 100644
index 471914a..0000000
--- a/tests/robotests/src/com/android/settings/gestures/WakeScreenGesturePreferenceControllerTest.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * 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.gestures;
-
-import static com.android.settings.core.BasePreferenceController.AVAILABLE;
-import static com.android.settings.core.BasePreferenceController.DISABLED_DEPENDENT_SETTING;
-import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.hardware.display.AmbientDisplayConfiguration;
-
-import com.android.settings.aware.AwareFeatureProvider;
-import com.android.settings.testutils.FakeFeatureFactory;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Answers;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-
-@RunWith(RobolectricTestRunner.class)
-public class WakeScreenGesturePreferenceControllerTest {
-
- private static final String KEY_WAKE_SCREEN = "gesture_wake_screen";
-
- @Mock(answer = Answers.RETURNS_DEEP_STUBS)
- private Context mContext;
- @Mock
- private AmbientDisplayConfiguration mAmbientDisplayConfiguration;
- private WakeScreenGesturePreferenceController mController;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
- AwareFeatureProvider featureProvider =
- FakeFeatureFactory.setupForTest().getAwareFeatureProvider();
- when(featureProvider.isSupported(any())).thenReturn(true);
- when(featureProvider.isEnabled(any())).thenReturn(true);
- mController = new WakeScreenGesturePreferenceController(mContext, KEY_WAKE_SCREEN);
- mController.setConfig(mAmbientDisplayConfiguration);
- }
-
- @Test
- public void testIsChecked_configIsSet_shouldReturnTrue() {
- // Set the setting to be enabled.
- when(mAmbientDisplayConfiguration.wakeScreenGestureEnabled(anyInt())).thenReturn(true);
- assertThat(mController.isChecked()).isTrue();
- }
-
- @Test
- public void testIsChecked_configIsNotSet_shouldReturnFalse() {
- // Set the setting to be disabled.
- when(mAmbientDisplayConfiguration.wakeScreenGestureEnabled(anyInt())).thenReturn(false);
- assertThat(mController.isChecked()).isFalse();
- }
-
- @Test
- public void getAvailabilityStatus_gestureNotSupported_UNSUPPORTED_ON_DEVICE() {
- when(mAmbientDisplayConfiguration.alwaysOnEnabled(anyInt())).thenReturn(true);
- when(mAmbientDisplayConfiguration.wakeScreenGestureAvailable()).thenReturn(false);
- final int availabilityStatus = mController.getAvailabilityStatus();
-
- assertThat(availabilityStatus).isEqualTo(UNSUPPORTED_ON_DEVICE);
- }
-
- @Test
- public void getAvailabilityStatus_gestureSupported_AVAILABLE() {
- when(mAmbientDisplayConfiguration.alwaysOnEnabled(anyInt())).thenReturn(true);
- when(mAmbientDisplayConfiguration.wakeScreenGestureAvailable()).thenReturn(true);
- final int availabilityStatus = mController.getAvailabilityStatus();
-
- assertThat(availabilityStatus).isEqualTo(AVAILABLE);
- }
-
- @Test
- public void getAvailabilityStatus_gestureSupported_DISABLED_DEPENDENT_SETTING() {
- when(mAmbientDisplayConfiguration.alwaysOnEnabled(anyInt())).thenReturn(false);
- when(mAmbientDisplayConfiguration.wakeScreenGestureAvailable()).thenReturn(true);
- final int availabilityStatus = mController.getAvailabilityStatus();
-
- assertThat(availabilityStatus).isEqualTo(DISABLED_DEPENDENT_SETTING);
- }
-
- @Test
- public void canHandleClicks_onlyWhenAlwaysOn() {
- when(mAmbientDisplayConfiguration.alwaysOnEnabled(anyInt())).thenReturn(false);
- assertThat(mController.canHandleClicks()).isEqualTo(false);
-
- reset(mAmbientDisplayConfiguration);
- when(mAmbientDisplayConfiguration.alwaysOnEnabled(anyInt())).thenReturn(true);
- assertThat(mController.canHandleClicks()).isEqualTo(true);
- }
-
- @Test
- public void isSliceableCorrectKey_returnsTrue() {
- final WakeScreenGesturePreferenceController controller =
- new WakeScreenGesturePreferenceController(mContext, "gesture_wake_screen");
- assertThat(controller.isSliceable()).isTrue();
- }
-
- @Test
- public void isSliceableIncorrectKey_returnsFalse() {
- final WakeScreenGesturePreferenceController controller =
- new WakeScreenGesturePreferenceController(mContext, "bad_key");
- assertThat(controller.isSliceable()).isFalse();
- }
-}
diff --git a/tests/robotests/src/com/android/settings/privacy/EnableContentCapturePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/privacy/EnableContentCapturePreferenceControllerTest.java
index a379858..179063d 100644
--- a/tests/robotests/src/com/android/settings/privacy/EnableContentCapturePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/privacy/EnableContentCapturePreferenceControllerTest.java
@@ -51,7 +51,7 @@
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = RuntimeEnvironment.application;
- mController = new EnableContentCapturePreferenceController(mContext);
+ mController = new EnableContentCapturePreferenceController(mContext, "THE_KEY_TO_SUCCESS");
mPreference = new Preference(mContext);
mPreference.setKey(mController.getPreferenceKey());
}
diff --git a/tests/robotests/src/com/android/settings/privacy/PrivacyDashboardFragmentTest.java b/tests/robotests/src/com/android/settings/privacy/PrivacyDashboardFragmentTest.java
index 482eaeb..80f3900 100644
--- a/tests/robotests/src/com/android/settings/privacy/PrivacyDashboardFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/privacy/PrivacyDashboardFragmentTest.java
@@ -80,10 +80,10 @@
}
@Test
- public void onViewCreated_shouldCallStyleActionBar() {
+ public void onViewCreated_shouldSetActionBarShadowAnimation() {
mFragment.onViewCreated(new View(mContext), new Bundle());
- verify(mFragment).styleActionBar();
+ assertThat(mFragment.getActivity().getActionBar().getElevation()).isEqualTo(0.f);
}
@Test
diff --git a/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java b/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java
index 23025b2..005ffbe 100644
--- a/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java
+++ b/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java
@@ -133,7 +133,6 @@
mProvider = spy(new SettingsSliceProvider());
ShadowStrictMode.reset();
mProvider.mSliceWeakDataCache = new HashMap<>();
- mProvider.mSliceDataCache = new HashMap<>();
mProvider.mSlicesDatabaseAccessor = new SlicesDatabaseAccessor(mContext);
when(mProvider.getContext()).thenReturn(mContext);
@@ -198,30 +197,6 @@
}
@Test
- public void testLoadSlice_doesNotCacheWithoutPin() {
- insertSpecialCase(KEY);
- final Uri uri = SliceBuilderUtils.getUri(INTENT_PATH, false);
-
- mProvider.loadSlice(uri);
- SliceData data = mProvider.mSliceDataCache.get(uri);
-
- assertThat(data).isNull();
- }
-
- @Test
- public void testLoadSlice_cachesWithPin() {
- insertSpecialCase(KEY);
- final Uri uri = SliceBuilderUtils.getUri(INTENT_PATH, false);
- when(mManager.getPinnedSlices()).thenReturn(Arrays.asList(uri));
-
- mProvider.loadSlice(uri);
- SliceData data = mProvider.mSliceDataCache.get(uri);
-
- assertThat(data.getKey()).isEqualTo(KEY);
- assertThat(data.getTitle()).isEqualTo(TITLE);
- }
-
- @Test
public void testLoadSlice_cachedEntryRemovedOnBuild() {
SliceData data = getDummyData();
mProvider.mSliceWeakDataCache.put(data.getUri(), data);
@@ -277,18 +252,6 @@
}
@Test
- public void testLoadSlice_cachedEntryRemovedOnUnpin() {
- SliceData data = getDummyData();
- mProvider.mSliceDataCache.put(data.getUri(), data);
- mProvider.onSliceUnpinned(data.getUri());
- insertSpecialCase(data.getKey());
-
- SliceData cachedData = mProvider.mSliceWeakDataCache.get(data.getUri());
-
- assertThat(cachedData).isNull();
- }
-
- @Test
public void getDescendantUris_fullActionUri_returnsSelf() {
final Uri uri = SliceBuilderUtils.getUri(
SettingsSlicesContract.PATH_SETTING_ACTION + "/key", true);
diff --git a/tests/robotests/src/com/android/settings/widget/AdaptiveOutlineDrawableTest.java b/tests/robotests/src/com/android/settings/widget/AdaptiveOutlineDrawableTest.java
new file mode 100644
index 0000000..f21fc34
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/widget/AdaptiveOutlineDrawableTest.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2019 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.widget;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.res.Resources;
+import android.graphics.Paint;
+
+import com.android.settings.R;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(RobolectricTestRunner.class)
+public class AdaptiveOutlineDrawableTest {
+
+ @Test
+ public void constructor_initPaint() {
+ final Resources resources = RuntimeEnvironment.application.getResources();
+ final AdaptiveOutlineDrawable drawable = new AdaptiveOutlineDrawable(resources, null);
+
+ assertThat(drawable.mOutlinePaint.getStyle()).isEqualTo(Paint.Style.STROKE);
+ assertThat(drawable.mOutlinePaint.getStrokeWidth()).isWithin(0.01f).of(
+ resources.getDimension(R.dimen.adaptive_outline_stroke));
+ }
+
+}
diff --git a/tests/unit/src/com/android/settings/display/ThemePreferenceControllerTest.java b/tests/unit/src/com/android/settings/display/ThemePreferenceControllerTest.java
index 3cdfb7c..c5ee000 100644
--- a/tests/unit/src/com/android/settings/display/ThemePreferenceControllerTest.java
+++ b/tests/unit/src/com/android/settings/display/ThemePreferenceControllerTest.java
@@ -69,9 +69,9 @@
@Test
public void testUpdateState() throws Exception {
- OverlayInfo info1 = new OverlayInfo("com.android.Theme1", "android",
+ OverlayInfo info1 = new OverlayInfo("com.android.Theme1", "android", "",
OverlayInfo.CATEGORY_THEME, "", OverlayInfo.STATE_ENABLED, 0, 0, true);
- OverlayInfo info2 = new OverlayInfo("com.android.Theme2", "android",
+ OverlayInfo info2 = new OverlayInfo("com.android.Theme2", "android", "",
OverlayInfo.CATEGORY_THEME, "", 0, 0, 0, true);
when(mMockPackageManager.getApplicationInfo(any(), anyInt())).thenAnswer(inv -> {
ApplicationInfo info = mock(ApplicationInfo.class);
@@ -105,9 +105,9 @@
@Test
public void testUpdateState_withStaticOverlay() throws Exception {
- OverlayInfo info1 = new OverlayInfo("com.android.Theme1", "android",
+ OverlayInfo info1 = new OverlayInfo("com.android.Theme1", "android", "",
OverlayInfo.CATEGORY_THEME, "", OverlayInfo.STATE_ENABLED, 0, 0, true);
- OverlayInfo info2 = new OverlayInfo("com.android.Theme2", "android",
+ OverlayInfo info2 = new OverlayInfo("com.android.Theme2", "android", "",
OverlayInfo.CATEGORY_THEME, "", OverlayInfo.STATE_ENABLED, 0, 0, true);
when(mMockPackageManager.getApplicationInfo(any(), anyInt())).thenAnswer(inv -> {
ApplicationInfo info = mock(ApplicationInfo.class);