Snap for 4677756 from 362ba01789 to pi-release
Change-Id: Ia10d254af68bd3fe7a6cc97cc5e0deee523c12d7
This commit is contained in:
@@ -255,6 +255,8 @@
|
||||
android:value="com.android.settings.wifi.WifiSettings" />
|
||||
<meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
|
||||
android:value="true" />
|
||||
<meta-data android:name="android.metadata.SLICE_URI"
|
||||
android:value="content://android.settings.slices/wifi" />
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
@@ -983,7 +985,7 @@
|
||||
</activity>
|
||||
|
||||
<activity android:name=".Settings$MyDeviceInfoActivity"
|
||||
android:label="@string/device_info_settings"
|
||||
android:label="@string/about_settings"
|
||||
android:icon="@drawable/ic_settings_about"
|
||||
android:taskAffinity="com.android.settings"
|
||||
android:parentActivityName="Settings">
|
||||
@@ -1127,6 +1129,17 @@
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity android:name=".slice.SliceDeepLinkSpringBoard"
|
||||
android:theme="@android:style/Theme.NoDisplay">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data android:scheme="settings"
|
||||
android:host="com.android.settings.slices" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<!-- Provide direct entry into manage apps showing running services.
|
||||
This is for compatibility with old shortcuts. -->
|
||||
<activity-alias android:name=".RunningServices"
|
||||
@@ -2384,6 +2397,10 @@
|
||||
android:taskAffinity="com.android.settings"
|
||||
android:parentActivityName="Settings">
|
||||
<!-- TODO(b/70950124): add shortcut intent-filter -->
|
||||
<intent-filter android:priority="1">
|
||||
<action android:name="android.settings.DATA_USAGE_SETTINGS" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
<intent-filter android:priority="10">
|
||||
<action android:name="com.android.settings.action.SETTINGS" />
|
||||
</intent-filter>
|
||||
@@ -2399,6 +2416,10 @@
|
||||
android:icon="@drawable/ic_settings_data_usage"
|
||||
android:taskAffinity="com.android.settings"
|
||||
android:parentActivityName="Settings">
|
||||
<intent-filter android:priority="1">
|
||||
<action android:name="android.settings.DATA_USAGE_SETTINGS" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
@@ -2661,6 +2682,23 @@
|
||||
android:resource="@string/sound_dashboard_summary"/>
|
||||
</activity>
|
||||
|
||||
<!-- Show apps for which application-level notification settings are applicable -->
|
||||
<activity android:name="Settings$NotificationAppListActivity"
|
||||
android:label="@string/app_notifications_title"
|
||||
android:icon="@drawable/ic_notifications"
|
||||
android:exported="true"
|
||||
android:taskAffinity="">
|
||||
<intent-filter android:priority="1">
|
||||
<action android:name="android.settings.ALL_APPS_NOTIFICATION_SETTINGS" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
<intent-filter android:priority="150">
|
||||
<action android:name="com.android.settings.action.SETTINGS" />
|
||||
</intent-filter>
|
||||
<meta-data android:name="com.android.settings.FRAGMENT_CLASS"
|
||||
android:value="com.android.settings.applications.manageapplications.ManageApplications" />
|
||||
</activity>
|
||||
|
||||
<!-- Show application-level notification settings (app passed in as extras) -->
|
||||
<activity android:name="Settings$AppNotificationSettingsActivity"
|
||||
android:exported="true">
|
||||
@@ -3244,7 +3282,16 @@
|
||||
|
||||
<provider android:name=".slices.SettingsSliceProvider"
|
||||
android:authorities="com.android.settings.slices;android.settings.slices"
|
||||
android:exported="true">
|
||||
android:exported="true"
|
||||
android:grantUriPermissions="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<category android:name="android.app.slice.category.SLICE" />
|
||||
<data android:scheme="settings"
|
||||
android:host="com.android.settings.slices" />
|
||||
</intent-filter>
|
||||
</provider>
|
||||
|
||||
<receiver
|
||||
|
||||
@@ -1276,7 +1276,7 @@
|
||||
errorLine1=" android:background="@color/lock_pattern_background" />"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/layout-land/confirm_lock_pattern_internal.xml"
|
||||
file="res/layout-land/confirm_lock_pattern_normal.xml"
|
||||
line="111"
|
||||
column="17"/>
|
||||
</issue>
|
||||
|
||||
@@ -82,7 +82,7 @@
|
||||
android:minLines="2"
|
||||
android:gravity="center"
|
||||
android:paddingHorizontal="?attr/suwMarginSides"
|
||||
android:textSize="18sp" />
|
||||
android:textSize="12sp" />
|
||||
|
||||
<com.android.setupwizardlib.view.FillContentLayout
|
||||
style="@style/LockPatternContainerStyle"
|
||||
|
||||
@@ -22,7 +22,15 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<!-- left : cancel, or re-try -->
|
||||
<!-- left : skip -->
|
||||
<Button android:id="@+id/skip_button"
|
||||
style="@style/SuwGlifButton.Secondary"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/skip_label"
|
||||
android:visibility="gone" />
|
||||
|
||||
<!-- left : retry -->
|
||||
<Button android:id="@+id/footerLeftButton"
|
||||
style="@style/SuwGlifButton.Secondary"
|
||||
android:layout_width="wrap_content"
|
||||
|
||||
@@ -69,6 +69,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:textAppearance="@style/TextAppearance.Small"
|
||||
android:textAlignment="viewStart"
|
||||
android:textColor="?android:attr/textColorSecondary" />
|
||||
|
||||
<TextView android:id="@+id/appendix"
|
||||
|
||||
@@ -37,6 +37,14 @@
|
||||
android:id="@+id/sort_order_size"
|
||||
android:title="@string/sort_order_size"
|
||||
android:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/sort_order_recent_notification"
|
||||
android:title="@string/sort_order_recent_notification"
|
||||
android:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/sort_order_frequent_notification"
|
||||
android:title="@string/sort_order_frequent_notification"
|
||||
android:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/reset_app_preferences"
|
||||
android:title="@string/reset_app_preferences"
|
||||
|
||||
@@ -20,6 +20,6 @@
|
||||
<item name="fingerprint_enroll_enrolling" type="layout">@layout/fingerprint_enroll_enrolling_base</item>
|
||||
<item name="fingerprint_enroll_finish" type="layout">@layout/fingerprint_enroll_finish_base</item>
|
||||
<item name="choose_lock_pattern" type="layout">@layout/choose_lock_pattern_common</item>
|
||||
<item name="confirm_lock_pattern_internal" type="layout">@layout/confirm_lock_pattern_internal_base</item>
|
||||
<item name="confirm_lock_pattern_normal" type="layout">@layout/confirm_lock_pattern_normal_base</item>
|
||||
</resources>
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<resources>
|
||||
<item name="notification_app_section" type="layout">@*android:layout/preference_category_material</item>
|
||||
<item name="confirm_lock_pattern" type="layout">@layout/confirm_lock_pattern_base</item>
|
||||
<item name="confirm_lock_pattern_internal" type="layout">@layout/confirm_lock_pattern_internal_base</item>
|
||||
<item name="confirm_lock_pattern_normal" type="layout">@layout/confirm_lock_pattern_normal_base</item>
|
||||
<item name="confirm_lock_password" type="layout">@layout/confirm_lock_password_base</item>
|
||||
<item name="fingerprint_enroll_find_sensor" type="layout">@layout/fingerprint_enroll_find_sensor_base</item>
|
||||
<item name="fingerprint_enroll_enrolling" type="layout">@layout/fingerprint_enroll_enrolling_base</item>
|
||||
|
||||
@@ -1095,4 +1095,17 @@
|
||||
<item>no</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="gesture_prevent_ringing_entries" translatable="false">
|
||||
<item>@string/prevent_ringing_option_vibrate</item>
|
||||
<item>@string/prevent_ringing_option_mute</item>
|
||||
<item>@string/prevent_ringing_option_none</item>
|
||||
</string-array>
|
||||
|
||||
<!-- Keep in sync with Settings.Secure.VOLUME_HUSH_* -->
|
||||
<string-array name="gesture_prevent_ringing_values" translatable="false">
|
||||
<item>1</item>
|
||||
<item>2</item>
|
||||
<item>0</item>
|
||||
</string-array>
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -128,5 +128,7 @@
|
||||
<color name="homepage_generic_icon_background">#1A73E8</color>
|
||||
<!-- End of dashboard/homepage icon background colors -->
|
||||
|
||||
<color name="glif_error_color">@*android:color/material_red_A700</color>
|
||||
|
||||
</resources>
|
||||
|
||||
|
||||
@@ -754,10 +754,14 @@
|
||||
<string name="date_time_set_date_title">Date</string>
|
||||
<!-- Date & time setting screen setting option title -->
|
||||
<string name="date_time_set_date">Set date</string>
|
||||
<!-- Text hint to search region in time zone setting screen -->
|
||||
<string name="date_time_search_region">Search region</string>
|
||||
<!-- Setting option title to select region in time zone setting screen [CHAR LIMIT=30] -->
|
||||
<string name="date_time_select_region">Region</string>
|
||||
<!-- Setting option title to select time zone in time zone setting screen [CHAR LIMIT=30]-->
|
||||
<string name="date_time_select_zone">Time Zone</string>
|
||||
<!-- Setting option title to select time zone in a region -->
|
||||
<string name="date_time_set_timezone_in_region">Time zones in <xliff:g id="region" example="United States">%1$s</xliff:g></string>
|
||||
<!-- Setting option title in time zone setting screen [CHAR LIMIT=30] -->
|
||||
<string name="date_time_select_fixed_offset_time_zones">Select UTC offset</string>
|
||||
<!-- Menu item on Select time zone screen -->
|
||||
@@ -1153,7 +1157,7 @@
|
||||
<string name="suggested_lock_settings_summary" product="default">Set screen lock to protect phone</string>
|
||||
|
||||
<!-- Title for suggested actions for settings up a fingerprint lock [CHAR LIMIT=46] -->
|
||||
<string name="suggested_fingerprint_lock_settings_title">Unlock with fingerprint</string>
|
||||
<string name="suggested_fingerprint_lock_settings_title">Add fingerprint to unlock</string>
|
||||
|
||||
<!-- Summary for suggested actions for settings up a fingerprint lock (tablet) [CHAR LIMIT=55] -->
|
||||
<string name="suggested_fingerprint_lock_settings_summary" product="tablet"></string>
|
||||
@@ -1808,6 +1812,8 @@
|
||||
<string name="wifi_wakeup">Turn on Wi\u2011Fi automatically</string>
|
||||
<!-- Checkbox summary for option to enable Wi-Fi when high quality saved networks are nearby-->
|
||||
<string name="wifi_wakeup_summary">Wi\u2011Fi will turn back on near high\u2011quality saved networks, like your home network</string>
|
||||
<!-- Checkbox summary for auto-wifi when user needs to enable location scanning to toggle it -->
|
||||
<string name="wifi_wakeup_summary_no_location">Unavailable because location is turned off. Turn on <annotation id="link">location</annotation>.</string>
|
||||
<!-- Checkbox summary for Wi-Fi wakeup option to explain that Wi-Fi wakeup is disabled because Wi-Fi scanning is turned off -->
|
||||
<string name="wifi_wakeup_summary_scanning_disabled">Unavailable because Wi\u2011Fi scanning is turned off</string>
|
||||
<!-- Checkbox summary for Wi-Fi wakeup option to explain that a network rating provider needs to be selected to use the feature. -->
|
||||
@@ -1901,6 +1907,14 @@
|
||||
<string name="wifi_more">More</string>
|
||||
<!-- Wi-Fi settings. wps menu title [CHAR LIMIT=25]-->
|
||||
<string name="wifi_setup_wps">Automatic setup (WPS)</string>
|
||||
<!-- Wi-Fi settings dialog. Title of dialog displayed asking user to enable Wi-Fi Scanning [CHAR LIMIT=60]-->
|
||||
<string name="wifi_settings_scanning_required_title">Turn on Wi\u2011Fi scanning?</string>
|
||||
<!-- Wi-Fi settings dialog. Summary text describing why we need Wi-Fi scanning on. [CHAR LIMIT=NONE]-->
|
||||
<string name="wifi_settings_scanning_required_summary">To turn on Wi\u2011Fi automatically, you first need to turn on Wi\u2011Fi scanning.</string>
|
||||
<!-- Wi-Fi settings dialog. Informational text describing what Wi-Fi scanning does. [CHAR LIMIT=NONE]-->
|
||||
<string name="wifi_settings_scanning_required_info">Wi\2011Fi scanning allows apps and services to scan for Wi\u2011Fi networks at any time, even when Wi\u2011Fi is off. This can be used, for example, to improve location\u2011based features and services.</string>
|
||||
<!-- Wi-Fi settings dialog. Text for the button that takes users to a help article about Wi-Fi scanning. [CHAR LIMIT = 20]-->
|
||||
<string name="wifi_settings_scanning_required_turn_on">Turn on</string>
|
||||
|
||||
<!-- Dialog for Access Points --> <skip />
|
||||
<!-- Label to show/hide advanced options [CHAR LIMIT=40] -->
|
||||
@@ -1915,6 +1929,10 @@
|
||||
<string name="wifi_ssid_hint">Enter the SSID</string>
|
||||
<!-- Label for the security of the connection -->
|
||||
<string name="wifi_security">Security</string>
|
||||
<!-- Label for the hidden network status of this network -->
|
||||
<string name="wifi_hidden_network">Hidden network</string>
|
||||
<!-- Label for the warning shown to users if they try to connect to a network as "hidden" -->
|
||||
<string name="wifi_hidden_network_warning">Hidden network might create privacy risk as this device has to broadcast this SSID name in order to connect.</string>
|
||||
<!-- Label for the signal strength of the connection -->
|
||||
<string name="wifi_signal">Signal strength</string>
|
||||
<!-- Label for the status of the connection -->
|
||||
@@ -1954,7 +1972,11 @@
|
||||
<!-- Label for the radio button to choose wifi ap 2.4 GHz band -->
|
||||
<string name="wifi_ap_choose_2G">2.4 GHz Band</string>
|
||||
<!-- Label for the radio button to choose wifi ap 5GHz band -->
|
||||
<string name="wifi_ap_choose_5G">5 GHz Band</string>
|
||||
<string name="wifi_ap_choose_5G">5.0 GHz Band</string>
|
||||
<!-- Label for adding to the list of selected bands when 2.4 GHz is selected -->
|
||||
<string name="wifi_ap_2G">2.4 GHz</string>
|
||||
<!-- Label for adding to the list of selected bands when 5.0 GHz is selected -->
|
||||
<string name="wifi_ap_5G">5.0 GHz</string>
|
||||
<!-- Label for the spinner to show ip settings [CHAR LIMIT=25] -->
|
||||
<string name="wifi_ip_settings">IP settings</string>
|
||||
<!-- Label for the check box to share a network with other users on the same device -->
|
||||
@@ -2033,6 +2055,10 @@
|
||||
<string name="wifi_failed_save_message">Failed to save network</string>
|
||||
<!-- Button label to dismiss the dialog -->
|
||||
<string name="wifi_cancel">Cancel</string>
|
||||
<!-- Dialog title for forget confirmation dialog -->
|
||||
<string name="wifi_forget_dialog_title">Forget network?</string>
|
||||
<!-- Dialog message for forget confirmation dialog -->
|
||||
<string name="wifi_forget_dialog_message">All passwords for this network will be deleted</string>
|
||||
|
||||
<!-- Wi-Fi Advanced Settings --> <skip />
|
||||
<!-- Wi-Fi settings screen, Saved networks, settings section. This is a header shown above Saved networks wifi settings. [CHAR LIMIT=30] -->
|
||||
@@ -2435,6 +2461,12 @@
|
||||
<string name="color_mode_option_boosted">Boosted</string>
|
||||
<!-- Display settings screen, Color mode option for "Saturated color" [CHAR LIMIT=45] -->
|
||||
<string name="color_mode_option_saturated">Saturated</string>
|
||||
<!-- Display settings screen, Color mode option for "Automatic color" [CHAR LIMIT=45] -->
|
||||
<string name="color_mode_option_automatic">Automatic</string>
|
||||
<!-- Display settings screen, "natural(sRGB) color" setting option summary [CHAR LIMIT=NONE] -->
|
||||
<string name="color_mode_summary_natural">Use accurate colors only</string>
|
||||
<!-- Display settings screen, "Automatic color" setting option summary [CHAR LIMIT=NONE] -->
|
||||
<string name="color_mode_summary_automatic">Adjust between vivid and accurate colors</string>
|
||||
|
||||
<!-- Sound & display settings screen, accelerometer-based rotation summary text when check box is selected -->
|
||||
<string name="accelerometer_summary_on" product="tablet">Switch orientation automatically when rotating tablet</string>
|
||||
@@ -2526,6 +2558,18 @@
|
||||
<string name="night_display_summary_on_auto_mode_custom">Will turn off automatically at <xliff:g name="time" example="10 PM">%1$s</xliff:g></string>
|
||||
<!-- Display settings screen, summary of night display when on and will turn off automatically at sunrise. [CHAR LIMIT=NONE] -->
|
||||
<string name="night_display_summary_on_auto_mode_twilight">Will turn off automatically at sunrise</string>
|
||||
<!-- Display settings screen, activation button action for manual mode. [CHAR LIMIT=40] -->
|
||||
<string name="night_display_activation_on_manual">Turn on now</string>
|
||||
<!-- Display settings screen, deactivation button action for manual mode. [CHAR LIMIT=40] -->
|
||||
<string name="night_display_activation_off_manual">Turn off now</string>
|
||||
<!-- Display settings screen, activation button action for sunset-to-sunrise schedule [CHAR LIMIT=40] -->
|
||||
<string name="night_display_activation_on_twilight">Turn on until sunrise</string>
|
||||
<!-- Display settings screen, deactivation button action for sunset-to-sunrise schedule [CHAR LIMIT=40] -->
|
||||
<string name="night_display_activation_off_twilight">Turn off until sunset</string>
|
||||
<!-- Display settings screen, activation button action for custom schedule [CHAR LIMIT=40] -->
|
||||
<string name="night_display_activation_on_custom">Turn on until <xliff:g name="time" example="6 AM">%1$s</xliff:g></string>
|
||||
<!-- Display settings screen, deactivation button action for custom schedule [CHAR LIMIT=40] -->
|
||||
<string name="night_display_activation_off_custom">Turn off until <xliff:g name="time" example="10 PM">%1$s</xliff:g></string>
|
||||
|
||||
<!-- Sound & display settings screen, setting option name to change screen timeout -->
|
||||
<string name="screen_timeout">Sleep</string>
|
||||
@@ -3531,6 +3575,8 @@
|
||||
<string name="lockpassword_confirm_passwords_dont_match">Passwords don\u2019t match</string>
|
||||
<!-- Header on pin confirm screen if second pin doesn't match the first. [CHAR LIMIT=30]-->
|
||||
<string name="lockpassword_confirm_pins_dont_match">PINs don\u2019t match</string>
|
||||
<!-- Header on pattern confirm screen [CHAR LIMIT=40] -->
|
||||
<string name="lockpassword_draw_your_pattern_again_header">Draw your pattern again</string>
|
||||
<!-- Header shown to ask the user to select an unlock method [CHAR LIMIT=30] -->
|
||||
<string name="lockpassword_choose_lock_generic_header">Unlock selection</string>
|
||||
<!-- Toast shown if setting password was successful -->
|
||||
@@ -3818,6 +3864,10 @@
|
||||
<string name="sort_order_alpha">Sort by name</string>
|
||||
<!-- Manage applications screen, menu item. Sorts all of the apps in the list based on their file size. This is used to uninstall when space is getting low. -->
|
||||
<string name="sort_order_size">Sort by size</string>
|
||||
<!-- Manage applications screen, menu item. Sorts all of the apps in the list based on how recently they sent notifications.-->
|
||||
<string name="sort_order_recent_notification">Most recent</string>
|
||||
<!-- Manage applications screen, menu item. Sorts all of the apps in the list based on how often they send notifications. -->
|
||||
<string name="sort_order_frequent_notification">Most frequent</string>
|
||||
<!-- [CHAR LIMIT=25] Manage applications screen, menu item. Show running services. -->
|
||||
<string name="show_running_services">Show running services</string>
|
||||
<!-- [CHAR LIMIT=25] Manage applications screen, menu item. Show background cached processes. -->
|
||||
@@ -4432,6 +4482,24 @@
|
||||
<!-- Used in the Captions settings screen to control turning on/off the feature entirely -->
|
||||
<string name="accessibility_caption_master_switch_title">Use captions</string>
|
||||
|
||||
<!-- Title for the accessibility preference for hearing aid. [CHAR LIMIT=35] -->
|
||||
<string name="accessibility_hearingaid_title">Hearing aids</string>
|
||||
<!-- Summary for the accessibility preference for hearing aid when not connected. [CHAR LIMIT=50] -->
|
||||
<string name="accessibility_hearingaid_not_connected_summary">No hearing aids connected</string>
|
||||
<!-- Summary for the accessibility preference for hearing aid when adding new devices. [CHAR LIMIT=50] -->
|
||||
<string name="accessibility_hearingaid_adding_summary">Add hearing aid</string>
|
||||
<!-- Message to ask the user that if they want to pair the hearing aid, then they should find and tap the hearing aid device from the list on the next screen. [CHAR LIMIT=NONE] -->
|
||||
<string name="accessibility_hearingaid_pair_instructions_first_message">To pair your hearing aids, find and tap your device on the next screen.</string>
|
||||
<!-- Message to ask the user to make sure that their hearing aid devices are in pairing mode. [CHAR LIMIT=NONE] -->
|
||||
<string name="accessibility_hearingaid_pair_instructions_second_message">Make sure your hearing aids are in pairing mode.</string>
|
||||
<!-- Summary for the accessibility preference for hearing aid when there is an active device. [CHAR LIMIT=50] -->
|
||||
<string name="accessibility_hearingaid_active_device_summary"><xliff:g id="device_name">%1$s</xliff:g> currently active</string>
|
||||
<!-- Summary for the accessibility preference for hearing aid when there are saved devices. [CHAR LIMIT=50] -->
|
||||
<plurals name="show_number_hearingaid_count">
|
||||
<item quantity="one"><xliff:g id="number_device_count">%1$d</xliff:g> saved hearing aid</item>
|
||||
<item quantity="other"><xliff:g id="number_device_count">%1$d</xliff:g> saved hearing aids</item>
|
||||
</plurals>
|
||||
|
||||
<!-- Preference's state when enabled. -->
|
||||
<string name="accessibility_summary_state_enabled">On</string>
|
||||
<!-- Preference's state when disabled. -->
|
||||
@@ -6299,7 +6367,7 @@
|
||||
<!-- Title for add user confirmation dialog [CHAR LIMIT=30] -->
|
||||
<string name="user_add_user_title">Add new user?</string>
|
||||
<!-- Message for add user confirmation dialog - long version. [CHAR LIMIT=none] -->
|
||||
<string name="user_add_user_message_long">You can share this device with other people by creating additional users. Each user has their own space, which they can customize with apps, wallpaper, and so on. Users can also adjust device settings like Wi\u2011Fi that affect everyone.\n\nWhen you add a new user, that person needs to set up their space.\n\nAny user can update apps for all other users.</string>
|
||||
<string name="user_add_user_message_long">You can share this device with other people by creating additional users. Each user has their own space, which they can customize with apps, wallpaper, and so on. Users can also adjust device settings like Wi\u2011Fi that affect everyone.\n\nWhen you add a new user, that person needs to set up their space.\n\nAny user can update apps for all other users. Accessibility settings and services may not transfer to the new user.</string>
|
||||
<!-- Message for add user confirmation dialog - short version. [CHAR LIMIT=none] -->
|
||||
<string name="user_add_user_message_short">When you add a new user, that person needs to set up their space.\n\nAny user can update apps for all other users. </string>
|
||||
<!-- Title of dialog to setup a new user [CHAR LIMIT=30] -->
|
||||
@@ -6780,16 +6848,16 @@
|
||||
</string>
|
||||
|
||||
<!--Search Keywords [CHAR LIMIT=NONE]-->
|
||||
<string name="keywords_wifi">wifi, wi-fi, network connection</string>
|
||||
<string name="keywords_wifi">wifi, wi-fi, network connection, internet, wireless, data, wi fi</string>
|
||||
<string name="keywords_change_wifi_state">wifi, wi-fi, toggle, control</string>
|
||||
<string name="keywords_more_default_sms_app">text message, texting, messages, messaging</string>
|
||||
<string name="keywords_more_default_sms_app">text message, texting, messages, messaging, default</string>
|
||||
<string name="keywords_more_mobile_networks">cellular, mobile, cell carrier, wireless, data, 4g,3g, 2g, lte</string>
|
||||
<string name="keywords_wifi_calling">wifi, wi-fi, call, calling</string>
|
||||
<string name="keywords_home">launcher</string>
|
||||
<string name="keywords_home">launcher, default, apps</string>
|
||||
<string name="keywords_display">screen, touchscreen</string>
|
||||
<string name="keywords_display_brightness_level">dim screen, touchscreen, battery</string>
|
||||
<string name="keywords_display_brightness_level">dim screen, touchscreen, battery, bright</string>
|
||||
<string name="keywords_display_auto_brightness">dim screen, touchscreen, battery</string>
|
||||
<string name="keywords_display_night_display">dim screen, night, tint</string>
|
||||
<string name="keywords_display_night_display">dim screen, night, tint, night shift, brightness, screen color, colour, color</string>
|
||||
<string name="keywords_display_wallpaper">background, personalize, customize display</string>
|
||||
<string name="keywords_display_font_size">text size</string>
|
||||
<string name="keywords_display_cast_screen">project, cast</string>
|
||||
@@ -6800,9 +6868,9 @@
|
||||
<string name="keywords_text_to_speech_output">rate, language, default, speak, speaking, tts, accessibility, screen reader, blind</string>
|
||||
<string name="keywords_date_and_time">clock, military</string>
|
||||
<string name="keywords_network_reset">reset, restore, factory</string>
|
||||
<string name="keywords_factory_data_reset">wipe, delete, restore, clear, remove</string>
|
||||
<string name="keywords_factory_data_reset">wipe, delete, restore, clear, remove, factory reset</string>
|
||||
<string name="keywords_printing">printer</string>
|
||||
<string name="keywords_sounds">speaker beep</string>
|
||||
<string name="keywords_sounds">speaker beep, speaker, volume, mute, silence, audio, music</string>
|
||||
<string name="keywords_sounds_and_notifications_interruptions">dont don\u2019t disturb, interrupt, interruption, break</string>
|
||||
<string name="keywords_app">RAM</string>
|
||||
<string name="keywords_location">nearby, location, history, reporting</string>
|
||||
@@ -6817,7 +6885,7 @@
|
||||
<string name="keywords_default_apps">apps, default</string>
|
||||
<string name="keywords_ignore_optimizations">ignore optimizations, doze, app standby</string>
|
||||
<string name="keywords_color_mode">vibrant, RGB, sRGB, color, natural, standard</string>
|
||||
<string name="keywords_color_temperature">color temperature D65 D73 white yellow blue warm cool</string>
|
||||
<string name="keywords_color_temperature">color, temperature, D65, D73, white, yellow, blue, warm, cool</string>
|
||||
<string name="keywords_lockscreen">slide to unlock, password, pattern, PIN</string>
|
||||
<string name="keywords_profile_challenge">work challenge, work, profile</string>
|
||||
<string name="keywords_unification">work profile, managed profile, unify, unification, work, profile</string>
|
||||
@@ -6834,6 +6902,51 @@
|
||||
<!-- Search keyword for fingerprint settings. -->
|
||||
<string name="keywords_fingerprint_settings">fingerprint</string>
|
||||
|
||||
<!-- List of synonyms for the auto rotate (rotate the virtual display when the device rotates) setting, used to match in settings search [CHAR LIMIT=NONE] -->
|
||||
<string name="keywords_auto_rotate">rotate, flip, rotation, portrait, landscape, orientation, vertical, horizontal</string>
|
||||
|
||||
<!-- List of synonyms for the System Update (update the operating system) setting, used to match in settings search [CHAR LIMIT=NONE] -->
|
||||
<string name="keywords_system_update_settings">upgrade, android</string>
|
||||
|
||||
<!-- List of synonyms for the Do Not Disturb setting, used to match in settings search. Do Not Disturb turns of notification volume, notifications, vibrations, among other things on the device. [CHAR LIMIT=NONE] -->
|
||||
<string name="keywords_zen_mode_settings">dnd, schedule, notifications, block, silence, vibrate, sleep, work, focus, sound, mute, day, weekday, weekend, weeknight, event</string>
|
||||
|
||||
<!-- List of synonyms for the display timeout (how long until the screen turns off) setting, used to match in settings search [CHAR LIMIT=NONE] -->
|
||||
<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>
|
||||
|
||||
<!-- 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>
|
||||
|
||||
<!-- List of synonyms for the Wallpaper picker setting, used to match in settings search [CHAR LIMIT=NONE] -->
|
||||
<string name="keywords_wallpaper">background, screen, lockscreen, theme</string>
|
||||
|
||||
<!-- List of synonyms for the Default Assist and Voice input setting, used to match in settings search [CHAR LIMIT=NONE] -->
|
||||
<string name="keywords_assist_input">default, assistant</string>
|
||||
|
||||
<!-- List of synonyms for the Wallpaper picker setting, used to match in settings search [CHAR LIMIT=NONE] -->
|
||||
<string name="keywords_default_browser">default, default browser</string>
|
||||
|
||||
<!-- List of synonyms for the default payment app setting, used to match in settings search [CHAR LIMIT=NONE] -->
|
||||
<string name="keywords_default_payment_app">payment, default</string>
|
||||
|
||||
<!-- List of synonyms for the default links setting, used to match in settings search [CHAR LIMIT=NONE] -->
|
||||
<string name="keywords_default_links">default</string>
|
||||
|
||||
<!-- List of synonyms for Ambient display setting (when the screen is off), used to match in settings search [CHAR LIMIT=NONE] -->
|
||||
<string name="keywords_ambient_display">incoming notification</string>
|
||||
|
||||
<!-- List of synonyms for hotspot and tethering setting (where you share your wifi with other devices), used to match in settings search [CHAR LIMIT=NONE] -->
|
||||
<string name="keywords_hotspot_tethering">usb tether, bluetooth tether, wifi hotspot</string>
|
||||
|
||||
<!-- List of synonyms for touch vibration setting (where you get a haptic response for touching things on the screen), used to match in settings search [CHAR LIMIT=NONE] -->
|
||||
<string name="keywords_touch_vibration">haptics, vibrate, screen, sensitivity</string>
|
||||
|
||||
<!-- List of synonyms for ring and notification vibration setting (changes whether your phone vibrates when it rings), used to match in settings search [CHAR LIMIT=NONE] -->
|
||||
<string name="keywords_ring_vibration">haptics, vibrate, phone, call, sensitivity</string>
|
||||
|
||||
<!-- NFC Wi-Fi pairing/setup strings-->
|
||||
|
||||
<!-- Write NFC tag for Wi-Fi pairing/setup title [CHAR_LIMIT=30]-->
|
||||
@@ -6925,7 +7038,10 @@
|
||||
<string name="touch_sounds_title">Touch sounds</string>
|
||||
|
||||
<!-- Sound: Other sounds: Title for the option enabling haptic feedback on touch. [CHAR LIMIT=30] -->
|
||||
<string name="vibrate_on_touch_title">Vibrate on tap</string>
|
||||
<string name="vibrate_on_touch_title">Touch vibration</string>
|
||||
|
||||
<!-- Sound: Other sounds: Preference summary to the option enabling haptic feedback on touch. -->
|
||||
<string name="vibrate_on_touch_summary">Haptic feedback for tap, keyboard, and more</string>
|
||||
|
||||
<!-- Sound: Other sounds: Title for the option enabling dock audio media. [CHAR LIMIT=50] -->
|
||||
<string name="dock_audio_media_title">Dock speaker plays</string>
|
||||
@@ -7305,6 +7421,13 @@
|
||||
<!-- Default Apps > Default notification assistant -->
|
||||
<string name="default_notification_assistant">Notification assistant</string>
|
||||
|
||||
<!-- app summary of notification app list screen [CHAR LIMIT=100] -->
|
||||
<string name="notifications_sent_daily">~<xliff:g id="number">%1$s</xliff:g> sent daily</string>
|
||||
<!-- app summary of notification app list screen [CHAR LIMIT=100] -->
|
||||
<string name="notifications_sent_weekly">~<xliff:g id="number">%1$s</xliff:g> sent weekly</string>
|
||||
<!-- app summary of notification app list screen [CHAR LIMIT=100] -->
|
||||
<string name="notifications_sent_never">Never</string>
|
||||
|
||||
<!-- Sound & notification > Advanced section: Title for managing notification listeners option. [CHAR LIMIT=30] -->
|
||||
<string name="manage_notification_access_title">Notification access</string>
|
||||
|
||||
@@ -7861,11 +7984,13 @@
|
||||
<string name="change_storage">Change storage</string>
|
||||
|
||||
<!-- Label for notification settings for an specific app [CHAR LIMIT=40] -->
|
||||
<string name="notifications_label">App notifications</string>
|
||||
<string name="notifications_label">Notifications</string>
|
||||
<!-- App notification summary with notifications enabled [CHAR LIMIT=40] -->
|
||||
<string name="notifications_enabled">On</string>
|
||||
<!-- App notification summary with notifications enabled [CHAR LIMIT=40] -->
|
||||
<string name="notifications_enabled_with_info">On / <xliff:g id="notifications_categories_off" example="3 categories turned off">%1$s</xliff:g> </string>
|
||||
<!-- Label for showing apps with blocked notifications in list [CHAR LIMIT=30] -->
|
||||
<string name="notifications_disabled">Everything turned off</string>
|
||||
<string name="notifications_disabled">Off</string>
|
||||
<!-- Label for showing apps with some blocked notifications in list [CHAR LIMIT=30] -->
|
||||
<string name="notifications_partly_blocked"><xliff:g id="count" example="1">%1$d</xliff:g> of <xliff:g id="count" example="10">%2$d</xliff:g> categories turned off</string>
|
||||
<!-- App notification summary with notifications silenced [CHAR LIMIT=40] -->
|
||||
@@ -7883,6 +8008,11 @@
|
||||
<!-- App notification summary channel divider-->
|
||||
<string name="notification_summary_channel"><xliff:g id="channel_name">%1$s</xliff:g> \u2022 <xliff:g id="group_name">%2$s</xliff:g></string>
|
||||
|
||||
<!-- Permissions preference summary [CHAR LIMIT=40] -->
|
||||
<plurals name="notifications_categories_off">
|
||||
<item quantity="one"><xliff:g id="count" example="1">%d</xliff:g> category turned off</item>
|
||||
<item quantity="other"><xliff:g id="count" example="10">%d</xliff:g> categories turned off</item>
|
||||
</plurals>
|
||||
|
||||
<!-- Permissions preference summary [CHAR LIMIT=40] -->
|
||||
<plurals name="permissions_summary">
|
||||
@@ -8047,6 +8177,9 @@
|
||||
<!-- Link to the apps page for app usage settings [CHAR LIMIT=45] -->
|
||||
<string name="app_usage_preference">App usage preferences</string>
|
||||
|
||||
<!-- Link title to show stats about how much time user spent in an app [CHAR LIMIT=45] -->
|
||||
<string name="time_spent_in_app_pref_title">Time spent in app</string>
|
||||
|
||||
<!-- Description of the usage access setting [CHAR LIMIT=NONE] -->
|
||||
<string name="usage_access_description">Usage access allows an app to track what other apps you\u2019re using and how often, as well as your carrier, language settings, and other details.</string>
|
||||
|
||||
@@ -8551,8 +8684,8 @@
|
||||
<!-- Summary of Android version info (when there is a pending upgrade available) [CHAR LIMIT=NONE] -->
|
||||
<string name="android_version_pending_update_summary">Update available</string>
|
||||
|
||||
<!-- Title for dialog displayed when user clicks on a setting locked by an admin [CHAR LIMIT=30] -->
|
||||
<string name="disabled_by_policy_title">Action not allowed</string>
|
||||
<!-- Title for dialog displayed when user selects on a setting locked by an admin [CHAR LIMIT=30] -->
|
||||
<string name="disabled_by_policy_title">Can\'t change this setting</string>
|
||||
<!-- Title for dialog displayed to tell user that changing volume was disallowed by an admin [CHAR LIMIT=50] -->
|
||||
<string name="disabled_by_policy_title_adjust_volume">Can\'t change volume</string>
|
||||
<!-- Title for dialog displayed to tell user that outgoing calls were disabled by an admin [CHAR LIMIT=50] -->
|
||||
@@ -8566,8 +8699,7 @@
|
||||
<!-- Title for dialog displayed to tell user that turning off backups is disallowed by an admin [CHAR LIMIT=50] -->
|
||||
<string name="disabled_by_policy_title_turn_off_backups">Can\'t turn off backups</string>
|
||||
<!-- Shown when the user tries to change a settings locked by an admin [CHAR LIMIT=200] -->
|
||||
<string name="default_admin_support_msg">This action is disabled. To learn more, contact your
|
||||
organization\'s admin.</string>
|
||||
<string name="default_admin_support_msg">If you have questions, contact your IT admin</string>
|
||||
<!-- Shown in dialog to allow user to see more information about the device admin [CHAR LIMIT=30] -->
|
||||
<string name="admin_support_more_info">More details</string>
|
||||
<!-- Shown in admin details page to warn user about policies the admin can set in a work profile. [CHAR LIMIT=NONE] -->
|
||||
@@ -8614,7 +8746,7 @@
|
||||
<string name="condition_battery_title">Battery Saver is on</string>
|
||||
|
||||
<!-- Summary of condition that battery saver is on [CHAR LIMIT=NONE] -->
|
||||
<string name="condition_battery_summary">Performance is reduced. Location services and background data are turned off.</string>
|
||||
<string name="condition_battery_summary">Battery Saver turns off some device features and restricts apps</string>
|
||||
|
||||
<!-- Title of condition that cellular data is off [CHAR LIMIT=50] -->
|
||||
<string name="condition_cellular_title">Mobile data is off</string>
|
||||
@@ -8634,6 +8766,27 @@
|
||||
<!-- Summary of condition that work mode is off [CHAR LIMIT=NONE] -->
|
||||
<string name="condition_work_summary">Apps, background sync, and other features related to your work profile are turned off.</string>
|
||||
|
||||
<!-- Title of condition that indicates device is muted [CHAR LIMIT=50] -->
|
||||
<string name="condition_device_muted_title" product="tablet">Device is muted</string>
|
||||
|
||||
<!-- Title of condition that indicates device is muted [CHAR LIMIT=50] -->
|
||||
<string name="condition_device_muted_title" product="default">Phone is muted</string>
|
||||
|
||||
<!-- Summary of condition that indicates device is muted -->
|
||||
<string name="condition_device_muted_summary">Calls and notifications will be muted</string>
|
||||
|
||||
<!-- Title of condition that indicates device is set to vibrate [CHAR LIMIT=50] -->
|
||||
<string name="condition_device_vibrate_title" product="tablet">Device is set to vibrate</string>
|
||||
|
||||
<!-- Title of condition that indicates device is muted [CHAR LIMIT=50] -->
|
||||
<string name="condition_device_vibrate_title" product="default">Phone is set to vibrate</string>
|
||||
|
||||
<!-- Summary of condition that indicates device is set to vibrate -->
|
||||
<string name="condition_device_vibrate_summary" product="tablet">Calls and notifications will vibrate device</string>
|
||||
|
||||
<!-- Summary of condition that indicates device is set to vibrate -->
|
||||
<string name="condition_device_vibrate_summary" product="default">Calls and notifications will vibrate phone</string>
|
||||
|
||||
<!-- Night display: Title for the night display option Suggestion (renamed "Night Light" with title caps). [CHAR LIMIT=46] -->
|
||||
<string name="night_display_suggestion_title">Set Night Light schedule</string>
|
||||
|
||||
@@ -8697,9 +8850,12 @@
|
||||
<!-- Title for Camera laser sensor switch [CHAR LIMIT=NONE] -->
|
||||
<string name="camera_laser_sensor_switch">Camera Laser Sensor</string>
|
||||
|
||||
<!-- Name of the setting to disable the automatic update -->
|
||||
<!-- Title of the setting to disable the automatic update -->
|
||||
<string name="ota_disable_automatic_update">Automatic system updates</string>
|
||||
|
||||
<!-- Summary for the setting to disable the automatic update -->
|
||||
<string name="ota_disable_automatic_update_summary">Apply updates when device restarts</string>
|
||||
|
||||
<!-- Label for category for data usage [CHAR LIMIT=30] -->
|
||||
<string name="usage">Usage</string>
|
||||
|
||||
@@ -8801,7 +8957,7 @@
|
||||
</plurals>
|
||||
|
||||
<!-- Data usage title text [CHAR LIMIT=30] -->
|
||||
<string name="data_usage_title">Primary data</string>
|
||||
<string name="data_usage_title">Current data</string>
|
||||
|
||||
<!-- Data usage remaining string [CHAR LIMIT=30] -->
|
||||
<string name="data_used"><xliff:g name="bytes" example="2 GB">^1</xliff:g> used</string>
|
||||
@@ -8857,6 +9013,9 @@
|
||||
<!-- Summary for the Data Saver feature being off [CHAR LIMIT=NONE] -->
|
||||
<string name="data_saver_off">Off</string>
|
||||
|
||||
<!-- Switch label to enable the Data Saver feature [CHAR LIMIT=NONE] -->
|
||||
<string name="data_saver_switch_title">Use Data Saver</string>
|
||||
|
||||
<!-- Title for switch to allow app unrestricted data usage [CHAR LIMIT=30] -->
|
||||
<string name="unrestricted_app_title">Unrestricted data usage</string>
|
||||
|
||||
@@ -9331,6 +9490,8 @@
|
||||
<item quantity="one"><xliff:g id="count">%d</xliff:g> attempt</item>
|
||||
<item quantity="other"><xliff:g id="count">%d</xliff:g> attempts</item>
|
||||
</plurals>
|
||||
<!-- List item in a work device's settings. This text lets the user know that their IT administrator requires their device's data to be backed up. The user can't change this setting. [CHAR LIMIT=NONE] -->
|
||||
<string name="enterprise_privacy_backups_enabled">This device\'s data is being backed up</string>
|
||||
<!-- Message indicating that the device is enterprise-managed by a Device Owner [CHAR LIMIT=NONE] -->
|
||||
<string name="do_disclosure_generic">This device is managed by your organization.</string>
|
||||
<!-- Message indicating that the device is enterprise-managed by a Device Owner [CHAR LIMIT=NONE] -->
|
||||
@@ -9507,6 +9668,27 @@
|
||||
show both names, with the directory name wrapped in parenthesis -->
|
||||
<string name="directory_on_volume"><xliff:g id="volume" example="SD Card">%1$s</xliff:g> (<xliff:g id="directory" example="Movies">%2$s</xliff:g>)</string>
|
||||
|
||||
<!-- Slices Strings -->
|
||||
|
||||
<!-- Summary text on a card explaining that a setting does not exist / is not supported on the device [CHAR_LIMIT=NONE]-->
|
||||
<string name="unsupported_setting_summary" product="default">Setting isn’t supported on this phone</string>
|
||||
|
||||
<!-- Summary text on a card explaining that a setting does not exist / is not supported on the device [CHAR_LIMIT=NONE]-->
|
||||
<string name="unsupported_setting_summary" product="tablet">Setting isn’t supported on this tablet</string>
|
||||
|
||||
<!-- Summary text on a card explaining that a setting does not exist / is not supported on the device [CHAR_LIMIT=NONE]-->
|
||||
<string name="unsupported_setting_summary" product="device">Setting isn’t supported on this device</string>
|
||||
|
||||
<!-- Summary text on a card explaining that a setting cannot be changed by the current user. [CHAR_LIMIT=NONE] -->
|
||||
<string name="disabled_for_user_setting_summary">Setting can’t be changed by current user</string>
|
||||
|
||||
<!-- Summary text on a card explaining a setting cannot be changed right now because it needs another setting to be changed. [CHAR_LIMIT=NONE] -->
|
||||
<string name="disabled_dependent_setting_summary">Depends on another setting</string>
|
||||
|
||||
<!-- Summary text on a card explaining a setting cannot be changed right now, but we don't know the reason. [CHAR_LIMIT=NONE] -->
|
||||
<string name="unknown_unavailability_setting_summary">Setting unavailable</string>
|
||||
|
||||
|
||||
<!-- Account type associated with the backup account. Empty for AOSP. [DO NOT TRANSLATE] -->
|
||||
<string name="account_type" translatable="false"></string>
|
||||
<!-- Package to target for Account credential confirmation. This will allow users to
|
||||
@@ -9518,12 +9700,6 @@
|
||||
[DO NOT TRANSLATE] -->
|
||||
<string name="account_confirmation_class" translatable="false"></string>
|
||||
|
||||
<!-- Title for the new About Phone screen [CHAR LIMIT=40] -->
|
||||
<string name="my_device_info_title" product="default">My Phone</string>
|
||||
<!-- Title for the new About Phone screen [CHAR LIMIT=40] -->
|
||||
<string name="my_device_info_title" product="tablet">My Tablet</string>
|
||||
<!-- Title for the new About Phone screen [CHAR LIMIT=40] -->
|
||||
<string name="my_device_info_title" product="device">My Device</string>
|
||||
<!-- Title for preference showing the primary account on the device [CHAR LIMIT=60]-->
|
||||
<string name="my_device_info_account_preference_title">Account</string>
|
||||
<!-- Title for preference showing the name of the device. [CHAR LIMIT=60]-->
|
||||
@@ -9575,7 +9751,27 @@
|
||||
<!-- Summary for battery Suggestion. [CHAR LIMIT=55] -->
|
||||
<string name="battery_suggestion_summary"></string>
|
||||
|
||||
<!-- Title for prevent ringing gesture screen -->
|
||||
<string name="gesture_prevent_ringing_screen_title">Prevent ringing</string>
|
||||
<!-- Title for prevent ringing setting -->
|
||||
<string name="gesture_prevent_ringing_title">Press Power & Volume Up together</string>
|
||||
<!-- Option for prevent ringing setting -->
|
||||
<string name="prevent_ringing_option_vibrate">Vibrate</string>
|
||||
<!-- Option for prevent ringing setting -->
|
||||
<string name="prevent_ringing_option_mute">Mute</string>
|
||||
<!-- Option for prevent ringing setting -->
|
||||
<string name="prevent_ringing_option_none">Do nothing</string>
|
||||
<!-- Summary for prevent ringing setting -->
|
||||
<string name="prevent_ringing_option_vibrate_summary">Vibrate all calls and notifications</string>
|
||||
<!-- Summary for prevent ringing setting -->
|
||||
<string name="prevent_ringing_option_mute_summary">Mute all calls and notifications</string>
|
||||
<!-- Summary for prevent ringing setting -->
|
||||
<string name="prevent_ringing_option_none_summary">Do nothing</string>
|
||||
|
||||
<!-- Title for detail page of wifi network [CHAR LIMIT=30] -->
|
||||
<string name="pref_title_network_details">Network details</string>
|
||||
|
||||
<!-- Warning text about the visibility of device name. [CHAR LIMIT=NONE] -->
|
||||
<string name="about_phone_device_name_warning">Your device name is visible to apps on your phone. It may also be seen by other people when you connect to Bluetooth devices or set up a Wi-Fi hotspot.</string>
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
<item name="preferenceTheme">@style/PreferenceTheme.SetupWizard</item>
|
||||
|
||||
<item name="*android:lockPatternStyle">@style/LockPatternStyle.Setup</item>
|
||||
<item name="*android:colorError">@color/glif_error_color</item>
|
||||
</style>
|
||||
|
||||
<style name="GlifV2Theme" parent="SuwThemeGlifV2">
|
||||
@@ -88,6 +89,7 @@
|
||||
<item name="preferenceTheme">@style/PreferenceTheme.SetupWizard</item>
|
||||
|
||||
<item name="*android:lockPatternStyle">@style/LockPatternStyle.Setup</item>
|
||||
<item name="*android:colorError">@color/glif_error_color</item>
|
||||
</style>
|
||||
|
||||
<style name="GlifV3Theme" parent="SuwThemeGlifV3">
|
||||
@@ -123,6 +125,7 @@
|
||||
<item name="preferenceTheme">@style/PreferenceTheme.SetupWizard</item>
|
||||
|
||||
<item name="*android:lockPatternStyle">@style/LockPatternStyle.Setup</item>
|
||||
<item name="*android:colorError">@color/glif_error_color</item>
|
||||
</style>
|
||||
|
||||
<style name="SetupWizardTheme.Transparent" parent="GlifTheme">
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
<PreferenceScreen
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:settings="http://schemas.android.com/apk/res-auto"
|
||||
android:key="accessibility_settings_vibration_screen"
|
||||
android:title="@string/accessibility_vibration_settings_title">
|
||||
|
||||
@@ -24,11 +25,13 @@
|
||||
android:fragment="com.android.settings.accessibility.NotificationVibrationPreferenceFragment"
|
||||
android:key="notification_vibration_preference_screen"
|
||||
android:title="@string/accessibility_notification_vibration_title"
|
||||
settings:keywords="@string/keywords_ring_vibration"
|
||||
app:controller="com.android.settings.accessibility.NotificationVibrationIntensityPreferenceController" />
|
||||
|
||||
<Preference
|
||||
android:fragment="com.android.settings.accessibility.TouchVibrationPreferenceFragment"
|
||||
android:key="touch_vibration_preference_screen"
|
||||
android:title="@string/accessibility_touch_vibration_title"
|
||||
settings:keywords="@string/keywords_touch_vibration"
|
||||
app:controller="com.android.settings.accessibility.HapticFeedbackIntensityPreferenceController" />
|
||||
</PreferenceScreen>
|
||||
|
||||
@@ -44,7 +44,8 @@
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory
|
||||
android:key="ambient_display_category_notification">
|
||||
android:key="ambient_display_category_notification"
|
||||
android:layout="@layout/preference_category_no_label">
|
||||
|
||||
<SwitchPreference
|
||||
android:key="ambient_display_notification"
|
||||
|
||||
@@ -47,7 +47,9 @@
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory
|
||||
android:key="app_data_usage_settings_category">
|
||||
android:key="app_data_usage_settings_category"
|
||||
android:layout="@layout/preference_category_no_label">
|
||||
|
||||
<Preference
|
||||
android:key="app_settings"
|
||||
android:title="@string/data_usage_app_settings" />
|
||||
|
||||
@@ -24,12 +24,14 @@
|
||||
<com.android.settings.widget.AppPreference
|
||||
android:key="assist_and_voice_input"
|
||||
android:title="@string/assist_and_voice_input_title"
|
||||
android:fragment="com.android.settings.applications.assist.ManageAssist" />
|
||||
android:fragment="com.android.settings.applications.assist.ManageAssist"
|
||||
settings:keywords="@string/keywords_assist_input"/>
|
||||
|
||||
<com.android.settings.widget.AppPreference
|
||||
android:key="default_browser"
|
||||
android:title="@string/default_browser_title"
|
||||
android:fragment="com.android.settings.applications.defaultapps.DefaultBrowserPicker">
|
||||
android:fragment="com.android.settings.applications.defaultapps.DefaultBrowserPicker"
|
||||
settings:keywords="@string/keywords_default_browser">
|
||||
<extra android:name="for_work" android:value="false" />
|
||||
</com.android.settings.widget.AppPreference>
|
||||
|
||||
@@ -55,7 +57,8 @@
|
||||
android:key="default_payment_app"
|
||||
android:title="@string/nfc_payment_settings_title"
|
||||
android:summary="@string/summary_placeholder"
|
||||
android:fragment="com.android.settings.nfc.PaymentSettings" />
|
||||
android:fragment="com.android.settings.nfc.PaymentSettings"
|
||||
settings:keywords="@string/keywords_default_payment_app"/>
|
||||
|
||||
<com.android.settings.widget.AppPreference
|
||||
android:key="default_emergency_app"
|
||||
@@ -73,7 +76,8 @@
|
||||
<com.android.settings.widget.AppPreference
|
||||
android:key="domain_urls"
|
||||
android:title="@string/domain_urls_title"
|
||||
android:fragment="com.android.settings.applications.ManageDomainUrls" />
|
||||
android:fragment="com.android.settings.applications.ManageDomainUrls"
|
||||
settings:keywords="@string/keywords_default_links"/>
|
||||
|
||||
<com.android.settings.widget.WorkOnlyCategory
|
||||
android:key="work_app_defaults"
|
||||
|
||||
@@ -25,13 +25,13 @@
|
||||
android:key="header_view"
|
||||
android:layout="@layout/settings_entity_header"
|
||||
android:selectable="false"
|
||||
android:order="-10000"/>
|
||||
android:order="-10000" />
|
||||
|
||||
<com.android.settings.applications.LayoutPreference
|
||||
android:key="instant_app_buttons"
|
||||
android:layout="@layout/instant_app_buttons"
|
||||
android:selectable="false"
|
||||
android:order="-9999"/>
|
||||
android:order="-9999" />
|
||||
|
||||
<com.android.settings.widget.ActionButtonPreference
|
||||
android:key="action_buttons"
|
||||
@@ -39,7 +39,7 @@
|
||||
|
||||
<Preference
|
||||
android:key="notification_settings"
|
||||
android:title="@string/notifications_label"/>
|
||||
android:title="@string/notifications_label" />
|
||||
|
||||
<com.android.settings.widget.FixedLineSummaryPreference
|
||||
android:key="permission_settings"
|
||||
@@ -50,7 +50,7 @@
|
||||
<Preference
|
||||
android:key="storage_settings"
|
||||
android:title="@string/storage_settings"
|
||||
android:summary="@string/summary_placeholder"/>
|
||||
android:summary="@string/summary_placeholder" />
|
||||
|
||||
<com.android.settings.applications.AppDomainsPreference
|
||||
android:key="instant_app_launch_supported_domain_urls"
|
||||
@@ -60,24 +60,29 @@
|
||||
<Preference
|
||||
android:key="data_settings"
|
||||
android:title="@string/data_usage_summary_title"
|
||||
android:summary="@string/summary_placeholder"/>
|
||||
android:summary="@string/summary_placeholder" />
|
||||
|
||||
<Preference
|
||||
android:key="time_spent_in_app"
|
||||
android:title="@string/time_spent_in_app_pref_title"
|
||||
app:controller="com.android.settings.applications.appinfo.TimeSpentInAppPreferenceController" />
|
||||
|
||||
<Preference
|
||||
android:key="battery"
|
||||
android:title="@string/power_usage_summary_title"
|
||||
android:summary="@string/summary_placeholder"/>
|
||||
android:summary="@string/summary_placeholder" />
|
||||
|
||||
<Preference
|
||||
android:key="preferred_settings"
|
||||
android:title="@string/launch_by_default"
|
||||
android:summary="@string/summary_placeholder"
|
||||
android:selectable="true"/>
|
||||
android:selectable="true" />
|
||||
|
||||
<Preference
|
||||
android:key="memory"
|
||||
android:title="@string/memory_settings_title"
|
||||
android:summary="@string/summary_placeholder"
|
||||
android:enabled="false"/>
|
||||
android:enabled="false" />
|
||||
|
||||
<!-- Default apps shortcuts -->
|
||||
<Preference
|
||||
@@ -146,6 +151,6 @@
|
||||
<Preference
|
||||
android:key="app_version"
|
||||
android:selectable="false"
|
||||
android:order="9999"/>
|
||||
android:order="9999" />
|
||||
|
||||
</PreferenceScreen>
|
||||
@@ -69,14 +69,13 @@
|
||||
|
||||
<!-- See all apps button -->
|
||||
<Preference
|
||||
android:title="@string/notifications_title"
|
||||
android:key="all_notifications"
|
||||
android:title="@string/notifications_title"
|
||||
android:fragment="com.android.settings.applications.manageapplications.ManageApplications"
|
||||
android:order="22">
|
||||
<intent
|
||||
android:action="android.intent.action.MAIN"
|
||||
android:targetPackage="com.android.settings"
|
||||
android:targetClass="com.android.settings.Settings$ManageApplicationsActivity">
|
||||
</intent>
|
||||
<extra
|
||||
android:name="classname"
|
||||
android:value="com.android.settings.Settings$NotificationAppListActivity" />
|
||||
</Preference>
|
||||
</PreferenceCategory>
|
||||
|
||||
|
||||
@@ -20,14 +20,15 @@
|
||||
android:key="connected_devices_advanced_screen"
|
||||
android:title="@string/connected_device_connections_title">
|
||||
|
||||
<SwitchPreference
|
||||
android:key="toggle_bluetooth_switch"
|
||||
android:title="@string/bluetooth_settings_title"
|
||||
android:icon="@drawable/ic_settings_bluetooth"
|
||||
android:summary="@string/bluetooth_pref_summary"
|
||||
android:order="-7"
|
||||
settings:controller="com.android.settings.bluetooth.BluetoothSwitchPreferenceController"
|
||||
settings:platform_slice="true"/>
|
||||
<com.android.settingslib.RestrictedSwitchPreference
|
||||
android:key="toggle_bluetooth_switch"
|
||||
android:title="@string/bluetooth_settings_title"
|
||||
android:icon="@drawable/ic_settings_bluetooth"
|
||||
android:summary="@string/bluetooth_pref_summary"
|
||||
android:order="-7"
|
||||
settings:controller="com.android.settings.bluetooth.BluetoothSwitchPreferenceController"
|
||||
settings:userRestriction="no_bluetooth"
|
||||
settings:platform_slice="true"/>
|
||||
|
||||
<SwitchPreference
|
||||
android:key="toggle_nfc"
|
||||
|
||||
@@ -22,7 +22,8 @@
|
||||
settings:keywords="@string/keywords_date_and_time">
|
||||
|
||||
<PreferenceCategory
|
||||
android:key="date_time_preference_category">
|
||||
android:key="date_time_preference_category"
|
||||
android:layout="@layout/preference_category_no_label">
|
||||
<com.android.settingslib.RestrictedSwitchPreference
|
||||
android:key="auto_time"
|
||||
android:title="@string/date_time_auto"
|
||||
@@ -46,7 +47,8 @@
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory
|
||||
android:key="time_zone_preference_category">
|
||||
android:key="time_zone_preference_category"
|
||||
android:layout="@layout/preference_category_no_label">
|
||||
<com.android.settingslib.RestrictedSwitchPreference
|
||||
android:key="auto_zone"
|
||||
android:title="@string/zone_auto"
|
||||
@@ -63,7 +65,8 @@
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory
|
||||
android:key="time_format_preference_category">
|
||||
android:key="time_format_preference_category"
|
||||
android:layout="@layout/preference_category_no_label">
|
||||
<SwitchPreference
|
||||
android:key="auto_24hour"
|
||||
android:title="@string/date_time_24hour_auto"
|
||||
|
||||
@@ -104,7 +104,8 @@
|
||||
|
||||
<SwitchPreference
|
||||
android:key="ota_disable_automatic_update"
|
||||
android:title="@string/ota_disable_automatic_update" />
|
||||
android:title="@string/ota_disable_automatic_update"
|
||||
android:summary="@string/ota_disable_automatic_update_summary" />
|
||||
|
||||
<Preference
|
||||
android:key="demo_mode"
|
||||
|
||||
@@ -65,11 +65,13 @@
|
||||
android:title="@string/screen_timeout"
|
||||
android:summary="@string/summary_placeholder"
|
||||
android:entries="@array/screen_timeout_entries"
|
||||
android:entryValues="@array/screen_timeout_values" />
|
||||
android:entryValues="@array/screen_timeout_values"
|
||||
settings:keywords="@string/keywords_screen_timeout"/>
|
||||
|
||||
<SwitchPreference
|
||||
android:key="auto_rotate"
|
||||
android:title="@string/accelerometer_title" />
|
||||
android:title="@string/accelerometer_title"
|
||||
settings:keywords="@string/keywords_auto_rotate"/>
|
||||
|
||||
<Preference
|
||||
android:key="color_mode"
|
||||
@@ -99,7 +101,6 @@
|
||||
android:title="@string/screensaver_settings_title"
|
||||
android:fragment="com.android.settings.dream.DreamSettings" />
|
||||
|
||||
<!-- Cross-listed item, if you change this, also change it in power_usage_summary.xml -->
|
||||
<com.android.settingslib.RestrictedPreference
|
||||
android:key="ambient_display"
|
||||
android:title="@string/ambient_display_screen_title"
|
||||
|
||||
@@ -50,4 +50,9 @@
|
||||
android:title="@string/ambient_display_pickup_title"
|
||||
android:fragment="com.android.settings.gestures.PickupGestureSettings" />
|
||||
|
||||
<Preference
|
||||
android:key="gesture_prevent_ringing_summary"
|
||||
android:title="@string/gesture_prevent_ringing_screen_title"
|
||||
android:fragment="com.android.settings.gestures.PreventRingingGestureSettings" />
|
||||
|
||||
</PreferenceScreen>
|
||||
|
||||
@@ -67,7 +67,8 @@
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory
|
||||
android:key="pointer_and_tts_category">
|
||||
android:key="pointer_and_tts_category"
|
||||
android:layout="@layout/preference_category_no_label">
|
||||
|
||||
<com.android.settings.PointerSpeedPreference
|
||||
android:key="pointer_speed"
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:settings="http://schemas.android.com/apk/res-auto"
|
||||
android:key="my_device_info_pref_screen"
|
||||
android:title="@string/my_device_info_title"
|
||||
android:title="@string/about_settings"
|
||||
settings:initialExpandedChildrenCount="7">
|
||||
|
||||
<com.android.settings.applications.LayoutPreference
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
android:icon="@drawable/ic_wifi_tethering"
|
||||
android:order="-5"
|
||||
android:summary="@string/summary_placeholder"
|
||||
settings:keywords="@string/keywords_hotspot_tethering"
|
||||
settings:userRestriction="no_config_tethering"
|
||||
settings:useAdminDisabledSummary="true" />
|
||||
|
||||
|
||||
@@ -16,8 +16,10 @@
|
||||
|
||||
<PreferenceScreen
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:settings="http://schemas.android.com/apk/res-auto"
|
||||
android:title="@string/night_display_title"
|
||||
android:key="night_display_title">
|
||||
android:key="night_display_title"
|
||||
settings:keywords="@string/keywords_display_night_display">
|
||||
|
||||
<DropDownPreference
|
||||
android:key="night_display_auto_mode"
|
||||
|
||||
@@ -47,7 +47,8 @@
|
||||
<!-- Vibrate on touch -->
|
||||
<SwitchPreference
|
||||
android:key="vibrate_on_touch"
|
||||
android:title="@string/vibrate_on_touch_title" />
|
||||
android:title="@string/vibrate_on_touch_title"
|
||||
android:summary="@string/vibrate_on_touch_summary" />
|
||||
|
||||
<!-- Dock speaker plays -->
|
||||
<DropDownPreference
|
||||
|
||||
@@ -24,48 +24,41 @@
|
||||
<com.android.settings.applications.LayoutPreference
|
||||
android:key="battery_header"
|
||||
android:selectable="false"
|
||||
android:layout="@layout/battery_header"/>
|
||||
android:layout="@layout/battery_header" />
|
||||
|
||||
<PreferenceCategory
|
||||
android:key="battery_tip"
|
||||
android:layout="@layout/preference_category_no_title"/>
|
||||
android:layout="@layout/preference_category_no_title" />
|
||||
|
||||
<PreferenceCategory
|
||||
android:key="power_management">
|
||||
<Preference
|
||||
android:fragment="com.android.settings.fuelgauge.batterysaver.BatterySaverSettings"
|
||||
android:key="battery_saver_summary"
|
||||
android:title="@string/battery_saver"
|
||||
settings:controller="com.android.settings.fuelgauge.BatterySaverController"
|
||||
settings:platform_slice="true"
|
||||
settings:allowDividerAbove="true" />
|
||||
|
||||
<Preference
|
||||
android:fragment="com.android.settings.fuelgauge.batterysaver.BatterySaverSettings"
|
||||
android:key="battery_saver_summary"
|
||||
android:title="@string/battery_saver"
|
||||
settings:controller="com.android.settings.fuelgauge.BatterySaverController"
|
||||
settings:platform_slice="true"/>
|
||||
<Preference
|
||||
android:fragment="com.android.settings.fuelgauge.SmartBatterySettings"
|
||||
android:key="smart_battery_manager"
|
||||
android:title="@string/smart_battery_manager_title"
|
||||
settings:controller="com.android.settings.fuelgauge.batterytip.BatteryManagerPreferenceController" />
|
||||
|
||||
<Preference
|
||||
android:fragment="com.android.settings.fuelgauge.SmartBatterySettings"
|
||||
android:key="smart_battery_manager"
|
||||
android:title="@string/smart_battery_manager_title"
|
||||
settings:controller="com.android.settings.fuelgauge.batterytip.BatteryManagerPreferenceController"/>
|
||||
<SwitchPreference
|
||||
android:key="battery_percentage"
|
||||
android:title="@string/battery_percentage"
|
||||
android:summary="@string/battery_percentage_description" />
|
||||
|
||||
<SwitchPreference
|
||||
android:key="battery_percentage"
|
||||
android:title="@string/battery_percentage"
|
||||
android:summary="@string/battery_percentage_description"/>
|
||||
|
||||
</PreferenceCategory>
|
||||
<com.android.settings.fuelgauge.PowerGaugePreference
|
||||
android:key="last_full_charge"
|
||||
android:title="@string/battery_last_full_charge"
|
||||
android:selectable="false"
|
||||
settings:allowDividerAbove="true" />
|
||||
|
||||
<PreferenceCategory
|
||||
android:key="device_usage_list">
|
||||
|
||||
<com.android.settings.fuelgauge.PowerGaugePreference
|
||||
android:key="last_full_charge"
|
||||
android:title="@string/battery_last_full_charge"
|
||||
android:selectable="false"/>
|
||||
|
||||
<com.android.settings.fuelgauge.PowerGaugePreference
|
||||
android:key="screen_usage"
|
||||
android:title="@string/device_screen_usage"
|
||||
android:selectable="false"/>
|
||||
|
||||
</PreferenceCategory>
|
||||
<com.android.settings.fuelgauge.PowerGaugePreference
|
||||
android:key="screen_usage"
|
||||
android:title="@string/device_screen_usage"
|
||||
android:selectable="false" />
|
||||
|
||||
</PreferenceScreen>
|
||||
|
||||
35
res/xml/prevent_ringing_gesture_settings.xml
Normal file
35
res/xml/prevent_ringing_gesture_settings.xml
Normal file
@@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
|
||||
<PreferenceScreen
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:key="gesture_prevent_ringing_screen"
|
||||
android:title="@string/gesture_prevent_ringing_screen_title">
|
||||
|
||||
<!-- TODO: Add video preference when it exists -->
|
||||
<com.android.settings.widget.VideoPreference
|
||||
android:key="gesture_prevent_ringing_video" />
|
||||
|
||||
<ListPreference
|
||||
android:key="gesture_prevent_ringing"
|
||||
android:title="@string/gesture_prevent_ringing_title"
|
||||
android:entries="@array/gesture_prevent_ringing_entries"
|
||||
android:entryValues="@array/gesture_prevent_ringing_values"
|
||||
app:keywords="@string/keywords_gesture" />
|
||||
|
||||
</PreferenceScreen>
|
||||
@@ -129,7 +129,8 @@
|
||||
<!-- Vibrate on touch -->
|
||||
<SwitchPreference
|
||||
android:key="vibrate_on_touch"
|
||||
android:title="@string/vibrate_on_touch_title" />
|
||||
android:title="@string/vibrate_on_touch_title"
|
||||
android:summary="@string/vibrate_on_touch_summary" />
|
||||
|
||||
<!-- Dock speaker plays -->
|
||||
<DropDownPreference
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
android:summary="@string/summary_placeholder"
|
||||
android:icon="@drawable/ic_system_update"
|
||||
android:order="-30"
|
||||
settings:keywords="@string/keywords_system_update_settings"
|
||||
settings:controller="com.android.settings.system.SystemUpdatePreferenceController">
|
||||
<intent android:action="android.settings.SYSTEM_UPDATE_SETTINGS" />
|
||||
</Preference>
|
||||
|
||||
@@ -20,11 +20,17 @@
|
||||
android:title="@string/wifi_settings"
|
||||
settings:keywords="@string/keywords_wifi">
|
||||
|
||||
<PreferenceCategory android:key="connected_access_point" />
|
||||
<PreferenceCategory
|
||||
android:key="connected_access_point"
|
||||
android:layout="@layout/preference_category_no_label"/>
|
||||
|
||||
<PreferenceCategory android:key="access_points"/>
|
||||
<PreferenceCategory
|
||||
android:key="access_points"
|
||||
android:layout="@layout/preference_category_no_label"/>
|
||||
|
||||
<PreferenceCategory android:key="additional_settings">
|
||||
<PreferenceCategory
|
||||
android:key="additional_settings"
|
||||
android:layout="@layout/preference_category_no_label">
|
||||
<Preference
|
||||
android:key="configure_settings"
|
||||
android:title="@string/wifi_configure_settings_preference_title"
|
||||
|
||||
@@ -15,9 +15,12 @@
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<PreferenceScreen
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:settings="http://schemas.android.com/apk/res-auto"
|
||||
android:key="zen_mode_settings"
|
||||
android:title="@string/zen_mode_settings_title">
|
||||
android:title="@string/zen_mode_settings_title"
|
||||
settings:keywords="@string/keywords_zen_mode_settings">
|
||||
|
||||
<!-- What to block (effects) -->
|
||||
<Preference
|
||||
|
||||
@@ -124,7 +124,6 @@ public class DisplaySettings extends DashboardFragment {
|
||||
List<String> keys = super.getNonIndexableKeys(context);
|
||||
keys.add(KEY_DISPLAY_SIZE);
|
||||
keys.add(WallpaperPreferenceController.KEY_WALLPAPER);
|
||||
keys.add(KEY_AMBIENT_DISPLAY);
|
||||
keys.add(KEY_NIGHT_DISPLAY);
|
||||
return keys;
|
||||
}
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2012 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.widget.EditText;
|
||||
|
||||
import com.android.settingslib.CustomEditTextPreference;
|
||||
|
||||
public class SelectableEditTextPreference extends CustomEditTextPreference {
|
||||
|
||||
private int mSelectionMode;
|
||||
|
||||
public static final int SELECTION_CURSOR_END = 0;
|
||||
public static final int SELECTION_CURSOR_START = 1;
|
||||
public static final int SELECTION_SELECT_ALL = 2;
|
||||
|
||||
public SelectableEditTextPreference(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the selection mode for the text when it shows up in the dialog
|
||||
* @hide
|
||||
* @param selectionMode can be SELECTION_CURSOR_START, SELECTION_CURSOR_END or
|
||||
* SELECTION_SELECT_ALL. Default is SELECTION_CURSOR_END
|
||||
*/
|
||||
public void setInitialSelectionMode(int selectionMode) {
|
||||
mSelectionMode = selectionMode;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onBindDialogView(View view) {
|
||||
super.onBindDialogView(view);
|
||||
|
||||
EditText editText = getEditText();
|
||||
// Set the selection based on the mSelectionMode
|
||||
int length = editText.getText() != null ? editText.getText().length() : 0;
|
||||
if (!TextUtils.isEmpty(editText.getText())) {
|
||||
switch (mSelectionMode) {
|
||||
case SELECTION_CURSOR_END:
|
||||
editText.setSelection(length);
|
||||
break;
|
||||
case SELECTION_CURSOR_START:
|
||||
editText.setSelection(0);
|
||||
break;
|
||||
case SELECTION_SELECT_ALL:
|
||||
editText.setSelection(0, length);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,6 +106,7 @@ public class Settings extends SettingsActivity {
|
||||
public static class ZenModeEventRuleSettingsActivity extends SettingsActivity { /* empty */ }
|
||||
public static class SoundSettingsActivity extends SettingsActivity { /* empty */ }
|
||||
public static class ConfigureNotificationSettingsActivity extends SettingsActivity { /* empty */ }
|
||||
public static class NotificationAppListActivity extends SettingsActivity { /* empty */ }
|
||||
public static class AppNotificationSettingsActivity extends SettingsActivity { /* empty */ }
|
||||
public static class ChannelNotificationSettingsActivity extends SettingsActivity { /* empty */ }
|
||||
public static class ChannelGroupNotificationSettingsActivity extends SettingsActivity { /* empty */ }
|
||||
|
||||
@@ -63,7 +63,9 @@ import com.android.settings.core.SubSettingLauncher;
|
||||
import com.android.settings.core.gateway.SettingsGateway;
|
||||
import com.android.settings.dashboard.DashboardFeatureProvider;
|
||||
import com.android.settings.dashboard.DashboardSummary;
|
||||
import com.android.settings.development.DevelopmentSettingsDashboardFragment;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settings.search.DeviceIndexFeatureProvider;
|
||||
import com.android.settings.wfd.WifiDisplaySettings;
|
||||
import com.android.settings.widget.SwitchBar;
|
||||
import com.android.settingslib.core.instrumentation.Instrumentable;
|
||||
@@ -71,6 +73,7 @@ import com.android.settingslib.core.instrumentation.SharedPreferencesLogger;
|
||||
import com.android.settingslib.development.DevelopmentSettingsEnabler;
|
||||
import com.android.settingslib.drawer.DashboardCategory;
|
||||
import com.android.settingslib.drawer.SettingsDrawerActivity;
|
||||
import com.android.settingslib.utils.ThreadUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -488,6 +491,7 @@ public class SettingsActivity extends SettingsDrawerActivity
|
||||
registerReceiver(mBatteryInfoReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
|
||||
|
||||
updateTilesList();
|
||||
updateDeviceIndex();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -608,6 +612,14 @@ public class SettingsActivity extends SettingsDrawerActivity
|
||||
});
|
||||
}
|
||||
|
||||
private void updateDeviceIndex() {
|
||||
DeviceIndexFeatureProvider indexProvider = FeatureFactory.getFactory(
|
||||
this).getDeviceIndexFeatureProvider();
|
||||
|
||||
ThreadUtils.postOnBackgroundThread(
|
||||
() -> indexProvider.updateIndex(SettingsActivity.this, false /* force */));
|
||||
}
|
||||
|
||||
private void doUpdateTilesList() {
|
||||
PackageManager pm = getPackageManager();
|
||||
final UserManager um = UserManager.get(this);
|
||||
@@ -686,10 +698,10 @@ public class SettingsActivity extends SettingsDrawerActivity
|
||||
|
||||
final boolean showDev = DevelopmentSettingsEnabler.isDevelopmentSettingsEnabled(this)
|
||||
&& !Utils.isMonkeyRunning();
|
||||
|
||||
final boolean isAdminOrDemo = um.isAdminUser() || um.isDemoUser();
|
||||
somethingChanged = setTileEnabled(new ComponentName(packageName,
|
||||
Settings.DevelopmentSettingsDashboardActivity.class.getName()),
|
||||
showDev, isAdmin)
|
||||
showDev, isAdminOrDemo)
|
||||
|| somethingChanged;
|
||||
|
||||
// Enable/disable backup settings depending on whether the user is admin.
|
||||
@@ -724,10 +736,11 @@ public class SettingsActivity extends SettingsDrawerActivity
|
||||
final int tileCount = category.getTilesCount();
|
||||
for (int i = 0; i < tileCount; i++) {
|
||||
final ComponentName component = category.getTile(i).intent.getComponent();
|
||||
|
||||
final String name = component.getClassName();
|
||||
final boolean isEnabledForRestricted = ArrayUtils.contains(
|
||||
SettingsGateway.SETTINGS_FOR_RESTRICTED, name);
|
||||
SettingsGateway.SETTINGS_FOR_RESTRICTED, name) || (isAdminOrDemo
|
||||
&& Settings.DevelopmentSettingsDashboardActivity.class.getName()
|
||||
.equals(name));
|
||||
if (packageName.equals(component.getPackageName())
|
||||
&& !isEnabledForRestricted) {
|
||||
somethingChanged = setTileEnabled(component, false, isAdmin)
|
||||
|
||||
@@ -15,70 +15,191 @@
|
||||
*/
|
||||
package com.android.settings.applications;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.usage.UsageEvents;
|
||||
import android.app.usage.UsageStatsManager;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.UserHandle;
|
||||
import android.service.notification.NotificationListenerService;
|
||||
import android.text.format.DateUtils;
|
||||
import android.util.ArrayMap;
|
||||
|
||||
import com.android.internal.widget.LockPatternUtils;
|
||||
import com.android.settings.notification.NotificationBackend;
|
||||
import com.android.settings.notification.NotificationBackend.AppRow;
|
||||
import com.android.settings.R;
|
||||
import com.android.settingslib.applications.ApplicationsState;
|
||||
import com.android.settingslib.applications.ApplicationsState.AppEntry;
|
||||
import com.android.settingslib.applications.ApplicationsState.AppFilter;
|
||||
import com.android.settingslib.utils.StringUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Connects the info provided by ApplicationsState and the NotificationBackend.
|
||||
* Connects the info provided by ApplicationsState and UsageStatsManager.
|
||||
* Also provides app filters that can use the notification data.
|
||||
*/
|
||||
public class AppStateNotificationBridge extends AppStateBaseBridge {
|
||||
|
||||
private final NotificationBackend mNotifBackend;
|
||||
private final PackageManager mPm;
|
||||
private final Context mContext;
|
||||
private UsageStatsManager mUsageStatsManager;
|
||||
private static final int DAYS_TO_CHECK = 7;
|
||||
|
||||
public AppStateNotificationBridge(Context context, ApplicationsState appState,
|
||||
Callback callback, NotificationBackend notifBackend) {
|
||||
public AppStateNotificationBridge(ApplicationsState appState,
|
||||
Callback callback, UsageStatsManager usageStatsManager) {
|
||||
super(appState, callback);
|
||||
mContext = context;
|
||||
mPm = mContext.getPackageManager();
|
||||
mNotifBackend = notifBackend;
|
||||
mUsageStatsManager = usageStatsManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void loadAllExtraInfo() {
|
||||
ArrayList<AppEntry> apps = mAppSession.getAllApps();
|
||||
final int N = apps.size();
|
||||
for (int i = 0; i < N; i++) {
|
||||
AppEntry app = apps.get(i);
|
||||
app.extraInfo = mNotifBackend.loadAppRow(mContext, mPm, app.info);
|
||||
if (apps == null) return;
|
||||
|
||||
final Map<String, NotificationsSentState> map = getAggregatedUsageEvents();
|
||||
for (AppEntry entry : apps) {
|
||||
NotificationsSentState stats = map.get(entry.info.packageName);
|
||||
calculateAvgSentCounts(stats);
|
||||
entry.extraInfo = stats;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateExtraInfo(AppEntry app, String pkg, int uid) {
|
||||
app.extraInfo = mNotifBackend.loadAppRow(mContext, mPm, app.info);
|
||||
protected void updateExtraInfo(AppEntry entry, String pkg, int uid) {
|
||||
Map<String, NotificationsSentState> map = getAggregatedUsageEvents();
|
||||
NotificationsSentState stats = map.get(entry.info.packageName);
|
||||
calculateAvgSentCounts(stats);
|
||||
entry.extraInfo = stats;
|
||||
}
|
||||
|
||||
public static final AppFilter FILTER_APP_NOTIFICATION_BLOCKED = new AppFilter() {
|
||||
public static CharSequence getSummary(Context context, NotificationsSentState state,
|
||||
boolean sortByRecency) {
|
||||
if (sortByRecency) {
|
||||
if (state.lastSent == 0) {
|
||||
return context.getString(R.string.notifications_sent_never);
|
||||
}
|
||||
return StringUtil.formatRelativeTime(
|
||||
context, System.currentTimeMillis() - state.lastSent, true);
|
||||
} else {
|
||||
if (state.avgSentWeekly > 0) {
|
||||
return context.getString(R.string.notifications_sent_weekly, state.avgSentWeekly);
|
||||
}
|
||||
return context.getString(R.string.notifications_sent_daily, state.avgSentDaily);
|
||||
}
|
||||
}
|
||||
|
||||
private void calculateAvgSentCounts(NotificationsSentState stats) {
|
||||
if (stats != null) {
|
||||
stats.avgSentDaily = Math.round((float) stats.sentCount / DAYS_TO_CHECK);
|
||||
if (stats.sentCount < DAYS_TO_CHECK) {
|
||||
stats.avgSentWeekly = stats.sentCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected Map<String, NotificationsSentState> getAggregatedUsageEvents() {
|
||||
ArrayMap<String, NotificationsSentState> aggregatedStats = new ArrayMap<>();
|
||||
|
||||
long now = System.currentTimeMillis();
|
||||
long startTime = now - (DateUtils.DAY_IN_MILLIS * DAYS_TO_CHECK);
|
||||
UsageEvents events = mUsageStatsManager.queryEvents(startTime, now);
|
||||
if (events != null) {
|
||||
UsageEvents.Event event = new UsageEvents.Event();
|
||||
while (events.hasNextEvent()) {
|
||||
events.getNextEvent(event);
|
||||
NotificationsSentState stats = aggregatedStats.get(event.getPackageName());
|
||||
if (stats == null) {
|
||||
stats = new NotificationsSentState();
|
||||
aggregatedStats.put(event.getPackageName(), stats);
|
||||
}
|
||||
|
||||
if (event.getEventType() == UsageEvents.Event.NOTIFICATION_INTERRUPTION) {
|
||||
if (event.getTimeStamp() > stats.lastSent) {
|
||||
stats.lastSent = event.getTimeStamp();
|
||||
}
|
||||
stats.sentCount++;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return aggregatedStats;
|
||||
}
|
||||
|
||||
private static NotificationsSentState getNotificationsSentState(AppEntry entry) {
|
||||
if (entry == null || entry.extraInfo == null) {
|
||||
return null;
|
||||
}
|
||||
if (entry.extraInfo instanceof NotificationsSentState) {
|
||||
return (NotificationsSentState) entry.extraInfo;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static final AppFilter FILTER_APP_NOTIFICATION_RECENCY = new AppFilter() {
|
||||
@Override
|
||||
public void init() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean filterApp(AppEntry info) {
|
||||
if (info == null || info.extraInfo == null) {
|
||||
return false;
|
||||
}
|
||||
if (info.extraInfo instanceof AppRow) {
|
||||
AppRow row = (AppRow) info.extraInfo;
|
||||
return row.banned;
|
||||
NotificationsSentState state = getNotificationsSentState(info);
|
||||
if (state != null) {
|
||||
return state.lastSent != 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
public static final AppFilter FILTER_APP_NOTIFICATION_FREQUENCY = new AppFilter() {
|
||||
@Override
|
||||
public void init() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean filterApp(AppEntry info) {
|
||||
NotificationsSentState state = getNotificationsSentState(info);
|
||||
if (state != null) {
|
||||
return state.sentCount != 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
public static final Comparator<AppEntry> RECENT_NOTIFICATION_COMPARATOR
|
||||
= new Comparator<AppEntry>() {
|
||||
@Override
|
||||
public int compare(AppEntry object1, AppEntry object2) {
|
||||
NotificationsSentState state1 = getNotificationsSentState(object1);
|
||||
NotificationsSentState state2 = getNotificationsSentState(object2);
|
||||
if (state1 == null && state2 != null) return -1;
|
||||
if (state1 != null && state2 == null) return 1;
|
||||
if (state1 != null && state2 != null) {
|
||||
if (state1.lastSent < state2.lastSent) return 1;
|
||||
if (state1.lastSent > state2.lastSent) return -1;
|
||||
}
|
||||
return ApplicationsState.ALPHA_COMPARATOR.compare(object1, object2);
|
||||
}
|
||||
};
|
||||
|
||||
public static final Comparator<AppEntry> FREQUENCY_NOTIFICATION_COMPARATOR
|
||||
= new Comparator<AppEntry>() {
|
||||
@Override
|
||||
public int compare(AppEntry object1, AppEntry object2) {
|
||||
NotificationsSentState state1 = getNotificationsSentState(object1);
|
||||
NotificationsSentState state2 = getNotificationsSentState(object2);
|
||||
if (state1 == null && state2 != null) return -1;
|
||||
if (state1 != null && state2 == null) return 1;
|
||||
if (state1 != null && state2 != null) {
|
||||
if (state1.sentCount < state2.sentCount) return 1;
|
||||
if (state1.sentCount > state2.sentCount) return -1;
|
||||
}
|
||||
return ApplicationsState.ALPHA_COMPARATOR.compare(object1, object2);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* NotificationsSentState contains how often an app sends notifications and how recently it sent
|
||||
* one.
|
||||
*/
|
||||
public static class NotificationsSentState {
|
||||
public int avgSentDaily = 0;
|
||||
public int avgSentWeekly = 0;
|
||||
public long lastSent = 0;
|
||||
public int sentCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,20 +45,16 @@ import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.settings.DeviceAdminAdd;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SettingsActivity;
|
||||
import com.android.settings.SettingsPreferenceFragment;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.applications.LayoutPreference;
|
||||
import com.android.settings.applications.manageapplications.ManageApplications;
|
||||
import com.android.settings.core.SubSettingLauncher;
|
||||
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
|
||||
import com.android.settings.dashboard.DashboardFragment;
|
||||
import com.android.settings.widget.EntityHeaderController;
|
||||
import com.android.settings.widget.PreferenceCategoryController;
|
||||
import com.android.settings.wrapper.DevicePolicyManagerWrapper;
|
||||
import com.android.settingslib.RestrictedLockUtils;
|
||||
@@ -157,7 +153,12 @@ public class AppInfoDashboardFragment extends DashboardFragment
|
||||
== PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
|
||||
}
|
||||
|
||||
/** Called when the activity is first created. */
|
||||
@Override
|
||||
public void onAttach(Context context) {
|
||||
super.onAttach(context);
|
||||
use(TimeSpentInAppPreferenceController.class).setPackageName(getPackageName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle icicle) {
|
||||
super.onCreate(icicle);
|
||||
@@ -191,9 +192,10 @@ public class AppInfoDashboardFragment extends DashboardFragment
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
mAppsControlDisallowedAdmin = RestrictedLockUtils.checkIfRestrictionEnforced(getActivity(),
|
||||
final Activity activity = getActivity();
|
||||
mAppsControlDisallowedAdmin = RestrictedLockUtils.checkIfRestrictionEnforced(activity,
|
||||
UserManager.DISALLOW_APPS_CONTROL, mUserId);
|
||||
mAppsControlDisallowedBySystem = RestrictedLockUtils.hasBaseUserRestriction(getActivity(),
|
||||
mAppsControlDisallowedBySystem = RestrictedLockUtils.hasBaseUserRestriction(activity,
|
||||
UserManager.DISALLOW_APPS_CONTROL, mUserId);
|
||||
|
||||
if (!refreshUi()) {
|
||||
@@ -300,7 +302,7 @@ public class AppInfoDashboardFragment extends DashboardFragment
|
||||
*
|
||||
* @return true if packageInfo is available.
|
||||
*/
|
||||
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
|
||||
@VisibleForTesting
|
||||
boolean ensurePackageInfoAvailable(Activity activity) {
|
||||
if (mPackageInfo == null) {
|
||||
mFinishing = true;
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.applications.appinfo;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.support.v7.preference.PreferenceScreen;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class TimeSpentInAppPreferenceController extends BasePreferenceController {
|
||||
|
||||
@VisibleForTesting
|
||||
static final Intent SEE_TIME_IN_APP_TEMPLATE =
|
||||
new Intent("com.android.settings.action.TIME_SPENT_IN_APP");
|
||||
|
||||
private final PackageManager mPackageManager;
|
||||
|
||||
private Intent mIntent;
|
||||
private String mPackageName;
|
||||
|
||||
public TimeSpentInAppPreferenceController(Context context, String preferenceKey) {
|
||||
super(context, preferenceKey);
|
||||
mPackageManager = context.getPackageManager();
|
||||
}
|
||||
|
||||
public void setPackageName(String packageName) {
|
||||
mPackageName = packageName;
|
||||
mIntent = new Intent(SEE_TIME_IN_APP_TEMPLATE)
|
||||
.putExtra(Intent.EXTRA_PACKAGE_NAME, mPackageName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAvailabilityStatus() {
|
||||
if (TextUtils.isEmpty(mPackageName)) {
|
||||
return DISABLED_UNSUPPORTED;
|
||||
}
|
||||
final List<ResolveInfo> resolved = mPackageManager.queryIntentActivities(mIntent,
|
||||
0 /* flags */);
|
||||
if (resolved == null || resolved.isEmpty()) {
|
||||
return DISABLED_UNSUPPORTED;
|
||||
}
|
||||
return AVAILABLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayPreference(PreferenceScreen screen) {
|
||||
super.displayPreference(screen);
|
||||
final Preference pref = screen.findPreference(getPreferenceKey());
|
||||
if (pref != null) {
|
||||
pref.setIntent(mIntent);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -41,7 +41,8 @@ public class AppFilterRegistry {
|
||||
FILTER_APPS_ENABLED,
|
||||
FILTER_APPS_INSTANT,
|
||||
FILTER_APPS_DISABLED,
|
||||
FILTER_APPS_BLOCKED,
|
||||
FILTER_APPS_RECENT,
|
||||
FILTER_APPS_FREQUENT,
|
||||
FILTER_APPS_PERSONAL,
|
||||
FILTER_APPS_WORK,
|
||||
FILTER_APPS_USAGE_ACCESS,
|
||||
@@ -60,23 +61,24 @@ public class AppFilterRegistry {
|
||||
public static final int FILTER_APPS_ENABLED = 3;
|
||||
public static final int FILTER_APPS_INSTANT = 4;
|
||||
public static final int FILTER_APPS_DISABLED = 5;
|
||||
public static final int FILTER_APPS_BLOCKED = 6;
|
||||
public static final int FILTER_APPS_PERSONAL = 7;
|
||||
public static final int FILTER_APPS_WORK = 8;
|
||||
public static final int FILTER_APPS_USAGE_ACCESS = 9;
|
||||
public static final int FILTER_APPS_WITH_OVERLAY = 10;
|
||||
public static final int FILTER_APPS_WRITE_SETTINGS = 11;
|
||||
public static final int FILTER_APPS_INSTALL_SOURCES = 12;
|
||||
public static final int FILTER_APP_HAS_DIRECTORY_ACCESS = 13;
|
||||
public static final int FILTER_APP_CAN_CHANGE_WIFI_STATE = 14;
|
||||
// Next id: 15
|
||||
public static final int FILTER_APPS_RECENT = 6;
|
||||
public static final int FILTER_APPS_FREQUENT = 7;
|
||||
public static final int FILTER_APPS_PERSONAL = 8;
|
||||
public static final int FILTER_APPS_WORK = 9;
|
||||
public static final int FILTER_APPS_USAGE_ACCESS = 10;
|
||||
public static final int FILTER_APPS_WITH_OVERLAY = 11;
|
||||
public static final int FILTER_APPS_WRITE_SETTINGS = 12;
|
||||
public static final int FILTER_APPS_INSTALL_SOURCES = 13;
|
||||
public static final int FILTER_APP_HAS_DIRECTORY_ACCESS = 14;
|
||||
public static final int FILTER_APP_CAN_CHANGE_WIFI_STATE = 15;
|
||||
// Next id: 16
|
||||
|
||||
private static AppFilterRegistry sRegistry;
|
||||
|
||||
private final AppFilterItem[] mFilters;
|
||||
|
||||
private AppFilterRegistry() {
|
||||
mFilters = new AppFilterItem[15];
|
||||
mFilters = new AppFilterItem[16];
|
||||
|
||||
// High power whitelist, on
|
||||
mFilters[FILTER_APPS_POWER_WHITELIST] = new AppFilterItem(
|
||||
@@ -118,11 +120,17 @@ public class AppFilterRegistry {
|
||||
FILTER_APPS_INSTANT,
|
||||
R.string.filter_instant_apps);
|
||||
|
||||
// Blocked Notifications
|
||||
mFilters[FILTER_APPS_BLOCKED] = new AppFilterItem(
|
||||
AppStateNotificationBridge.FILTER_APP_NOTIFICATION_BLOCKED,
|
||||
FILTER_APPS_BLOCKED,
|
||||
R.string.filter_notif_blocked_apps);
|
||||
// Recent Notifications
|
||||
mFilters[FILTER_APPS_RECENT] = new AppFilterItem(
|
||||
AppStateNotificationBridge.FILTER_APP_NOTIFICATION_RECENCY,
|
||||
FILTER_APPS_RECENT,
|
||||
R.string.sort_order_recent_notification);
|
||||
|
||||
// Frequent Notifications
|
||||
mFilters[FILTER_APPS_FREQUENT] = new AppFilterItem(
|
||||
AppStateNotificationBridge.FILTER_APP_NOTIFICATION_FREQUENCY,
|
||||
FILTER_APPS_FREQUENT,
|
||||
R.string.sort_order_frequent_notification);
|
||||
|
||||
// Personal
|
||||
mFilters[FILTER_APPS_PERSONAL] = new AppFilterItem(
|
||||
@@ -196,6 +204,8 @@ public class AppFilterRegistry {
|
||||
return FILTER_APP_HAS_DIRECTORY_ACCESS;
|
||||
case ManageApplications.LIST_TYPE_WIFI_ACCESS:
|
||||
return FILTER_APP_CAN_CHANGE_WIFI_STATE;
|
||||
case ManageApplications.LIST_TYPE_NOTIFICATION:
|
||||
return FILTER_APPS_RECENT;
|
||||
default:
|
||||
return FILTER_APPS_ALL;
|
||||
}
|
||||
|
||||
@@ -17,11 +17,13 @@
|
||||
package com.android.settings.applications.manageapplications;
|
||||
|
||||
import static com.android.settings.applications.manageapplications.AppFilterRegistry
|
||||
.FILTER_APPS_BLOCKED;
|
||||
.FILTER_APPS_ALL;
|
||||
import static com.android.settings.applications.manageapplications.AppFilterRegistry
|
||||
.FILTER_APPS_DISABLED;
|
||||
import static com.android.settings.applications.manageapplications.AppFilterRegistry
|
||||
.FILTER_APPS_ENABLED;
|
||||
import static com.android.settings.applications.manageapplications.AppFilterRegistry
|
||||
.FILTER_APPS_FREQUENT;
|
||||
import static com.android.settings.applications.manageapplications.AppFilterRegistry
|
||||
.FILTER_APPS_INSTANT;
|
||||
import static com.android.settings.applications.manageapplications.AppFilterRegistry
|
||||
@@ -30,12 +32,15 @@ import static com.android.settings.applications.manageapplications.AppFilterRegi
|
||||
.FILTER_APPS_POWER_WHITELIST;
|
||||
import static com.android.settings.applications.manageapplications.AppFilterRegistry
|
||||
.FILTER_APPS_POWER_WHITELIST_ALL;
|
||||
import static com.android.settings.applications.manageapplications.AppFilterRegistry
|
||||
.FILTER_APPS_RECENT;
|
||||
import static com.android.settings.applications.manageapplications.AppFilterRegistry
|
||||
.FILTER_APPS_WORK;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.StringRes;
|
||||
import android.app.Activity;
|
||||
import android.app.usage.UsageStatsManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
@@ -81,6 +86,7 @@ import com.android.settings.applications.AppStateBaseBridge;
|
||||
import com.android.settings.applications.AppStateDirectoryAccessBridge;
|
||||
import com.android.settings.applications.AppStateInstallAppsBridge;
|
||||
import com.android.settings.applications.AppStateNotificationBridge;
|
||||
import com.android.settings.applications.AppStateNotificationBridge.NotificationsSentState;
|
||||
import com.android.settings.applications.AppStateOverlayBridge;
|
||||
import com.android.settings.applications.AppStatePowerBridge;
|
||||
import com.android.settings.applications.AppStateUsageBridge;
|
||||
@@ -92,7 +98,6 @@ import com.android.settings.applications.DirectoryAccessDetails;
|
||||
import com.android.settings.applications.InstalledAppCounter;
|
||||
import com.android.settings.applications.UsageAccessDetails;
|
||||
import com.android.settings.applications.appinfo.AppInfoDashboardFragment;
|
||||
import com.android.settings.applications.appinfo.AppNotificationPreferenceController;
|
||||
import com.android.settings.applications.appinfo.DrawOverlayDetails;
|
||||
import com.android.settings.applications.appinfo.ExternalSourcesDetails;
|
||||
import com.android.settings.applications.appinfo.WriteSettingsDetails;
|
||||
@@ -102,8 +107,6 @@ import com.android.settings.dashboard.SummaryLoader;
|
||||
import com.android.settings.fuelgauge.HighPowerDetail;
|
||||
import com.android.settings.notification.AppNotificationSettings;
|
||||
import com.android.settings.notification.ConfigureNotificationSettings;
|
||||
import com.android.settings.notification.NotificationBackend;
|
||||
import com.android.settings.notification.NotificationBackend.AppRow;
|
||||
import com.android.settings.widget.LoadingViewController;
|
||||
import com.android.settings.wifi.AppStateChangeWifiStateBridge;
|
||||
import com.android.settings.wifi.ChangeWifiStateDetails;
|
||||
@@ -217,7 +220,7 @@ public class ManageApplications extends InstrumentedFragment
|
||||
private View mSpinnerHeader;
|
||||
private Spinner mFilterSpinner;
|
||||
private FilterSpinnerAdapter mFilterAdapter;
|
||||
private NotificationBackend mNotifBackend;
|
||||
private UsageStatsManager mUsageStatsManager;
|
||||
private ResetAppsHelper mResetAppsHelper;
|
||||
private String mVolumeUuid;
|
||||
private int mStorageType;
|
||||
@@ -283,6 +286,12 @@ public class ManageApplications extends InstrumentedFragment
|
||||
} else if (className.equals(Settings.ChangeWifiStateActivity.class.getName())) {
|
||||
mListType = LIST_TYPE_WIFI_ACCESS;
|
||||
screenTitle = R.string.change_wifi_state_title;
|
||||
} else if (className.equals(Settings.NotificationAppListActivity.class.getName())) {
|
||||
mListType = LIST_TYPE_NOTIFICATION;
|
||||
mUsageStatsManager =
|
||||
(UsageStatsManager) getContext().getSystemService(Context.USAGE_STATS_SERVICE);
|
||||
mSortOrder = R.id.sort_order_recent_notification;
|
||||
screenTitle = R.string.app_notifications_title;
|
||||
} else {
|
||||
if (screenTitle == -1) {
|
||||
screenTitle = R.string.application_info_label;
|
||||
@@ -383,7 +392,9 @@ public class ManageApplications extends InstrumentedFragment
|
||||
}
|
||||
}
|
||||
if (mListType == LIST_TYPE_NOTIFICATION) {
|
||||
mFilterAdapter.enableFilter(FILTER_APPS_BLOCKED);
|
||||
mFilterAdapter.enableFilter(FILTER_APPS_RECENT);
|
||||
mFilterAdapter.enableFilter(FILTER_APPS_FREQUENT);
|
||||
mFilterAdapter.disableFilter(FILTER_APPS_ALL);
|
||||
}
|
||||
if (mListType == LIST_TYPE_HIGH_POWER) {
|
||||
mFilterAdapter.enableFilter(FILTER_APPS_POWER_WHITELIST_ALL);
|
||||
@@ -579,6 +590,7 @@ public class ManageApplications extends InstrumentedFragment
|
||||
HelpUtils.prepareHelpMenuItem(activity, menu, getHelpResource(), getClass().getName());
|
||||
mOptionsMenu = menu;
|
||||
inflater.inflate(R.menu.manage_apps, menu);
|
||||
|
||||
updateOptionsMenu();
|
||||
}
|
||||
|
||||
@@ -620,6 +632,10 @@ public class ManageApplications extends InstrumentedFragment
|
||||
&& mListType != LIST_TYPE_HIGH_POWER);
|
||||
|
||||
mOptionsMenu.findItem(R.id.reset_app_preferences).setVisible(mListType == LIST_TYPE_MAIN);
|
||||
|
||||
// Hide notification menu items, because sorting happens when filtering
|
||||
mOptionsMenu.findItem(R.id.sort_order_recent_notification).setVisible(false);
|
||||
mOptionsMenu.findItem(R.id.sort_order_frequent_notification).setVisible(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -846,8 +862,8 @@ public class ManageApplications extends InstrumentedFragment
|
||||
mContext = manageApplications.getActivity();
|
||||
mAppFilter = appFilter;
|
||||
if (mManageApplications.mListType == LIST_TYPE_NOTIFICATION) {
|
||||
mExtraInfoBridge = new AppStateNotificationBridge(mContext, mState, this,
|
||||
manageApplications.mNotifBackend);
|
||||
mExtraInfoBridge = new AppStateNotificationBridge(mState, this,
|
||||
manageApplications.mUsageStatsManager);
|
||||
} else if (mManageApplications.mListType == LIST_TYPE_USAGE_ACCESS) {
|
||||
mExtraInfoBridge = new AppStateUsageBridge(mContext, mState, this);
|
||||
} else if (mManageApplications.mListType == LIST_TYPE_HIGH_POWER) {
|
||||
@@ -877,7 +893,15 @@ public class ManageApplications extends InstrumentedFragment
|
||||
|
||||
public void setFilter(AppFilterItem appFilter) {
|
||||
mAppFilter = appFilter;
|
||||
rebuild();
|
||||
|
||||
// Notification filters require resorting the list
|
||||
if (FILTER_APPS_FREQUENT == appFilter.getFilterType()) {
|
||||
rebuild(R.id.sort_order_frequent_notification);
|
||||
} else if (FILTER_APPS_RECENT == appFilter.getFilterType()) {
|
||||
rebuild(R.id.sort_order_recent_notification);
|
||||
} else {
|
||||
rebuild();
|
||||
}
|
||||
}
|
||||
|
||||
public void setExtraViewController(FileViewHolderController extraViewController) {
|
||||
@@ -995,6 +1019,12 @@ public class ManageApplications extends InstrumentedFragment
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case R.id.sort_order_recent_notification:
|
||||
comparatorObj = AppStateNotificationBridge.RECENT_NOTIFICATION_COMPARATOR;
|
||||
break;
|
||||
case R.id.sort_order_frequent_notification:
|
||||
comparatorObj = AppStateNotificationBridge.FREQUENCY_NOTIFICATION_COMPARATOR;
|
||||
break;
|
||||
default:
|
||||
comparatorObj = ApplicationsState.ALPHA_COMPARATOR;
|
||||
break;
|
||||
@@ -1235,9 +1265,9 @@ public class ManageApplications extends InstrumentedFragment
|
||||
switch (mManageApplications.mListType) {
|
||||
case LIST_TYPE_NOTIFICATION:
|
||||
if (entry.extraInfo != null) {
|
||||
holder.setSummary(
|
||||
AppNotificationPreferenceController.getNotificationSummary(
|
||||
(AppRow) entry.extraInfo, mContext));
|
||||
holder.setSummary(AppStateNotificationBridge.getSummary(mContext,
|
||||
(NotificationsSentState) entry.extraInfo,
|
||||
(mLastSortMode == R.id.sort_order_recent_notification)));
|
||||
} else {
|
||||
holder.setSummary(null);
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.TextView;
|
||||
@@ -89,8 +90,15 @@ abstract class BluetoothNameDialogFragment extends InstrumentedDialogFragment
|
||||
})
|
||||
.setNegativeButton(android.R.string.cancel, null);
|
||||
mAlertDialog = builder.create();
|
||||
mAlertDialog.getWindow().setSoftInputMode(
|
||||
WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
|
||||
mAlertDialog.setOnShowListener(d -> {
|
||||
if (mDeviceNameView != null && mDeviceNameView.requestFocus()) {
|
||||
InputMethodManager imm = (InputMethodManager) getContext().getSystemService(
|
||||
Context.INPUT_METHOD_SERVICE);
|
||||
if (imm != null) {
|
||||
imm.showSoftInput(mDeviceNameView, InputMethodManager.SHOW_IMPLICIT);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return mAlertDialog;
|
||||
}
|
||||
|
||||
@@ -434,6 +434,7 @@ public class BluetoothSettings extends DeviceListPreferenceFragment implements I
|
||||
data.title = res.getString(R.string.bluetooth_settings);
|
||||
data.screenTitle = res.getString(R.string.bluetooth_settings);
|
||||
data.key = DATA_KEY_REFERENCE;
|
||||
data.keywords = res.getString(R.string.keywords_bluetooth_settings);
|
||||
result.add(data);
|
||||
|
||||
// Removed paired bluetooth device indexing. See BluetoothSettingsObsolete.java.
|
||||
|
||||
@@ -109,7 +109,7 @@ public class BluetoothSwitchPreferenceController extends TogglePreferenceControl
|
||||
* Control the switch inside {@link SwitchPreference}
|
||||
*/
|
||||
@VisibleForTesting
|
||||
class SwitchController extends SwitchWidgetController implements
|
||||
static class SwitchController extends SwitchWidgetController implements
|
||||
Preference.OnPreferenceChangeListener {
|
||||
private SwitchPreference mSwitchPreference;
|
||||
|
||||
@@ -156,7 +156,7 @@ public class BluetoothSwitchPreferenceController extends TogglePreferenceControl
|
||||
|
||||
@Override
|
||||
public void setDisabledByAdmin(RestrictedLockUtils.EnforcedAdmin admin) {
|
||||
mBtPreference.setEnabled(admin == null);
|
||||
mSwitchPreference.setEnabled(admin == null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ public class PreferenceControllerListHelper {
|
||||
preferenceMetadata = PreferenceXmlParserUtils.extractMetadata(context, xmlResId,
|
||||
MetadataFlag.FLAG_NEED_KEY | MetadataFlag.FLAG_NEED_PREF_CONTROLLER);
|
||||
} catch (IOException | XmlPullParserException e) {
|
||||
Log.e(TAG, "Failed to parse preference xml for getting controllers");
|
||||
Log.e(TAG, "Failed to parse preference xml for getting controllers", e);
|
||||
return controllers;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* 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.core;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.support.v7.preference.SeekBarPreference;
|
||||
|
||||
import com.android.settings.slices.SliceData;
|
||||
|
||||
public abstract class SliderPreferenceController extends BasePreferenceController implements
|
||||
Preference.OnPreferenceChangeListener {
|
||||
|
||||
public SliderPreferenceController(Context context, String preferenceKey) {
|
||||
super(context, preferenceKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
return setSliderPosition((int) newValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
((SeekBarPreference) preference).setValue(getSliderPosition());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the value of the Slider's position based on the range: [0, maxSteps).
|
||||
*/
|
||||
public abstract int getSliderPosition();
|
||||
|
||||
/**
|
||||
* Set the slider to a new value.
|
||||
*
|
||||
* @param position of the slider.
|
||||
* @return {@code true} if the position is successfully set.
|
||||
*/
|
||||
public abstract boolean setSliderPosition(int position);
|
||||
|
||||
/**
|
||||
* @return the number of steps supported by the slider.
|
||||
*/
|
||||
public abstract int getMaxSteps();
|
||||
|
||||
@Override
|
||||
public int getSliceType() {
|
||||
return SliceData.SliceType.SLIDER;
|
||||
}
|
||||
}
|
||||
@@ -58,7 +58,7 @@ public abstract class TogglePreferenceController extends BasePreferenceControlle
|
||||
|
||||
@Override
|
||||
public final boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
return setChecked((Boolean) newValue);
|
||||
return setChecked((boolean) newValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -152,7 +152,9 @@ public class DndCondition extends Condition {
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
mManager.getContext().unregisterReceiver(mReceiver);
|
||||
mRegistered = false;
|
||||
if (mRegistered) {
|
||||
mManager.getContext().unregisterReceiver(mReceiver);
|
||||
mRegistered = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import static android.telephony.TelephonyManager.SIM_STATE_READY;
|
||||
import android.app.ActivityManager;
|
||||
import android.app.LoaderManager.LoaderCallbacks;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.Loader;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.graphics.Color;
|
||||
@@ -39,6 +40,8 @@ import android.os.RemoteException;
|
||||
import android.os.SystemProperties;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.provider.Settings;
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.support.v7.preference.PreferenceGroup;
|
||||
import android.telephony.SubscriptionInfo;
|
||||
@@ -98,8 +101,10 @@ public class DataUsageList extends DataUsageBase {
|
||||
private INetworkStatsSession mStatsSession;
|
||||
private ChartDataUsagePreference mChart;
|
||||
|
||||
private NetworkTemplate mTemplate;
|
||||
private int mSubId;
|
||||
@VisibleForTesting
|
||||
NetworkTemplate mTemplate;
|
||||
@VisibleForTesting
|
||||
int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
|
||||
private ChartData mChartData;
|
||||
|
||||
private LoadingViewController mLoadingViewController;
|
||||
@@ -138,10 +143,7 @@ public class DataUsageList extends DataUsageBase {
|
||||
mUsageAmount = findPreference(KEY_USAGE_AMOUNT);
|
||||
mChart = (ChartDataUsagePreference) findPreference(KEY_CHART_DATA);
|
||||
mApps = (PreferenceGroup) findPreference(KEY_APPS_GROUP);
|
||||
|
||||
final Bundle args = getArguments();
|
||||
mSubId = args.getInt(EXTRA_SUB_ID, SubscriptionManager.INVALID_SUBSCRIPTION_ID);
|
||||
mTemplate = args.getParcelable(EXTRA_NETWORK_TEMPLATE);
|
||||
processArgument();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -232,6 +234,20 @@ public class DataUsageList extends DataUsageBase {
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
void processArgument() {
|
||||
final Bundle args = getArguments();
|
||||
if (args != null) {
|
||||
mSubId = args.getInt(EXTRA_SUB_ID, SubscriptionManager.INVALID_SUBSCRIPTION_ID);
|
||||
mTemplate = args.getParcelable(EXTRA_NETWORK_TEMPLATE);
|
||||
}
|
||||
if (mTemplate == null && mSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
|
||||
final Intent intent = getIntent();
|
||||
mSubId = intent.getIntExtra(Settings.EXTRA_SUB_ID,
|
||||
SubscriptionManager.INVALID_SUBSCRIPTION_ID);
|
||||
mTemplate = intent.getParcelableExtra(Settings.EXTRA_NETWORK_TEMPLATE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update body content based on current tab. Loads
|
||||
* {@link NetworkStatsHistory} and {@link NetworkPolicy} from system, and
|
||||
|
||||
@@ -27,13 +27,19 @@ import java.util.stream.Collectors;
|
||||
*/
|
||||
public class FilteredCountryTimeZones {
|
||||
|
||||
// New timezone list and the meta data of time zone, notUsedAfter, is introduced in Android P
|
||||
// in 2018. Only show time zone used in or after 2018.
|
||||
private static final long MIN_USE_DATE_OF_TIMEZONE = 1514764800000L; // 1/1/2018 00:00 UTC
|
||||
|
||||
private final CountryTimeZones mCountryTimeZones;
|
||||
private final List<String> mTimeZoneIds;
|
||||
|
||||
public FilteredCountryTimeZones(CountryTimeZones countryTimeZones) {
|
||||
mCountryTimeZones = countryTimeZones;
|
||||
List<String> timeZoneIds = countryTimeZones.getTimeZoneMappings().stream()
|
||||
.filter(timeZoneMapping -> timeZoneMapping.showInPicker)
|
||||
.filter(timeZoneMapping ->
|
||||
timeZoneMapping.showInPicker && (timeZoneMapping.notUsedAfter == null
|
||||
|| timeZoneMapping.notUsedAfter >= MIN_USE_DATE_OF_TIMEZONE))
|
||||
.map(timeZoneMapping -> timeZoneMapping.timeZoneId)
|
||||
.collect(Collectors.toList());
|
||||
mTimeZoneIds = Collections.unmodifiableList(timeZoneIds);
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package com.android.settings.datetime.timezone.model;
|
||||
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
import android.support.v4.util.ArraySet;
|
||||
|
||||
import libcore.util.CountryTimeZones;
|
||||
import libcore.util.CountryZonesFinder;
|
||||
@@ -27,12 +28,11 @@ import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Wrapper of CountryZonesFinder to normalize the country code and only show the regions that are
|
||||
* has time zone shown in the time zone picker.
|
||||
* The constructor reads the data from underlying file, and this means it should not be called
|
||||
* getInstance() reads the data from underlying file, and this means it should not be called
|
||||
* from the UI thread.
|
||||
*/
|
||||
public class TimeZoneData {
|
||||
@@ -47,15 +47,11 @@ public class TimeZoneData {
|
||||
if (data != null) {
|
||||
return data;
|
||||
}
|
||||
data = new TimeZoneData();
|
||||
data = new TimeZoneData(TimeZoneFinder.getInstance().getCountryZonesFinder());
|
||||
sCache = new WeakReference<>(data);
|
||||
return data;
|
||||
}
|
||||
|
||||
public TimeZoneData() {
|
||||
this(TimeZoneFinder.getInstance().getCountryZonesFinder());
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public TimeZoneData(CountryZonesFinder countryZonesFinder) {
|
||||
mCountryZonesFinder = countryZonesFinder;
|
||||
@@ -70,13 +66,16 @@ public class TimeZoneData {
|
||||
if (tzId == null) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
return mCountryZonesFinder.lookupCountryTimeZonesForZoneId(tzId).stream()
|
||||
.filter(countryTimeZones ->
|
||||
countryTimeZones.getTimeZoneMappings().stream()
|
||||
.anyMatch(mapping ->
|
||||
mapping.timeZoneId.equals(tzId) && mapping.showInPicker))
|
||||
.map(countryTimeZones -> normalizeRegionId(countryTimeZones.getCountryIso()))
|
||||
.collect(Collectors.toSet());
|
||||
List<CountryTimeZones> countryTimeZones = mCountryZonesFinder
|
||||
.lookupCountryTimeZonesForZoneId(tzId);
|
||||
Set<String> regionIds = new ArraySet<>();
|
||||
for (CountryTimeZones countryTimeZone : countryTimeZones) {
|
||||
FilteredCountryTimeZones filteredZones = new FilteredCountryTimeZones(countryTimeZone);
|
||||
if (filteredZones.getTimeZoneIds().contains(tzId)) {
|
||||
regionIds.add(filteredZones.getRegionId());
|
||||
}
|
||||
}
|
||||
return regionIds;
|
||||
}
|
||||
|
||||
public FilteredCountryTimeZones lookupCountryTimeZones(String regionId) {
|
||||
|
||||
@@ -32,7 +32,7 @@ public class TimeZoneDataLoader extends AsyncLoader<TimeZoneData> {
|
||||
@Override
|
||||
public TimeZoneData loadInBackground() {
|
||||
// Heavy operation due to reading the underlying file
|
||||
return new TimeZoneData();
|
||||
return TimeZoneData.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -18,8 +18,10 @@ package com.android.settings.deviceinfo;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Fragment;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.os.Build;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
@@ -118,8 +120,8 @@ public class BuildNumberPreferenceController extends AbstractPreferenceControlle
|
||||
if (Utils.isMonkeyRunning()) {
|
||||
return false;
|
||||
}
|
||||
// Don't enable developer options for secondary users.
|
||||
if (!mUm.isAdminUser()) {
|
||||
// Don't enable developer options for secondary non-demo users.
|
||||
if (!(mUm.isAdminUser() || mUm.isDemoUser())) {
|
||||
mMetricsFeatureProvider.action(
|
||||
mContext, MetricsEvent.ACTION_SETTINGS_BUILD_NUMBER_PREF);
|
||||
return false;
|
||||
@@ -133,6 +135,21 @@ public class BuildNumberPreferenceController extends AbstractPreferenceControlle
|
||||
}
|
||||
|
||||
if (mUm.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES)) {
|
||||
if (mUm.isDemoUser()) {
|
||||
// Route to demo device owner to lift the debugging restriction.
|
||||
final ComponentName componentName = Utils.getDeviceOwnerComponent(mContext);
|
||||
if (componentName != null) {
|
||||
final Intent requestDebugFeatures = new Intent()
|
||||
.setPackage(componentName.getPackageName())
|
||||
.setAction("com.android.settings.action.REQUEST_DEBUG_FEATURES");
|
||||
final ResolveInfo resolveInfo = mContext.getPackageManager().resolveActivity(
|
||||
requestDebugFeatures, 0);
|
||||
if (resolveInfo != null) {
|
||||
mContext.startActivity(requestDebugFeatures);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mDebuggingFeaturesDisallowedAdmin != null &&
|
||||
!mDebuggingFeaturesDisallowedBySystem) {
|
||||
RestrictedLockUtils.sendShowAdminSupportDetailsIntent(mContext,
|
||||
|
||||
@@ -571,6 +571,7 @@ public class StorageSettings extends SettingsPreferenceFragment implements Index
|
||||
data.title = context.getString(R.string.storage_settings);
|
||||
data.key = "storage_settings";
|
||||
data.screenTitle = context.getString(R.string.storage_settings);
|
||||
data.keywords = context.getString(R.string.keywords_storage_settings);
|
||||
result.add(data);
|
||||
|
||||
data = new SearchIndexableRaw(context);
|
||||
|
||||
@@ -38,6 +38,9 @@ public class ColorModePreferenceFragment extends RadioButtonPickerFragment {
|
||||
static final String KEY_COLOR_MODE_BOOSTED = "color_mode_boosted";
|
||||
@VisibleForTesting
|
||||
static final String KEY_COLOR_MODE_SATURATED = "color_mode_saturated";
|
||||
// TODO have a real key for "automatic" rather than just re-using "saturated"
|
||||
@VisibleForTesting
|
||||
static final String KEY_COLOR_MODE_AUTOMATIC = "color_mode_saturated";
|
||||
|
||||
private ColorDisplayController mController;
|
||||
|
||||
@@ -74,7 +77,9 @@ public class ColorModePreferenceFragment extends RadioButtonPickerFragment {
|
||||
new ColorModeCandidateInfo(c.getString(R.string.color_mode_option_boosted),
|
||||
KEY_COLOR_MODE_BOOSTED),
|
||||
new ColorModeCandidateInfo(c.getString(R.string.color_mode_option_saturated),
|
||||
KEY_COLOR_MODE_SATURATED)
|
||||
KEY_COLOR_MODE_SATURATED),
|
||||
new ColorModeCandidateInfo(c.getString(R.string.color_mode_option_automatic),
|
||||
KEY_COLOR_MODE_AUTOMATIC)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -244,7 +244,8 @@ public class EnterprisePrivacyFeatureProviderImpl implements EnterprisePrivacyFe
|
||||
|
||||
@Override
|
||||
public void onClick(View widget) {
|
||||
mContext.startActivity(new Intent(Settings.ACTION_ENTERPRISE_PRIVACY_SETTINGS));
|
||||
mContext.startActivity(new Intent(Settings.ACTION_ENTERPRISE_PRIVACY_SETTINGS)
|
||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -38,13 +38,16 @@ import android.os.UserManager;
|
||||
import android.provider.Settings;
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.internal.os.BatteryStatsHelper;
|
||||
import com.android.internal.util.ArrayUtils;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.fuelgauge.BatteryUtils;
|
||||
import com.android.settings.fuelgauge.PowerUsageFeatureProvider;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
|
||||
import com.android.settingslib.fuelgauge.PowerWhitelistBackend;
|
||||
import com.android.settingslib.utils.ThreadUtils;
|
||||
|
||||
@@ -78,6 +81,7 @@ public class AnomalyDetectionJobService extends JobService {
|
||||
@Override
|
||||
public boolean onStartJob(JobParameters params) {
|
||||
ThreadUtils.postOnBackgroundThread(() -> {
|
||||
final Context context = AnomalyDetectionJobService.this;
|
||||
final BatteryDatabaseManager batteryDatabaseManager =
|
||||
BatteryDatabaseManager.getInstance(this);
|
||||
final BatteryTipPolicy policy = new BatteryTipPolicy(this);
|
||||
@@ -89,12 +93,14 @@ public class AnomalyDetectionJobService extends JobService {
|
||||
final PowerWhitelistBackend powerWhitelistBackend = PowerWhitelistBackend.getInstance();
|
||||
final PowerUsageFeatureProvider powerUsageFeatureProvider = FeatureFactory
|
||||
.getFactory(this).getPowerUsageFeatureProvider(this);
|
||||
final MetricsFeatureProvider metricsFeatureProvider = FeatureFactory
|
||||
.getFactory(this).getMetricsFeatureProvider();
|
||||
|
||||
for (JobWorkItem item = params.dequeueWork(); item != null;
|
||||
item = params.dequeueWork()) {
|
||||
saveAnomalyToDatabase(batteryStatsHelper, userManager, batteryDatabaseManager,
|
||||
batteryUtils, policy, powerWhitelistBackend, contentResolver,
|
||||
powerUsageFeatureProvider,
|
||||
saveAnomalyToDatabase(context, batteryStatsHelper, userManager,
|
||||
batteryDatabaseManager, batteryUtils, policy, powerWhitelistBackend,
|
||||
contentResolver, powerUsageFeatureProvider, metricsFeatureProvider,
|
||||
item.getIntent().getExtras());
|
||||
}
|
||||
jobFinished(params, false /* wantsReschedule */);
|
||||
@@ -109,11 +115,12 @@ public class AnomalyDetectionJobService extends JobService {
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void saveAnomalyToDatabase(BatteryStatsHelper batteryStatsHelper, UserManager userManager,
|
||||
void saveAnomalyToDatabase(Context context, BatteryStatsHelper batteryStatsHelper,
|
||||
UserManager userManager,
|
||||
BatteryDatabaseManager databaseManager, BatteryUtils batteryUtils,
|
||||
BatteryTipPolicy policy, PowerWhitelistBackend powerWhitelistBackend,
|
||||
ContentResolver contentResolver, PowerUsageFeatureProvider powerUsageFeatureProvider,
|
||||
Bundle bundle) {
|
||||
MetricsFeatureProvider metricsFeatureProvider, Bundle bundle) {
|
||||
// The Example of intentDimsValue is: 35:{1:{1:{1:10013|}|}|}
|
||||
final StatsDimensionsValue intentDimsValue =
|
||||
bundle.getParcelable(StatsManager.EXTRA_STATS_DIMENSIONS_VALUE);
|
||||
@@ -158,6 +165,11 @@ public class AnomalyDetectionJobService extends JobService {
|
||||
AnomalyDatabaseHelper.State.NEW,
|
||||
timeMs);
|
||||
}
|
||||
metricsFeatureProvider.action(context,
|
||||
MetricsProto.MetricsEvent.ACTION_ANOMALY_TRIGGERED,
|
||||
packageName,
|
||||
Pair.create(MetricsProto.MetricsEvent.FIELD_CONTEXT,
|
||||
anomalyInfo.anomalyType));
|
||||
}
|
||||
}
|
||||
} catch (NullPointerException | IndexOutOfBoundsException e) {
|
||||
|
||||
@@ -44,6 +44,7 @@ public class GestureSettings extends DashboardFragment {
|
||||
private static final String KEY_DOUBLE_TWIST = "gesture_double_twist_input_summary";
|
||||
private static final String KEY_DOUBLE_TAP_SCREEN = "gesture_double_tap_screen_input_summary";
|
||||
private static final String KEY_PICK_UP = "gesture_pick_up_input_summary";
|
||||
private static final String KEY_PREVENT_RINGING = "gesture_prevent_ringing_summary";
|
||||
|
||||
private AmbientDisplayConfiguration mAmbientDisplayConfig;
|
||||
|
||||
@@ -86,6 +87,8 @@ public class GestureSettings extends DashboardFragment {
|
||||
ambientDisplayConfiguration, UserHandle.myUserId(), KEY_PICK_UP));
|
||||
controllers.add(new DoubleTapScreenPreferenceController(context, lifecycle,
|
||||
ambientDisplayConfiguration, UserHandle.myUserId(), KEY_DOUBLE_TAP_SCREEN));
|
||||
controllers.add(new PreventRingingPreferenceController(
|
||||
context, lifecycle, UserHandle.myUserId(), KEY_PREVENT_RINGING));
|
||||
return controllers;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* 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 android.content.Context;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.SearchIndexableResource;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.dashboard.DashboardFragment;
|
||||
import com.android.settings.search.BaseSearchIndexProvider;
|
||||
import com.android.settingslib.core.AbstractPreferenceController;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class PreventRingingGestureSettings extends DashboardFragment {
|
||||
|
||||
private static final String TAG = "RingingGestureSettings";
|
||||
private static final String KEY_PREVENT_RINGING = "gesture_prevent_ringing";
|
||||
|
||||
@Override
|
||||
public void onAttach(Context context) {
|
||||
super.onAttach(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMetricsCategory() {
|
||||
return MetricsProto.MetricsEvent.SETTINGS_PREVENT_RINGING;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getLogTag() {
|
||||
return TAG;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getPreferenceScreenResId() {
|
||||
return R.xml.prevent_ringing_gesture_settings;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHelpResource() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
|
||||
return buildPreferenceControllers(context, getLifecycle());
|
||||
}
|
||||
|
||||
private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
|
||||
Lifecycle lifecycle) {
|
||||
final List<AbstractPreferenceController> controllers = new ArrayList<>();
|
||||
controllers.add(new PreventRingingPreferenceController(context, lifecycle,
|
||||
UserHandle.myUserId(), KEY_PREVENT_RINGING));
|
||||
return controllers;
|
||||
}
|
||||
|
||||
public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
|
||||
new BaseSearchIndexProvider() {
|
||||
@Override
|
||||
public List<SearchIndexableResource> getXmlResourcesToIndex(
|
||||
Context context, boolean enabled) {
|
||||
final SearchIndexableResource sir = new SearchIndexableResource(context);
|
||||
sir.xmlResId = R.xml.prevent_ringing_gesture_settings;
|
||||
return Arrays.asList(sir);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AbstractPreferenceController> createPreferenceControllers(
|
||||
Context context) {
|
||||
return buildPreferenceControllers(context, null /* lifecycle */);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,169 @@
|
||||
/*
|
||||
* 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.VOLUME_HUSH_GESTURE;
|
||||
import static android.provider.Settings.Secure.VOLUME_HUSH_MUTE;
|
||||
import static android.provider.Settings.Secure.VOLUME_HUSH_OFF;
|
||||
import static android.provider.Settings.Secure.VOLUME_HUSH_VIBRATE;
|
||||
|
||||
import android.annotation.UserIdInt;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.provider.Settings;
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
import android.support.v7.preference.ListPreference;
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.support.v7.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.PreferenceControllerMixin;
|
||||
import com.android.settings.widget.VideoPreference;
|
||||
import com.android.settingslib.core.AbstractPreferenceController;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
import com.android.settingslib.core.lifecycle.LifecycleObserver;
|
||||
import com.android.settingslib.core.lifecycle.events.OnCreate;
|
||||
import com.android.settingslib.core.lifecycle.events.OnPause;
|
||||
import com.android.settingslib.core.lifecycle.events.OnResume;
|
||||
import com.android.settingslib.core.lifecycle.events.OnSaveInstanceState;
|
||||
|
||||
public class PreventRingingPreferenceController extends AbstractPreferenceController
|
||||
implements PreferenceControllerMixin, Preference.OnPreferenceChangeListener,
|
||||
LifecycleObserver, OnResume, OnPause, OnCreate, OnSaveInstanceState {
|
||||
|
||||
private static final String PREF_KEY_VIDEO = "gesture_prevent_ringing_video";
|
||||
private final String mPrefKey;
|
||||
@VisibleForTesting
|
||||
static final String KEY_VIDEO_PAUSED = "key_video_paused";
|
||||
|
||||
private VideoPreference mVideoPreference;
|
||||
@VisibleForTesting
|
||||
boolean mVideoPaused;
|
||||
|
||||
private final String SECURE_KEY = VOLUME_HUSH_GESTURE;
|
||||
|
||||
@UserIdInt
|
||||
private final int mUserId;
|
||||
|
||||
public PreventRingingPreferenceController(Context context, Lifecycle lifecycle,
|
||||
@UserIdInt int userId, String key) {
|
||||
super(context);
|
||||
if (lifecycle != null) {
|
||||
lifecycle.addObserver(this);
|
||||
}
|
||||
mUserId = userId;
|
||||
mPrefKey = key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayPreference(PreferenceScreen screen) {
|
||||
super.displayPreference(screen);
|
||||
if (isAvailable()) {
|
||||
mVideoPreference = (VideoPreference) screen.findPreference(getVideoPrefKey());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
super.updateState(preference);
|
||||
if (preference != null) {
|
||||
if (preference instanceof ListPreference) {
|
||||
ListPreference pref = (ListPreference) preference;
|
||||
int value = Settings.Secure.getInt(
|
||||
mContext.getContentResolver(), SECURE_KEY, VOLUME_HUSH_VIBRATE);
|
||||
switch (value) {
|
||||
case VOLUME_HUSH_VIBRATE:
|
||||
pref.setValue(String.valueOf(value));
|
||||
break;
|
||||
case VOLUME_HUSH_MUTE:
|
||||
pref.setValue(String.valueOf(value));
|
||||
break;
|
||||
default:
|
||||
pref.setValue(String.valueOf(VOLUME_HUSH_OFF));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getSummary() {
|
||||
int value = Settings.Secure.getInt(
|
||||
mContext.getContentResolver(), SECURE_KEY, VOLUME_HUSH_VIBRATE);
|
||||
int summary;
|
||||
switch (value) {
|
||||
case VOLUME_HUSH_VIBRATE:
|
||||
summary = R.string.prevent_ringing_option_vibrate_summary;
|
||||
break;
|
||||
case VOLUME_HUSH_MUTE:
|
||||
summary = R.string.prevent_ringing_option_mute_summary;
|
||||
break;
|
||||
default:
|
||||
summary = R.string.prevent_ringing_option_none_summary;
|
||||
}
|
||||
return mContext.getString(summary);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
if (savedInstanceState != null) {
|
||||
mVideoPaused = savedInstanceState.getBoolean(KEY_VIDEO_PAUSED, false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle outState) {
|
||||
outState.putBoolean(KEY_VIDEO_PAUSED, mVideoPaused);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
if (mVideoPreference != null) {
|
||||
mVideoPaused = mVideoPreference.isVideoPaused();
|
||||
mVideoPreference.onViewInvisible();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
if (mVideoPreference != null) {
|
||||
mVideoPreference.onViewVisible(mVideoPaused);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return mContext.getResources()
|
||||
.getBoolean(com.android.internal.R.bool.config_volumeHushGestureEnabled);
|
||||
}
|
||||
|
||||
protected String getVideoPrefKey() {
|
||||
return PREF_KEY_VIDEO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreferenceKey() {
|
||||
return mPrefKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
int value = Integer.parseInt((String) newValue);
|
||||
Settings.Secure.putInt(mContext.getContentResolver(), SECURE_KEY, value);
|
||||
preference.setSummary(getSummary());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -30,6 +30,7 @@ import com.android.settings.enterprise.EnterprisePrivacyFeatureProvider;
|
||||
import com.android.settings.fuelgauge.PowerUsageFeatureProvider;
|
||||
import com.android.settings.gestures.AssistGestureFeatureProvider;
|
||||
import com.android.settings.localepicker.LocaleFeatureProvider;
|
||||
import com.android.settings.search.DeviceIndexFeatureProvider;
|
||||
import com.android.settings.search.SearchFeatureProvider;
|
||||
import com.android.settings.security.SecurityFeatureProvider;
|
||||
import com.android.settings.slices.SlicesFeatureProvider;
|
||||
@@ -106,6 +107,8 @@ public abstract class FeatureFactory {
|
||||
|
||||
public abstract AccountFeatureProvider getAccountFeatureProvider();
|
||||
|
||||
public abstract DeviceIndexFeatureProvider getDeviceIndexFeatureProvider();
|
||||
|
||||
public static final class FactoryNotFoundException extends RuntimeException {
|
||||
public FactoryNotFoundException(Throwable throwable) {
|
||||
super("Unable to create factory. Did you misconfigure Proguard?", throwable);
|
||||
|
||||
@@ -41,6 +41,8 @@ import com.android.settings.gestures.AssistGestureFeatureProvider;
|
||||
import com.android.settings.gestures.AssistGestureFeatureProviderImpl;
|
||||
import com.android.settings.localepicker.LocaleFeatureProvider;
|
||||
import com.android.settings.localepicker.LocaleFeatureProviderImpl;
|
||||
import com.android.settings.search.DeviceIndexFeatureProvider;
|
||||
import com.android.settings.search.DeviceIndexFeatureProviderImpl;
|
||||
import com.android.settings.search.SearchFeatureProvider;
|
||||
import com.android.settings.search.SearchFeatureProviderImpl;
|
||||
import com.android.settings.security.SecurityFeatureProvider;
|
||||
@@ -75,6 +77,7 @@ public class FeatureFactoryImpl extends FeatureFactory {
|
||||
private BluetoothFeatureProvider mBluetoothFeatureProvider;
|
||||
private SlicesFeatureProvider mSlicesFeatureProvider;
|
||||
private AccountFeatureProvider mAccountFeatureProvider;
|
||||
private DeviceIndexFeatureProviderImpl mDeviceIndexFeatureProvider;
|
||||
|
||||
@Override
|
||||
public SupportFeatureProvider getSupportFeatureProvider(Context context) {
|
||||
@@ -208,4 +211,12 @@ public class FeatureFactoryImpl extends FeatureFactory {
|
||||
}
|
||||
return mAccountFeatureProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DeviceIndexFeatureProvider getDeviceIndexFeatureProvider() {
|
||||
if (mDeviceIndexFeatureProvider == null) {
|
||||
mDeviceIndexFeatureProvider = new DeviceIndexFeatureProviderImpl();
|
||||
}
|
||||
return mDeviceIndexFeatureProvider;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,9 +20,11 @@ import android.app.Activity;
|
||||
import android.app.Fragment;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.content.res.Resources.Theme;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.util.TypedValue;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
@@ -171,6 +173,7 @@ public class ChooseLockPattern extends SettingsActivity {
|
||||
private String mCurrentPattern;
|
||||
private boolean mHasChallenge;
|
||||
private long mChallenge;
|
||||
protected TextView mTitleText;
|
||||
protected TextView mHeaderText;
|
||||
protected TextView mMessageText;
|
||||
protected LockPatternView mLockPatternView;
|
||||
@@ -179,6 +182,7 @@ public class ChooseLockPattern extends SettingsActivity {
|
||||
private TextView mFooterRightButton;
|
||||
protected List<LockPatternView.Cell> mChosenPattern = null;
|
||||
private boolean mHideDrawer = false;
|
||||
private ColorStateList mDefaultHeaderColorList;
|
||||
|
||||
// ScrollView that contains title and header, only exist in land mode
|
||||
private ScrollView mTitleHeaderScrollView;
|
||||
@@ -265,6 +269,9 @@ public class ChooseLockPattern extends SettingsActivity {
|
||||
|
||||
private void patternInProgress() {
|
||||
mHeaderText.setText(R.string.lockpattern_recording_inprogress);
|
||||
if (mDefaultHeaderColorList != null) {
|
||||
mHeaderText.setTextColor(mDefaultHeaderColorList);
|
||||
}
|
||||
mFooterText.setText("");
|
||||
mFooterLeftButton.setEnabled(false);
|
||||
mFooterRightButton.setEnabled(false);
|
||||
@@ -465,10 +472,13 @@ public class ChooseLockPattern extends SettingsActivity {
|
||||
return layout;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
mTitleText = view.findViewById(R.id.suw_layout_title);
|
||||
mHeaderText = (TextView) view.findViewById(R.id.headerText);
|
||||
mDefaultHeaderColorList = mHeaderText.getTextColors();
|
||||
mMessageText = view.findViewById(R.id.message);
|
||||
mLockPatternView = (LockPatternView) view.findViewById(R.id.lockPattern);
|
||||
mLockPatternView.setOnPatternListener(mChooseNewLockPatternListener);
|
||||
@@ -664,6 +674,23 @@ public class ChooseLockPattern extends SettingsActivity {
|
||||
mFooterText.setText(stage.footerMessage);
|
||||
}
|
||||
|
||||
if (stage == Stage.ConfirmWrong || stage == Stage.ChoiceTooShort) {
|
||||
TypedValue typedValue = new TypedValue();
|
||||
Theme theme = getActivity().getTheme();
|
||||
theme.resolveAttribute(R.attr.colorError, typedValue, true);
|
||||
mHeaderText.setTextColor(typedValue.data);
|
||||
|
||||
} else {
|
||||
if (mDefaultHeaderColorList != null) {
|
||||
mHeaderText.setTextColor(mDefaultHeaderColorList);
|
||||
}
|
||||
|
||||
if (stage == Stage.NeedToConfirm && mForFingerprint) {
|
||||
mHeaderText.setText("");
|
||||
mTitleText.setText(R.string.lockpassword_draw_your_pattern_again_header);
|
||||
}
|
||||
}
|
||||
|
||||
updateFooterLeftButton(stage, mFooterLeftButton);
|
||||
|
||||
setRightButtonText(stage.rightMode.text);
|
||||
|
||||
@@ -279,13 +279,12 @@ public final class ChooseLockSettingsHelper {
|
||||
CharSequence message, Class<?> activityClass, boolean returnCredentials,
|
||||
boolean external, boolean hasChallenge, long challenge,
|
||||
int userId, @Nullable CharSequence alternateButton, Bundle extras) {
|
||||
final boolean frp = (userId == LockPatternUtils.USER_FRP);
|
||||
final Intent intent = new Intent();
|
||||
intent.putExtra(ConfirmDeviceCredentialBaseFragment.TITLE_TEXT, title);
|
||||
intent.putExtra(ConfirmDeviceCredentialBaseFragment.HEADER_TEXT, header);
|
||||
intent.putExtra(ConfirmDeviceCredentialBaseFragment.DETAILS_TEXT, message);
|
||||
intent.putExtra(ConfirmDeviceCredentialBaseFragment.ALLOW_FP_AUTHENTICATION, external);
|
||||
intent.putExtra(ConfirmDeviceCredentialBaseFragment.DARK_THEME, external && !frp);
|
||||
intent.putExtra(ConfirmDeviceCredentialBaseFragment.DARK_THEME, false);
|
||||
intent.putExtra(ConfirmDeviceCredentialBaseFragment.SHOW_CANCEL_BUTTON, external);
|
||||
intent.putExtra(ConfirmDeviceCredentialBaseFragment.SHOW_WHEN_LOCKED, external);
|
||||
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_RETURN_CREDENTIALS, returnCredentials);
|
||||
|
||||
@@ -34,8 +34,8 @@ public abstract class ConfirmDeviceCredentialBaseActivity extends SettingsActivi
|
||||
private static final String STATE_IS_KEYGUARD_LOCKED = "STATE_IS_KEYGUARD_LOCKED";
|
||||
|
||||
enum ConfirmCredentialTheme {
|
||||
INTERNAL,
|
||||
DARK,
|
||||
NORMAL,
|
||||
DARK, // TODO(yukl): Clean up DARK theme, as it should no longer be used
|
||||
WORK
|
||||
}
|
||||
|
||||
@@ -63,11 +63,11 @@ public abstract class ConfirmDeviceCredentialBaseActivity extends SettingsActivi
|
||||
mConfirmCredentialTheme = ConfirmCredentialTheme.DARK;
|
||||
} else {
|
||||
setTheme(SetupWizardUtils.getTheme(getIntent()));
|
||||
mConfirmCredentialTheme = ConfirmCredentialTheme.INTERNAL;
|
||||
mConfirmCredentialTheme = ConfirmCredentialTheme.NORMAL;
|
||||
}
|
||||
super.onCreate(savedState);
|
||||
|
||||
if (mConfirmCredentialTheme == ConfirmCredentialTheme.INTERNAL) {
|
||||
if (mConfirmCredentialTheme == ConfirmCredentialTheme.NORMAL) {
|
||||
// Prevent the content parent from consuming the window insets because GlifLayout uses
|
||||
// it to show the status bar background.
|
||||
LinearLayout layout = (LinearLayout) findViewById(R.id.content_parent);
|
||||
|
||||
@@ -121,8 +121,8 @@ public class ConfirmLockPassword extends ConfirmDeviceCredentialBaseActivity {
|
||||
|
||||
ConfirmLockPassword activity = (ConfirmLockPassword) getActivity();
|
||||
View view = inflater.inflate(
|
||||
activity.getConfirmCredentialTheme() == ConfirmCredentialTheme.INTERNAL
|
||||
? R.layout.confirm_lock_password_internal
|
||||
activity.getConfirmCredentialTheme() == ConfirmCredentialTheme.NORMAL
|
||||
? R.layout.confirm_lock_password_normal
|
||||
: R.layout.confirm_lock_password,
|
||||
container,
|
||||
false);
|
||||
|
||||
@@ -109,8 +109,8 @@ public class ConfirmLockPattern extends ConfirmDeviceCredentialBaseActivity {
|
||||
Bundle savedInstanceState) {
|
||||
ConfirmLockPattern activity = (ConfirmLockPattern) getActivity();
|
||||
View view = inflater.inflate(
|
||||
activity.getConfirmCredentialTheme() == ConfirmCredentialTheme.INTERNAL
|
||||
? R.layout.confirm_lock_pattern_internal
|
||||
activity.getConfirmCredentialTheme() == ConfirmCredentialTheme.NORMAL
|
||||
? R.layout.confirm_lock_pattern_normal
|
||||
: R.layout.confirm_lock_pattern,
|
||||
container,
|
||||
false);
|
||||
|
||||
@@ -25,7 +25,6 @@ import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SetupRedactionInterstitial;
|
||||
@@ -70,6 +69,17 @@ public class SetupChooseLockPattern extends ChooseLockPattern {
|
||||
ChooseLockTypeDialogFragment.newInstance(mUserId)
|
||||
.show(getChildFragmentManager(), null));
|
||||
}
|
||||
// enable skip button only during setup wizard and not with fingerprint flow.
|
||||
if (!mForFingerprint) {
|
||||
Button skipButton = view.findViewById(R.id.skip_button);
|
||||
skipButton.setVisibility(View.VISIBLE);
|
||||
skipButton.setOnClickListener(v -> {
|
||||
SetupSkipDialog dialog = SetupSkipDialog.newInstance(
|
||||
getActivity().getIntent()
|
||||
.getBooleanExtra(SetupSkipDialog.EXTRA_FRP_SUPPORTED, false));
|
||||
dialog.show(getFragmentManager());
|
||||
});
|
||||
}
|
||||
return view;
|
||||
}
|
||||
|
||||
@@ -81,16 +91,6 @@ public class SetupChooseLockPattern extends ChooseLockPattern {
|
||||
startChooseLockActivity(lock, getActivity());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateFooterLeftButton(Stage stage, TextView footerLeftButton) {
|
||||
super.updateFooterLeftButton(stage, footerLeftButton);
|
||||
// enable skip button only during setupwizard and not with fingerprint flow.
|
||||
if (!mForFingerprint) {
|
||||
footerLeftButton.setVisibility(View.VISIBLE);
|
||||
footerLeftButton.setText(R.string.skip_label);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateStage(Stage stage) {
|
||||
super.updateStage(stage);
|
||||
@@ -101,14 +101,6 @@ public class SetupChooseLockPattern extends ChooseLockPattern {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleLeftButton() {
|
||||
SetupSkipDialog dialog = SetupSkipDialog.newInstance(
|
||||
getActivity().getIntent()
|
||||
.getBooleanExtra(SetupSkipDialog.EXTRA_FRP_SUPPORTED, false));
|
||||
dialog.show(getFragmentManager());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Intent getRedactionInterstitialIntent(Context context) {
|
||||
// Setup wizard's redaction interstitial is deferred to optional step. Enable that
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* 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.search;
|
||||
|
||||
import static com.android.settings.slices.SliceDeepLinkSpringBoard.INTENT;
|
||||
import static com.android.settings.slices.SliceDeepLinkSpringBoard.SETTINGS;
|
||||
|
||||
import android.app.slice.SliceManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.net.Uri;
|
||||
import android.provider.Settings;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.settings.slices.SettingsSliceProvider;
|
||||
|
||||
public interface DeviceIndexFeatureProvider {
|
||||
|
||||
// TODO: Remove this and index all action and intent slices through search index.
|
||||
String[] ACTIONS_TO_INDEX = new String[]{
|
||||
Settings.ACTION_WIFI_SETTINGS,
|
||||
};
|
||||
|
||||
String TAG = "DeviceIndex";
|
||||
|
||||
String INDEX_VERSION = "settings:index_version";
|
||||
|
||||
// Increment when new items are added to ensure they get pushed to the device index.
|
||||
int VERSION = 1;
|
||||
|
||||
boolean isIndexingEnabled();
|
||||
|
||||
void index(Context context, CharSequence title, Uri sliceUri, Uri launchUri);
|
||||
|
||||
default void updateIndex(Context context, boolean force) {
|
||||
if (!isIndexingEnabled()) return;
|
||||
|
||||
if (!force && Settings.Secure.getInt(context.getContentResolver(), INDEX_VERSION, -1)
|
||||
== VERSION) {
|
||||
// No need to update.
|
||||
return;
|
||||
}
|
||||
|
||||
PackageManager pm = context.getPackageManager();
|
||||
for (String action : ACTIONS_TO_INDEX) {
|
||||
Intent intent = new Intent(action);
|
||||
intent.setPackage(context.getPackageName());
|
||||
ResolveInfo activity = pm.resolveActivity(intent, PackageManager.GET_META_DATA);
|
||||
if (activity == null) {
|
||||
Log.e(TAG, "Unable to resolve " + action);
|
||||
continue;
|
||||
}
|
||||
String sliceUri = activity.activityInfo.metaData
|
||||
.getString(SliceManager.SLICE_METADATA_KEY);
|
||||
if (sliceUri != null) {
|
||||
Log.d(TAG, "Intent: " + createDeepLink(intent.toUri(Intent.URI_ANDROID_APP_SCHEME)));
|
||||
index(context, activity.activityInfo.loadLabel(pm),
|
||||
Uri.parse(sliceUri),
|
||||
Uri.parse(createDeepLink(intent.toUri(Intent.URI_ANDROID_APP_SCHEME))));
|
||||
} else {
|
||||
Log.e(TAG, "No slice uri found for " + activity.activityInfo.name);
|
||||
}
|
||||
}
|
||||
|
||||
Settings.Secure.putInt(context.getContentResolver(), INDEX_VERSION, VERSION);
|
||||
}
|
||||
|
||||
static String createDeepLink(String s) {
|
||||
return new Uri.Builder().scheme(SETTINGS)
|
||||
.authority(SettingsSliceProvider.SLICE_AUTHORITY)
|
||||
.appendQueryParameter(INTENT, s)
|
||||
.build()
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
* 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
|
||||
@@ -12,18 +12,20 @@
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.wrapper;
|
||||
package com.android.settings.search;
|
||||
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
|
||||
/**
|
||||
* Wrapper class around android.webkit.UserPackage - to be able to use UserPackage in Robolectric
|
||||
* tests (such tests currently don't support mocking hidden classes).
|
||||
*/
|
||||
public interface UserPackageWrapper {
|
||||
UserInfo getUserInfo();
|
||||
PackageInfo getPackageInfo();
|
||||
boolean isEnabledPackage();
|
||||
boolean isInstalledPackage();
|
||||
public class DeviceIndexFeatureProviderImpl implements DeviceIndexFeatureProvider {
|
||||
|
||||
@Override
|
||||
public boolean isIndexingEnabled() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void index(Context context, CharSequence title, Uri sliceUri, Uri launchUri) {
|
||||
// Not enabled by default.
|
||||
}
|
||||
}
|
||||
@@ -17,27 +17,26 @@
|
||||
package com.android.settings.slices;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.app.slice.SliceManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.drawable.Icon;
|
||||
import android.net.Uri;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.provider.SettingsSlicesContract;
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settingslib.utils.ThreadUtils;
|
||||
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
import androidx.slice.Slice;
|
||||
import androidx.slice.SliceProvider;
|
||||
import androidx.slice.builders.SliceAction;
|
||||
import androidx.slice.builders.ListBuilder;
|
||||
import androidx.slice.builders.SliceAction;
|
||||
|
||||
/**
|
||||
* A {@link SliceProvider} for Settings to enabled inline results in system apps.
|
||||
@@ -74,11 +73,29 @@ public class SettingsSliceProvider extends SliceProvider {
|
||||
public static final String ACTION_WIFI_CHANGED =
|
||||
"com.android.settings.slice.action.WIFI_CHANGED";
|
||||
|
||||
/**
|
||||
* Action passed for changes to Toggle Slices.
|
||||
*/
|
||||
public static final String ACTION_TOGGLE_CHANGED =
|
||||
"com.android.settings.slice.action.TOGGLE_CHANGED";
|
||||
|
||||
/**
|
||||
* Action passed for changes to Slider Slices.
|
||||
*/
|
||||
public static final String ACTION_SLIDER_CHANGED =
|
||||
"com.android.settings.slice.action.SLIDER_CHANGED";
|
||||
|
||||
/**
|
||||
* Intent Extra passed for the key identifying the Setting Slice.
|
||||
*/
|
||||
public static final String EXTRA_SLICE_KEY = "com.android.settings.slice.extra.key";
|
||||
|
||||
/**
|
||||
* Boolean extra to indicate if the Slice is platform-defined.
|
||||
*/
|
||||
public static final String EXTRA_SLICE_PLATFORM_DEFINED =
|
||||
"com.android.settings.slice.extra.platform";
|
||||
|
||||
// TODO -- Associate slice URI with search result instead of separate hardcoded thing
|
||||
|
||||
@VisibleForTesting
|
||||
@@ -94,6 +111,17 @@ public class SettingsSliceProvider extends SliceProvider {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Uri onMapIntentToUri(Intent intent) {
|
||||
try {
|
||||
return getContext().getSystemService(SliceManager.class).mapIntentToUri(
|
||||
SliceDeepLinkSpringBoard.parse(
|
||||
intent.getData(), getContext().getPackageName()));
|
||||
} catch (URISyntaxException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Slice onBindSlice(Uri sliceUri) {
|
||||
String path = sliceUri.getPath();
|
||||
|
||||
@@ -16,22 +16,30 @@
|
||||
|
||||
package com.android.settings.slices;
|
||||
|
||||
import static com.android.settings.slices.SettingsSliceProvider.ACTION_SLIDER_CHANGED;
|
||||
import static com.android.settings.slices.SettingsSliceProvider.ACTION_TOGGLE_CHANGED;
|
||||
import static com.android.settings.slices.SettingsSliceProvider.ACTION_WIFI_CHANGED;
|
||||
import static com.android.settings.slices.SettingsSliceProvider.EXTRA_SLICE_KEY;
|
||||
import static com.android.settings.slices.SettingsSliceProvider.EXTRA_SLICE_PLATFORM_DEFINED;
|
||||
|
||||
import android.app.slice.Slice;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.os.Handler;
|
||||
import android.provider.SettingsSlicesContract;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
import com.android.settings.core.SliderPreferenceController;
|
||||
import com.android.settings.core.TogglePreferenceController;
|
||||
|
||||
import android.app.slice.Slice;
|
||||
|
||||
import androidx.slice.core.SliceHints;
|
||||
|
||||
/**
|
||||
* Responds to actions performed on slices and notifies slices of updates in state changes.
|
||||
*/
|
||||
@@ -44,12 +52,18 @@ public class SliceBroadcastReceiver extends BroadcastReceiver {
|
||||
*/
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
String action = intent.getAction();
|
||||
String key = intent.getStringExtra(EXTRA_SLICE_KEY);
|
||||
final String action = intent.getAction();
|
||||
final String key = intent.getStringExtra(EXTRA_SLICE_KEY);
|
||||
final boolean isPlatformDefined = intent.getBooleanExtra(EXTRA_SLICE_PLATFORM_DEFINED,
|
||||
false /* default */);
|
||||
|
||||
switch (action) {
|
||||
case ACTION_TOGGLE_CHANGED:
|
||||
handleToggleAction(context, key);
|
||||
handleToggleAction(context, key, isPlatformDefined);
|
||||
break;
|
||||
case ACTION_SLIDER_CHANGED:
|
||||
int newPosition = intent.getIntExtra(SliceHints.EXTRA_RANGE_VALUE, -1);
|
||||
handleSliderAction(context, key, newPosition);
|
||||
break;
|
||||
case ACTION_WIFI_CHANGED:
|
||||
WifiManager wm = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
|
||||
@@ -67,7 +81,7 @@ public class SliceBroadcastReceiver extends BroadcastReceiver {
|
||||
}
|
||||
}
|
||||
|
||||
private void handleToggleAction(Context context, String key) {
|
||||
private void handleToggleAction(Context context, String key, boolean isPlatformSlice) {
|
||||
if (TextUtils.isEmpty(key)) {
|
||||
throw new IllegalStateException("No key passed to Intent for toggle controller");
|
||||
}
|
||||
@@ -78,11 +92,44 @@ public class SliceBroadcastReceiver extends BroadcastReceiver {
|
||||
throw new IllegalStateException("Toggle action passed for a non-toggle key: " + key);
|
||||
}
|
||||
|
||||
if (!controller.isAvailable()) {
|
||||
Log.d(TAG, "Can't update " + key + " since the setting is unavailable");
|
||||
updateUri(context, key, isPlatformSlice);
|
||||
}
|
||||
|
||||
// TODO post context.getContentResolver().notifyChanged(uri, null) in the Toggle controller
|
||||
// so that it's automatically broadcast to any slice.
|
||||
final TogglePreferenceController toggleController = (TogglePreferenceController) controller;
|
||||
final boolean currentValue = toggleController.isChecked();
|
||||
toggleController.setChecked(!currentValue);
|
||||
updateUri(context, key, isPlatformSlice);
|
||||
}
|
||||
|
||||
private void handleSliderAction(Context context, String key, int newPosition) {
|
||||
if (TextUtils.isEmpty(key)) {
|
||||
throw new IllegalArgumentException(
|
||||
"No key passed to Intent for slider controller. Use extra: " + EXTRA_SLICE_KEY);
|
||||
}
|
||||
|
||||
if (newPosition == -1) {
|
||||
throw new IllegalArgumentException("Invalid position passed to Slider controller");
|
||||
}
|
||||
|
||||
final BasePreferenceController controller = getPreferenceController(context, key);
|
||||
|
||||
if (!(controller instanceof SliderPreferenceController)) {
|
||||
throw new IllegalArgumentException("Slider action passed for a non-slider key: " + key);
|
||||
}
|
||||
|
||||
final SliderPreferenceController sliderController = (SliderPreferenceController) controller;
|
||||
final int maxSteps = sliderController.getMaxSteps();
|
||||
if (newPosition < 0 || newPosition > maxSteps) {
|
||||
throw new IllegalArgumentException(
|
||||
"Invalid position passed to Slider controller. Expected between 0 and "
|
||||
+ maxSteps + " but found " + newPosition);
|
||||
}
|
||||
|
||||
sliderController.setSliderPosition(newPosition);
|
||||
}
|
||||
|
||||
private BasePreferenceController getPreferenceController(Context context, String key) {
|
||||
@@ -90,4 +137,10 @@ public class SliceBroadcastReceiver extends BroadcastReceiver {
|
||||
final SliceData sliceData = accessor.getSliceDataFromKey(key);
|
||||
return SliceBuilderUtils.getPreferenceController(context, sliceData);
|
||||
}
|
||||
|
||||
private void updateUri(Context context, String key, boolean isPlatformDefined) {
|
||||
final String path = SettingsSlicesContract.PATH_SETTING_ACTION + "/" + key;
|
||||
final Uri uri = SliceBuilderUtils.getUri(path, isPlatformDefined);
|
||||
context.getContentResolver().notifyChange(uri, null /* observer */);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,12 +16,20 @@
|
||||
|
||||
package com.android.settings.slices;
|
||||
|
||||
import static com.android.settings.core.BasePreferenceController.DISABLED_DEPENDENT_SETTING;
|
||||
import static com.android.settings.core.BasePreferenceController.DISABLED_FOR_USER;
|
||||
import static com.android.settings.core.BasePreferenceController.DISABLED_UNSUPPORTED;
|
||||
import static com.android.settings.core.BasePreferenceController.UNAVAILABLE_UNKNOWN;
|
||||
import static com.android.settings.slices.SettingsSliceProvider.EXTRA_SLICE_KEY;
|
||||
import static com.android.settings.slices.SettingsSliceProvider.EXTRA_SLICE_PLATFORM_DEFINED;
|
||||
|
||||
import static androidx.slice.builders.ListBuilder.ICON_IMAGE;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.drawable.Icon;
|
||||
import android.net.Uri;
|
||||
import android.provider.SettingsSlicesContract;
|
||||
@@ -32,6 +40,7 @@ import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SubSettings;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
import com.android.settings.core.SliderPreferenceController;
|
||||
import com.android.settings.core.TogglePreferenceController;
|
||||
import com.android.settings.search.DatabaseIndexingUtils;
|
||||
import com.android.settingslib.core.AbstractPreferenceController;
|
||||
@@ -39,7 +48,7 @@ import com.android.settingslib.core.AbstractPreferenceController;
|
||||
import androidx.slice.Slice;
|
||||
import androidx.slice.builders.SliceAction;
|
||||
import androidx.slice.builders.ListBuilder;
|
||||
import androidx.slice.builders.ListBuilder.RowBuilder;
|
||||
|
||||
|
||||
/**
|
||||
* Utility class to build Slices objects and Preference Controllers based on the Database managed
|
||||
@@ -57,28 +66,23 @@ public class SliceBuilderUtils {
|
||||
* {@param sliceData} is an inline controller.
|
||||
*/
|
||||
public static Slice buildSlice(Context context, SliceData sliceData) {
|
||||
final PendingIntent contentIntent = getContentIntent(context, sliceData);
|
||||
final Icon icon = Icon.createWithResource(context, sliceData.getIconResource());
|
||||
final BasePreferenceController controller = getPreferenceController(context, sliceData);
|
||||
|
||||
final CharSequence subtitleText = getSubtitleText(context, controller, sliceData);
|
||||
|
||||
final RowBuilder builder = new RowBuilder(context, sliceData.getUri())
|
||||
.setTitle(sliceData.getTitle())
|
||||
.setTitleItem(icon)
|
||||
.setSubtitle(subtitleText)
|
||||
.setPrimaryAction(new SliceAction(contentIntent, null, null));
|
||||
|
||||
// TODO (b/71640747) Respect setting availability.
|
||||
|
||||
if (sliceData.getSliceType() == SliceData.SliceType.SWITCH) {
|
||||
addToggleAction(context, builder, ((TogglePreferenceController) controller).isChecked(),
|
||||
sliceData.getKey());
|
||||
if (!controller.isAvailable()) {
|
||||
return buildUnavailableSlice(context, sliceData, controller);
|
||||
}
|
||||
|
||||
return new ListBuilder(context, sliceData.getUri())
|
||||
.addRow(builder)
|
||||
.build();
|
||||
switch (sliceData.getSliceType()) {
|
||||
case SliceData.SliceType.INTENT:
|
||||
return buildIntentSlice(context, sliceData, controller);
|
||||
case SliceData.SliceType.SWITCH:
|
||||
return buildToggleSlice(context, sliceData, controller);
|
||||
case SliceData.SliceType.SLIDER:
|
||||
return buildSliderSlice(context, sliceData, controller);
|
||||
default:
|
||||
throw new IllegalArgumentException(
|
||||
"Slice type passed was invalid: " + sliceData.getSliceType());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -125,8 +129,8 @@ public class SliceBuilderUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks at the {@link SliceData#preferenceController} from {@param sliceData} and attempts to
|
||||
* build an {@link AbstractPreferenceController}.
|
||||
* Looks at the controller classname in in {@link SliceData} from {@param sliceData}
|
||||
* and attempts to build an {@link AbstractPreferenceController}.
|
||||
*/
|
||||
public static BasePreferenceController getPreferenceController(Context context,
|
||||
SliceData sliceData) {
|
||||
@@ -145,6 +149,55 @@ public class SliceBuilderUtils {
|
||||
.build();
|
||||
}
|
||||
|
||||
private static Slice buildToggleSlice(Context context, SliceData sliceData,
|
||||
BasePreferenceController controller) {
|
||||
final PendingIntent contentIntent = getContentIntent(context, sliceData);
|
||||
final Icon icon = Icon.createWithResource(context, sliceData.getIconResource());
|
||||
final CharSequence subtitleText = getSubtitleText(context, controller, sliceData);
|
||||
final TogglePreferenceController toggleController =
|
||||
(TogglePreferenceController) controller;
|
||||
final SliceAction sliceAction = getToggleAction(context, sliceData,
|
||||
toggleController.isChecked());
|
||||
|
||||
return new ListBuilder(context, sliceData.getUri())
|
||||
.addRow(rowBuilder -> rowBuilder
|
||||
.setTitle(sliceData.getTitle())
|
||||
.setTitleItem(icon, ICON_IMAGE)
|
||||
.setSubtitle(subtitleText)
|
||||
.setPrimaryAction(new SliceAction(contentIntent, null, null))
|
||||
.addEndItem(sliceAction))
|
||||
.build();
|
||||
}
|
||||
|
||||
private static Slice buildIntentSlice(Context context, SliceData sliceData,
|
||||
BasePreferenceController controller) {
|
||||
final PendingIntent contentIntent = getContentIntent(context, sliceData);
|
||||
final Icon icon = Icon.createWithResource(context, sliceData.getIconResource());
|
||||
final CharSequence subtitleText = getSubtitleText(context, controller, sliceData);
|
||||
|
||||
return new ListBuilder(context, sliceData.getUri())
|
||||
.addRow(rowBuilder -> rowBuilder
|
||||
.setTitle(sliceData.getTitle())
|
||||
.setTitleItem(icon, ICON_IMAGE)
|
||||
.setSubtitle(subtitleText)
|
||||
.setPrimaryAction(new SliceAction(contentIntent, null, null)))
|
||||
.build();
|
||||
}
|
||||
|
||||
private static Slice buildSliderSlice(Context context, SliceData sliceData,
|
||||
BasePreferenceController controller) {
|
||||
final SliderPreferenceController sliderController =
|
||||
(SliderPreferenceController) controller;
|
||||
final PendingIntent actionIntent = getSliderAction(context, sliceData);
|
||||
return new ListBuilder(context, sliceData.getUri())
|
||||
.addInputRange(builder -> builder
|
||||
.setTitle(sliceData.getTitle())
|
||||
.setMax(sliderController.getMaxSteps())
|
||||
.setValue(sliderController.getSliderPosition())
|
||||
.setAction(actionIntent))
|
||||
.build();
|
||||
}
|
||||
|
||||
private static BasePreferenceController getPreferenceController(Context context,
|
||||
String controllerClassName, String controllerKey) {
|
||||
try {
|
||||
@@ -156,17 +209,22 @@ public class SliceBuilderUtils {
|
||||
return BasePreferenceController.createInstance(context, controllerClassName, controllerKey);
|
||||
}
|
||||
|
||||
private static void addToggleAction(Context context, RowBuilder builder, boolean isChecked,
|
||||
String key) {
|
||||
private static SliceAction getToggleAction(Context context, SliceData sliceData,
|
||||
boolean isChecked) {
|
||||
PendingIntent actionIntent = getActionIntent(context,
|
||||
SettingsSliceProvider.ACTION_TOGGLE_CHANGED, key);
|
||||
builder.addEndItem(new SliceAction(actionIntent, null, isChecked));
|
||||
SettingsSliceProvider.ACTION_TOGGLE_CHANGED, sliceData);
|
||||
return new SliceAction(actionIntent, null, isChecked);
|
||||
}
|
||||
|
||||
private static PendingIntent getActionIntent(Context context, String action, String key) {
|
||||
private static PendingIntent getSliderAction(Context context, SliceData sliceData) {
|
||||
return getActionIntent(context, SettingsSliceProvider.ACTION_SLIDER_CHANGED, sliceData);
|
||||
}
|
||||
|
||||
private static PendingIntent getActionIntent(Context context, String action, SliceData data) {
|
||||
Intent intent = new Intent(action);
|
||||
intent.setClass(context, SliceBroadcastReceiver.class);
|
||||
intent.putExtra(EXTRA_SLICE_KEY, key);
|
||||
intent.putExtra(EXTRA_SLICE_KEY, data.getKey());
|
||||
intent.putExtra(EXTRA_SLICE_PLATFORM_DEFINED, data.isPlatformDefined());
|
||||
return PendingIntent.getBroadcast(context, 0 /* requestCode */, intent,
|
||||
PendingIntent.FLAG_CANCEL_CURRENT);
|
||||
}
|
||||
@@ -179,6 +237,12 @@ public class SliceBuilderUtils {
|
||||
return PendingIntent.getActivity(context, 0 /* requestCode */, intent, 0 /* flags */);
|
||||
}
|
||||
|
||||
private static PendingIntent getSettingsIntent(Context context) {
|
||||
final PackageManager manager = context.getPackageManager();
|
||||
final Intent intent = manager.getLaunchIntentForPackage(context.getPackageName());
|
||||
return PendingIntent.getActivity(context, 0 /* requestCode */, intent, 0 /* flags */);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static CharSequence getSubtitleText(Context context, AbstractPreferenceController controller,
|
||||
SliceData sliceData) {
|
||||
@@ -210,4 +274,41 @@ public class SliceBuilderUtils {
|
||||
return !(TextUtils.equals(summary, placeHolder)
|
||||
|| TextUtils.equals(summary, doublePlaceHolder));
|
||||
}
|
||||
|
||||
private static Slice buildUnavailableSlice(Context context, SliceData data,
|
||||
BasePreferenceController controller) {
|
||||
final String title = data.getTitle();
|
||||
final String summary;
|
||||
final SliceAction primaryAction;
|
||||
|
||||
switch (controller.getAvailabilityStatus()) {
|
||||
case DISABLED_UNSUPPORTED:
|
||||
summary = context.getString(R.string.unsupported_setting_summary);
|
||||
primaryAction = new SliceAction(getSettingsIntent(context), null /* actionIcon */,
|
||||
null /* actionTitle */);
|
||||
break;
|
||||
case DISABLED_FOR_USER:
|
||||
summary = context.getString(R.string.disabled_for_user_setting_summary);
|
||||
primaryAction = new SliceAction(getContentIntent(context, data),
|
||||
null /* actionIcon */, null /* actionTitle */);
|
||||
break;
|
||||
case DISABLED_DEPENDENT_SETTING:
|
||||
summary = context.getString(R.string.disabled_dependent_setting_summary);
|
||||
primaryAction = new SliceAction(getContentIntent(context, data),
|
||||
null /* actionIcon */, null /* actionTitle */);
|
||||
break;
|
||||
case UNAVAILABLE_UNKNOWN:
|
||||
default:
|
||||
summary = context.getString(R.string.unknown_unavailability_setting_summary);
|
||||
primaryAction = new SliceAction(getSettingsIntent(context),
|
||||
null /* actionIcon */, null /* actionTitle */);
|
||||
}
|
||||
|
||||
return new ListBuilder(context, data.getUri())
|
||||
.addRow(builder -> builder
|
||||
.setTitle(title)
|
||||
.setSubtitle(summary)
|
||||
.setPrimaryAction(primaryAction))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* 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.slices;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
public class SliceDeepLinkSpringBoard extends Activity {
|
||||
|
||||
private static final String TAG = "DeeplinkSpringboard";
|
||||
public static final String INTENT = "intent";
|
||||
public static final String SETTINGS = "settings";
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
Uri uri = getIntent().getData();
|
||||
if (uri == null) {
|
||||
Log.e(TAG, "No data found");
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
try {
|
||||
Intent intent = parse(uri, getPackageName());
|
||||
startActivity(intent);
|
||||
finish();
|
||||
} catch (URISyntaxException e) {
|
||||
Log.e(TAG, "Error decoding uri", e);
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
public static Intent parse(Uri uri, String pkg) throws URISyntaxException {
|
||||
Intent intent = Intent.parseUri(uri.getQueryParameter(INTENT),
|
||||
Intent.URI_ANDROID_APP_SCHEME);
|
||||
// Start with some really strict constraints and loosen them if we need to.
|
||||
// Don't allow components.
|
||||
intent.setComponent(null);
|
||||
// Clear out the extras.
|
||||
if (intent.getExtras() != null) {
|
||||
intent.getExtras().clear();
|
||||
}
|
||||
// Make sure this points at Settings.
|
||||
intent.setPackage(pkg);
|
||||
return intent;
|
||||
}
|
||||
}
|
||||
@@ -118,6 +118,7 @@ public class WallpaperTypeSettings extends SettingsPreferenceFragment implements
|
||||
data.intentAction = Intent.ACTION_SET_WALLPAPER;
|
||||
data.intentTargetPackage = info.activityInfo.packageName;
|
||||
data.intentTargetClass = info.activityInfo.name;
|
||||
data.keywords = context.getString(R.string.keywords_wallpaper);
|
||||
result.add(data);
|
||||
}
|
||||
|
||||
|
||||
@@ -27,11 +27,11 @@ import android.content.pm.PackageItemInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
import android.text.TextUtils;
|
||||
import android.webkit.UserPackage;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.applications.defaultapps.DefaultAppPickerFragment;
|
||||
import com.android.settings.wrapper.UserPackageWrapper;
|
||||
import com.android.settingslib.applications.DefaultAppInfo;
|
||||
import com.android.settingslib.wrapper.PackageManagerWrapper;
|
||||
|
||||
@@ -150,9 +150,9 @@ public class WebViewAppPicker extends DefaultAppPickerFragment {
|
||||
@VisibleForTesting
|
||||
String getDisabledReason(WebViewUpdateServiceWrapper webviewUpdateServiceWrapper,
|
||||
Context context, String packageName) {
|
||||
List<UserPackageWrapper> userPackages =
|
||||
List<UserPackage> userPackages =
|
||||
webviewUpdateServiceWrapper.getPackageInfosAllUsers(context, packageName);
|
||||
for (UserPackageWrapper userPackage : userPackages) {
|
||||
for (UserPackage userPackage : userPackages) {
|
||||
if (!userPackage.isInstalledPackage()) {
|
||||
// Package uninstalled/hidden
|
||||
return context.getString(
|
||||
|
||||
@@ -28,8 +28,6 @@ import android.webkit.WebViewProviderInfo;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.wrapper.UserPackageWrapper;
|
||||
import com.android.settings.wrapper.UserPackageWrapperImpl;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -37,7 +35,8 @@ import java.util.List;
|
||||
public class WebViewUpdateServiceWrapper {
|
||||
private static final String TAG = "WVUSWrapper";
|
||||
|
||||
public WebViewUpdateServiceWrapper() {}
|
||||
public WebViewUpdateServiceWrapper() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the package currently used as WebView implementation.
|
||||
@@ -75,6 +74,7 @@ public class WebViewUpdateServiceWrapper {
|
||||
|
||||
/**
|
||||
* Change WebView provider to {@param packageName}.
|
||||
*
|
||||
* @return whether the change succeeded.
|
||||
*/
|
||||
public boolean setWebViewProvider(String packageName) {
|
||||
@@ -90,14 +90,8 @@ public class WebViewUpdateServiceWrapper {
|
||||
/**
|
||||
* Fetch PackageInfos for the package named {@param packageName} for all users on the device.
|
||||
*/
|
||||
public List<UserPackageWrapper> getPackageInfosAllUsers(Context context, String packageName) {
|
||||
List<UserPackageWrapper> userPackageWrappers = new ArrayList<>();
|
||||
List<UserPackage> userPackages =
|
||||
UserPackage.getPackageInfosAllUsers(context, packageName, PACKAGE_FLAGS);
|
||||
for (UserPackage userPackage : userPackages) {
|
||||
userPackageWrappers.add(new UserPackageWrapperImpl(userPackage));
|
||||
}
|
||||
return userPackageWrappers;
|
||||
public List<UserPackage> getPackageInfosAllUsers(Context context, String packageName) {
|
||||
return UserPackage.getPackageInfosAllUsers(context, packageName, PACKAGE_FLAGS);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.android.settings.widget;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
import android.support.v7.preference.PreferenceViewHolder;
|
||||
import android.text.Editable;
|
||||
import android.text.InputType;
|
||||
import android.text.TextUtils;
|
||||
@@ -27,6 +28,7 @@ import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.EditText;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.settingslib.CustomEditTextPreference;
|
||||
|
||||
@@ -42,6 +44,7 @@ public class ValidatedEditTextPreference extends CustomEditTextPreference {
|
||||
private final EditTextWatcher mTextWatcher = new EditTextWatcher();
|
||||
private Validator mValidator;
|
||||
private boolean mIsPassword;
|
||||
private boolean mIsSummaryPassword;
|
||||
|
||||
public ValidatedEditTextPreference(Context context, AttributeSet attrs,
|
||||
int defStyleAttr, int defStyleRes) {
|
||||
@@ -78,10 +81,25 @@ public class ValidatedEditTextPreference extends CustomEditTextPreference {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(PreferenceViewHolder holder) {
|
||||
super.onBindViewHolder(holder);
|
||||
|
||||
final TextView textView = (TextView) holder.findViewById(android.R.id.summary);
|
||||
if (textView != null && mIsSummaryPassword) {
|
||||
textView.setInputType(
|
||||
InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
|
||||
}
|
||||
}
|
||||
|
||||
public void setIsPassword(boolean isPassword) {
|
||||
mIsPassword = isPassword;
|
||||
}
|
||||
|
||||
public void setIsSummaryPassword(boolean isPassword) {
|
||||
mIsSummaryPassword = isPassword;
|
||||
}
|
||||
|
||||
@VisibleForTesting(otherwise = VisibleForTesting.NONE)
|
||||
public boolean isPassword() {
|
||||
return mIsPassword;
|
||||
|
||||
@@ -51,6 +51,7 @@ public class WifiTetherPasswordPreferenceController extends WifiTetherBasePrefer
|
||||
Log.d(TAG, "Updating password in Preference, " + mPassword);
|
||||
}
|
||||
((ValidatedEditTextPreference) mPreference).setValidator(this);
|
||||
((ValidatedEditTextPreference) mPreference).setIsSummaryPassword(true);
|
||||
updatePasswordDisplay((EditTextPreference) mPreference);
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ import android.net.wifi.WifiManager;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.provider.Settings;
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
|
||||
import com.android.settings.datausage.DataSaverBackend;
|
||||
import com.android.settings.widget.SwitchWidgetController;
|
||||
@@ -44,6 +45,16 @@ public class WifiTetherSwitchBarController implements SwitchWidgetController.OnS
|
||||
private final ConnectivityManager mConnectivityManager;
|
||||
private final DataSaverBackend mDataSaverBackend;
|
||||
private final WifiManager mWifiManager;
|
||||
@VisibleForTesting
|
||||
final ConnectivityManager.OnStartTetheringCallback mOnStartTetheringCallback =
|
||||
new ConnectivityManager.OnStartTetheringCallback() {
|
||||
@Override
|
||||
public void onTetheringFailed() {
|
||||
super.onTetheringFailed();
|
||||
mSwitchBar.setChecked(false);
|
||||
updateWifiSwitch();
|
||||
}
|
||||
};
|
||||
|
||||
static {
|
||||
WIFI_INTENT_FILTER = new IntentFilter(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
|
||||
@@ -59,6 +70,7 @@ public class WifiTetherSwitchBarController implements SwitchWidgetController.OnS
|
||||
mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
|
||||
mSwitchBar.setChecked(mWifiManager.getWifiApState() == WifiManager.WIFI_AP_STATE_ENABLED);
|
||||
mSwitchBar.setListener(this);
|
||||
updateWifiSwitch();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -91,7 +103,7 @@ public class WifiTetherSwitchBarController implements SwitchWidgetController.OnS
|
||||
void startTether() {
|
||||
mSwitchBar.setEnabled(false);
|
||||
mConnectivityManager.startTethering(TETHERING_WIFI, true /* showProvisioningUi */,
|
||||
NoOpOnStartTetheringCallback.newInstance(), new Handler(Looper.getMainLooper()));
|
||||
mOnStartTetheringCallback, new Handler(Looper.getMainLooper()));
|
||||
}
|
||||
|
||||
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
|
||||
@@ -103,7 +115,7 @@ public class WifiTetherSwitchBarController implements SwitchWidgetController.OnS
|
||||
WifiManager.EXTRA_WIFI_AP_STATE, WifiManager.WIFI_AP_STATE_FAILED);
|
||||
handleWifiApStateChanged(state);
|
||||
} else if (Intent.ACTION_AIRPLANE_MODE_CHANGED.equals(action)) {
|
||||
enableWifiSwitch();
|
||||
updateWifiSwitch();
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -117,7 +129,7 @@ public class WifiTetherSwitchBarController implements SwitchWidgetController.OnS
|
||||
if (!mSwitchBar.isChecked()) {
|
||||
mSwitchBar.setChecked(true);
|
||||
}
|
||||
enableWifiSwitch();
|
||||
updateWifiSwitch();
|
||||
break;
|
||||
case WifiManager.WIFI_AP_STATE_DISABLING:
|
||||
if (mSwitchBar.isChecked()) {
|
||||
@@ -127,16 +139,16 @@ public class WifiTetherSwitchBarController implements SwitchWidgetController.OnS
|
||||
break;
|
||||
case WifiManager.WIFI_AP_STATE_DISABLED:
|
||||
mSwitchBar.setChecked(false);
|
||||
enableWifiSwitch();
|
||||
updateWifiSwitch();
|
||||
break;
|
||||
default:
|
||||
mSwitchBar.setChecked(false);
|
||||
enableWifiSwitch();
|
||||
updateWifiSwitch();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void enableWifiSwitch() {
|
||||
private void updateWifiSwitch() {
|
||||
boolean isAirplaneMode = Settings.Global.getInt(mContext.getContentResolver(),
|
||||
Settings.Global.AIRPLANE_MODE_ON, 0) != 0;
|
||||
if (!isAirplaneMode) {
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the
|
||||
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.wrapper;
|
||||
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.webkit.UserPackage;
|
||||
|
||||
/**
|
||||
* Default implementation of UserPackageWrapper.
|
||||
*/
|
||||
public class UserPackageWrapperImpl implements UserPackageWrapper {
|
||||
private final UserPackage mUserPackage;
|
||||
|
||||
public UserPackageWrapperImpl(UserPackage userPackage) {
|
||||
mUserPackage = userPackage;
|
||||
}
|
||||
|
||||
public UserInfo getUserInfo() {
|
||||
return mUserPackage.getUserInfo();
|
||||
}
|
||||
|
||||
public PackageInfo getPackageInfo() {
|
||||
return mUserPackage.getPackageInfo();
|
||||
}
|
||||
|
||||
public boolean isEnabledPackage() {
|
||||
return mUserPackage.isEnabledPackage();
|
||||
}
|
||||
|
||||
public boolean isInstalledPackage() {
|
||||
return mUserPackage.isInstalledPackage();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,413 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License
|
||||
*/
|
||||
|
||||
package com.android.settings.applications;
|
||||
|
||||
import static android.text.format.DateUtils.DAY_IN_MILLIS;
|
||||
|
||||
import static com.android.settings.applications.AppStateNotificationBridge
|
||||
.FILTER_APP_NOTIFICATION_FREQUENCY;
|
||||
import static com.android.settings.applications.AppStateNotificationBridge
|
||||
.FILTER_APP_NOTIFICATION_RECENCY;
|
||||
import static com.android.settings.applications.AppStateNotificationBridge
|
||||
.FREQUENCY_NOTIFICATION_COMPARATOR;
|
||||
import static com.android.settings.applications.AppStateNotificationBridge
|
||||
.RECENT_NOTIFICATION_COMPARATOR;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static junit.framework.Assert.assertFalse;
|
||||
import static junit.framework.Assert.assertTrue;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyLong;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.usage.UsageEvents;
|
||||
import android.app.usage.UsageEvents.Event;
|
||||
import android.app.usage.UsageStatsManager;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.os.Looper;
|
||||
import android.os.Parcel;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.applications.AppStateNotificationBridge.NotificationsSentState;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
import com.android.settingslib.applications.ApplicationsState;
|
||||
import com.android.settingslib.applications.ApplicationsState.AppEntry;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
public class AppStateNotificationBridgeTest {
|
||||
|
||||
private static String PKG1 = "pkg1";
|
||||
private static String PKG2 = "pkg2";
|
||||
|
||||
@Mock
|
||||
private ApplicationsState.Session mSession;
|
||||
@Mock
|
||||
private ApplicationsState mState;
|
||||
@Mock
|
||||
private UsageStatsManager mUsageStats;
|
||||
private Context mContext;
|
||||
private AppStateNotificationBridge mBridge;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
when(mState.newSession(any())).thenReturn(mSession);
|
||||
when(mState.getBackgroundLooper()).thenReturn(mock(Looper.class));
|
||||
mContext = RuntimeEnvironment.application.getApplicationContext();
|
||||
|
||||
mBridge = new AppStateNotificationBridge(mState,
|
||||
mock(AppStateBaseBridge.Callback.class), mUsageStats);
|
||||
}
|
||||
|
||||
private AppEntry getMockAppEntry(String pkg) {
|
||||
AppEntry entry = mock(AppEntry.class);
|
||||
entry.info = mock(ApplicationInfo.class);
|
||||
entry.info.packageName = pkg;
|
||||
return entry;
|
||||
}
|
||||
|
||||
private UsageEvents getUsageEvents(List<Event> events) {
|
||||
UsageEvents usageEvents = new UsageEvents(events, new String[] {PKG1, PKG2});
|
||||
Parcel parcel = Parcel.obtain();
|
||||
parcel.setDataPosition(0);
|
||||
usageEvents.writeToParcel(parcel, 0);
|
||||
parcel.setDataPosition(0);
|
||||
return UsageEvents.CREATOR.createFromParcel(parcel);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAggregatedUsageEvents_noEvents() {
|
||||
when(mUsageStats.queryEvents(anyLong(), anyLong())).thenReturn(mock(UsageEvents.class));
|
||||
|
||||
assertThat(mBridge.getAggregatedUsageEvents()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAggregatedUsageEvents_onlyNotificationEvents() {
|
||||
List<Event> events = new ArrayList<>();
|
||||
Event good = new Event();
|
||||
good.mEventType = Event.NOTIFICATION_INTERRUPTION;
|
||||
good.mPackage = PKG1;
|
||||
good.mTimeStamp = 1;
|
||||
events.add(good);
|
||||
Event bad = new Event();
|
||||
bad.mEventType = Event.CHOOSER_ACTION;
|
||||
bad.mPackage = PKG1;
|
||||
bad.mTimeStamp = 2;
|
||||
events.add(bad);
|
||||
|
||||
UsageEvents usageEvents = getUsageEvents(events);
|
||||
when(mUsageStats.queryEvents(anyLong(), anyLong())).thenReturn(usageEvents);
|
||||
|
||||
Map<String, NotificationsSentState> map = mBridge.getAggregatedUsageEvents();
|
||||
assertThat(map.get(PKG1).sentCount).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAggregatedUsageEvents_multipleEventsAgg() {
|
||||
List<Event> events = new ArrayList<>();
|
||||
Event good = new Event();
|
||||
good.mEventType = Event.NOTIFICATION_INTERRUPTION;
|
||||
good.mPackage = PKG1;
|
||||
good.mTimeStamp = 6;
|
||||
events.add(good);
|
||||
Event good1 = new Event();
|
||||
good1.mEventType = Event.NOTIFICATION_INTERRUPTION;
|
||||
good1.mPackage = PKG1;
|
||||
good1.mTimeStamp = 1;
|
||||
events.add(good1);
|
||||
|
||||
UsageEvents usageEvents = getUsageEvents(events);
|
||||
when(mUsageStats.queryEvents(anyLong(), anyLong())).thenReturn(usageEvents);
|
||||
|
||||
Map<String, NotificationsSentState> map = mBridge.getAggregatedUsageEvents();
|
||||
assertThat(map.get(PKG1).sentCount).isEqualTo(2);
|
||||
assertThat(map.get(PKG1).lastSent).isEqualTo(6);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAggregatedUsageEvents_multiplePkgs() {
|
||||
List<Event> events = new ArrayList<>();
|
||||
Event good = new Event();
|
||||
good.mEventType = Event.NOTIFICATION_INTERRUPTION;
|
||||
good.mPackage = PKG1;
|
||||
good.mTimeStamp = 6;
|
||||
events.add(good);
|
||||
Event good1 = new Event();
|
||||
good1.mEventType = Event.NOTIFICATION_INTERRUPTION;
|
||||
good1.mPackage = PKG2;
|
||||
good1.mTimeStamp = 1;
|
||||
events.add(good1);
|
||||
|
||||
UsageEvents usageEvents = getUsageEvents(events);
|
||||
when(mUsageStats.queryEvents(anyLong(), anyLong())).thenReturn(usageEvents);
|
||||
|
||||
Map<String, NotificationsSentState> map
|
||||
= mBridge.getAggregatedUsageEvents();
|
||||
assertThat(map.get(PKG1).sentCount).isEqualTo(1);
|
||||
assertThat(map.get(PKG2).sentCount).isEqualTo(1);
|
||||
assertThat(map.get(PKG1).lastSent).isEqualTo(6);
|
||||
assertThat(map.get(PKG2).lastSent).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoadAllExtraInfo_noEvents() {
|
||||
when(mUsageStats.queryEvents(anyLong(), anyLong())).thenReturn(mock(UsageEvents.class));
|
||||
ArrayList<AppEntry> apps = new ArrayList<>();
|
||||
apps.add(getMockAppEntry(PKG1));
|
||||
when(mSession.getAllApps()).thenReturn(apps);
|
||||
|
||||
mBridge.loadAllExtraInfo();
|
||||
assertThat(apps.get(0).extraInfo).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoadAllExtraInfo_multipleEventsAgg() {
|
||||
List<Event> events = new ArrayList<>();
|
||||
for (int i = 0; i < 7; i++) {
|
||||
Event good = new Event();
|
||||
good.mEventType = Event.NOTIFICATION_INTERRUPTION;
|
||||
good.mPackage = PKG1;
|
||||
good.mTimeStamp = i;
|
||||
events.add(good);
|
||||
}
|
||||
|
||||
UsageEvents usageEvents = getUsageEvents(events);
|
||||
when(mUsageStats.queryEvents(anyLong(), anyLong())).thenReturn(usageEvents);
|
||||
|
||||
ArrayList<AppEntry> apps = new ArrayList<>();
|
||||
apps.add(getMockAppEntry(PKG1));
|
||||
when(mSession.getAllApps()).thenReturn(apps);
|
||||
|
||||
mBridge.loadAllExtraInfo();
|
||||
assertThat(((NotificationsSentState) apps.get(0).extraInfo).sentCount).isEqualTo(7);
|
||||
assertThat(((NotificationsSentState) apps.get(0).extraInfo).lastSent).isEqualTo(6);
|
||||
assertThat(((NotificationsSentState) apps.get(0).extraInfo).avgSentDaily).isEqualTo(1);
|
||||
assertThat(((NotificationsSentState) apps.get(0).extraInfo).avgSentWeekly).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoadAllExtraInfo_multiplePkgs() {
|
||||
List<Event> events = new ArrayList<>();
|
||||
for (int i = 0; i < 8; i++) {
|
||||
Event good = new Event();
|
||||
good.mEventType = Event.NOTIFICATION_INTERRUPTION;
|
||||
good.mPackage = PKG1;
|
||||
good.mTimeStamp = i;
|
||||
events.add(good);
|
||||
}
|
||||
Event good1 = new Event();
|
||||
good1.mEventType = Event.NOTIFICATION_INTERRUPTION;
|
||||
good1.mPackage = PKG2;
|
||||
good1.mTimeStamp = 1;
|
||||
events.add(good1);
|
||||
|
||||
UsageEvents usageEvents = getUsageEvents(events);
|
||||
when(mUsageStats.queryEvents(anyLong(), anyLong())).thenReturn(usageEvents);
|
||||
|
||||
ArrayList<AppEntry> apps = new ArrayList<>();
|
||||
apps.add(getMockAppEntry(PKG1));
|
||||
apps.add(getMockAppEntry(PKG2));
|
||||
when(mSession.getAllApps()).thenReturn(apps);
|
||||
|
||||
mBridge.loadAllExtraInfo();
|
||||
assertThat(((NotificationsSentState) apps.get(0).extraInfo).sentCount).isEqualTo(8);
|
||||
assertThat(((NotificationsSentState) apps.get(0).extraInfo).lastSent).isEqualTo(7);
|
||||
assertThat(((NotificationsSentState) apps.get(0).extraInfo).avgSentWeekly).isEqualTo(0);
|
||||
assertThat(((NotificationsSentState) apps.get(0).extraInfo).avgSentDaily).isEqualTo(1);
|
||||
|
||||
assertThat(((NotificationsSentState) apps.get(1).extraInfo).sentCount).isEqualTo(1);
|
||||
assertThat(((NotificationsSentState) apps.get(1).extraInfo).lastSent).isEqualTo(1);
|
||||
assertThat(((NotificationsSentState) apps.get(1).extraInfo).avgSentWeekly).isEqualTo(1);
|
||||
assertThat(((NotificationsSentState) apps.get(1).extraInfo).avgSentDaily).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateExtraInfo_noEvents() {
|
||||
when(mUsageStats.queryEvents(anyLong(), anyLong())).thenReturn(mock(UsageEvents.class));
|
||||
AppEntry entry = getMockAppEntry(PKG1);
|
||||
|
||||
mBridge.updateExtraInfo(entry, "", 0);
|
||||
assertThat(entry.extraInfo).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateExtraInfo_multipleEventsAgg() {
|
||||
List<Event> events = new ArrayList<>();
|
||||
for (int i = 0; i < 13; i++) {
|
||||
Event good = new Event();
|
||||
good.mEventType = Event.NOTIFICATION_INTERRUPTION;
|
||||
good.mPackage = PKG1;
|
||||
good.mTimeStamp = i;
|
||||
events.add(good);
|
||||
}
|
||||
|
||||
UsageEvents usageEvents = getUsageEvents(events);
|
||||
when(mUsageStats.queryEvents(anyLong(), anyLong())).thenReturn(usageEvents);
|
||||
|
||||
AppEntry entry = getMockAppEntry(PKG1);
|
||||
mBridge.updateExtraInfo(entry, "", 0);
|
||||
|
||||
assertThat(((NotificationsSentState) entry.extraInfo).sentCount).isEqualTo(13);
|
||||
assertThat(((NotificationsSentState) entry.extraInfo).lastSent).isEqualTo(12);
|
||||
assertThat(((NotificationsSentState) entry.extraInfo).avgSentDaily).isEqualTo(2);
|
||||
assertThat(((NotificationsSentState) entry.extraInfo).avgSentWeekly).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSummary_recency() {
|
||||
NotificationsSentState neverSent = new NotificationsSentState();
|
||||
NotificationsSentState sent = new NotificationsSentState();
|
||||
sent.lastSent = System.currentTimeMillis() - (2 * DAY_IN_MILLIS);
|
||||
|
||||
assertThat(AppStateNotificationBridge.getSummary(mContext, neverSent, true)).isEqualTo(
|
||||
mContext.getString(R.string.notifications_sent_never));
|
||||
assertThat(AppStateNotificationBridge.getSummary(mContext, sent, true).toString())
|
||||
.contains("2");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSummary_frequency() {
|
||||
NotificationsSentState sentRarely = new NotificationsSentState();
|
||||
sentRarely.avgSentWeekly = 1;
|
||||
NotificationsSentState sentOften = new NotificationsSentState();
|
||||
sentOften.avgSentDaily = 8;
|
||||
|
||||
assertThat(AppStateNotificationBridge.getSummary(mContext, sentRarely, false).toString())
|
||||
.contains("1");
|
||||
assertThat(AppStateNotificationBridge.getSummary(mContext, sentOften, false).toString())
|
||||
.contains("8");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFilterRecency() {
|
||||
NotificationsSentState allowState = new NotificationsSentState();
|
||||
allowState.lastSent = 1;
|
||||
AppEntry allow = mock(AppEntry.class);
|
||||
allow.extraInfo = allowState;
|
||||
|
||||
assertTrue(FILTER_APP_NOTIFICATION_RECENCY.filterApp(allow));
|
||||
|
||||
NotificationsSentState denyState = new NotificationsSentState();
|
||||
denyState.lastSent = 0;
|
||||
AppEntry deny = mock(AppEntry.class);
|
||||
deny.extraInfo = denyState;
|
||||
|
||||
assertFalse(FILTER_APP_NOTIFICATION_RECENCY.filterApp(deny));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFilterFrequency() {
|
||||
NotificationsSentState allowState = new NotificationsSentState();
|
||||
allowState.sentCount = 1;
|
||||
AppEntry allow = mock(AppEntry.class);
|
||||
allow.extraInfo = allowState;
|
||||
|
||||
assertTrue(FILTER_APP_NOTIFICATION_FREQUENCY.filterApp(allow));
|
||||
|
||||
NotificationsSentState denyState = new NotificationsSentState();
|
||||
denyState.sentCount = 0;
|
||||
AppEntry deny = mock(AppEntry.class);
|
||||
deny.extraInfo = denyState;
|
||||
|
||||
assertFalse(FILTER_APP_NOTIFICATION_FREQUENCY.filterApp(deny));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testComparators_nullsNoCrash() {
|
||||
List<AppEntry> entries = new ArrayList<>();
|
||||
AppEntry a = mock(AppEntry.class);
|
||||
a.label = "1";
|
||||
AppEntry b = mock(AppEntry.class);
|
||||
b.label = "2";
|
||||
entries.add(a);
|
||||
entries.add(b);
|
||||
|
||||
entries.sort(RECENT_NOTIFICATION_COMPARATOR);
|
||||
entries.sort(FREQUENCY_NOTIFICATION_COMPARATOR);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRecencyComparator() {
|
||||
List<AppEntry> entries = new ArrayList<>();
|
||||
|
||||
NotificationsSentState earlier = new NotificationsSentState();
|
||||
earlier.lastSent = 1;
|
||||
AppEntry earlyEntry = mock(AppEntry.class);
|
||||
earlyEntry.extraInfo = earlier;
|
||||
entries.add(earlyEntry);
|
||||
|
||||
NotificationsSentState later = new NotificationsSentState();
|
||||
later.lastSent = 8;
|
||||
AppEntry lateEntry = mock(AppEntry.class);
|
||||
lateEntry.extraInfo = later;
|
||||
entries.add(lateEntry);
|
||||
|
||||
entries.sort(RECENT_NOTIFICATION_COMPARATOR);
|
||||
|
||||
assertThat(entries).containsExactly(lateEntry, earlyEntry);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFrequencyComparator() {
|
||||
List<AppEntry> entries = new ArrayList<>();
|
||||
|
||||
NotificationsSentState notFrequentWeekly = new NotificationsSentState();
|
||||
notFrequentWeekly.sentCount = 2;
|
||||
AppEntry notFrequentWeeklyEntry = mock(AppEntry.class);
|
||||
notFrequentWeeklyEntry.extraInfo = notFrequentWeekly;
|
||||
entries.add(notFrequentWeeklyEntry);
|
||||
|
||||
NotificationsSentState notFrequentDaily = new NotificationsSentState();
|
||||
notFrequentDaily.sentCount = 7;
|
||||
AppEntry notFrequentDailyEntry = mock(AppEntry.class);
|
||||
notFrequentDailyEntry.extraInfo = notFrequentDaily;
|
||||
entries.add(notFrequentDailyEntry);
|
||||
|
||||
NotificationsSentState veryFrequentWeekly = new NotificationsSentState();
|
||||
veryFrequentWeekly.sentCount = 6;
|
||||
AppEntry veryFrequentWeeklyEntry = mock(AppEntry.class);
|
||||
veryFrequentWeeklyEntry.extraInfo = veryFrequentWeekly;
|
||||
entries.add(veryFrequentWeeklyEntry);
|
||||
|
||||
NotificationsSentState veryFrequentDaily = new NotificationsSentState();
|
||||
veryFrequentDaily.sentCount = 19;
|
||||
AppEntry veryFrequentDailyEntry = mock(AppEntry.class);
|
||||
veryFrequentDailyEntry.extraInfo = veryFrequentDaily;
|
||||
entries.add(veryFrequentDailyEntry);
|
||||
|
||||
entries.sort(FREQUENCY_NOTIFICATION_COMPARATOR);
|
||||
|
||||
assertThat(entries).containsExactly(veryFrequentDailyEntry, notFrequentDailyEntry,
|
||||
veryFrequentWeeklyEntry, notFrequentWeeklyEntry);
|
||||
}
|
||||
}
|
||||
@@ -312,7 +312,7 @@ public class RecentAppsPreferenceControllerTest {
|
||||
|
||||
mController.displayPreference(mScreen);
|
||||
|
||||
verify(mCategory).addPreference(argThat(summaryMatches("0 min. ago")));
|
||||
verify(mCategory).addPreference(argThat(summaryMatches("0 minutes ago")));
|
||||
}
|
||||
|
||||
private static ArgumentMatcher<Preference> summaryMatches(String expected) {
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.applications.appinfo;
|
||||
|
||||
import static android.content.Intent.EXTRA_PACKAGE_NAME;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.support.v7.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.Shadows;
|
||||
import org.robolectric.shadows.ShadowPackageManager;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
public class TimeSpentInAppPreferenceControllerTest {
|
||||
|
||||
private static final String TEST_KEY = "test_tey";
|
||||
private static final Intent TEST_INTENT = new Intent(
|
||||
TimeSpentInAppPreferenceController.SEE_TIME_IN_APP_TEMPLATE)
|
||||
.putExtra(EXTRA_PACKAGE_NAME, "com.android.settings");
|
||||
|
||||
@Mock
|
||||
private PreferenceScreen mScreen;
|
||||
|
||||
private Context mContext;
|
||||
private ShadowPackageManager mPackageManager;
|
||||
private TimeSpentInAppPreferenceController mController;
|
||||
private Preference mPreference;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = RuntimeEnvironment.application;
|
||||
mPackageManager = Shadows.shadowOf(mContext.getPackageManager());
|
||||
mController = new TimeSpentInAppPreferenceController(mContext, TEST_KEY);
|
||||
mPreference = new Preference(mContext);
|
||||
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noPackageName_shouldBeDisabled() {
|
||||
mController.setPackageName(null);
|
||||
|
||||
assertThat(mController.getAvailabilityStatus())
|
||||
.isEqualTo(BasePreferenceController.DISABLED_UNSUPPORTED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noIntentHandler_shouldBeDisabled() {
|
||||
mController.setPackageName(TEST_INTENT.getStringExtra(EXTRA_PACKAGE_NAME));
|
||||
|
||||
assertThat(mController.getAvailabilityStatus())
|
||||
.isEqualTo(BasePreferenceController.DISABLED_UNSUPPORTED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hasIntentHandler_shouldBeAvailable() {
|
||||
mPackageManager.addResolveInfoForIntent(TEST_INTENT, new ResolveInfo());
|
||||
mController.setPackageName(TEST_INTENT.getStringExtra(EXTRA_PACKAGE_NAME));
|
||||
|
||||
assertThat(mController.getAvailabilityStatus())
|
||||
.isEqualTo(BasePreferenceController.AVAILABLE);
|
||||
|
||||
mController.displayPreference(mScreen);
|
||||
|
||||
final Intent intent = mPreference.getIntent();
|
||||
assertThat(intent.getAction()).isEqualTo(TEST_INTENT.getAction());
|
||||
assertThat(intent.getStringExtra(EXTRA_PACKAGE_NAME))
|
||||
.isEqualTo(TEST_INTENT.getStringExtra(EXTRA_PACKAGE_NAME));
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package com.android.settings.applications.manageapplications;
|
||||
|
||||
import static com.android.settings.applications.manageapplications.AppFilterRegistry.FILTER_APPS_BLOCKED;
|
||||
import static com.android.settings.applications.manageapplications.AppFilterRegistry.FILTER_APPS_ENABLED;
|
||||
import static com.android.settings.applications.manageapplications.AppFilterRegistry.FILTER_APPS_USAGE_ACCESS;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
@@ -80,7 +79,7 @@ public class AppFilterItemTest {
|
||||
@Test
|
||||
public void hash_differentItem_differentHash() {
|
||||
final AppFilterItem item = AppFilterRegistry.getInstance().get(FILTER_APPS_USAGE_ACCESS);
|
||||
final AppFilterItem item2 = AppFilterRegistry.getInstance().get(FILTER_APPS_BLOCKED);
|
||||
final AppFilterItem item2 = AppFilterRegistry.getInstance().get(FILTER_APPS_ENABLED);
|
||||
|
||||
assertThat(item.hashCode()).isNotEqualTo(item2.hashCode());
|
||||
}
|
||||
|
||||
@@ -19,6 +19,9 @@ package com.android.settings.applications.manageapplications;
|
||||
import static com.android.settings.applications.manageapplications.AppFilterRegistry.FILTER_APPS_ALL;
|
||||
import static com.android.settings.applications.manageapplications.AppFilterRegistry.FILTER_APPS_INSTALL_SOURCES;
|
||||
import static com.android.settings.applications.manageapplications.AppFilterRegistry.FILTER_APPS_POWER_WHITELIST;
|
||||
|
||||
import static com.android.settings.applications.manageapplications.AppFilterRegistry
|
||||
.FILTER_APPS_RECENT;
|
||||
import static com.android.settings.applications.manageapplications.AppFilterRegistry.FILTER_APPS_USAGE_ACCESS;
|
||||
import static com.android.settings.applications.manageapplications.AppFilterRegistry.FILTER_APPS_WITH_OVERLAY;
|
||||
import static com.android.settings.applications.manageapplications.AppFilterRegistry.FILTER_APPS_WRITE_SETTINGS;
|
||||
@@ -45,24 +48,25 @@ public class AppFilterRegistryTest {
|
||||
|
||||
@Test
|
||||
public void getDefaultType_shouldMatchForAllListType() {
|
||||
final AppFilterRegistry registry = AppFilterRegistry.getInstance();
|
||||
assertThat(registry.getDefaultFilterType(LIST_TYPE_USAGE_ACCESS))
|
||||
.isEqualTo(FILTER_APPS_USAGE_ACCESS);
|
||||
assertThat(registry.getDefaultFilterType(LIST_TYPE_HIGH_POWER))
|
||||
.isEqualTo(FILTER_APPS_POWER_WHITELIST);
|
||||
assertThat(registry.getDefaultFilterType(LIST_TYPE_OVERLAY))
|
||||
.isEqualTo(FILTER_APPS_WITH_OVERLAY);
|
||||
assertThat(registry.getDefaultFilterType(LIST_TYPE_WRITE_SETTINGS))
|
||||
.isEqualTo(FILTER_APPS_WRITE_SETTINGS);
|
||||
assertThat(registry.getDefaultFilterType(LIST_TYPE_MANAGE_SOURCES))
|
||||
.isEqualTo(FILTER_APPS_INSTALL_SOURCES);
|
||||
final AppFilterRegistry registry = AppFilterRegistry.getInstance();
|
||||
assertThat(registry.getDefaultFilterType(LIST_TYPE_USAGE_ACCESS))
|
||||
.isEqualTo(FILTER_APPS_USAGE_ACCESS);
|
||||
assertThat(registry.getDefaultFilterType(LIST_TYPE_HIGH_POWER))
|
||||
.isEqualTo(FILTER_APPS_POWER_WHITELIST);
|
||||
assertThat(registry.getDefaultFilterType(LIST_TYPE_OVERLAY))
|
||||
.isEqualTo(FILTER_APPS_WITH_OVERLAY);
|
||||
assertThat(registry.getDefaultFilterType(LIST_TYPE_WRITE_SETTINGS))
|
||||
.isEqualTo(FILTER_APPS_WRITE_SETTINGS);
|
||||
assertThat(registry.getDefaultFilterType(LIST_TYPE_MANAGE_SOURCES))
|
||||
.isEqualTo(FILTER_APPS_INSTALL_SOURCES);
|
||||
|
||||
assertThat(registry.getDefaultFilterType(LIST_TYPE_MAIN)).isEqualTo(FILTER_APPS_ALL);
|
||||
assertThat(registry.getDefaultFilterType(LIST_TYPE_NOTIFICATION)).isEqualTo(FILTER_APPS_ALL);
|
||||
assertThat(registry.getDefaultFilterType(LIST_TYPE_STORAGE)).isEqualTo(FILTER_APPS_ALL);
|
||||
assertThat(registry.getDefaultFilterType(LIST_TYPE_MAIN)).isEqualTo(FILTER_APPS_ALL);
|
||||
assertThat(registry.getDefaultFilterType(LIST_TYPE_NOTIFICATION))
|
||||
.isEqualTo(FILTER_APPS_RECENT);
|
||||
assertThat(registry.getDefaultFilterType(LIST_TYPE_STORAGE)).isEqualTo(FILTER_APPS_ALL);
|
||||
|
||||
assertThat(registry.getDefaultFilterType(LIST_TYPE_GAMES)).isEqualTo(FILTER_APPS_ALL);
|
||||
assertThat(registry.getDefaultFilterType(LIST_TYPE_MOVIES)).isEqualTo(FILTER_APPS_ALL);
|
||||
assertThat(registry.getDefaultFilterType(LIST_TYPE_PHOTOGRAPHY)).isEqualTo(FILTER_APPS_ALL);
|
||||
assertThat(registry.getDefaultFilterType(LIST_TYPE_GAMES)).isEqualTo(FILTER_APPS_ALL);
|
||||
assertThat(registry.getDefaultFilterType(LIST_TYPE_MOVIES)).isEqualTo(FILTER_APPS_ALL);
|
||||
assertThat(registry.getDefaultFilterType(LIST_TYPE_PHOTOGRAPHY)).isEqualTo(FILTER_APPS_ALL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,12 +67,16 @@ public class ManageApplicationsTest {
|
||||
@Mock
|
||||
private Menu mMenu;
|
||||
private MenuItem mAppReset;
|
||||
private MenuItem mSortRecent;
|
||||
private MenuItem mSortFrequent;
|
||||
private ManageApplications mFragment;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mAppReset = new RoboMenuItem(R.id.reset_app_preferences);
|
||||
mSortRecent = new RoboMenuItem(R.id.sort_order_recent_notification);
|
||||
mSortFrequent = new RoboMenuItem(R.id.sort_order_frequent_notification);
|
||||
ReflectionHelpers.setStaticField(ApplicationsState.class, "sInstance", mState);
|
||||
when(mState.newSession(any())).thenReturn(mSession);
|
||||
when(mState.getBackgroundLooper()).thenReturn(Looper.myLooper());
|
||||
@@ -100,6 +104,18 @@ public class ManageApplicationsTest {
|
||||
assertThat(mMenu.findItem(R.id.reset_app_preferences).isVisible()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateMenu_hideNotificationOptions() {
|
||||
setUpOptionMenus();
|
||||
ReflectionHelpers.setField(mFragment, "mListType", LIST_TYPE_NOTIFICATION);
|
||||
ReflectionHelpers.setField(mFragment, "mOptionsMenu", mMenu);
|
||||
|
||||
mFragment.updateOptionsMenu();
|
||||
assertThat(mMenu.findItem(R.id.sort_order_recent_notification).isVisible()).isFalse();
|
||||
assertThat(mMenu.findItem(R.id.sort_order_frequent_notification).isVisible()).isFalse();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void onCreateView_shouldNotShowLoadingContainer() {
|
||||
final ManageApplications fragment = spy(new ManageApplications());
|
||||
@@ -220,6 +236,12 @@ public class ManageApplicationsTest {
|
||||
if (id == mAppReset.getItemId()) {
|
||||
return mAppReset;
|
||||
}
|
||||
if (id == mSortFrequent.getItemId()) {
|
||||
return mSortFrequent;
|
||||
}
|
||||
if (id == mSortRecent.getItemId()) {
|
||||
return mSortRecent;
|
||||
}
|
||||
return new RoboMenuItem(id);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package com.android.settings.bluetooth;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.anyBoolean;
|
||||
import static org.mockito.Mockito.mock;
|
||||
@@ -36,11 +37,11 @@ import android.view.View;
|
||||
import android.widget.Switch;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.bluetooth.BluetoothSwitchPreferenceController.SwitchController;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
import com.android.settings.testutils.shadow.SettingsShadowResources;
|
||||
import com.android.settings.widget.MasterSwitchController;
|
||||
import com.android.settings.widget.MasterSwitchPreference;
|
||||
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
|
||||
import com.android.settingslib.RestrictedSwitchPreference;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothManager;
|
||||
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
|
||||
@@ -60,6 +61,8 @@ import org.robolectric.annotation.Config;
|
||||
public class BluetoothEnablerTest {
|
||||
|
||||
private static EnforcedAdmin sFakeEnforcedAdmin;
|
||||
private PreferenceViewHolder mHolder;
|
||||
private RestrictedSwitchPreference mRestrictedSwitchPreference;
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeClass() {
|
||||
@@ -76,8 +79,7 @@ public class BluetoothEnablerTest {
|
||||
private LocalBluetoothAdapter mBluetoothAdapter;
|
||||
|
||||
private Context mContext;
|
||||
private Switch mSwitch;
|
||||
private MasterSwitchController mMasterSwitchController;
|
||||
private SwitchController mSwitchController;
|
||||
private BluetoothEnabler mBluetoothEnabler;
|
||||
|
||||
@Before
|
||||
@@ -86,19 +88,17 @@ public class BluetoothEnablerTest {
|
||||
mContext = spy(RuntimeEnvironment.application);
|
||||
when(mBluetoothManager.getBluetoothAdapter()).thenReturn(mBluetoothAdapter);
|
||||
|
||||
mSwitch = new Switch(mContext);
|
||||
MasterSwitchPreference masterSwitchPreference = new MasterSwitchPreference(mContext);
|
||||
mMasterSwitchController = spy(new MasterSwitchController(masterSwitchPreference));
|
||||
mRestrictedSwitchPreference = new RestrictedSwitchPreference(mContext);
|
||||
mSwitchController = spy(new SwitchController(mRestrictedSwitchPreference));
|
||||
mBluetoothEnabler = new BluetoothEnabler(
|
||||
mContext,
|
||||
mMasterSwitchController,
|
||||
mSwitchController,
|
||||
mMetricsFeatureProvider,
|
||||
mBluetoothManager,
|
||||
123,
|
||||
mRestrictionUtils);
|
||||
PreferenceViewHolder holder = PreferenceViewHolder.createInstanceForTests(mock(View.class));
|
||||
when(holder.findViewById(R.id.switchWidget)).thenReturn(mSwitch);
|
||||
masterSwitchPreference.onBindViewHolder(holder);
|
||||
mHolder = PreferenceViewHolder.createInstanceForTests(mock(View.class));
|
||||
mRestrictedSwitchPreference.onBindViewHolder(mHolder);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -121,9 +121,9 @@ public class BluetoothEnablerTest {
|
||||
assertThat(mBluetoothEnabler.maybeEnforceRestrictions()).isFalse();
|
||||
|
||||
// THEN a null EnfoceAdmin is set.
|
||||
verify(mMasterSwitchController).setDisabledByAdmin(null);
|
||||
verify(mSwitchController).setDisabledByAdmin(null);
|
||||
// THEN the state of the switch isn't changed.
|
||||
verify(mMasterSwitchController, never()).setChecked(anyBoolean());
|
||||
verify(mSwitchController, never()).setChecked(anyBoolean());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -139,10 +139,10 @@ public class BluetoothEnablerTest {
|
||||
assertThat(mBluetoothEnabler.maybeEnforceRestrictions()).isTrue();
|
||||
|
||||
// THEN the expected EnfoceAdmin is set.
|
||||
verify(mMasterSwitchController).setDisabledByAdmin(sFakeEnforcedAdmin);
|
||||
verify(mSwitchController).setDisabledByAdmin(sFakeEnforcedAdmin);
|
||||
|
||||
// THEN the switch is unchecked.
|
||||
verify(mMasterSwitchController).setChecked(false);
|
||||
verify(mSwitchController).setChecked(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -158,10 +158,10 @@ public class BluetoothEnablerTest {
|
||||
assertThat(mBluetoothEnabler.maybeEnforceRestrictions()).isTrue();
|
||||
|
||||
// THEN the expected EnfoceAdmin is set.
|
||||
verify(mMasterSwitchController).setDisabledByAdmin(sFakeEnforcedAdmin);
|
||||
verify(mSwitchController).setDisabledByAdmin(sFakeEnforcedAdmin);
|
||||
|
||||
// THEN the switch is unchecked.
|
||||
verify(mMasterSwitchController).setChecked(false);
|
||||
verify(mSwitchController).setChecked(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -174,37 +174,36 @@ public class BluetoothEnablerTest {
|
||||
|
||||
mBluetoothEnabler.resume(mContext);
|
||||
|
||||
verify(mMasterSwitchController, never()).setEnabled(true);
|
||||
verify(mSwitchController, never()).setEnabled(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void startWithBluetoothOff_switchIsOff() {
|
||||
when(mBluetoothAdapter.getBluetoothState()).thenReturn(BluetoothAdapter.STATE_OFF);
|
||||
verify(mMasterSwitchController, never()).setChecked(anyBoolean());
|
||||
verify(mSwitchController, never()).setChecked(anyBoolean());
|
||||
mBluetoothEnabler.resume(mContext);
|
||||
verify(mMasterSwitchController, never()).setChecked(true);
|
||||
verify(mSwitchController, never()).setChecked(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void startWithBluetoothOn_switchIsOn() {
|
||||
when(mBluetoothAdapter.getBluetoothState()).thenReturn(BluetoothAdapter.STATE_ON);
|
||||
verify(mMasterSwitchController, never()).setChecked(anyBoolean());
|
||||
verify(mSwitchController, never()).setChecked(anyBoolean());
|
||||
mBluetoothEnabler.resume(mContext);
|
||||
verify(mMasterSwitchController, never()).setChecked(false);
|
||||
verify(mMasterSwitchController).setChecked(true);
|
||||
verify(mSwitchController, never()).setChecked(false);
|
||||
verify(mSwitchController).setChecked(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bluetoothTurnsOff_switchTurnsOff() {
|
||||
// Start up with bluetooth turned on. The switch should get turned on.
|
||||
assertThat(mSwitch.isChecked()).isFalse();
|
||||
ArgumentCaptor<BroadcastReceiver> captor = ArgumentCaptor.forClass(BroadcastReceiver.class);
|
||||
when(mContext.registerReceiver(captor.capture(), any(IntentFilter.class))).thenReturn(null);
|
||||
when(mBluetoothAdapter.getBluetoothState()).thenReturn(BluetoothAdapter.STATE_ON);
|
||||
verify(mMasterSwitchController, never()).setChecked(anyBoolean());
|
||||
verify(mSwitchController, never()).setChecked(anyBoolean());
|
||||
mBluetoothEnabler.resume(mContext);
|
||||
verify(mMasterSwitchController, never()).setChecked(false);
|
||||
verify(mMasterSwitchController).setChecked(true);
|
||||
verify(mSwitchController, never()).setChecked(false);
|
||||
verify(mSwitchController).setChecked(true);
|
||||
|
||||
// Now simulate bluetooth being turned off via an event.
|
||||
BroadcastReceiver receiver = captor.getValue();
|
||||
@@ -216,20 +215,18 @@ public class BluetoothEnablerTest {
|
||||
receiver.onReceive(mContext, off);
|
||||
|
||||
// Make sure the switch was turned off.
|
||||
verify(mMasterSwitchController).setChecked(false);
|
||||
assertThat(mSwitch.isChecked()).isFalse();
|
||||
verify(mSwitchController).setChecked(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bluetoothTurnsOn_switchTurnsOn() {
|
||||
// Start up with bluetooth turned on. The switch should be left off.
|
||||
assertThat(mSwitch.isChecked()).isFalse();
|
||||
ArgumentCaptor<BroadcastReceiver> captor = ArgumentCaptor.forClass(BroadcastReceiver.class);
|
||||
when(mContext.registerReceiver(captor.capture(), any(IntentFilter.class))).thenReturn(null);
|
||||
when(mBluetoothAdapter.getBluetoothState()).thenReturn(BluetoothAdapter.STATE_OFF);
|
||||
verify(mMasterSwitchController, never()).setChecked(anyBoolean());
|
||||
verify(mSwitchController, never()).setChecked(anyBoolean());
|
||||
mBluetoothEnabler.resume(mContext);
|
||||
verify(mMasterSwitchController, never()).setChecked(anyBoolean());
|
||||
verify(mSwitchController, never()).setChecked(anyBoolean());
|
||||
|
||||
// Now simulate bluetooth being turned on via an event.
|
||||
BroadcastReceiver receiver = captor.getValue();
|
||||
@@ -241,7 +238,6 @@ public class BluetoothEnablerTest {
|
||||
receiver.onReceive(mContext, on);
|
||||
|
||||
// Make sure the switch was turned on.
|
||||
verify(mMasterSwitchController).setChecked(true);
|
||||
assertThat(mSwitch.isChecked()).isTrue();
|
||||
verify(mSwitchController).setChecked(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* 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.bluetooth;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
import android.view.View;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothManager;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.shadows.ShadowAlertDialog;
|
||||
import org.robolectric.util.FragmentTestUtil;
|
||||
import org.robolectric.util.ReflectionHelpers;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
public class LocalDeviceNameDialogFragmentTest {
|
||||
@Mock
|
||||
private LocalBluetoothManager mManager;
|
||||
@Mock
|
||||
private LocalBluetoothAdapter mAdapter;
|
||||
@Mock
|
||||
private InputMethodManager mInputMethodManager;
|
||||
|
||||
private Context mContext;
|
||||
private LocalDeviceNameDialogFragment mFragment;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = spy(RuntimeEnvironment.application);
|
||||
doReturn(mInputMethodManager).when(mContext).getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
ReflectionHelpers.setStaticField(LocalBluetoothManager.class, "sInstance", mManager);
|
||||
when(mManager.getBluetoothAdapter()).thenReturn(mAdapter);
|
||||
|
||||
mFragment = spy(LocalDeviceNameDialogFragment.newInstance());
|
||||
when(mFragment.getContext()).thenReturn(mContext);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void diaglogTriggersShowSoftInput() {
|
||||
FragmentTestUtil.startFragment(mFragment);
|
||||
AlertDialog dialog = ShadowAlertDialog.getLatestAlertDialog();
|
||||
assertThat(dialog).isNotNull();
|
||||
View view = dialog.findViewById(R.id.edittext);
|
||||
verify(mInputMethodManager).showSoftInput(view, InputMethodManager.SHOW_IMPLICIT);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* 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.core;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.v7.preference.SeekBarPreference;
|
||||
|
||||
import com.android.settings.slices.SliceData;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
public class SliderPreferenceControllerTest {
|
||||
|
||||
FakeSlider mSliderController;
|
||||
|
||||
Context mContext;
|
||||
SeekBarPreference mPreference;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mContext = RuntimeEnvironment.application;
|
||||
mPreference = new SeekBarPreference(mContext);
|
||||
mSliderController = new FakeSlider(mContext, "key");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onPreferenceChange_updatesPosition() {
|
||||
final int newValue = 28;
|
||||
|
||||
mSliderController.onPreferenceChange(mPreference, newValue);
|
||||
|
||||
assertThat(mSliderController.getSliderPosition()).isEqualTo(newValue);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_setsPreferenceToCurrentValue() {
|
||||
final int newValue = 28;
|
||||
mSliderController.setSliderPosition(newValue);
|
||||
|
||||
mSliderController.updateState(mPreference);
|
||||
|
||||
assertThat(mPreference.getValue()).isEqualTo(newValue);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSliceType_returnsSliceType() {
|
||||
assertThat(mSliderController.getSliceType()).isEqualTo(
|
||||
SliceData.SliceType.SLIDER);
|
||||
}
|
||||
|
||||
private class FakeSlider extends SliderPreferenceController {
|
||||
|
||||
private final int MAX_STEPS = 2112;
|
||||
private int mPosition;
|
||||
|
||||
public FakeSlider(Context context, String key) {
|
||||
super(context, key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSliderPosition() {
|
||||
return mPosition;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setSliderPosition(int position) {
|
||||
mPosition = position;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxSteps() {
|
||||
return MAX_STEPS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAvailabilityStatus() {
|
||||
return AVAILABLE;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,7 @@ package com.android.settings.dashboard.conditional;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.reset;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
@@ -26,6 +27,7 @@ import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
|
||||
import com.android.settings.testutils.FakeFeatureFactory;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
|
||||
import org.junit.Before;
|
||||
@@ -47,6 +49,7 @@ public class DndConditionTest {
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
FakeFeatureFactory.setupForTest();
|
||||
when(mConditionManager.getContext()).thenReturn(mContext);
|
||||
when(mContext.getPackageManager()).thenReturn(mPackageManager);
|
||||
}
|
||||
@@ -90,4 +93,15 @@ public class DndConditionTest {
|
||||
|
||||
verify(mContext).unregisterReceiver(any(DndCondition.Receiver.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onPause_noReceiverRegistered_shouldNotUnregisterReceiver() {
|
||||
DndCondition condition = new DndCondition(mConditionManager);
|
||||
condition.onPause();
|
||||
reset(mContext);
|
||||
|
||||
condition.onPause();
|
||||
|
||||
verify(mContext, never()).unregisterReceiver(any(DndCondition.Receiver.class));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,12 +16,19 @@
|
||||
|
||||
package com.android.settings.datausage;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.NetworkTemplate;
|
||||
import android.os.Bundle;
|
||||
import android.provider.Settings;
|
||||
|
||||
import com.android.settings.testutils.FakeFeatureFactory;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
@@ -62,10 +69,38 @@ public class DataUsageListTest {
|
||||
mDataUsageList.onAttach(mContext);
|
||||
mDataUsageList.onResume();
|
||||
|
||||
verify(mListener).setListener(true, 0, mContext);
|
||||
verify(mListener).setListener(true, mDataUsageList.mSubId, mContext);
|
||||
|
||||
mDataUsageList.onPause();
|
||||
|
||||
verify(mListener).setListener(false, 0, mContext);
|
||||
verify(mListener).setListener(false, mDataUsageList.mSubId, mContext);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void processArgument_shouldGetTemplateFromArgument() {
|
||||
final Bundle args = new Bundle();
|
||||
args.putParcelable(DataUsageList.EXTRA_NETWORK_TEMPLATE, mock(NetworkTemplate.class));
|
||||
args.putInt(DataUsageList.EXTRA_SUB_ID, 3);
|
||||
mDataUsageList.setArguments(args);
|
||||
|
||||
mDataUsageList.processArgument();
|
||||
|
||||
assertThat(mDataUsageList.mTemplate).isNotNull();
|
||||
assertThat(mDataUsageList.mSubId).isEqualTo(3);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void processArgument_fromIntent_shouldGetTemplateFromIntent() {
|
||||
final Activity activity = mock(Activity.class);
|
||||
final Intent intent = new Intent();
|
||||
intent.putExtra(Settings.EXTRA_NETWORK_TEMPLATE, mock(NetworkTemplate.class));
|
||||
intent.putExtra(Settings.EXTRA_SUB_ID, 3);
|
||||
when(activity.getIntent()).thenReturn(intent);
|
||||
doReturn(activity).when(mDataUsageList).getActivity();
|
||||
|
||||
mDataUsageList.processArgument();
|
||||
|
||||
assertThat(mDataUsageList.mTemplate).isNotNull();
|
||||
assertThat(mDataUsageList.mSubId).isEqualTo(3);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,6 +118,7 @@ public class DevelopmentSettingsDashboardFragmentTest {
|
||||
final Context appContext = RuntimeEnvironment.application;
|
||||
DevelopmentSettingsEnabler.setDevelopmentSettingsEnabled(appContext, true);
|
||||
mShadowUserManager.setIsAdminUser(false);
|
||||
mShadowUserManager.setIsDemoUser(false);
|
||||
|
||||
final List<String> nonIndexableKeys =
|
||||
DevelopmentSettingsDashboardFragment.SEARCH_INDEX_DATA_PROVIDER
|
||||
|
||||
@@ -22,7 +22,6 @@ import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@@ -57,7 +56,6 @@ import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.Shadows;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.shadows.ShadowUserManager;
|
||||
import org.robolectric.util.ReflectionHelpers;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
@Config(shadows = ShadowUtils.class)
|
||||
@@ -84,24 +82,27 @@ public class BuildNumberPreferenceControllerTest {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = RuntimeEnvironment.application;
|
||||
final UserManager userManager =
|
||||
(UserManager) mContext.getSystemService(Context.USER_SERVICE);
|
||||
(UserManager) mContext.getSystemService(Context.USER_SERVICE);
|
||||
mShadowUserManager = Shadows.shadowOf(userManager);
|
||||
mShadowUserManager.setIsAdminUser(true);
|
||||
mFactory = FakeFeatureFactory.setupForTest();
|
||||
mLifecycleOwner = () -> mLifecycle;
|
||||
mLifecycle = new Lifecycle(mLifecycleOwner);
|
||||
mController =
|
||||
new BuildNumberPreferenceController(mContext, mActivity, mFragment, mLifecycle);
|
||||
new BuildNumberPreferenceController(mContext, mActivity, mFragment, mLifecycle);
|
||||
|
||||
mPreference = new Preference(mContext);
|
||||
mPreference.setKey(mController.getPreferenceKey());
|
||||
DevelopmentSettingsEnabler.setDevelopmentSettingsEnabled(mContext, false);
|
||||
Settings.Global.putInt(mContext.getContentResolver(),
|
||||
Settings.Global.DEVICE_PROVISIONED, 1);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
ShadowUtils.reset();
|
||||
mShadowUserManager.setIsAdminUser(false);
|
||||
mShadowUserManager.setIsDemoUser(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -119,20 +120,36 @@ public class BuildNumberPreferenceControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handlePrefTreeClick_notAdminUser_doNothing() {
|
||||
public void handlePrefTreeClick_notAdminUser_notDemoUser_doNothing() {
|
||||
mShadowUserManager.setIsAdminUser(false);
|
||||
mShadowUserManager.setIsDemoUser(false);
|
||||
|
||||
assertThat(mController.handlePreferenceTreeClick(mPreference)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handlePrefTreeClick_deviceNotProvisioned_doNothing() {
|
||||
final Context context = RuntimeEnvironment.application;
|
||||
Settings.Global.putInt(context.getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 0);
|
||||
public void handlePrefTreeClick_isAdminUser_notDemoUser_handleBuildNumberPref() {
|
||||
mShadowUserManager.setIsAdminUser(true);
|
||||
mShadowUserManager.setIsDemoUser(false);
|
||||
|
||||
mController =
|
||||
new BuildNumberPreferenceController(context, mActivity, mFragment, mLifecycle);
|
||||
ReflectionHelpers.setField(mController, "mContext", context);
|
||||
assertThat(mController.handlePreferenceTreeClick(mPreference)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handlePrefTreeClick_notAdminUser_isDemoUser_handleBuildNumberPref() {
|
||||
mShadowUserManager.setIsAdminUser(false);
|
||||
mShadowUserManager.setIsDemoUser(true);
|
||||
|
||||
assertThat(mController.handlePreferenceTreeClick(mPreference)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handlePrefTreeClick_deviceNotProvisioned_doNothing() {
|
||||
mShadowUserManager.setIsAdminUser(true);
|
||||
mShadowUserManager.setIsDemoUser(false);
|
||||
|
||||
Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.DEVICE_PROVISIONED,
|
||||
0);
|
||||
|
||||
assertThat(mController.handlePreferenceTreeClick(mPreference)).isFalse();
|
||||
verify(mFactory.metricsFeatureProvider).action(
|
||||
@@ -142,26 +159,17 @@ public class BuildNumberPreferenceControllerTest {
|
||||
|
||||
@Test
|
||||
public void handlePrefTreeClick_isMonkeyRun_doNothing() {
|
||||
final Context context = spy(RuntimeEnvironment.application);
|
||||
Settings.Global.putInt(context.getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 1);
|
||||
ShadowUtils.setIsUserAMonkey(true);
|
||||
mController =
|
||||
new BuildNumberPreferenceController(context, mActivity, mFragment, mLifecycle);
|
||||
|
||||
assertThat(mController.handlePreferenceTreeClick(mPreference)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handlePrefTreeClick_userHasRestriction_doNothing() {
|
||||
final Context context = spy(RuntimeEnvironment.application);
|
||||
Settings.Global.putInt(context.getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 1);
|
||||
mShadowUserManager.setIsAdminUser(true);
|
||||
mShadowUserManager.setIsDemoUser(false);
|
||||
|
||||
mShadowUserManager.setUserRestriction(Process.myUserHandle(),
|
||||
UserManager.DISALLOW_DEBUGGING_FEATURES, true);
|
||||
|
||||
mController =
|
||||
new BuildNumberPreferenceController(mContext, mActivity, mFragment, mLifecycle);
|
||||
ReflectionHelpers.setField(mController, "mContext", context);
|
||||
UserManager.DISALLOW_DEBUGGING_FEATURES, true);
|
||||
|
||||
assertThat(mController.handlePreferenceTreeClick(mPreference)).isFalse();
|
||||
verify(mFactory.metricsFeatureProvider).action(
|
||||
@@ -197,7 +205,7 @@ public class BuildNumberPreferenceControllerTest {
|
||||
.thenReturn(mock(DatabaseIndexingManager.class));
|
||||
|
||||
mController =
|
||||
new BuildNumberPreferenceController(mContext, mActivity, mFragment, mLifecycle);
|
||||
new BuildNumberPreferenceController(mContext, mActivity, mFragment, mLifecycle);
|
||||
|
||||
final boolean activityResultHandled = mController.onActivityResult(
|
||||
BuildNumberPreferenceController.REQUEST_CONFIRM_PASSWORD_FOR_DEV_PREF,
|
||||
|
||||
@@ -73,13 +73,15 @@ public class ColorModePreferenceFragmentTest {
|
||||
when(mFragment.getContext()).thenReturn(RuntimeEnvironment.application);
|
||||
List<? extends CandidateInfo> candidates = mFragment.getCandidates();
|
||||
|
||||
assertThat(candidates.size()).isEqualTo(3);
|
||||
assertThat(candidates.size()).isEqualTo(4);
|
||||
assertThat(candidates.get(0).getKey())
|
||||
.isEqualTo(ColorModePreferenceFragment.KEY_COLOR_MODE_NATURAL);
|
||||
assertThat(candidates.get(1).getKey())
|
||||
.isEqualTo(ColorModePreferenceFragment.KEY_COLOR_MODE_BOOSTED);
|
||||
assertThat(candidates.get(2).getKey())
|
||||
.isEqualTo(ColorModePreferenceFragment.KEY_COLOR_MODE_SATURATED);
|
||||
assertThat(candidates.get(3).getKey())
|
||||
.isEqualTo(ColorModePreferenceFragment.KEY_COLOR_MODE_AUTOMATIC);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user