Snap for 4719555 from cc9c84646c to qt-release

Change-Id: I4576bbf11db19c73d6eb707e0446117ae8e70e4c
This commit is contained in:
android-build-team Robot
2018-04-13 09:38:41 +00:00
144 changed files with 3071 additions and 727 deletions

View File

@@ -207,6 +207,8 @@
android:value="com.android.settings.category.ia.homepage"/>
<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/action/toggle_bluetooth_switch" />
</activity>
<activity android:name="AirplaneModeVoiceActivity"
@@ -700,6 +702,7 @@
</activity>
<activity android:name=".inputmethod.UserDictionaryAddWordActivity"
android:visibleToInstantApps="true"
android:label="@string/user_dict_settings_title"
android:theme="@*android:style/Theme.DeviceDefault.Settings.Dialog.NoActionBar"
android:windowSoftInputMode="stateVisible"
@@ -742,12 +745,30 @@
android:exported="true"
android:taskAffinity="com.android.settings"
android:parentActivityName="Settings">
<intent-filter android:priority="1">
<action android:name="android.settings.ZEN_MODE_BLOCKED_EFFECTS_SETTINGS" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<meta-data android:name="com.android.settings.FRAGMENT_CLASS"
android:value="com.android.settings.notification.ZenModeBlockedEffectsSettings" />
<meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
android:value="true" />
</activity>
<activity
android:name=".notification.ZenOnboardingActivity"
android:label="@string/zen_onboarding_dnd_visual_disturbances_header"
android:icon="@drawable/ic_settings_notifications"
android:theme="@style/Theme.Settings.NoActionBar"
android:exported="true"
android:taskAffinity="com.android.settings"
android:parentActivityName="Settings">
<intent-filter android:priority="1">
<action android:name="android.settings.ZEN_MODE_ONBOARDING" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity
android:name="Settings$ZenModeBehaviorSettingsActivity"
android:label="@string/zen_mode_behavior_settings_title"
@@ -771,7 +792,7 @@
android:icon="@drawable/ic_settings_notifications"
android:exported="true"
android:taskAffinity="com.android.settings"
android:parentActivityName="Settings">
android:parentActivityName="Settings$ZenModeSettingsActivity">
<intent-filter android:priority="1">
<action android:name="android.settings.ZEN_MODE_AUTOMATION_SETTINGS" />
<category android:name="android.intent.category.DEFAULT" />
@@ -834,7 +855,7 @@
android:name="Settings$ZenModeScheduleRuleSettingsActivity"
android:exported="true"
android:taskAffinity="com.android.settings"
android:parentActivityName="Settings">
android:parentActivityName="Settings$ZenModeAutomationSettingsActivity">
<intent-filter android:priority="1">
<action android:name="android.settings.ZEN_MODE_SCHEDULE_RULE_SETTINGS" />
<category android:name="android.intent.category.DEFAULT" />
@@ -853,7 +874,7 @@
android:name="Settings$ZenModeEventRuleSettingsActivity"
android:exported="true"
android:taskAffinity="com.android.settings"
android:parentActivityName="Settings">
android:parentActivityName="Settings$ZenModeAutomationSettingsActivity">
<intent-filter android:priority="1">
<action android:name="android.settings.ZEN_MODE_EVENT_RULE_SETTINGS" />
<category android:name="android.intent.category.DEFAULT" />
@@ -2216,6 +2237,8 @@
android:value="com.android.settings.category.ia.homepage" />
<meta-data android:name="com.android.settings.FRAGMENT_CLASS"
android:value="com.android.settings.fuelgauge.PowerUsageSummary" />
<meta-data android:name="android.metadata.SLICE_URI"
android:value="content://android.settings.slices/action/auto_brightness" />
</activity>
<activity
@@ -2232,6 +2255,8 @@
android:value="com.android.settings.fuelgauge.batterysaver.BatterySaverSettings" />
<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/action/battery_saver_summary" />
</activity>
<activity android:name=".fuelgauge.BatterySaverModeVoiceActivity"
@@ -2614,6 +2639,8 @@
</intent-filter>
<meta-data android:name="com.android.settings.category"
android:value="com.android.settings.category.ia.apps"/>
<meta-data android:name="com.android.settings.summary"
android:resource="@string/summary_empty"/>
<meta-data android:name="com.android.settings.FRAGMENT_CLASS"
android:value="com.android.settings.notification.ConfigureNotificationSettings" />
<meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
@@ -2651,6 +2678,8 @@
android:value="true" />
<meta-data android:name="com.android.settings.summary"
android:resource="@string/sound_dashboard_summary"/>
<meta-data android:name="android.metadata.SLICE_URI"
android:value="content://android.settings.slices/action/alarm_volume" />
</activity>
<!-- Show apps for which application-level notification settings are applicable -->

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

View File

@@ -0,0 +1,29 @@
<!--
Copyright 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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:viewportWidth="24"
android:viewportHeight="24"
android:width="24dp"
android:height="24dp">
<path android:fillColor="#FF000000"
android:pathData="M3 6h18V4H3C1.9 4 1 4.9 1 6v12c0 1.10.9 2 2 2h4v-2H3V6z M13 12H9
v1.78C8.39 14.33 8 15.11 8 16c0 0.89 0.39 1.67 1 2.22 V20h4v-1.78c0.61-0.55 1-1.34
1-2.22s-0.39-1.67-1-2.22V12z M11 17.5c-0.83 0-1.5-0.67-1.5-1.5s0.67-1.5 1.5-1.5s1.5
0.67 1.5 1.5 S11.83 17.5 11 17.5z M22 8h-6c-0.5 0-1 0.5-1 1v10c0 0.5 0.5 1 1
1h6c0.5 0 1-0.5 1-1V9C23 8.5 22.5 8 22 8z M21 18h-4v-8h4V18z" />
<path android:fillColor="#00000000"
android:pathData="M0 0h24v24H0V0z"/>
</vector>

View File

@@ -120,6 +120,14 @@
android:clipToPadding="false"
android:orientation="horizontal">
<!-- 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 / top button: skip, or re-try -->
<Button android:id="@+id/footerLeftButton"
style="@style/SetupWizardButton.Negative"

View File

@@ -16,9 +16,9 @@
-->
<!-- TODO: Use aapt:attr when it is fixed (b/36809755) -->
<LinearLayout
<com.android.setupwizardlib.view.ButtonBarLayout
xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/SuwGlifButtonBar"
style="@style/SuwGlifButtonBar.Stackable"
android:layout_width="match_parent"
android:layout_height="wrap_content">
@@ -49,4 +49,4 @@
android:layout_height="wrap_content"
android:text="@string/lockpattern_tutorial_continue_label" />
</LinearLayout>
</com.android.setupwizardlib.view.ButtonBarLayout>

View File

@@ -16,8 +16,9 @@
-->
<!-- TODO: Use aapt:attr when it is fixed (b/36809755) -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/SuwGlifButtonBar"
<com.android.setupwizardlib.view.ButtonBarLayout
xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/SuwGlifButtonBar.Stackable"
android:layout_width="match_parent"
android:layout_height="wrap_content">
@@ -40,4 +41,4 @@
android:layout_height="wrap_content"
android:text="@string/security_settings_fingerprint_enroll_done" />
</LinearLayout>
</com.android.setupwizardlib.view.ButtonBarLayout>

View File

@@ -16,8 +16,9 @@
-->
<!-- TODO: Use aapt:attr when it is fixed (b/36809755) -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/SuwGlifButtonBar"
<com.android.setupwizardlib.view.ButtonBarLayout
xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/SuwGlifButtonBar.Stackable"
android:layout_width="match_parent"
android:layout_height="wrap_content">
@@ -40,4 +41,4 @@
android:layout_height="wrap_content"
android:text="@string/suw_next_button_label" />
</LinearLayout>
</com.android.setupwizardlib.view.ButtonBarLayout>

View File

@@ -95,8 +95,8 @@
android:id="@android:id/widget_frame"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="end|center_vertical"
android:paddingStart="16dp"
android:gravity="center"
android:minWidth="64dp"
android:orientation="vertical" />
</LinearLayout>

View File

@@ -56,7 +56,7 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:paddingStart="16dp"
android:paddingStart="12dp"
android:singleLine="true"
android:textAppearance="@android:style/TextAppearance.Material.Subhead"
android:textColor="?android:attr/textColorPrimary"
@@ -68,7 +68,7 @@
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="end|center_vertical"
android:paddingStart="16dp"
android:paddingStart="12dp"
android:orientation="vertical"/>
</LinearLayout>
@@ -80,6 +80,7 @@
<SeekBar
android:id="@*android:id/seekbar"
android:layout_gravity="center_vertical"
android:paddingStart="12dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
@@ -87,7 +88,7 @@
android:id="@+id/suppression_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="16dp"
android:paddingStart="12dp"
android:layout_gravity="center_vertical|start"
android:textAlignment="viewStart"
android:singleLine="true"

View File

@@ -0,0 +1,167 @@
<?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.
-->
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="20dp">
<ImageView
android:id="@+id/header_icon"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:src="@drawable/ic_zen"
android:tint="?android:attr/colorAccent"/>
<TextView
android:id="@+id/header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/header_icon"
android:layout_centerHorizontal="true"
android:layout_marginTop="12dp"
android:text="@string/zen_onboarding_dnd_visual_disturbances_header"
android:textAppearance="@android:style/TextAppearance.Material.Headline" />
<TextView
android:id="@+id/feature_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/header"
android:layout_centerHorizontal="true"
android:textAlignment="center"
android:layout_marginTop="14dp"
android:textAppearance="?android:attr/textAppearanceListItem"
android:text="@string/zen_onboarding_dnd_visual_disturbances_description" />
<LinearLayout
android:id="@+id/screen_off"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/feature_description"
android:layout_centerHorizontal="true"
android:layout_marginTop="35dp"
android:orientation="horizontal">
<CheckBox
android:id="@+id/screen_off_option"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingHorizontal="8dp"
android:onClick="logClick" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/screen_off_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/zen_onboarding_screen_off_title"
android:textAppearance="?android:attr/textAppearanceListItem" />
<TextView
android:id="@+id/screen_off_summary"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/zen_onboarding_screen_off_summary" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/screen_on"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/screen_off"
android:layout_centerHorizontal="true"
android:layout_marginTop="10dp"
android:orientation="horizontal">
<CheckBox
android:id="@+id/screen_on_option"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingHorizontal="8dp"
android:onClick="logClick" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/screen_on_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/zen_onboarding_screen_off_title"
android:textAppearance="?android:attr/textAppearanceListItem" />
<TextView
android:id="@+id/screen_on_summary"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/zen_onboarding_screen_on_summary" />
</LinearLayout>
</LinearLayout>
<TextView
android:id="@+id/further_customize"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/screen_on"
android:layout_centerHorizontal="true"
android:layout_marginTop="20dp"
android:textAppearance="?android:attr/textAppearanceListItem"
android:text="@string/zen_onboarding_more_options" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/further_customize"
android:layout_marginTop="35dp"
android:id="@+id/buttons">
<TextView
android:id="@+id/settings"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_weight="1"
android:layout_centerInParent="true"
android:text="@string/zen_onboarding_settings"
android:textAppearance="?android:attr/textAppearanceListItem"
android:textColor="?android:attr/colorControlActivated"
android:onClick="launchSettings" />
<Button
android:id="@+id/ok"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_weight="1"
android:layout_centerInParent="true"
android:text="@string/zen_onboarding_ok"
style="@style/ActionPrimaryButton"
android:onClick="save" />
</RelativeLayout>
</RelativeLayout>

View File

View File

Binary file not shown.

View File

@@ -778,10 +778,10 @@
<string name="zone_time_type_dst">Daylight savings time</string>
<!-- Describes the time type "standard time" (used in zone_change_to_from_dst, when no zone specific name is available) -->
<string name="zone_time_type_standard">Standard time</string>
<!-- The menu item to switch to selecting a time zone by region (default) -->
<string name="zone_menu_by_region">Show time zones by region</string>
<!-- The menu item to switch to selecting a time zone with a fixed offset (such as UTC or GMT+0200) -->
<string name="zone_menu_by_offset">Show time zones by UTC offset</string>
<!-- The menu item to switch to selecting a time zone by region (default) [CHAR LIMIT=30] -->
<string name="zone_menu_by_region">Select by region</string>
<!-- The menu item to switch to selecting a time zone with a fixed offset (such as UTC or GMT+0200) [CHAR LIMIT=30] -->
<string name="zone_menu_by_offset">Select by UTC offset</string>
<!-- Title string shown above DatePicker, letting a user select system date
[CHAR LIMIT=20] -->
@@ -1584,7 +1584,7 @@
<!-- Bluetooth settings: The sub heading for devices which have already been paired with this device. [CHAR LIMIT=40] -->
<string name="bluetooth_preference_paired_devices">Paired devices</string>
<!-- Bluetooth settings: The sub heading for available devices during and after scanning. [CHAR LIMIT=40] -->
<string name="bluetooth_preference_found_media_devices">Available media devices</string>
<string name="bluetooth_preference_found_media_devices">Available devices</string>
<!-- Bluetooth settings: The message displayed if no Bluetooth devices were found. [CHAR LIMIT=40] -->
<string name="bluetooth_preference_no_found_devices">No devices available</string>
<!-- Bluetooth settings. Context menu item for a device. Action will connect to all profiles on the device. -->
@@ -4891,10 +4891,6 @@
<string name="background_activity_title">Background restriction</string>
<!-- Summary for the background activity [CHAR_LIMIT=120] -->
<string name="background_activity_summary">Allow the app to run in the background</string>
<!-- Summary for the background activity when it is on [CHAR_LIMIT=120] -->
<string name="background_activity_summary_on">App can run in the background when not in use</string>
<!-- Summary for the background activity when it is off [CHAR_LIMIT=120] -->
<string name="background_activity_summary_off">App\'s background activity is limited when not in use</string>
<!-- Summary for the background activity when it is disabled [CHAR_LIMIT=120] -->
<string name="background_activity_summary_disabled">App not allowed to run in background</string>
<!-- TODO: Pending UX review. Summary for the background activity when it is whitlisted [CHAR_LIMIT=120] -->
@@ -5015,11 +5011,11 @@
<!-- Summary for the battery high usage tip, which presents battery may run out soon [CHAR LIMIT=NONE] -->
<string name="battery_tip_high_usage_summary">Battery may run out soon</string>
<!-- Message for battery tip dialog to show the status about the battery [CHAR LIMIT=NONE] -->
<string name="battery_tip_dialog_message" product="default">Your phone has been used more than usual. Your battery may run out sooner than expected.\n\nTop <xliff:g id="number">%1$d</xliff:g> apps since last charge:</string>
<string name="battery_tip_dialog_message" product="default">Your phone has been used more than usual. Your battery may run out sooner than expected.\n\nTop <xliff:g id="number">%1$d</xliff:g> apps since last full charge(<xliff:g id="time_period_ago" example="1 hr ago">%2$s</xliff:g>):</string>
<!-- Message for battery tip dialog to show the status about the battery [CHAR LIMIT=NONE] -->
<string name="battery_tip_dialog_message" product="tablet">Your tablet has been used more than usual. Your battery may run out sooner than expected.\n\nTop <xliff:g id="number">%1$d</xliff:g> apps since last charge:</string>
<string name="battery_tip_dialog_message" product="tablet">Your tablet has been used more than usual. Your battery may run out sooner than expected.\n\nTop <xliff:g id="number">%1$d</xliff:g> apps since last full charge(<xliff:g id="time_period_ago" example="1 hr ago">%2$s</xliff:g>):</string>
<!-- Message for battery tip dialog to show the status about the battery [CHAR LIMIT=NONE] -->
<string name="battery_tip_dialog_message" product="device">Your device has been used more than usual. Your battery may run out sooner than expected.\n\nTop <xliff:g id="number">%1$d</xliff:g> apps since last charge:</string>
<string name="battery_tip_dialog_message" product="device">Your device has been used more than usual. Your battery may run out sooner than expected.\n\nTop <xliff:g id="number">%1$d</xliff:g> apps since last full charge(<xliff:g id="time_period_ago" example="1 hr ago">%2$s</xliff:g>):</string>
<!-- Title for restricted app preference, showing how many app need to be restricted [CHAR LIMIT=NONE] -->
<plurals name="battery_tip_restrict_title">
<item quantity="one">Restrict %1$d app</item>
@@ -5089,7 +5085,7 @@
</plurals>
<!-- Footer message for restrict app details page -->
<string name="restricted_app_detail_footer">Apps shown here aren\'t behaving properly and have been using battery in the background.\n\nThese apps are now blocked from using battery in the background. As a result, some app notifications may be delayed.</string>
<string name="restricted_app_detail_footer">These apps have been using battery in the background. Restricted apps may not work properly and notifications may be delayed.</string>
<!-- Title for auto restriction toggle -->
<string name="battery_auto_restriction_title">Use Battery Manager</string>
@@ -5916,10 +5912,6 @@
<string name="really_remove_account_message" product="device">Removing this account will delete all of its messages, contacts, and other data from the device!</string>
<!-- This is shown if the autheticator for a given account fails to remove it. [CHAR LIMIT=NONE] -->
<string name="remove_account_failed">This change isn\'t allowed by your admin</string>
<!-- What to show in messaging that refers to this provider, e.g. AccountSyncSettings -->
<string name="provider_label">Push subscriptions</string>
<!-- Formatter in AccountSyncSettings for each application we wish to synchronize, e.g. "Sync Calendar" -->
<string name="sync_item_title"><xliff:g id="authority" example="Calendar">%s</xliff:g></string>
<!-- Title of dialog shown when you can't manually sync an item because it's disabled -->
<string name="cant_sync_dialog_title">Can\u2019t manually sync</string>
<!-- Messaage shown in dialog when you can't manually sync -->
@@ -6660,6 +6652,10 @@
<string name="help_url_font_size" translatable="false"></string>
<!-- Help URL, Display size [DO NOT TRANSLATE] -->
<string name="help_url_display_size" translatable="false"></string>
<!-- Help URL, Auto brightness [DO NOT TRANSLATE] -->
<string name="help_url_auto_brightness" translatable="false" />
<!-- Help URL, Previously connected bluetooth devices [DO NOT TRANSLATE] -->
<string name="help_url_previously_connected_devices" translatable="false"></string>
<string name="help_url_network_dashboard" translatable="false"></string>
<string name="help_url_connected_devices" translatable="false"></string>
@@ -7230,7 +7226,7 @@
<!-- Do not disturb: what to block option [CHAR LIMIT=NONE] -->
<string name="zen_mode_block_effect_badge">Hide notification dots</string>
<!-- Do not disturb: what to block option [CHAR LIMIT=NONE] -->
<string name="zen_mode_block_effect_ambient">Hide from ambient display</string>
<string name="zen_mode_block_effect_ambient">Don\'t wake for notifications</string>
<!-- Do not disturb: what to block option [CHAR LIMIT=NONE] -->
<string name="zen_mode_block_effect_list">Hide from notification list</string>
@@ -7317,6 +7313,16 @@
<item quantity="other"><xliff:g id="on_count" example="3">%d</xliff:g> rules can turn on automatically</item>
</plurals>
<string name="zen_onboarding_ok">Ok</string>
<string name="zen_onboarding_settings">Settings</string>
<string name="zen_onboarding_more_options">You can further customize this in Settings.</string>
<string name="zen_onboarding_screen_on_title">Block when the screen is on</string>
<string name="zen_onboarding_screen_off_title">Block when the screen is off</string>
<string name="zen_onboarding_dnd_visual_disturbances_description">Do Not Disturb can do more than block unwanted sounds - it can block visuals too. This may be helpful if you\'re trying to sleep, focus, or limit time spent on your phone.</string>
<string name="zen_onboarding_dnd_visual_disturbances_header">Block sounds and visuals</string>
<string name="zen_onboarding_screen_off_summary">Don\'t turn on the screen or wake for notifications</string>
<string name="zen_onboarding_screen_on_summary">Don\'t show notifications at all, except for basic phone activity and status</string>
<!-- Work Sounds: Work sound settings section header. [CHAR LIMIT=50] -->
<string name="sound_work_settings">Work profile sounds</string>
@@ -7507,9 +7513,9 @@
<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>
<string name="notifications_sent_daily">~<xliff:g id="number">%1$s</xliff:g> per day</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>
<string name="notifications_sent_weekly">~<xliff:g id="number">%1$s</xliff:g> per week</string>
<!-- app summary of notification app list screen [CHAR LIMIT=100] -->
<string name="notifications_sent_never">Never</string>
@@ -7633,11 +7639,11 @@
<string name="app_settings_link">Additional settings in the app</string>
<!-- [CHAR LIMIT=45] App notification listing summary, blocked apps -->
<string name="app_notification_listing_summary_zero">Turned on for all apps</string>
<string name="app_notification_listing_summary_zero">On for all apps</string>
<!-- [CHAR LIMIT=45] App notification listing summary, blocked apps -->
<plurals name="app_notification_listing_summary_others">
<item quantity="one">Turned off for <xliff:g id="count" example="1">%d</xliff:g> app</item>
<item quantity="other">Turned off for <xliff:g id="count" example="10">%d</xliff:g> apps</item>
<item quantity="one">Off for <xliff:g id="count" example="1">%d</xliff:g> app</item>
<item quantity="other">Off for <xliff:g id="count" example="10">%d</xliff:g> apps</item>
</plurals>
<!-- [CHAR LIMIT=NONE] Footer listing a count of deleted channels. -->
@@ -8006,7 +8012,7 @@
<string name="encryption_interstitial_no">No</string>
<!-- Label to say yes to the question of whether app is restricted. [CHAR LIMIT=20] -->
<string name="restricted_true_label">App can\u2019t use battery in background</string>
<string name="restricted_true_label">Restricted</string>
<!-- Label to say no to the question of whether app is restricted. [CHAR LIMIT=20] -->
<string name="restricted_false_label">App can use battery in background</string>
@@ -9861,6 +9867,8 @@
<string name="gesture_prevent_ringing_screen_title">Prevent ringing</string>
<!-- Title for prevent ringing setting -->
<string name="gesture_prevent_ringing_title">Press Power &amp; Volume Up together</string>
<!-- Title for prevent ringing setting -->
<string name="gesture_prevent_ringing_sound_title">Shortcut to prevent ringing</string>
<!-- Option for prevent ringing setting -->
<string name="prevent_ringing_option_vibrate">Vibrate</string>
<!-- Option for prevent ringing setting -->
@@ -9868,11 +9876,11 @@
<!-- 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>
<string name="prevent_ringing_option_vibrate_summary">On (vibrate)</string>
<!-- Summary for prevent ringing setting -->
<string name="prevent_ringing_option_mute_summary">Mute all calls and notifications</string>
<string name="prevent_ringing_option_mute_summary">On (mute)</string>
<!-- Summary for prevent ringing setting -->
<string name="prevent_ringing_option_none_summary">Do nothing</string>
<string name="prevent_ringing_option_none_summary">Off</string>
<!-- Title for detail page of wifi network [CHAR LIMIT=30] -->
<string name="pref_title_network_details">Network details</string>

View File

@@ -0,0 +1,38 @@
<?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:settings="http://schemas.android.com/apk/res-auto"
android:key="auto_brightness_detail"
android:title="@string/auto_brightness_title"
settings:keywords="@string/keywords_display_auto_brightness">
<com.android.settings.widget.VideoPreference
android:key="auto_brightness_video"
settings:animation="@raw/aab_brightness"
settings:preview="@drawable/aab_brightness"/>
<!-- Cross-listed item, if you change this, also change it in power_usage_summary.xml -->
<com.android.settingslib.RestrictedSwitchPreference
android:key="auto_brightness"
android:title="@string/auto_brightness_title"
settings:controller="com.android.settings.display.AutoBrightnessPreferenceController"
settings:useAdminDisabledSummary="true"
settings:userRestriction="no_config_brightness" />
</PreferenceScreen>

View File

@@ -24,27 +24,29 @@
android:key="connected_device_list"
android:title="@string/connected_device_connected_title"/>
<PreferenceCategory
android:key="saved_device_list"
android:title="@string/connected_device_saved_title"/>
<com.android.settingslib.RestrictedPreference
android:fragment="com.android.settings.bluetooth.BluetoothPairingDetail"
android:key="add_bt_devices"
android:title="@string/connected_device_add_device_title"
android:icon="@drawable/ic_menu_add"
android:summary="@string/connected_device_add_device_summary"
android:fragment="com.android.settings.bluetooth.BluetoothPairingDetail"
settings:allowDividerAbove="true"
settings:userRestriction="no_config_bluetooth"
settings:useAdminDisabledSummary="true"
settings:controller="com.android.settings.connecteddevice.AddDevicePreferenceController"/>
<Preference
android:key="previously_connected_devices"
android:title="@string/connected_device_previously_connected_title"
android:icon="@drawable/ic_devices_other_black"
android:fragment="com.android.settings.connecteddevice.PreviouslyConnectedDeviceDashboardFragment"
settings:allowDividerAbove="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"
settings:allowDividerAbove="true"
settings:controller="com.android.settings.bluetooth.BluetoothSwitchPreferenceController"
settings:userRestriction="no_bluetooth"
settings:platform_slice="true"/>
@@ -56,7 +58,7 @@
android:summary="@string/nfc_quick_toggle_summary"/>
<Preference
android:fragment="com.android.settings.connecteddevice.AdvancedConnectedDeviceDashboardFragment"
android:key="connection_preferences"
android:title="@string/connected_device_connections_title"/>
android:title="@string/connected_device_connections_title"
android:fragment="com.android.settings.connecteddevice.AdvancedConnectedDeviceDashboardFragment"/>
</PreferenceScreen>

View File

@@ -39,15 +39,12 @@
settings:widgetLayout="@null"
settings:keywords="@string/keywords_display_night_display" />
<!-- Cross-listed item, if you change this, also change it in power_usage_summary.xml -->
<com.android.settingslib.RestrictedSwitchPreference
android:key="auto_brightness"
<Preference
android:key="auto_brightness_entry"
android:title="@string/auto_brightness_title"
android:summary="@string/auto_brightness_summary"
settings:keywords="@string/keywords_display_auto_brightness"
settings:controller="com.android.settings.display.AutoBrightnessPreferenceController"
settings:useAdminDisabledSummary="true"
settings:userRestriction="no_config_brightness" />
android:fragment="com.android.settings.display.AutoBrightnessSettings"
settings:controller="com.android.settings.display.AutoBrightnessPreferenceController" />
<com.android.settingslib.RestrictedPreference
android:key="wallpaper"

View File

@@ -45,6 +45,12 @@
android:fragment="com.android.settings.gestures.DoubleTwistGestureSettings"
settings:controller="com.android.settings.gestures.DoubleTwistPreferenceController" />
<Preference
android:key="gesture_swipe_up_input_summary"
android:title="@string/swipe_up_to_switch_apps_title"
android:fragment="com.android.settings.gestures.SwipeUpGestureSettings"
settings:controller="com.android.settings.gestures.SwipeUpPreferenceController" />
<Preference
android:key="gesture_double_tap_screen_input_summary"
android:title="@string/ambient_display_title"
@@ -60,6 +66,7 @@
<Preference
android:key="gesture_prevent_ringing_summary"
android:title="@string/gesture_prevent_ringing_screen_title"
android:fragment="com.android.settings.gestures.PreventRingingGestureSettings" />
android:fragment="com.android.settings.gestures.PreventRingingGestureSettings"
settings:controller="com.android.settings.gestures.PreventRingingPreferenceController" />
</PreferenceScreen>

View File

@@ -73,6 +73,7 @@
android:icon="@drawable/ic_airplanemode_active"
android:disableDependentsState="true"
android:order="5"
settings:controller="com.android.settings.network.AirplaneModePreferenceController"
settings:userRestriction="no_airplane_mode"/>
<Preference

View File

@@ -21,15 +21,17 @@
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" />
android:key="gesture_prevent_ringing_video"
app:animation="@raw/gesture_prevent_ringing"
app:preview="@drawable/gesture_prevent_ringing" />
<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:controller="com.android.settings.gestures.PreventRingingPreferenceController"
app:keywords="@string/keywords_gesture" />
</PreferenceScreen>

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 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:settings="http://schemas.android.com/apk/res-auto"
android:key="connected_devices_screen_previously"
android:title="@string/connected_device_previously_connected_title">
<PreferenceCategory
android:key="saved_device_list"
settings:controller="com.android.settings.connecteddevice.SavedDeviceGroupController"/>
</PreferenceScreen>

View File

@@ -20,55 +20,65 @@
android:title="@string/sound_settings"
android:key="sound_settings"
settings:keywords="@string/keywords_sounds"
settings:initialExpandedChildrenCount="7">
settings:initialExpandedChildrenCount="8">
<!-- Media volume -->
<com.android.settings.notification.VolumeSeekBarPreference
android:key="media_volume"
android:icon="@*android:drawable/ic_audio_media"
android:title="@string/media_volume_option_title"
settings:controller="com.android.settings.notification.MediaVolumePreferenceController"
android:order="-170"/>
<!-- Alarm volume -->
<com.android.settings.notification.VolumeSeekBarPreference
android:key="alarm_volume"
android:icon="@*android:drawable/ic_audio_alarm"
android:title="@string/alarm_volume_option_title"
settings:controller="com.android.settings.notification.AlarmVolumePreferenceController"
android:order="-160"/>
android:order="-180"
settings:controller="com.android.settings.notification.MediaVolumePreferenceController"/>
<!-- Ring volume -->
<com.android.settings.notification.VolumeSeekBarPreference
android:key="ring_volume"
android:icon="@*android:drawable/ic_audio_ring_notif"
android:title="@string/ring_volume_option_title"
android:order="-170"
settings:controller="com.android.settings.notification.RingVolumePreferenceController"
android:order="-150"/>
settings:allowDividerAbove="true"/>
<!-- Also vibrate for calls -->
<SwitchPreference
android:key="vibrate_when_ringing"
android:title="@string/vibrate_when_ringing_title"
android:order="-160"/>
<!-- Alarm volume -->
<com.android.settings.notification.VolumeSeekBarPreference
android:key="alarm_volume"
android:icon="@*android:drawable/ic_audio_alarm"
android:title="@string/alarm_volume_option_title"
android:order="-150"
settings:allowDividerAbove="true"
settings:controller="com.android.settings.notification.AlarmVolumePreferenceController"/>
<!-- Notification volume -->
<com.android.settings.notification.VolumeSeekBarPreference
android:key="notification_volume"
android:icon="@*android:drawable/ic_audio_ring_notif"
android:title="@string/notification_volume_option_title"
settings:controller="com.android.settings.notification.NotificationVolumePreferenceController"
android:order="-140"/>
<!-- Also vibrate for calls -->
<SwitchPreference
android:key="vibrate_when_ringing"
android:title="@string/vibrate_when_ringing_title"
android:order="-130"/>
android:order="-140"
settings:controller="com.android.settings.notification.NotificationVolumePreferenceController"/>
<!-- Interruptions -->
<com.android.settingslib.RestrictedPreference
android:key="zen_mode"
android:title="@string/zen_mode_settings_title"
android:fragment="com.android.settings.notification.ZenModeSettings"
android:order="-120"
settings:useAdminDisabledSummary="true"
settings:keywords="@string/keywords_sounds_and_notifications_interruptions"
android:fragment="com.android.settings.notification.ZenModeSettings"
settings:allowDividerAbove="true"/>
<Preference
android:key="gesture_prevent_ringing_sound"
android:title="@string/gesture_prevent_ringing_sound_title"
android:order="-110"
android:fragment="com.android.settings.gestures.PreventRingingGestureSettings"
settings:allowDividerAbove="true"
android:order="-120"/>
settings:controller="com.android.settings.gestures.PreventRingingPreferenceController" />
<!-- Phone ringtone -->
<com.android.settings.DefaultRingtonePreference
@@ -77,8 +87,8 @@
android:dialogTitle="@string/ringtone_title"
android:summary="@string/summary_placeholder"
android:ringtoneType="ringtone"
settings:allowDividerAbove="true"
android:order="-100"/>
android:order="-100"
settings:allowDividerAbove="true"/>
<!-- Default notification ringtone -->
<com.android.settings.DefaultRingtonePreference

View File

@@ -0,0 +1,36 @@
<?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_swipe_up_screen"
android:title="@string/swipe_up_to_switch_apps_title">
<com.android.settings.widget.VideoPreference
android:key="gesture_swipe_up_video"
app:animation="@raw/gesture_swipe_up"
app:preview="@drawable/gesture_swipe_up" />
<SwitchPreference
android:key="gesture_swipe_up"
android:title="@string/swipe_up_to_switch_apps_title"
android:summary="@string/swipe_up_to_switch_apps_summary"
app:keywords="@string/keywords_gesture"
app:controller="com.android.settings.gestures.SwipeUpPreferenceController" />
</PreferenceScreen>

View File

@@ -23,10 +23,9 @@
settings:keywords="@string/keywords_zen_mode_settings">
<!-- sound vibration -->
<CheckBoxPreference
<com.android.settings.widget.DisabledCheckBoxPreference
android:key="zen_effect_sound"
android:title="@string/zen_mode_block_effect_sound"
android:enabled="false" />
android:title="@string/zen_mode_block_effect_sound" />
<!-- What to block (effects) -->
<Preference

View File

@@ -24,8 +24,6 @@ import android.os.Message;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.provider.Settings;
import android.support.v14.preference.SwitchPreference;
import android.support.v7.preference.Preference;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.telephony.PhoneStateIntentReceiver;
@@ -33,16 +31,26 @@ import com.android.internal.telephony.TelephonyProperties;
import com.android.settingslib.WirelessUtils;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
public class AirplaneModeEnabler implements Preference.OnPreferenceChangeListener {
public class AirplaneModeEnabler {
private static final int EVENT_SERVICE_STATE_CHANGED = 3;
private final Context mContext;
private final SwitchPreference mSwitchPref;
private final MetricsFeatureProvider mMetricsFeatureProvider;
private PhoneStateIntentReceiver mPhoneStateReceiver;
private OnAirplaneModeChangedListener mOnAirplaneModeChangedListener;
public interface OnAirplaneModeChangedListener {
/**
* Called when airplane mode status is changed.
*
* @param isAirplaneModeOn the airplane mode is on
*/
void onAirplaneModeChanged(boolean isAirplaneModeOn);
}
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
@@ -61,25 +69,19 @@ public class AirplaneModeEnabler implements Preference.OnPreferenceChangeListene
}
};
public AirplaneModeEnabler(Context context, SwitchPreference airplaneModeSwitchPreference,
MetricsFeatureProvider metricsFeatureProvider) {
public AirplaneModeEnabler(Context context, MetricsFeatureProvider metricsFeatureProvider,
OnAirplaneModeChangedListener listener) {
mContext = context;
mSwitchPref = airplaneModeSwitchPreference;
mMetricsFeatureProvider = metricsFeatureProvider;
airplaneModeSwitchPreference.setPersistent(false);
mOnAirplaneModeChangedListener = listener;
mPhoneStateReceiver = new PhoneStateIntentReceiver(mContext, mHandler);
mPhoneStateReceiver.notifyServiceState(EVENT_SERVICE_STATE_CHANGED);
}
public void resume() {
mSwitchPref.setChecked(WirelessUtils.isAirplaneModeOn(mContext));
mPhoneStateReceiver.registerIntent();
mSwitchPref.setOnPreferenceChangeListener(this);
mContext.getContentResolver().registerContentObserver(
Settings.Global.getUriFor(Settings.Global.AIRPLANE_MODE_ON), true,
mAirplaneModeObserver);
@@ -87,7 +89,6 @@ public class AirplaneModeEnabler implements Preference.OnPreferenceChangeListene
public void pause() {
mPhoneStateReceiver.unregisterIntent();
mSwitchPref.setOnPreferenceChangeListener(null);
mContext.getContentResolver().unregisterContentObserver(mAirplaneModeObserver);
}
@@ -95,8 +96,11 @@ public class AirplaneModeEnabler implements Preference.OnPreferenceChangeListene
// Change the system setting
Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON,
enabling ? 1 : 0);
// Update the UI to reflect system setting
mSwitchPref.setChecked(enabling);
// Notify listener the system setting is changed.
if (mOnAirplaneModeChangedListener != null) {
mOnAirplaneModeChangedListener.onAirplaneModeChanged(enabling);
}
// Post the intent
Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
@@ -113,22 +117,20 @@ public class AirplaneModeEnabler implements Preference.OnPreferenceChangeListene
* - mobile does not send failure notification, fail on timeout.
*/
private void onAirplaneModeChanged() {
mSwitchPref.setChecked(WirelessUtils.isAirplaneModeOn(mContext));
if (mOnAirplaneModeChangedListener != null) {
mOnAirplaneModeChangedListener.onAirplaneModeChanged(isAirplaneModeOn());
}
}
/**
* Called when someone clicks on the checkbox preference.
*/
public boolean onPreferenceChange(Preference preference, Object newValue) {
public void setAirplaneMode(boolean isAirplaneModeOn) {
if (Boolean.parseBoolean(
SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE))) {
// In ECM mode, do not update database at this point
} else {
Boolean value = (Boolean) newValue;
mMetricsFeatureProvider.action(mContext, MetricsEvent.ACTION_AIRPLANE_TOGGLE, value);
setAirplaneModeOn(value);
mMetricsFeatureProvider.action(mContext, MetricsEvent.ACTION_AIRPLANE_TOGGLE,
isAirplaneModeOn);
setAirplaneModeOn(isAirplaneModeOn);
}
return true;
}
public void setAirplaneModeInECM(boolean isECMExit, boolean isAirplaneModeOn) {
@@ -141,4 +143,7 @@ public class AirplaneModeEnabler implements Preference.OnPreferenceChangeListene
}
}
public boolean isAirplaneModeOn() {
return WirelessUtils.isAirplaneModeOn(mContext);
}
}

View File

@@ -23,7 +23,6 @@ import com.android.internal.hardware.AmbientDisplayConfiguration;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.display.AmbientDisplayPreferenceController;
import com.android.settings.display.AutoRotatePreferenceController;
import com.android.settings.display.BrightnessLevelPreferenceController;
import com.android.settings.display.CameraGesturePreferenceController;
import com.android.settings.display.ColorModePreferenceController;
@@ -54,7 +53,7 @@ public class DisplaySettings extends DashboardFragment {
private static final String KEY_SCREEN_TIMEOUT = "screen_timeout";
private static final String KEY_AMBIENT_DISPLAY = "ambient_display";
private static final String KEY_AUTO_BRIGHTNESS = "auto_brightness_entry";
private static final String KEY_NIGHT_DISPLAY = "night_display";
@Override
@@ -124,6 +123,7 @@ public class DisplaySettings extends DashboardFragment {
keys.add(KEY_DISPLAY_SIZE);
keys.add(WallpaperPreferenceController.KEY_WALLPAPER);
keys.add(KEY_NIGHT_DISPLAY);
keys.add(KEY_AUTO_BRIGHTNESS);
return keys;
}

View File

@@ -194,25 +194,24 @@ public class AccountSyncSettings extends AccountPreferenceBase {
} else {
item.setup(account, authority, packageName, uid);
}
final PackageManager packageManager = getPackageManager();
item.setPersistent(false);
final ProviderInfo providerInfo = getPackageManager().resolveContentProviderAsUser(
final ProviderInfo providerInfo = packageManager.resolveContentProviderAsUser(
authority, 0, mUserHandle.getIdentifier());
if (providerInfo == null) {
return;
}
CharSequence providerLabel = providerInfo.loadLabel(getPackageManager());
final CharSequence providerLabel = providerInfo.loadLabel(packageManager);
if (TextUtils.isEmpty(providerLabel)) {
Log.e(TAG, "Provider needs a label for authority '" + authority + "'");
return;
}
String title = getString(R.string.sync_item_title, providerLabel);
item.setTitle(title);
item.setTitle(providerLabel);
item.setKey(authority);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
MenuItem syncNow = menu.add(0, MENU_SYNC_NOW_ID, 0,
getString(R.string.sync_menu_sync_now))
.setIcon(R.drawable.ic_menu_refresh_holo_dark);

View File

@@ -21,6 +21,7 @@ import android.app.ActivityManager;
import android.content.Context;
import android.support.v14.preference.SwitchPreference;
import android.support.v7.preference.PreferenceViewHolder;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
@@ -64,6 +65,7 @@ public class SyncStateSwitchPreference extends SwitchPreference {
mAuthority = authority;
mPackageName = packageName;
mUid = uid;
setVisible(!TextUtils.isEmpty(mAuthority));
notifyChanged();
}

View File

@@ -81,11 +81,15 @@ public class AppNotificationPreferenceController extends AppInfoPreferenceContro
if (appRow == null) {
return "";
}
if (appRow.banned || appRow.channelCount == appRow.blockedChannelCount) {
return context.getString(R.string.notifications_disabled);
if (appRow.banned) {
return context.getText(R.string.notifications_disabled);
} else if (appRow.channelCount == 0) {
return context.getText(R.string.notifications_enabled);
} else if (appRow.channelCount == appRow.blockedChannelCount) {
return context.getText(R.string.notifications_disabled);
} else {
if (appRow.blockedChannelCount == 0) {
return context.getString(R.string.notifications_enabled);
return context.getText(R.string.notifications_enabled);
}
return context.getString(R.string.notifications_enabled_with_info,
context.getResources().getQuantityString(R.plurals.notifications_categories_off,

View File

@@ -177,7 +177,8 @@ public class ManageApplications extends InstrumentedFragment
private static final int NO_USER_SPECIFIED = -1;
// sort order
private int mSortOrder = R.id.sort_order_alpha;
@VisibleForTesting
int mSortOrder = R.id.sort_order_alpha;
// whether showing system apps.
private boolean mShowSystem;
@@ -654,9 +655,8 @@ public class ManageApplications extends InstrumentedFragment
switch (item.getItemId()) {
case R.id.sort_order_alpha:
case R.id.sort_order_size:
mSortOrder = menuId;
if (mApplications != null) {
mApplications.rebuild(mSortOrder);
mApplications.rebuild(menuId);
}
break;
case R.id.show_system:
@@ -717,6 +717,7 @@ public class ManageApplications extends InstrumentedFragment
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
mFilter = mFilterAdapter.getFilter(position);
mApplications.setFilter(mFilter);
if (DEBUG) Log.d(TAG, "Selecting filter " + mFilter);
}
@@ -1001,6 +1002,7 @@ public class ManageApplications extends InstrumentedFragment
if (sort == mLastSortMode) {
return;
}
mManageApplications.mSortOrder = sort;
mLastSortMode = sort;
rebuild();
}

View File

@@ -167,7 +167,7 @@ public abstract class BluetoothDeviceUpdater implements BluetoothCallback {
}
@Override
public void onProfileAudioStateChanged(int bluetoothProfile, int state) {
public void onAudioModeChanged() {
}
/**

View File

@@ -81,7 +81,7 @@ public final class BluetoothSummaryUpdater extends SummaryUpdater implements Blu
}
@Override
public void onProfileAudioStateChanged(int bluetoothProfile, int state) {
public void onAudioModeChanged() {
}
@Override

View File

@@ -276,7 +276,7 @@ public abstract class DeviceListPreferenceFragment extends
public void onActiveDeviceChanged(CachedBluetoothDevice activeDevice, int bluetoothProfile) { }
@Override
public void onProfileAudioStateChanged(int bluetoothProfile, int state) { }
public void onAudioModeChanged() { }
/**
* Return the key of the {@link PreferenceGroup} that contains the bluetooth devices

View File

@@ -74,7 +74,6 @@ public class ConnectedDeviceDashboardFragment extends DashboardFragment {
Lifecycle lifecycle, DashboardFragment dashboardFragment) {
final List<AbstractPreferenceController> controllers = new ArrayList<>();
controllers.add(new ConnectedDeviceGroupController(context, dashboardFragment, lifecycle));
controllers.add(new SavedDeviceGroupController(context, dashboardFragment, lifecycle));
final NfcPreferenceController nfcPreferenceController =
new NfcPreferenceController(context);

View File

@@ -0,0 +1,87 @@
/*
* Copyright 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.connecteddevice;
import android.content.Context;
import android.content.res.Resources;
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.settings.search.SearchIndexableRaw;
import com.android.settingslib.search.SearchIndexable;
import java.util.ArrayList;
import java.util.List;
/**
* This fragment contains previously connected device
*/
@SearchIndexable(forTarget = SearchIndexable.MOBILE)
public class PreviouslyConnectedDeviceDashboardFragment extends DashboardFragment {
private static final String TAG = "PreConnectedDeviceFrag";
static final String KEY_PREVIOUSLY_CONNECTED_DEVICES = "saved_device_list";
@Override
public int getHelpResource() {
return R.string.help_url_previously_connected_devices;
}
@Override
protected int getPreferenceScreenResId() {
return R.xml.previously_connected_devices;
}
@Override
protected String getLogTag() {
return TAG;
}
@Override
public int getMetricsCategory() {
return MetricsProto.MetricsEvent.PREVIOUSLY_CONNECTED_DEVICES;
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
use(SavedDeviceGroupController.class).init(this);
}
/**
* For Search.
*/
public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider() {
@Override
public List<SearchIndexableRaw> getRawDataToIndex(
Context context, boolean enabled) {
final List<SearchIndexableRaw> result = new ArrayList<SearchIndexableRaw>();
final Resources res = context.getResources();
// Add fragment title
SearchIndexableRaw data = new SearchIndexableRaw(context);
data.key = KEY_PREVIOUSLY_CONNECTED_DEVICES;
data.title = res.getString(
R.string.connected_device_previously_connected_title);
data.screenTitle = res.getString(
R.string.connected_device_previously_connected_title);
result.add(data);
return result;
}
};
}

View File

@@ -46,18 +46,15 @@ public class SavedDeviceGroupController extends BasePreferenceController
PreferenceGroup mPreferenceGroup;
private BluetoothDeviceUpdater mBluetoothDeviceUpdater;
public SavedDeviceGroupController(Context context, DashboardFragment fragment,
Lifecycle lifecycle) {
public SavedDeviceGroupController(Context context) {
super(context, KEY);
init(lifecycle, new SavedBluetoothDeviceUpdater(context, fragment,
SavedDeviceGroupController.this));
}
@VisibleForTesting
SavedDeviceGroupController(DashboardFragment fragment, Lifecycle lifecycle,
SavedDeviceGroupController(DashboardFragment fragment,
BluetoothDeviceUpdater bluetoothDeviceUpdater) {
super(fragment.getContext(), KEY);
init(lifecycle, bluetoothDeviceUpdater);
mBluetoothDeviceUpdater = bluetoothDeviceUpdater;
}
@Override
@@ -108,10 +105,8 @@ public class SavedDeviceGroupController extends BasePreferenceController
}
}
private void init(Lifecycle lifecycle, BluetoothDeviceUpdater bluetoothDeviceUpdater) {
if (lifecycle != null && isAvailable()) {
lifecycle.addObserver(this);
}
mBluetoothDeviceUpdater = bluetoothDeviceUpdater;
public void init(DashboardFragment fragment) {
mBluetoothDeviceUpdater = new SavedBluetoothDeviceUpdater(fragment.getContext(),
fragment, SavedDeviceGroupController.this);
}
}

View File

@@ -55,6 +55,7 @@ import com.android.settings.backup.ToggleBackupSettingFragment;
import com.android.settings.bluetooth.BluetoothDeviceDetailsFragment;
import com.android.settings.connecteddevice.AdvancedConnectedDeviceDashboardFragment;
import com.android.settings.connecteddevice.ConnectedDeviceDashboardFragment;
import com.android.settings.connecteddevice.PreviouslyConnectedDeviceDashboardFragment;
import com.android.settings.connecteddevice.usb.UsbDetailsFragment;
import com.android.settings.datausage.DataUsageList;
import com.android.settings.datausage.DataUsageSummary;
@@ -78,6 +79,7 @@ import com.android.settings.gestures.AssistGestureSettings;
import com.android.settings.gestures.DoubleTapPowerSettings;
import com.android.settings.gestures.DoubleTapScreenSettings;
import com.android.settings.gestures.DoubleTwistGestureSettings;
import com.android.settings.gestures.SwipeUpGestureSettings;
import com.android.settings.gestures.PickupGestureSettings;
import com.android.settings.gestures.SwipeToNotificationSettings;
import com.android.settings.inputmethod.AvailableVirtualKeyboardFragment;
@@ -188,6 +190,7 @@ public class SettingsGateway {
DoubleTapScreenSettings.class.getName(),
PickupGestureSettings.class.getName(),
DoubleTwistGestureSettings.class.getName(),
SwipeUpGestureSettings.class.getName(),
CryptKeeperSettings.class.getName(),
DataUsageSummary.class.getName(),
DataUsageSummaryLegacy.class.getName(),
@@ -255,6 +258,7 @@ public class SettingsGateway {
DataUsageList.class.getName(),
DirectoryAccessDetails.class.getName(),
ToggleBackupSettingFragment.class.getName(),
PreviouslyConnectedDeviceDashboardFragment.class.getName(),
};
public static final String[] SETTINGS_FOR_RESTRICTED = {

View File

@@ -35,7 +35,6 @@ import android.os.UserHandle;
import android.support.annotation.VisibleForTesting;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceCategory;
import android.text.format.Formatter;
import android.util.ArraySet;
import android.util.IconDrawableFactory;
import android.util.Log;
@@ -308,9 +307,9 @@ public class AppDataUsage extends DataUsageBase implements Preference.OnPreferen
final long totalBytes = backgroundBytes + foregroundBytes;
final Context context = getContext();
mTotalUsage.setSummary(Formatter.formatFileSize(context, totalBytes));
mForegroundUsage.setSummary(Formatter.formatFileSize(context, foregroundBytes));
mBackgroundUsage.setSummary(Formatter.formatFileSize(context, backgroundBytes));
mTotalUsage.setSummary(DataUsageUtils.formatDataUsage(context, totalBytes));
mForegroundUsage.setSummary(DataUsageUtils.formatDataUsage(context, foregroundBytes));
mBackgroundUsage.setSummary(DataUsageUtils.formatDataUsage(context, backgroundBytes));
}
private boolean getAppRestrictBackground() {

View File

@@ -16,7 +16,6 @@ package com.android.settings.datausage;
import android.content.Context;
import android.support.v7.preference.PreferenceViewHolder;
import android.text.format.Formatter;
import android.view.View;
import android.widget.ProgressBar;
@@ -41,7 +40,7 @@ public class AppDataUsagePreference extends AppPreference {
if (item.restricted && item.total <= 0) {
setSummary(com.android.settings.R.string.data_usage_app_restricted);
} else {
setSummary(Formatter.formatFileSize(context, item.total));
setSummary(DataUsageUtils.formatDataUsage(context, item.total));
}
mDetail = provider.getUidDetail(item.key, false /* blocking */);
if (mDetail != null) {

View File

@@ -29,7 +29,6 @@ import android.net.NetworkTemplate;
import android.os.Bundle;
import android.support.v14.preference.SwitchPreference;
import android.support.v7.preference.Preference;
import android.text.format.Formatter;
import android.text.format.Time;
import android.util.FeatureFlagUtils;
import android.util.Log;
@@ -52,11 +51,10 @@ public class BillingCycleSettings extends DataUsageBase implements
private static final String TAG = "BillingCycleSettings";
private static final boolean LOGD = false;
public static final long KB_IN_BYTES = 1000;
public static final long MB_IN_BYTES = KB_IN_BYTES * 1000;
public static final long GB_IN_BYTES = MB_IN_BYTES * 1000;
public static final long MIB_IN_BYTES = 1024 * 1024;
public static final long GIB_IN_BYTES = MIB_IN_BYTES * 1024;
private static final long MAX_DATA_LIMIT_BYTES = 50000 * GB_IN_BYTES;
private static final long MAX_DATA_LIMIT_BYTES = 50000 * GIB_IN_BYTES;
private static final String TAG_CONFIRM_LIMIT = "confirmLimit";
private static final String TAG_CYCLE_EDITOR = "cycleEditor";
@@ -130,7 +128,7 @@ public class BillingCycleSettings extends DataUsageBase implements
}
final long warningBytes = services.mPolicyEditor.getPolicyWarningBytes(mNetworkTemplate);
if (warningBytes != WARNING_DISABLED) {
mDataWarning.setSummary(Formatter.formatFileSize(getContext(), warningBytes));
mDataWarning.setSummary(DataUsageUtils.formatDataUsage(getContext(), warningBytes));
mDataWarning.setEnabled(true);
mEnableDataWarning.setChecked(true);
} else {
@@ -140,7 +138,7 @@ public class BillingCycleSettings extends DataUsageBase implements
}
final long limitBytes = services.mPolicyEditor.getPolicyLimitBytes(mNetworkTemplate);
if (limitBytes != LIMIT_DISABLED) {
mDataLimit.setSummary(Formatter.formatFileSize(getContext(), limitBytes));
mDataLimit.setSummary(DataUsageUtils.formatDataUsage(getContext(), limitBytes));
mDataLimit.setEnabled(true);
mEnableDataLimit.setChecked(true);
} else {
@@ -275,14 +273,14 @@ public class BillingCycleSettings extends DataUsageBase implements
: editor.getPolicyWarningBytes(template);
final long limitDisabled = isLimit ? LIMIT_DISABLED : WARNING_DISABLED;
if (bytes > 1.5f * GB_IN_BYTES) {
final String bytesText = formatText(bytes / (float) GB_IN_BYTES);
if (bytes > 1.5f * GIB_IN_BYTES) {
final String bytesText = formatText(bytes / (float) GIB_IN_BYTES);
bytesPicker.setText(bytesText);
bytesPicker.setSelection(0, bytesText.length());
type.setSelection(1);
} else {
final String bytesText = formatText(bytes / (float) MB_IN_BYTES);
final String bytesText = formatText(bytes / (float) MIB_IN_BYTES);
bytesPicker.setText(bytesText);
bytesPicker.setSelection(0, bytesText.length());
@@ -313,7 +311,7 @@ public class BillingCycleSettings extends DataUsageBase implements
bytesString = "0";
}
final long bytes = (long) (Float.valueOf(bytesString)
* (spinner.getSelectedItemPosition() == 0 ? MB_IN_BYTES : GB_IN_BYTES));
* (spinner.getSelectedItemPosition() == 0 ? MIB_IN_BYTES : GIB_IN_BYTES));
// to fix the overflow problem
final long correctedBytes = Math.min(MAX_DATA_LIMIT_BYTES, bytes);
@@ -422,7 +420,7 @@ public class BillingCycleSettings extends DataUsageBase implements
// TODO: customize default limits based on network template
message = res.getString(R.string.data_usage_limit_dialog_mobile);
limitBytes = Math.max(5 * GB_IN_BYTES, minLimitBytes);
limitBytes = Math.max(5 * GIB_IN_BYTES, minLimitBytes);
final Bundle args = new Bundle();
args.putCharSequence(EXTRA_MESSAGE, message);

View File

@@ -27,6 +27,7 @@ import android.text.format.Formatter;
import android.text.style.ForegroundColorSpan;
import android.util.AttributeSet;
import android.util.SparseIntArray;
import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.graph.UsageView;
@@ -50,8 +51,8 @@ public class ChartDataUsagePreference extends Preference {
public ChartDataUsagePreference(Context context, AttributeSet attrs) {
super(context, attrs);
setSelectable(false);
mLimitColor = Utils.getColorAttr(context, android.R.attr.colorError);
mWarningColor = Utils.getColorAttr(context, android.R.attr.textColorSecondary);
mLimitColor = Utils.getColorAttrDefaultColor(context, android.R.attr.colorError);
mWarningColor = Utils.getColorAttrDefaultColor(context, android.R.attr.textColorSecondary);
setLayoutResource(R.layout.data_usage_graph);
}
@@ -155,7 +156,7 @@ public class ChartDataUsagePreference extends Preference {
private CharSequence getLabel(long bytes, int str, int mLimitColor) {
Formatter.BytesResult result = Formatter.formatBytes(getContext().getResources(),
bytes, Formatter.FLAG_SHORTER);
bytes, Formatter.FLAG_SHORTER | Formatter.FLAG_IEC_UNITS);
CharSequence label = TextUtils.expandTemplate(getContext().getText(str),
result.value, result.units);
return new SpannableStringBuilder().append(label, new ForegroundColorSpan(mLimitColor), 0);

View File

@@ -48,7 +48,6 @@ import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.text.format.DateUtils;
import android.text.format.Formatter;
import android.util.Log;
import android.util.SparseArray;
import android.view.View;
@@ -329,7 +328,7 @@ public class DataUsageList extends DataUsageBase {
SummaryForAllUidLoader.buildArgs(mTemplate, start, end), mSummaryCallbacks);
final long totalBytes = entry != null ? entry.rxBytes + entry.txBytes : 0;
final String totalPhrase = Formatter.formatFileSize(context, totalBytes);
final CharSequence totalPhrase = DataUsageUtils.formatDataUsage(context, totalBytes);
mUsageAmount.setTitle(getString(R.string.data_used_template, totalPhrase));
}

View File

@@ -21,7 +21,6 @@ import android.net.NetworkTemplate;
import android.os.Bundle;
import android.support.v4.content.res.TypedArrayUtils;
import android.support.v7.preference.Preference;
import android.text.format.Formatter;
import android.util.AttributeSet;
import android.util.FeatureFlagUtils;
@@ -61,13 +60,13 @@ public class DataUsagePreference extends Preference implements TemplatePreferenc
} else {
setTitle(mTitleRes);
setSummary(getContext().getString(R.string.data_usage_template,
Formatter.formatFileSize(getContext(), usageInfo.usageLevel),
DataUsageUtils.formatDataUsage(getContext(), usageInfo.usageLevel),
usageInfo.period));
}
} else {
setTitle(mTitleRes);
setSummary(getContext().getString(R.string.data_usage_template,
Formatter.formatFileSize(getContext(), usageInfo.usageLevel),
DataUsageUtils.formatDataUsage(getContext(), usageInfo.usageLevel),
usageInfo.period));
}
setIntent(getIntent());

View File

@@ -14,7 +14,6 @@
package com.android.settings.datausage;
import android.util.Log;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
@@ -28,7 +27,6 @@ import android.support.v7.preference.PreferenceScreen;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.SubscriptionPlan;
import android.telephony.TelephonyManager;
import android.text.BidiFormatter;
import android.text.Spannable;
import android.text.SpannableString;
@@ -233,7 +231,7 @@ public class DataUsageSummary extends DataUsageBaseFragment implements Indexable
final int FLAGS = Spannable.SPAN_INCLUSIVE_INCLUSIVE;
final Formatter.BytesResult usedResult = Formatter.formatBytes(context.getResources(),
usageLevel, Formatter.FLAG_CALCULATE_ROUNDED);
usageLevel, Formatter.FLAG_CALCULATE_ROUNDED | Formatter.FLAG_IEC_UNITS);
final SpannableString enlargedValue = new SpannableString(usedResult.value);
enlargedValue.setSpan(new RelativeSizeSpan(larger), 0, enlargedValue.length(), FLAGS);
@@ -311,7 +309,7 @@ public class DataUsageSummary extends DataUsageBaseFragment implements Indexable
final CharSequence wifiFormat = mActivity
.getText(R.string.data_usage_wifi_format);
final CharSequence sizeText =
Formatter.formatFileSize(mActivity, info.usageLevel);
DataUsageUtils.formatDataUsage(mActivity, info.usageLevel);
mSummaryLoader.setSummary(this,
TextUtils.expandTemplate(wifiFormat, sizeText));
}
@@ -319,7 +317,7 @@ public class DataUsageSummary extends DataUsageBaseFragment implements Indexable
}
}
private String formatUsedData() {
private CharSequence formatUsedData() {
SubscriptionManager subscriptionManager = (SubscriptionManager) mActivity
.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
int defaultSubId = subscriptionManager.getDefaultSubscriptionId();
@@ -332,19 +330,19 @@ public class DataUsageSummary extends DataUsageBaseFragment implements Indexable
return formatFallbackData();
}
if (DataUsageSummaryPreferenceController.unlimited(dfltPlan.getDataLimitBytes())) {
return Formatter.formatFileSize(mActivity, dfltPlan.getDataUsageBytes());
return DataUsageUtils.formatDataUsage(mActivity, dfltPlan.getDataUsageBytes());
} else {
return Utils.formatPercentage(dfltPlan.getDataUsageBytes(),
dfltPlan.getDataLimitBytes());
}
}
private String formatFallbackData() {
private CharSequence formatFallbackData() {
DataUsageController.DataUsageInfo info = mDataController.getDataUsageInfo();
if (info == null) {
return Formatter.formatFileSize(mActivity, 0);
return DataUsageUtils.formatDataUsage(mActivity, 0);
} else if (info.limitLevel <= 0) {
return Formatter.formatFileSize(mActivity, info.usageLevel);
return DataUsageUtils.formatDataUsage(mActivity, info.usageLevel);
} else {
return Utils.formatPercentage(info.usageLevel, info.limitLevel);
}

View File

@@ -39,7 +39,6 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
import com.android.settings.core.SubSettingLauncher;
import com.android.settingslib.AppItem;
import com.android.settingslib.Utils;
import com.android.settingslib.utils.StringUtil;
@@ -52,12 +51,13 @@ import java.util.concurrent.TimeUnit;
public class DataUsageSummaryPreference extends Preference {
private static final long MILLIS_IN_A_DAY = TimeUnit.DAYS.toMillis(1);
private static final long WARNING_AGE = TimeUnit.HOURS.toMillis(6L);
@VisibleForTesting static final Typeface SANS_SERIF_MEDIUM =
@VisibleForTesting
static final Typeface SANS_SERIF_MEDIUM =
Typeface.create("sans-serif-medium", Typeface.NORMAL);
private boolean mChartEnabled = true;
private String mStartLabel;
private String mEndLabel;
private CharSequence mStartLabel;
private CharSequence mEndLabel;
/** large vs small size is 36/16 ~ 2.25 */
private static final float LARGER_FONT_RATIO = 2.25f;
@@ -126,7 +126,7 @@ public class DataUsageSummaryPreference extends Preference {
}
}
public void setLabels(String start, String end) {
public void setLabels(CharSequence start, CharSequence end) {
mStartLabel = start;
mEndLabel = end;
notifyChanged();
@@ -215,7 +215,7 @@ public class DataUsageSummaryPreference extends Preference {
TextView usageNumberField = (TextView) holder.findViewById(R.id.data_usage_view);
final Formatter.BytesResult usedResult = Formatter.formatBytes(getContext().getResources(),
mDataplanUse, Formatter.FLAG_CALCULATE_ROUNDED);
mDataplanUse, Formatter.FLAG_CALCULATE_ROUNDED | Formatter.FLAG_IEC_UNITS);
final SpannableString usageNumberText = new SpannableString(usedResult.value);
final int textSize =
getContext().getResources().getDimensionPixelSize(R.dimen.usage_number_text_size);
@@ -233,13 +233,13 @@ public class DataUsageSummaryPreference extends Preference {
if (dataRemaining >= 0) {
usageRemainingField.setText(
TextUtils.expandTemplate(getContext().getText(R.string.data_remaining),
Formatter.formatFileSize(getContext(), dataRemaining)));
DataUsageUtils.formatDataUsage(getContext(), dataRemaining)));
usageRemainingField.setTextColor(
Utils.getColorAttr(getContext(), android.R.attr.colorAccent));
} else {
usageRemainingField.setText(
TextUtils.expandTemplate(getContext().getText(R.string.data_overusage),
Formatter.formatFileSize(getContext(), -dataRemaining)));
DataUsageUtils.formatDataUsage(getContext(), -dataRemaining)));
usageRemainingField.setTextColor(
Utils.getColorAttr(getContext(), android.R.attr.colorError));
}
@@ -253,10 +253,10 @@ public class DataUsageSummaryPreference extends Preference {
if (millisLeft <= 0) {
cycleTime.setText(getContext().getString(R.string.billing_cycle_none_left));
} else {
int daysLeft = (int)(millisLeft / MILLIS_IN_A_DAY);
int daysLeft = (int) (millisLeft / MILLIS_IN_A_DAY);
cycleTime.setText(daysLeft < 1
? getContext().getString(R.string.billing_cycle_less_than_one_day_left)
: getContext().getResources().getQuantityString(
? getContext().getString(R.string.billing_cycle_less_than_one_day_left)
: getContext().getResources().getQuantityString(
R.plurals.billing_cycle_days_left, daysLeft, daysLeft));
}
}

View File

@@ -23,20 +23,16 @@ import android.net.NetworkPolicyManager;
import android.net.NetworkTemplate;
import android.support.annotation.VisibleForTesting;
import android.support.v7.preference.Preference;
import android.support.v7.widget.RecyclerView;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.SubscriptionPlan;
import android.text.BidiFormatter;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.TextUtils;
import android.text.format.Formatter;
import android.text.style.RelativeSizeSpan;
import android.util.Log;
import android.util.RecurrenceRule;
import com.android.internal.util.CollectionUtils;
import android.support.v7.widget.RecyclerView;
import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.core.PreferenceControllerMixin;
@@ -220,18 +216,18 @@ public class DataUsageSummaryPreferenceController extends BasePreferenceControll
}
if (info.warningLevel > 0 && info.limitLevel > 0) {
summaryPreference.setLimitInfo(TextUtils.expandTemplate(
mContext.getText(R.string.cell_data_warning_and_limit),
Formatter.formatFileSize(mContext, info.warningLevel),
Formatter.formatFileSize(mContext, info.limitLevel)));
summaryPreference.setLimitInfo(TextUtils.expandTemplate(
mContext.getText(R.string.cell_data_warning_and_limit),
DataUsageUtils.formatDataUsage(mContext, info.warningLevel),
DataUsageUtils.formatDataUsage(mContext, info.limitLevel)));
} else if (info.warningLevel > 0) {
summaryPreference.setLimitInfo(TextUtils.expandTemplate(
mContext.getText(R.string.cell_data_warning),
Formatter.formatFileSize(mContext, info.warningLevel)));
summaryPreference.setLimitInfo(TextUtils.expandTemplate(
mContext.getText(R.string.cell_data_warning),
DataUsageUtils.formatDataUsage(mContext, info.warningLevel)));
} else if (info.limitLevel > 0) {
summaryPreference.setLimitInfo(TextUtils.expandTemplate(
mContext.getText(R.string.cell_data_limit),
Formatter.formatFileSize(mContext, info.limitLevel)));
DataUsageUtils.formatDataUsage(mContext, info.limitLevel)));
} else {
summaryPreference.setLimitInfo(null);
}
@@ -243,20 +239,13 @@ public class DataUsageSummaryPreferenceController extends BasePreferenceControll
} else {
summaryPreference.setChartEnabled(true);
summaryPreference.setLabels(Formatter.formatFileSize(mContext, 0 /* sizeBytes */),
Formatter.formatFileSize(mContext, mDataBarSize));
DataUsageUtils.formatDataUsage(mContext, mDataBarSize));
summaryPreference.setProgress(mDataplanUse / (float) mDataBarSize);
}
summaryPreference.setUsageInfo(mCycleEnd, mSnapshotTime, mCarrierName,
mDataplanCount, mManageSubscriptionIntent);
}
private String getLimitText(long limit, int textId) {
if (limit <= 0) {
return null;
}
return mContext.getString(textId, Formatter.formatFileSize(mContext, limit));
}
// TODO(b/70950124) add test for this method once the robolectric shadow run script is
// completed (b/3526807)
private void refreshDataplanInfo(DataUsageController.DataUsageInfo info) {
@@ -318,27 +307,4 @@ public class DataUsageSummaryPreferenceController extends BasePreferenceControll
public static boolean unlimited(long size) {
return size == SubscriptionPlan.BYTES_UNLIMITED;
}
@VisibleForTesting
private static CharSequence formatUsage(Context context, String template, long usageLevel) {
final int FLAGS = Spannable.SPAN_INCLUSIVE_INCLUSIVE;
final Formatter.BytesResult usedResult = Formatter.formatBytes(context.getResources(),
usageLevel, Formatter.FLAG_CALCULATE_ROUNDED);
final SpannableString enlargedValue = new SpannableString(usedResult.value);
enlargedValue.setSpan(
new RelativeSizeSpan(RELATIVE_SIZE_LARGE), 0, enlargedValue.length(), FLAGS);
final SpannableString amountTemplate = new SpannableString(
context.getString(com.android.internal.R.string.fileSizeSuffix)
.replace("%1$s", "^1").replace("%2$s", "^2"));
final CharSequence formattedUsage = TextUtils.expandTemplate(amountTemplate,
enlargedValue, usedResult.units);
final SpannableString fullTemplate = new SpannableString(template);
fullTemplate.setSpan(
new RelativeSizeSpan(RELATIVE_SIZE_SMALL), 0, fullTemplate.length(), FLAGS);
return TextUtils.expandTemplate(fullTemplate,
BidiFormatter.getInstance().unicodeWrap(formattedUsage.toString()));
}
}

View File

@@ -14,7 +14,6 @@
package com.android.settings.datausage;
import static android.net.ConnectivityManager.TYPE_ETHERNET;
import static android.net.ConnectivityManager.TYPE_WIFI;
import android.content.Context;
@@ -29,6 +28,10 @@ import android.os.SystemProperties;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.text.BidiFormatter;
import android.text.format.Formatter;
import android.text.format.Formatter.BytesResult;
import java.util.List;
/**
@@ -42,6 +45,16 @@ public final class DataUsageUtils {
private DataUsageUtils() {
}
/**
* Format byte value to readable string using IEC units.
*/
public static CharSequence formatDataUsage(Context context, long byteValue) {
final BytesResult res = Formatter.formatBytes(context.getResources(), byteValue,
Formatter.FLAG_IEC_UNITS);
return BidiFormatter.getInstance().unicodeWrap(context.getString(
com.android.internal.R.string.fileSizeSuffix, res.value, res.units));
}
/**
* Test if device has an ethernet network connection.
*/

View File

@@ -21,32 +21,49 @@ import android.content.Context;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen;
import android.text.SpannedString;
import com.android.internal.annotations.VisibleForTesting;
import com.android.settings.bluetooth.BluetoothLengthDeviceNameFilter;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.widget.ValidatedEditTextPreference;
import com.android.settings.wifi.tether.WifiDeviceNameTextValidator;
import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
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.OnSaveInstanceState;
public class DeviceNamePreferenceController extends BasePreferenceController
implements ValidatedEditTextPreference.Validator, Preference.OnPreferenceChangeListener {
implements ValidatedEditTextPreference.Validator,
Preference.OnPreferenceChangeListener,
LifecycleObserver,
OnSaveInstanceState,
OnCreate {
private static final String PREF_KEY = "device_name";
public static final int DEVICE_NAME_SET_WARNING_ID = 1;
private static final String KEY_PENDING_DEVICE_NAME = "key_pending_device_name";
private String mDeviceName;
protected WifiManager mWifiManager;
private final WifiDeviceNameTextValidator mWifiDeviceNameTextValidator;
private ValidatedEditTextPreference mPreference;
@Nullable
private LocalBluetoothManager mBluetoothManager;
private DeviceNamePreferenceHost mHost;
private String mPendingDeviceName;
public DeviceNamePreferenceController(Context context) {
super(context, PREF_KEY);
mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
mWifiDeviceNameTextValidator = new WifiDeviceNameTextValidator();
initializeDeviceName();
}
@@ -85,9 +102,10 @@ public class DeviceNamePreferenceController extends BasePreferenceController
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
mDeviceName = (String) newValue;
setDeviceName(mDeviceName);
preference.setSummary(getSummary());
mPendingDeviceName = (String) newValue;
if (mHost != null) {
mHost.showDeviceNameWarningDialog(mPendingDeviceName);
}
return true;
}
@@ -103,13 +121,25 @@ public class DeviceNamePreferenceController extends BasePreferenceController
mBluetoothManager = localBluetoothManager;
}
public void confirmDeviceName() {
if (mPendingDeviceName != null) {
setDeviceName(mPendingDeviceName);
}
}
public void setHost(DeviceNamePreferenceHost host) {
mHost = host;
}
/**
* This method presumes that security/validity checks have already been passed.
*/
private void setDeviceName(String deviceName) {
mDeviceName = deviceName;
setSettingsGlobalDeviceName(deviceName);
setBluetoothDeviceName(deviceName);
setTetherSsidName(deviceName);
mPreference.setSummary(getSummary());
}
private void setSettingsGlobalDeviceName(String deviceName) {
@@ -150,4 +180,20 @@ public class DeviceNamePreferenceController extends BasePreferenceController
// TODO: If tether is running, turn off the AP and restart it after setting config.
mWifiManager.setWifiApConfiguration(config);
}
@Override
public void onCreate(Bundle savedInstanceState) {
if (savedInstanceState != null) {
mPendingDeviceName = savedInstanceState.getString(KEY_PENDING_DEVICE_NAME, null);
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
outState.putString(KEY_PENDING_DEVICE_NAME, mPendingDeviceName);
}
public interface DeviceNamePreferenceHost {
void showDeviceNameWarningDialog(String deviceName);
}
}

View File

@@ -106,7 +106,7 @@ public class StorageVolumePreference extends Preference {
}
if (freeBytes < mStorageManager.getStorageLowBytes(path)) {
mColor = Utils.getColorAttr(context, android.R.attr.colorError);
mColor = Utils.getColorAttrDefaultColor(context, android.R.attr.colorError);
icon = context.getDrawable(R.drawable.ic_warning_24dp);
}

View File

@@ -0,0 +1,71 @@
/*
* 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.deviceinfo.aboutphone;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.FragmentManager;
import android.content.DialogInterface;
import android.os.Bundle;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
/**
* Warning dialog to let the user know where the device name will be shown before setting it.
*/
public class DeviceNameWarningDialog extends InstrumentedDialogFragment
implements DialogInterface.OnClickListener {
public static final String TAG = "DeviceNameWarningDlg";
public static void show(MyDeviceInfoFragment host) {
final FragmentManager manager = host.getActivity().getFragmentManager();
if (manager.findFragmentByTag(TAG) != null) {
return;
}
final DeviceNameWarningDialog dialog = new DeviceNameWarningDialog();
dialog.setTargetFragment(host, 0 /* requestCode */);
dialog.show(manager, TAG);
}
@Override
public int getMetricsCategory() {
return MetricsProto.MetricsEvent.DIALOG_ENABLE_DEVELOPMENT_OPTIONS;
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return new AlertDialog.Builder(getActivity())
.setTitle(R.string.my_device_info_device_name_preference_title)
.setMessage(R.string.about_phone_device_name_warning)
.setCancelable(false)
.setPositiveButton(com.android.internal.R.string.ok, this)
.setNegativeButton(com.android.internal.R.string.cancel, this)
.create();
}
@Override
public void onClick(DialogInterface dialog, int which) {
final MyDeviceInfoFragment host = (MyDeviceInfoFragment) getTargetFragment();
if (which == DialogInterface.BUTTON_POSITIVE) {
host.onSetDeviceNameConfirm();
}
}
}

View File

@@ -19,7 +19,6 @@ package com.android.settings.deviceinfo.aboutphone;
import static com.android.settings.bluetooth.Utils.getLocalBtManager;
import android.app.Activity;
import android.app.Fragment;
import android.content.Context;
import android.content.Intent;
import android.content.pm.UserInfo;
@@ -62,7 +61,8 @@ import java.util.Arrays;
import java.util.List;
@SearchIndexable
public class MyDeviceInfoFragment extends DashboardFragment {
public class MyDeviceInfoFragment extends DashboardFragment
implements DeviceNamePreferenceController.DeviceNamePreferenceHost {
private static final String LOG_TAG = "MyDeviceInfoFragment";
private static final String KEY_MY_DEVICE_INFO_HEADER = "my_device_info_header";
@@ -100,8 +100,11 @@ public class MyDeviceInfoFragment extends DashboardFragment {
getLifecycle());
}
private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
Activity activity, Fragment fragment, Lifecycle lifecycle) {
private static List<AbstractPreferenceController> buildPreferenceControllers(
Context context,
Activity activity,
MyDeviceInfoFragment fragment,
Lifecycle lifecycle) {
final List<AbstractPreferenceController> controllers = new ArrayList<>();
controllers.add(new EmergencyInfoPreferenceController(context));
controllers.add(new PhoneNumberPreferenceController(context));
@@ -109,6 +112,10 @@ public class MyDeviceInfoFragment extends DashboardFragment {
DeviceNamePreferenceController deviceNamePreferenceController =
new DeviceNamePreferenceController(context);
deviceNamePreferenceController.setLocalBluetoothManager(getLocalBtManager(context));
deviceNamePreferenceController.setHost(fragment);
if (lifecycle != null) {
lifecycle.addObserver(deviceNamePreferenceController);
}
controllers.add(deviceNamePreferenceController);
controllers.add(new SimStatusPreferenceController(context, fragment));
controllers.add(new DeviceModelPreferenceController(context, fragment));
@@ -164,6 +171,16 @@ public class MyDeviceInfoFragment extends DashboardFragment {
controller.done(context, true /* rebindActions */);
}
@Override
public void showDeviceNameWarningDialog(String deviceName) {
DeviceNameWarningDialog.show(this);
}
public void onSetDeviceNameConfirm() {
final DeviceNamePreferenceController controller = use(DeviceNamePreferenceController.class);
controller.confirmDeviceName();
}
private static class SummaryProvider implements SummaryLoader.SummaryProvider {
private final SummaryLoader mSummaryLoader;

View File

@@ -130,7 +130,7 @@ public class UserProfileController extends AbstractPreferenceController implemen
private static Drawable applyTint(Context context, Drawable icon) {
icon = icon.mutate();
icon.setTint(Utils.getColorAttr(context, android.R.attr.colorControlNormal));
icon.setTintList(Utils.getColorAttr(context, android.R.attr.colorControlNormal));
return icon;
}

View File

@@ -0,0 +1,74 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.display;
import android.content.Context;
import android.os.Bundle;
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.search.SearchIndexable;
import java.util.Arrays;
import java.util.List;
@SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC)
public class AutoBrightnessSettings extends DashboardFragment {
private static final String TAG = "AutoBrightnessSettings";
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
mFooterPreferenceMixin.createFooterPreference()
.setTitle(R.string.auto_brightness_description);
}
@Override
protected int getPreferenceScreenResId() {
return R.xml.auto_brightness_detail;
}
@Override
protected String getLogTag() {
return TAG;
}
@Override
public int getMetricsCategory() {
return MetricsProto.MetricsEvent.SETTINGS_AUTO_BRIGHTNESS;
}
@Override
public int getHelpResource() {
return R.string.help_url_auto_brightness;
}
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.auto_brightness_detail;
return Arrays.asList(sir);
}
};
}

View File

@@ -41,7 +41,9 @@ public class ColorModePreferenceController extends BasePreferenceController {
@Override
public int getAvailabilityStatus() {
return mConfigWrapper.isScreenWideColorGamut() ? AVAILABLE : DISABLED_FOR_USER;
return mConfigWrapper.isScreenWideColorGamut()
&& !getColorDisplayController().getAccessibilityTransformActivated() ?
AVAILABLE : DISABLED_FOR_USER;
}
@Override

View File

@@ -16,7 +16,6 @@ package com.android.settings.display;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.support.annotation.VisibleForTesting;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen;
import com.android.internal.app.ColorDisplayController;
@@ -25,7 +24,6 @@ import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.applications.LayoutPreference;
import com.android.settings.R;
import com.android.settings.widget.RadioButtonPickerFragment;
import com.android.settings.widget.RadioButtonPreference;
import com.android.settingslib.widget.CandidateInfo;
import java.util.Arrays;
@@ -81,14 +79,13 @@ public class ColorModePreferenceFragment extends RadioButtonPickerFragment
@Override
protected List<? extends CandidateInfo> getCandidates() {
Context c = getContext();
final boolean enabled = !mController.getAccessibilityTransformActivated();
return Arrays.asList(
new ColorModeCandidateInfo(c.getText(R.string.color_mode_option_natural),
KEY_COLOR_MODE_NATURAL, enabled),
KEY_COLOR_MODE_NATURAL, true /* enabled */),
new ColorModeCandidateInfo(c.getText(R.string.color_mode_option_boosted),
KEY_COLOR_MODE_BOOSTED, enabled),
KEY_COLOR_MODE_BOOSTED, true /* enabled */),
new ColorModeCandidateInfo(c.getText(R.string.color_mode_option_saturated),
KEY_COLOR_MODE_SATURATED, enabled)
KEY_COLOR_MODE_SATURATED, true /* enabled */)
);
}
@@ -153,16 +150,10 @@ public class ColorModePreferenceFragment extends RadioButtonPickerFragment
@Override
public void onAccessibilityTransformChanged(boolean state) {
// Disable controls when a11y transforms are enabled, and vice versa
final PreferenceScreen screen = getPreferenceScreen();
if (screen != null) {
final int count = screen.getPreferenceCount();
for (int i = 0; i < count; i++) {
final Preference pref = screen.getPreference(i);
if (pref instanceof RadioButtonPreference) {
pref.setEnabled(!state);
}
}
// Color modes are no not configurable when Accessibility transforms are enabled. Close
// this fragment in that case.
if (state) {
getActivity().onBackPressed();
}
}
}

View File

@@ -18,19 +18,16 @@ package com.android.settings.enterprise;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.AppGlobals;
import android.app.admin.DevicePolicyManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.graphics.drawable.Drawable;
import android.os.Process;
import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
import android.support.annotation.VisibleForTesting;
import android.util.Log;
import android.util.IconDrawableFactory;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -40,6 +37,7 @@ import android.widget.TextView;
import com.android.settings.DeviceAdminAdd;
import com.android.settings.R;
import com.android.settings.Settings;
import com.android.settings.Utils;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
@@ -99,20 +97,12 @@ public class ActionDisabledByAdminDialogHelper {
|| !RestrictedLockUtils.isCurrentUserOrProfile(mActivity, userId)) {
admin = null;
} else {
ActivityInfo ai = null;
try {
ai = AppGlobals.getPackageManager().getReceiverInfo(admin, 0 /* flags */,
userId);
} catch (RemoteException e) {
Log.w(TAG, "Missing reciever info", e);
}
if (ai != null) {
final Drawable icon = ai.loadIcon(mActivity.getPackageManager());
final Drawable badgedIcon = mActivity.getPackageManager().getUserBadgedIcon(
icon, new UserHandle(userId));
((ImageView) root.findViewById(R.id.admin_support_icon)).setImageDrawable(
badgedIcon);
}
final Drawable badgedIcon = Utils.getBadgedIcon(
IconDrawableFactory.newInstance(mActivity),
mActivity.getPackageManager(),
admin.getPackageName(),
userId);
((ImageView) root.findViewById(R.id.admin_support_icon)).setImageDrawable(badgedIcon);
}
setAdminSupportTitle(root, restriction);

View File

@@ -51,7 +51,8 @@ public class BatteryMeterView extends ImageView {
final int frameColor = context.getColor(R.color.meter_background_color);
mAccentColorFilter = new PorterDuffColorFilter(
Utils.getColorAttr(context, android.R.attr.colorAccent), PorterDuff.Mode.SRC_IN);
Utils.getColorAttrDefaultColor(context, android.R.attr.colorAccent),
PorterDuff.Mode.SRC_IN);
mErrorColorFilter = new PorterDuffColorFilter(
context.getColor(R.color.battery_icon_color_error), PorterDuff.Mode.SRC_IN);

View File

@@ -37,7 +37,7 @@ public class BatterySaverDrawable extends BatteryMeterDrawableBase {
setPowerSave(true);
setCharging(false);
setPowerSaveAsColorError(false);
final int tintColor = Utils.getColorAttr(context, android.R.attr.colorAccent);
final int tintColor = Utils.getColorAttrDefaultColor(context, android.R.attr.colorAccent);
setColorFilter(new PorterDuffColorFilter(tintColor, PorterDuff.Mode.SRC_IN));
}
}
}

View File

@@ -20,18 +20,22 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.BatteryManager;
import android.content.pm.ResolveInfo;
import android.os.BatteryStats;
import android.os.Bundle;
import android.os.Build;
import android.os.Process;
import android.os.SystemClock;
import android.os.UserHandle;
import android.os.UserManager;
import android.support.annotation.IntDef;
import android.support.annotation.Nullable;
import android.support.annotation.StringRes;
import android.support.annotation.VisibleForTesting;
import android.support.annotation.WorkerThread;
import android.text.TextUtils;
import android.text.format.DateUtils;
import android.util.Log;
import android.util.SparseLongArray;
@@ -43,6 +47,7 @@ import com.android.settings.R;
import com.android.settings.fuelgauge.anomaly.Anomaly;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.fuelgauge.PowerWhitelistBackend;
import com.android.settingslib.utils.PowerUtil;
import java.lang.annotation.Retention;
@@ -531,5 +536,81 @@ public class BatteryUtils {
return false;
}
/**
* Return {@code true} if we should hide anomaly app represented by {@code uid}
*/
public boolean shouldHideAnomaly(PowerWhitelistBackend powerWhitelistBackend, int uid) {
final String[] packageNames = mPackageManager.getPackagesForUid(uid);
if (ArrayUtils.isEmpty(packageNames)) {
// Don't show it if app has been uninstalled
return true;
}
return isSystemUid(uid) || powerWhitelistBackend.isSysWhitelistedExceptIdle(packageNames)
|| (isSystemApp(mPackageManager, packageNames) && !hasLauncherEntry(packageNames));
}
private boolean isSystemUid(int uid) {
final int appUid = UserHandle.getAppId(uid);
return appUid >= Process.ROOT_UID && appUid < Process.FIRST_APPLICATION_UID;
}
private boolean isSystemApp(PackageManager packageManager, String[] packageNames) {
for (String packageName : packageNames) {
try {
final ApplicationInfo info = packageManager.getApplicationInfo(packageName,
0 /* flags */);
if ((info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
return true;
}
} catch (PackageManager.NameNotFoundException e) {
Log.e(TAG, "Package not found: " + packageName, e);
}
}
return false;
}
private boolean hasLauncherEntry(String[] packageNames) {
final Intent launchIntent = new Intent(Intent.ACTION_MAIN, null);
launchIntent.addCategory(Intent.CATEGORY_LAUNCHER);
// If we do not specify MATCH_DIRECT_BOOT_AWARE or
// MATCH_DIRECT_BOOT_UNAWARE, system will derive and update the flags
// according to the user's lock state. When the user is locked,
// components
// with ComponentInfo#directBootAware == false will be filtered. We should
// explicitly include both direct boot aware and unaware components here.
final List<ResolveInfo> resolveInfos = mPackageManager.queryIntentActivities(launchIntent,
PackageManager.MATCH_DISABLED_COMPONENTS
| PackageManager.MATCH_DIRECT_BOOT_AWARE
| PackageManager.MATCH_DIRECT_BOOT_UNAWARE
| PackageManager.MATCH_SYSTEM_ONLY);
for (int i = 0, size = resolveInfos.size(); i < size; i++) {
final ResolveInfo resolveInfo = resolveInfos.get(i);
if (ArrayUtils.contains(packageNames, resolveInfo.activityInfo.packageName)) {
return true;
}
}
return false;
}
/**
* Return version number of an app represented by {@code packageName}, and return -1 if not
* found.
*/
public long getAppLongVersionCode(String packageName) {
try {
final PackageInfo packageInfo = mPackageManager.getPackageInfo(packageName,
0 /* flags */);
return packageInfo.getLongVersionCode();
} catch (PackageManager.NameNotFoundException e) {
Log.e(TAG, "Cannot find package: " + packageName, e);
}
return -1L;
}
}

View File

@@ -72,8 +72,8 @@ public class RestrictAppPreferenceController extends BasePreferenceController {
mAppInfos = BatteryTipUtils.getRestrictedAppsList(mAppOpsManager, mUserManager);
final int num = mAppInfos.size();
// Enable the preference if some apps already been restricted, otherwise disable it
preference.setEnabled(num > 0);
// Don't show it if no app been restricted
preference.setVisible(num > 0);
preference.setSummary(
mContext.getResources().getQuantityString(R.plurals.restricted_app_summary, num,
num));

View File

@@ -28,7 +28,6 @@ import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.search.SearchIndexable;
import com.android.settingslib.widget.FooterPreferenceMixin;
import java.util.ArrayList;
import java.util.Arrays;
@@ -41,9 +40,6 @@ import java.util.List;
public class SmartBatterySettings extends DashboardFragment {
public static final String TAG = "SmartBatterySettings";
private final FooterPreferenceMixin mFooterPreferenceMixin =
new FooterPreferenceMixin(this, getLifecycle());
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
@@ -95,11 +91,6 @@ public class SmartBatterySettings extends DashboardFragment {
return Arrays.asList(sir);
}
@Override
public List<String> getNonIndexableKeys(Context context) {
return super.getNonIndexableKeys(context);
}
@Override
public List<AbstractPreferenceController> createPreferenceControllers(
Context context) {

View File

@@ -71,7 +71,11 @@ public class AnomalyConfigJobService extends JobService {
ThreadUtils.postOnBackgroundThread(() -> {
final StatsManager statsManager = getSystemService(StatsManager.class);
checkAnomalyConfig(statsManager);
BatteryTipUtils.uploadAnomalyPendingIntent(this, statsManager);
try {
BatteryTipUtils.uploadAnomalyPendingIntent(this, statsManager);
} catch (StatsManager.StatsUnavailableException e) {
Log.w(TAG, "Failed to uploadAnomalyPendingIntent.", e);
}
jobFinished(params, false /* wantsReschedule */);
});
@@ -96,23 +100,26 @@ public class AnomalyConfigJobService extends JobService {
Log.i(TAG, "CurrentVersion: " + currentVersion + " new version: " + newVersion);
if (newVersion > currentVersion) {
statsManager.removeConfiguration(StatsManagerConfig.ANOMALY_CONFIG_KEY);
try {
statsManager.removeConfig(StatsManagerConfig.ANOMALY_CONFIG_KEY);
} catch (StatsManager.StatsUnavailableException e) {
Log.i(TAG, "When updating anomaly config, failed to first remove the old config "
+ StatsManagerConfig.ANOMALY_CONFIG_KEY, e);
}
if (!TextUtils.isEmpty(rawConfig)) {
try {
final byte[] config = Base64.decode(rawConfig, Base64.DEFAULT);
if (statsManager.addConfiguration(StatsManagerConfig.ANOMALY_CONFIG_KEY,
config)) {
Log.i(TAG, "Upload the anomaly config. configKey: "
+ StatsManagerConfig.ANOMALY_CONFIG_KEY);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putInt(KEY_ANOMALY_CONFIG_VERSION, newVersion);
editor.commit();
} else {
Log.i(TAG, "Upload the anomaly config failed. configKey: "
+ StatsManagerConfig.ANOMALY_CONFIG_KEY);
}
statsManager.addConfig(StatsManagerConfig.ANOMALY_CONFIG_KEY, config);
Log.i(TAG, "Upload the anomaly config. configKey: "
+ StatsManagerConfig.ANOMALY_CONFIG_KEY);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putInt(KEY_ANOMALY_CONFIG_VERSION, newVersion);
editor.commit();
} catch (IllegalArgumentException e) {
Log.e(TAG, "Anomaly raw config is in wrong format", e);
} catch (StatsManager.StatsUnavailableException e) {
Log.i(TAG, "Upload of anomaly config failed for configKey "
+ StatsManagerConfig.ANOMALY_CONFIG_KEY, e);
}
}
}

View File

@@ -41,7 +41,11 @@ public class AnomalyConfigReceiver extends BroadcastReceiver {
// Check whether to update the config
AnomalyConfigJobService.scheduleConfigUpdate(context);
BatteryTipUtils.uploadAnomalyPendingIntent(context, statsManager);
try {
BatteryTipUtils.uploadAnomalyPendingIntent(context, statsManager);
} catch (StatsManager.StatsUnavailableException e) {
Log.w(TAG, "Failed to uploadAnomalyPendingIntent.", e);
}
if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
AnomalyCleanupJobService.scheduleCleanUp(context);

View File

@@ -30,6 +30,7 @@ import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Process;
@@ -145,21 +146,27 @@ public class AnomalyDetectionJobService extends JobService {
: Settings.Global.getInt(contentResolver,
Settings.Global.APP_AUTO_RESTRICTION_ENABLED, ON) == ON;
final String packageName = batteryUtils.getPackageName(uid);
if (uid != UID_NULL && !isSystemUid(uid)
&& !powerWhitelistBackend.isSysWhitelistedExceptIdle(
packageManager.getPackagesForUid(uid))) {
boolean anomalyDetected = true;
if (anomalyInfo.anomalyType
== StatsManagerConfig.AnomalyType.EXCESSIVE_BACKGROUND_SERVICE) {
if (!batteryUtils.isPreOApp(packageName)
|| !batteryUtils.isAppHeavilyUsed(batteryStatsHelper, userManager, uid,
policy.excessiveBgDrainPercentage)) {
// Don't report if it is not legacy app or haven't used much battery
anomalyDetected = false;
}
}
final long versionCode = batteryUtils.getAppLongVersionCode(packageName);
if (anomalyDetected) {
final boolean anomalyDetected;
if (isExcessiveBackgroundAnomaly(anomalyInfo)) {
anomalyDetected = batteryUtils.isPreOApp(packageName)
&& batteryUtils.isAppHeavilyUsed(batteryStatsHelper, userManager, uid,
policy.excessiveBgDrainPercentage);
} else {
anomalyDetected = true;
}
if (anomalyDetected) {
if (batteryUtils.shouldHideAnomaly(powerWhitelistBackend, uid)) {
metricsFeatureProvider.action(context,
MetricsProto.MetricsEvent.ACTION_ANOMALY_IGNORED,
packageName,
Pair.create(MetricsProto.MetricsEvent.FIELD_CONTEXT,
anomalyInfo.anomalyType),
Pair.create(MetricsProto.MetricsEvent.FIELD_APP_VERSION_CODE,
versionCode));
} else {
if (autoFeatureOn && anomalyInfo.autoRestriction) {
// Auto restrict this app
batteryUtils.setForceAppStandby(uid, packageName,
@@ -175,8 +182,10 @@ public class AnomalyDetectionJobService extends JobService {
metricsFeatureProvider.action(context,
MetricsProto.MetricsEvent.ACTION_ANOMALY_TRIGGERED,
packageName,
Pair.create(MetricsProto.MetricsEvent.FIELD_CONTEXT,
anomalyInfo.anomalyType));
Pair.create(MetricsProto.MetricsEvent.FIELD_ANOMALY_TYPE,
anomalyInfo.anomalyType),
Pair.create(MetricsProto.MetricsEvent.FIELD_APP_VERSION_CODE,
versionCode));
}
}
} catch (NullPointerException | IndexOutOfBoundsException e) {
@@ -215,8 +224,8 @@ public class AnomalyDetectionJobService extends JobService {
return UID_NULL;
}
private boolean isSystemUid(int uid) {
final int appUid = UserHandle.getAppId(uid);
return appUid >= Process.ROOT_UID && appUid < Process.FIRST_APPLICATION_UID;
private boolean isExcessiveBackgroundAnomaly(AnomalyInfo anomalyInfo) {
return anomalyInfo.anomalyType
== StatsManagerConfig.AnomalyType.EXCESSIVE_BACKGROUND_SERVICE;
}
}

View File

@@ -102,7 +102,10 @@ public class BatteryTipDialogFragment extends InstrumentedDialogFragment impleme
return new AlertDialog.Builder(context)
.setMessage(getString(R.string.battery_tip_dialog_message,
highUsageTip.getHighUsageAppList().size()))
highUsageTip.getHighUsageAppList().size(),
StringUtil.formatRelativeTime(context,
highUsageTip.getLastFullChargeTimeMs(),
false /* withSeconds */)))
.setView(view)
.setPositiveButton(android.R.string.ok, null)
.create();

View File

@@ -47,6 +47,10 @@ public class BatteryTipPolicy {
private static final String KEY_DATA_HISTORY_RETAIN_DAY = "data_history_retain_day";
private static final String KEY_EXCESSIVE_BG_DRAIN_PERCENTAGE = "excessive_bg_drain_percentage";
private static final String KEY_TEST_BATTERY_SAVER_TIP = "test_battery_saver_tip";
private static final String KEY_TEST_HIGH_USAGE_TIP = "test_high_usage_tip";
private static final String KEY_TEST_SMART_BATTERY_TIP = "test_smart_battery_tip";
/**
* {@code true} if general battery tip is enabled
*
@@ -164,6 +168,30 @@ public class BatteryTipPolicy {
*/
public final int excessiveBgDrainPercentage;
/**
* {@code true} if we want to test battery saver tip.
*
* @see Settings.Global#BATTERY_TIP_CONSTANTS
* @see #KEY_TEST_BATTERY_SAVER_TIP
*/
public final boolean testBatterySaverTip;
/**
* {@code true} if we want to test high usage tip.
*
* @see Settings.Global#BATTERY_TIP_CONSTANTS
* @see #KEY_TEST_HIGH_USAGE_TIP
*/
public final boolean testHighUsageTip;
/**
* {@code true} if we want to test smart battery tip.
*
* @see Settings.Global#BATTERY_TIP_CONSTANTS
* @see #KEY_TEST_SMART_BATTERY_TIP
*/
public final boolean testSmartBatteryTip;
private final KeyValueListParser mParser;
public BatteryTipPolicy(Context context) {
@@ -197,6 +225,10 @@ public class BatteryTipPolicy {
lowBatteryHour = mParser.getInt(KEY_LOW_BATTERY_HOUR, 16);
dataHistoryRetainDay = mParser.getInt(KEY_DATA_HISTORY_RETAIN_DAY, 30);
excessiveBgDrainPercentage = mParser.getInt(KEY_EXCESSIVE_BG_DRAIN_PERCENTAGE, 10);
testBatterySaverTip = mParser.getBoolean(KEY_TEST_BATTERY_SAVER_TIP, false);
testHighUsageTip = mParser.getBoolean(KEY_TEST_HIGH_USAGE_TIP, false);
testSmartBatteryTip = mParser.getBoolean(KEY_TEST_SMART_BATTERY_TIP, false);
}
}

View File

@@ -30,6 +30,7 @@ import com.android.settings.SettingsActivity;
import com.android.settings.core.InstrumentedPreferenceFragment;
import com.android.settings.fuelgauge.batterytip.actions.BatterySaverAction;
import com.android.settings.fuelgauge.batterytip.actions.BatteryTipAction;
import com.android.settings.fuelgauge.batterytip.actions.OpenBatterySaverAction;
import com.android.settings.fuelgauge.batterytip.actions.OpenRestrictAppFragmentAction;
import com.android.settings.fuelgauge.batterytip.actions.RestrictAppAction;
import com.android.settings.fuelgauge.batterytip.actions.SmartBatteryAction;
@@ -93,7 +94,11 @@ public class BatteryTipUtils {
case BatteryTip.TipType.SMART_BATTERY_MANAGER:
return new SmartBatteryAction(settingsActivity, fragment);
case BatteryTip.TipType.BATTERY_SAVER:
return new BatterySaverAction(settingsActivity);
if (batteryTip.getState() == BatteryTip.StateType.HANDLED) {
return new OpenBatterySaverAction(settingsActivity);
} else {
return new BatterySaverAction(settingsActivity);
}
case BatteryTip.TipType.APP_RESTRICTION:
if (batteryTip.getState() == BatteryTip.StateType.HANDLED) {
return new OpenRestrictAppFragmentAction(settingsActivity, fragment,
@@ -110,12 +115,14 @@ public class BatteryTipUtils {
/**
* Upload the {@link PendingIntent} to {@link StatsManager} for anomaly detection
* @throws StatsManager.StatsUnavailableException if failed to communicate with stats service
*/
public static void uploadAnomalyPendingIntent(Context context, StatsManager statsManager) {
public static void uploadAnomalyPendingIntent(Context context, StatsManager statsManager)
throws StatsManager.StatsUnavailableException {
final Intent extraIntent = new Intent(context, AnomalyDetectionReceiver.class);
final PendingIntent pendingIntent = PendingIntent.getBroadcast(context, REQUEST_CODE,
extraIntent, PendingIntent.FLAG_UPDATE_CURRENT);
statsManager.setBroadcastSubscriber(StatsManagerConfig.ANOMALY_CONFIG_KEY,
StatsManagerConfig.SUBSCRIBER_ID, pendingIntent);
statsManager.setBroadcastSubscriber(pendingIntent,
StatsManagerConfig.ANOMALY_CONFIG_KEY, StatsManagerConfig.SUBSCRIBER_ID);
}
}

View File

@@ -0,0 +1,56 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.fuelgauge.batterytip.actions;
import android.content.Context;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
import com.android.settings.SettingsActivity;
import com.android.settings.core.InstrumentedPreferenceFragment;
import com.android.settings.core.SubSettingLauncher;
import com.android.settings.fuelgauge.BatteryUtils;
import com.android.settings.fuelgauge.RestrictedAppDetails;
import com.android.settings.fuelgauge.batterysaver.BatterySaverSettings;
import com.android.settings.fuelgauge.batterytip.AppInfo;
import com.android.settings.fuelgauge.batterytip.tips.RestrictAppTip;
import java.util.List;
/**
*
* Action to open the {@link com.android.settings.fuelgauge.batterysaver.BatterySaverSettings}
*/
public class OpenBatterySaverAction extends BatteryTipAction {
public OpenBatterySaverAction(Context context) {
super(context);
}
/**
* Handle the action when user clicks positive button
*/
@Override
public void handlePositiveAction(int metricsKey) {
mMetricsFeatureProvider.action(mContext,
MetricsProto.MetricsEvent.ACTION_TIP_OPEN_BATTERY_SAVER_PAGE, metricsKey);
new SubSettingLauncher(mContext)
.setDestination(BatterySaverSettings.class.getName())
.setSourceMetricsCategory(metricsKey)
.launch();
}
}

View File

@@ -53,7 +53,7 @@ public class EarlyWarningDetector implements BatteryTipDetector {
batteryBroadcast.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1) == 0;
final boolean powerSaveModeOn = mPowerManager.isPowerSaveMode();
final boolean earlyWarning = mPowerUsageFeatureProvider.getEarlyWarningSignal(mContext,
EarlyWarningDetector.class.getName());
EarlyWarningDetector.class.getName()) || mPolicy.testBatterySaverTip;
final int state = powerSaveModeOn
? BatteryTip.StateType.HANDLED

View File

@@ -34,6 +34,7 @@ import com.android.settings.fuelgauge.batterytip.tips.HighUsageTip;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
* Detector whether to show summary tip. This detector should be executed as the last
@@ -62,10 +63,11 @@ public class HighUsageDetector implements BatteryTipDetector {
@Override
public BatteryTip detect() {
final long screenUsageTimeMs = mBatteryUtils.calculateScreenUsageTime(mBatteryStatsHelper);
final long lastFullChargeTimeMs = mBatteryUtils.calculateLastFullChargeTime(
mBatteryStatsHelper, System.currentTimeMillis());
if (mPolicy.highUsageEnabled) {
parseBatteryData();
if (mDataParser.isDeviceHeavilyUsed()) {
if (mDataParser.isDeviceHeavilyUsed() || mPolicy.testHighUsageTip) {
final List<BatterySipper> batterySippers = mBatteryStatsHelper.getUsageList();
for (int i = 0, size = batterySippers.size(); i < size; i++) {
final BatterySipper batterySipper = batterySippers.get(i);
@@ -84,13 +86,21 @@ public class HighUsageDetector implements BatteryTipDetector {
}
}
// When in test mode, add an app if necessary
if (mPolicy.testHighUsageTip && mHighUsageAppList.isEmpty()) {
mHighUsageAppList.add(new AppInfo.Builder()
.setPackageName("com.android.settings")
.setScreenOnTimeMs(TimeUnit.HOURS.toMillis(3))
.build());
}
Collections.sort(mHighUsageAppList, Collections.reverseOrder());
mHighUsageAppList = mHighUsageAppList.subList(0,
Math.min(mPolicy.highUsageAppCount, mHighUsageAppList.size()));
}
}
return new HighUsageTip(screenUsageTimeMs, mHighUsageAppList);
return new HighUsageTip(lastFullChargeTimeMs, mHighUsageAppList);
}
@VisibleForTesting

View File

@@ -38,10 +38,10 @@ public class SmartBatteryDetector implements BatteryTipDetector {
@Override
public BatteryTip detect() {
// Show it if there is no other tips shown
final boolean smartBatteryOn = Settings.Global.getInt(mContentResolver,
Settings.Global.APP_STANDBY_ENABLED, 1) != 0;
final boolean smartBatteryOff = Settings.Global.getInt(mContentResolver,
Settings.Global.APP_STANDBY_ENABLED, 1) == 0 || mPolicy.testSmartBatteryTip;
final int state =
smartBatteryOn ? BatteryTip.StateType.INVISIBLE : BatteryTip.StateType.NEW;
smartBatteryOff ? BatteryTip.StateType.NEW : BatteryTip.StateType.INVISIBLE;
return new SmartBatteryTip(state);
}
}

View File

@@ -26,7 +26,7 @@ import com.android.settings.R;
import com.android.settings.fuelgauge.batterytip.AppInfo;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
import com.android.settingslib.utils.StringUtil;
import java.util.List;
/**
@@ -34,28 +34,28 @@ import java.util.List;
*/
public class HighUsageTip extends BatteryTip {
private final long mScreenTimeMs;
private final long mLastFullChargeTimeMs;
@VisibleForTesting
final List<AppInfo> mHighUsageAppList;
public HighUsageTip(long screenTimeMs, List<AppInfo> appList) {
public HighUsageTip(long lastFullChargeTimeMs, List<AppInfo> appList) {
super(TipType.HIGH_DEVICE_USAGE, appList.isEmpty() ? StateType.INVISIBLE : StateType.NEW,
true /* showDialog */);
mScreenTimeMs = screenTimeMs;
mLastFullChargeTimeMs = lastFullChargeTimeMs;
mHighUsageAppList = appList;
}
@VisibleForTesting
HighUsageTip(Parcel in) {
super(in);
mScreenTimeMs = in.readLong();
mLastFullChargeTimeMs = in.readLong();
mHighUsageAppList = in.createTypedArrayList(AppInfo.CREATOR);
}
@Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeLong(mScreenTimeMs);
dest.writeLong(mLastFullChargeTimeMs);
dest.writeTypedList(mHighUsageAppList);
}
@@ -91,8 +91,8 @@ public class HighUsageTip extends BatteryTip {
}
}
public long getScreenTimeMs() {
return mScreenTimeMs;
public long getLastFullChargeTimeMs() {
return mLastFullChargeTimeMs;
}
public List<AppInfo> getHighUsageAppList() {

View File

@@ -47,6 +47,7 @@ public class GestureSettings extends DashboardFragment {
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 static final String KEY_SWIPE_UP = "gesture_swipe_up_input_summary";
private AmbientDisplayConfiguration mAmbientDisplayConfig;
@@ -65,19 +66,6 @@ public class GestureSettings extends DashboardFragment {
return R.xml.gestures;
}
@Override
protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
return buildPreferenceControllers(context, getLifecycle());
}
static List<AbstractPreferenceController> buildPreferenceControllers(
@NonNull Context context, @Nullable Lifecycle lifecycle) {
final List<AbstractPreferenceController> controllers = new ArrayList<>();
controllers.add(new PreventRingingPreferenceController(
context, lifecycle, UserHandle.myUserId(), KEY_PREVENT_RINGING));
return controllers;
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
@@ -103,12 +91,6 @@ public class GestureSettings extends DashboardFragment {
return Arrays.asList(sir);
}
@Override
public List<AbstractPreferenceController> createPreferenceControllers(
Context context) {
return buildPreferenceControllers(context, null);
}
@Override
public List<String> getNonIndexableKeys(Context context) {
List<String> keys = super.getNonIndexableKeys(context);
@@ -117,8 +99,10 @@ public class GestureSettings extends DashboardFragment {
keys.add(KEY_SWIPE_DOWN);
keys.add(KEY_DOUBLE_TAP_POWER);
keys.add(KEY_DOUBLE_TWIST);
keys.add(KEY_SWIPE_UP);
keys.add(KEY_DOUBLE_TAP_SCREEN);
keys.add(KEY_PICK_UP);
keys.add(KEY_PREVENT_RINGING);
return keys;
}

View File

@@ -27,6 +27,7 @@ import com.android.settings.core.BasePreferenceController;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.core.AbstractPreferenceController;
import java.util.ArrayList;
import java.util.List;
public class GesturesSettingPreferenceController extends BasePreferenceController {
@@ -63,8 +64,7 @@ public class GesturesSettingPreferenceController extends BasePreferenceControlle
@NonNull Context context) {
final AmbientDisplayConfiguration ambientDisplayConfiguration =
new AmbientDisplayConfiguration(context);
final List<AbstractPreferenceController> controllers =
GestureSettings.buildPreferenceControllers(context, null);
final List<AbstractPreferenceController> controllers = new ArrayList<>();
controllers.add(new AssistGestureSettingsPreferenceController(context, FAKE_PREF_KEY)
.setAssistOnly(false));
@@ -75,6 +75,7 @@ public class GesturesSettingPreferenceController extends BasePreferenceControlle
.setConfig(ambientDisplayConfiguration));
controllers.add(new DoubleTapScreenPreferenceController(context, FAKE_PREF_KEY)
.setConfig(ambientDisplayConfiguration));
controllers.add(new PreventRingingPreferenceController(context, FAKE_PREF_KEY));
return controllers;
}

View File

@@ -63,19 +63,6 @@ public class PreventRingingGestureSettings extends DashboardFragment {
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
@@ -85,12 +72,6 @@ public class PreventRingingGestureSettings extends DashboardFragment {
sir.xmlResId = R.xml.prevent_ringing_gesture_settings;
return Arrays.asList(sir);
}
@Override
public List<AbstractPreferenceController> createPreferenceControllers(
Context context) {
return buildPreferenceControllers(context, null /* lifecycle */);
}
};
}

View File

@@ -21,7 +21,6 @@ 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;
@@ -31,22 +30,20 @@ import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen;
import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
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
public class PreventRingingPreferenceController extends BasePreferenceController
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";
@@ -56,17 +53,15 @@ public class PreventRingingPreferenceController extends AbstractPreferenceContro
private final String SECURE_KEY = VOLUME_HUSH_GESTURE;
@UserIdInt
private final int mUserId;
public PreventRingingPreferenceController(Context context, String key) {
super(context, key);
}
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 int getAvailabilityStatus() {
return mContext.getResources().getBoolean(
com.android.internal.R.bool.config_volumeHushGestureEnabled)
? AVAILABLE : DISABLED_UNSUPPORTED;
}
@Override
@@ -144,21 +139,10 @@ public class PreventRingingPreferenceController extends AbstractPreferenceContro
}
}
@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);

View File

@@ -0,0 +1,81 @@
/*
* 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.content.SharedPreferences;
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.dashboard.suggestions.SuggestionFeatureProvider;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settingslib.search.SearchIndexable;
import java.util.Arrays;
import java.util.List;
@SearchIndexable
public class SwipeUpGestureSettings extends DashboardFragment {
private static final String TAG = "SwipeUpGesture";
public static final String PREF_KEY_SUGGESTION_COMPLETE =
"pref_swipe_up_suggestion_complete";
@Override
public void onAttach(Context context) {
super.onAttach(context);
SuggestionFeatureProvider suggestionFeatureProvider = FeatureFactory.getFactory(context)
.getSuggestionFeatureProvider(context);
SharedPreferences prefs = suggestionFeatureProvider.getSharedPrefs(context);
prefs.edit().putBoolean(PREF_KEY_SUGGESTION_COMPLETE, true).apply();
}
@Override
public int getMetricsCategory() {
return MetricsProto.MetricsEvent.SETTINGS_GESTURE_SWIPE_UP;
}
@Override
protected String getLogTag() {
return TAG;
}
@Override
protected int getPreferenceScreenResId() {
return R.xml.swipe_up_gesture_settings;
}
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.swipe_up_gesture_settings;
return Arrays.asList(sir);
}
@Override
protected boolean isPageSearchEnabled(Context context) {
return SwipeUpPreferenceController.isGestureAvailable(context);
}
};
}

View File

@@ -0,0 +1,76 @@
/*
* 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.content.SharedPreferences;
import android.content.res.Resources;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
import android.support.annotation.VisibleForTesting;
import android.text.TextUtils;
import com.android.settings.R;
import com.android.settings.Utils;
public class SwipeUpPreferenceController extends GesturePreferenceController {
private final int ON = 1;
private final int OFF = 0;
private static final String PREF_KEY_VIDEO = "gesture_swipe_up_video";
private final UserManager mUserManager;
public SwipeUpPreferenceController(Context context, String key) {
super(context, key);
mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
}
static boolean isGestureAvailable(Context context) {
return true;
}
@Override
public int getAvailabilityStatus() {
return isGestureAvailable(mContext) ? AVAILABLE : DISABLED_UNSUPPORTED;
}
@Override
protected String getVideoPrefKey() {
return PREF_KEY_VIDEO;
}
@Override
public boolean setChecked(boolean isChecked) {
setSwipeUpPreference(mContext, mUserManager, isChecked ? ON : OFF);
return true;
}
public static void setSwipeUpPreference(Context context, UserManager userManager,
int enabled) {
Settings.Secure.putInt(context.getContentResolver(),
Settings.Secure.SWIPE_UP_TO_SWITCH_APPS_ENABLED, enabled);
}
@Override
public boolean isChecked() {
final int swipeUpEnabled = Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.SWIPE_UP_TO_SWITCH_APPS_ENABLED, OFF);
return swipeUpEnabled != OFF;
}
}

View File

@@ -27,17 +27,17 @@ import android.support.v7.preference.PreferenceScreen;
import com.android.internal.telephony.TelephonyIntents;
import com.android.internal.telephony.TelephonyProperties;
import com.android.settings.AirplaneModeEnabler;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.core.TogglePreferenceController;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.R;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnPause;
import com.android.settingslib.core.lifecycle.events.OnResume;
public class AirplaneModePreferenceController extends AbstractPreferenceController
implements PreferenceControllerMixin, LifecycleObserver, OnResume, OnPause {
public class AirplaneModePreferenceController extends TogglePreferenceController
implements LifecycleObserver, OnResume, OnPause,
AirplaneModeEnabler.OnAirplaneModeChangedListener {
public static final int REQUEST_CODE_EXIT_ECM = 1;
@@ -45,18 +45,21 @@ public class AirplaneModePreferenceController extends AbstractPreferenceControll
private static final String EXIT_ECM_RESULT = "exit_ecm_result";
private final Fragment mFragment;
private Fragment mFragment;
private final MetricsFeatureProvider mMetricsFeatureProvider;
private AirplaneModeEnabler mAirplaneModeEnabler;
private SwitchPreference mAirplaneModePreference;
public AirplaneModePreferenceController(Context context, Fragment hostFragment) {
super(context);
mFragment = hostFragment;
public AirplaneModePreferenceController(Context context, String key) {
super(context, key);
mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
}
public void setFragment(Fragment hostFragment) {
mFragment = hostFragment;
}
@Override
public boolean handlePreferenceTreeClick(Preference preference) {
if (KEY_TOGGLE_AIRPLANE.equals(preference.getKey()) && Boolean.parseBoolean(
@@ -75,30 +78,22 @@ public class AirplaneModePreferenceController extends AbstractPreferenceControll
@Override
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
if (isAvailable()) {
mAirplaneModePreference = (SwitchPreference) screen.findPreference(getPreferenceKey());
if (mAirplaneModePreference != null) {
mAirplaneModeEnabler = new AirplaneModeEnabler(mContext, mAirplaneModePreference,
mMetricsFeatureProvider);
}
} else {
setVisible(screen, getPreferenceKey(), false /* visible */);
mAirplaneModeEnabler = new AirplaneModeEnabler(mContext, mMetricsFeatureProvider, this);
}
}
@Override
public boolean isAvailable() {
return isAvailable(mContext);
}
public static boolean isAvailable(Context context) {
return context.getResources().getBoolean(R.bool.config_show_toggle_airplane)
&& !context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK);
}
@Override
public String getPreferenceKey() {
return KEY_TOGGLE_AIRPLANE;
@AvailabilityStatus
public int getAvailabilityStatus() {
return isAvailable(mContext) ? AVAILABLE : DISABLED_UNSUPPORTED;
}
public void onResume() {
@@ -122,4 +117,23 @@ public class AirplaneModePreferenceController extends AbstractPreferenceControll
mAirplaneModePreference.isChecked());
}
}
@Override
public boolean isChecked() {
return mAirplaneModeEnabler.isAirplaneModeOn();
}
@Override
public boolean setChecked(boolean isChecked) {
if (isChecked() == isChecked) {
return false;
}
mAirplaneModeEnabler.setAirplaneMode(isChecked);
return true;
}
@Override
public void onAirplaneModeChanged(boolean isAirplaneModeOn) {
mAirplaneModePreference.setChecked(isAirplaneModeOn);
}
}

View File

@@ -73,6 +73,8 @@ public class NetworkDashboardFragment extends DashboardFragment implements
public void onAttach(Context context) {
super.onAttach(context);
mNetworkResetController = new NetworkResetActionMenuController(context, MENU_NETWORK_RESET);
use(AirplaneModePreferenceController.class).setFragment(this);
}
@Override
@@ -96,8 +98,6 @@ public class NetworkDashboardFragment extends DashboardFragment implements
private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
Lifecycle lifecycle, MetricsFeatureProvider metricsFeatureProvider, Fragment fragment,
MobilePlanPreferenceHost mobilePlanHost) {
final AirplaneModePreferenceController airplaneModePreferenceController =
new AirplaneModePreferenceController(context, fragment);
final MobilePlanPreferenceController mobilePlanPreferenceController =
new MobilePlanPreferenceController(context, mobilePlanHost);
final WifiMasterSwitchPreferenceController wifiPreferenceController =
@@ -110,7 +110,6 @@ public class NetworkDashboardFragment extends DashboardFragment implements
new PrivateDnsPreferenceController(context);
if (lifecycle != null) {
lifecycle.addObserver(airplaneModePreferenceController);
lifecycle.addObserver(mobilePlanPreferenceController);
lifecycle.addObserver(wifiPreferenceController);
lifecycle.addObserver(mobileNetworkPreferenceController);
@@ -119,7 +118,6 @@ public class NetworkDashboardFragment extends DashboardFragment implements
}
final List<AbstractPreferenceController> controllers = new ArrayList<>();
controllers.add(airplaneModePreferenceController);
controllers.add(mobileNetworkPreferenceController);
controllers.add(new TetherPreferenceController(context, lifecycle));
controllers.add(vpnPreferenceController);

View File

@@ -159,9 +159,10 @@ public class VpnPreferenceController extends AbstractPreferenceController
ThreadUtils.postOnMainThread(() -> mPreference.setSummary(summary));
}
private String getNameForVpnConfig(VpnConfig cfg, UserHandle user) {
@VisibleForTesting
String getNameForVpnConfig(VpnConfig cfg, UserHandle user) {
if (cfg.legacy) {
return mContext.getString(R.string.bluetooth_connected);
return mContext.getString(R.string.wifi_display_status_connected);
}
// The package name for an active VPN is stored in the 'user' field of its VpnConfig
final String vpnPackage = cfg.user;

View File

@@ -167,9 +167,9 @@ public class AppNotificationSettings extends NotificationSettingsBase {
getPreferenceScreen().addPreference(groupCategory);
mDynamicPreferences.add(groupCategory);
if (group.getId() == null) {
groupCategory.setTitle(mChannelGroupList.size() > 1
? R.string.notification_channels_other
: R.string.notification_channels);
if (mChannelGroupList.size() > 1) {
groupCategory.setTitle(R.string.notification_channels_other);
}
groupCategory.setKey(KEY_GENERAL_CATEGORY);
} else {
groupCategory.setTitle(group.getName());

View File

@@ -57,7 +57,7 @@ public class BadgePreferenceController extends NotificationPreferenceController
return false;
}
if (mChannel != null) {
if (NotificationChannel.DEFAULT_CHANNEL_ID.equals(mChannel.getId())) {
if (isDefaultChannel()) {
return true;
} else {
return mAppRow.showBadge;

View File

@@ -98,8 +98,7 @@ public class BlockPreferenceController extends NotificationPreferenceController
// it was blocked and we are unblocking it.
if (blocked || originalImportance == IMPORTANCE_NONE) {
final int importance = blocked ? IMPORTANCE_NONE
: DEFAULT_CHANNEL_ID.equals(mChannel.getId())
? IMPORTANCE_UNSPECIFIED : IMPORTANCE_DEFAULT;
: isDefaultChannel() ? IMPORTANCE_UNSPECIFIED : IMPORTANCE_DEFAULT;
mChannel.setImportance(importance);
saveChannel();
}

View File

@@ -26,11 +26,13 @@ import android.os.UserHandle;
import android.provider.SearchIndexableResource;
import android.support.annotation.VisibleForTesting;
import android.support.v7.preference.Preference;
import android.text.TextUtils;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.RingtonePreference;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.dashboard.SummaryLoader;
import com.android.settings.gestures.SwipeToNotificationPreferenceController;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable;
@@ -153,6 +155,54 @@ public class ConfigureNotificationSettings extends DashboardFragment {
}
}
/**
* For summary
*/
static class SummaryProvider implements SummaryLoader.SummaryProvider {
private final Context mContext;
private final SummaryLoader mSummaryLoader;
private NotificationBackend mBackend;
public SummaryProvider(Context context, SummaryLoader summaryLoader) {
mContext = context;
mSummaryLoader = summaryLoader;
mBackend = new NotificationBackend();
}
@VisibleForTesting
protected void setBackend(NotificationBackend backend) {
mBackend = backend;
}
@Override
public void setListening(boolean listening) {
if (!listening) {
return;
}
int blockedAppCount = mBackend.getBlockedAppCount();
if (blockedAppCount == 0) {
mSummaryLoader.setSummary(this,
mContext.getText(R.string.app_notification_listing_summary_zero));
} else {
mSummaryLoader.setSummary(this,
mContext.getResources().getQuantityString(
R.plurals.app_notification_listing_summary_others,
blockedAppCount, blockedAppCount));
}
}
}
public static final SummaryLoader.SummaryProviderFactory SUMMARY_PROVIDER_FACTORY =
new SummaryLoader.SummaryProviderFactory() {
@Override
public SummaryLoader.SummaryProvider createSummaryProvider(Activity activity,
SummaryLoader summaryLoader) {
return new ConfigureNotificationSettings.SummaryProvider(
activity, summaryLoader);
}
};
/**
* For Search.
*/

View File

@@ -31,6 +31,8 @@ import com.android.settings.applications.LayoutPreference;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.widget.EntityHeaderController;
import java.util.Objects;
public class HeaderPreferenceController extends NotificationPreferenceController
implements PreferenceControllerMixin {
@@ -72,7 +74,7 @@ public class HeaderPreferenceController extends NotificationPreferenceController
}
CharSequence getLabel() {
return mChannel != null ? mChannel.getName()
return (mChannel != null && !isDefaultChannel()) ? mChannel.getName()
: mChannelGroup != null
? mChannelGroup.getName()
: mAppRow.label;
@@ -80,7 +82,7 @@ public class HeaderPreferenceController extends NotificationPreferenceController
@Override
public CharSequence getSummary() {
if (mChannel != null) {
if (mChannel != null && !isDefaultChannel()) {
if (mChannelGroup != null
&& !TextUtils.isEmpty(mChannelGroup.getName())) {
final SpannableStringBuilder summary = new SpannableStringBuilder();

View File

@@ -58,7 +58,7 @@ public class ImportancePreferenceController extends NotificationPreferenceContro
if (mChannel == null) {
return false;
}
return !NotificationChannel.DEFAULT_CHANNEL_ID.equals(mChannel.getId());
return !isDefaultChannel();
}
@Override

View File

@@ -50,8 +50,9 @@ public class LightsPreferenceController extends NotificationPreferenceController
if (mChannel == null) {
return false;
}
return checkCanBeVisible(NotificationManager.IMPORTANCE_DEFAULT) && canPulseLight()
&& !NotificationChannel.DEFAULT_CHANNEL_ID.equals(mChannel.getId());
return checkCanBeVisible(NotificationManager.IMPORTANCE_DEFAULT)
&& canPulseLight()
&& !isDefaultChannel();
}
public void updateState(Preference preference) {

View File

@@ -250,6 +250,15 @@ public class NotificationBackend {
}
}
public int getBlockedAppCount() {
try {
return sINM.getBlockedAppCount(UserHandle.myUserId());
} catch (Exception e) {
Log.w(TAG, "Error calling NoMan", e);
return 0;
}
}
static class Row {
public String section;
}

View File

@@ -184,4 +184,11 @@ public abstract class NotificationPreferenceController extends AbstractPreferenc
protected boolean hasValidGroup() {
return mChannelGroup != null;
}
protected final boolean isDefaultChannel() {
if (mChannel == null) {
return false;
}
return Objects.equals(NotificationChannel.DEFAULT_CHANNEL_ID, mChannel.getId());
}
}

View File

@@ -37,14 +37,13 @@ import android.util.Log;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
import com.android.settings.applications.AppInfoBase;
import com.android.settings.applications.InstalledAppCounter;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.core.SubSettingLauncher;
import com.android.settingslib.TwoTargetPreference;
import com.android.settingslib.applications.AppUtils;
import com.android.settingslib.applications.ApplicationsState;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.utils.StringUtil;
import com.android.settingslib.wrapper.PackageManagerWrapper;
import java.util.ArrayList;
import java.util.Arrays;
@@ -211,6 +210,7 @@ public class RecentNotifyingAppsPreferenceController extends AbstractPreferenceC
pref.setKey(pkgName);
pref.setTitle(appEntry.label);
pref.setIcon(mIconDrawableFactory.getBadgedIcon(appEntry.info));
pref.setIconSize(TwoTargetPreference.ICON_SIZE_SMALL);
pref.setSummary(StringUtil.formatRelativeTime(mContext,
System.currentTimeMillis() - app.getLastNotified(), true));
pref.setOrder(i);

View File

@@ -59,8 +59,7 @@ public class SoundPreferenceController extends NotificationPreferenceController
if (mChannel == null) {
return false;
}
return checkCanBeVisible(NotificationManager.IMPORTANCE_DEFAULT)
&& !NotificationChannel.DEFAULT_CHANNEL_ID.equals(mChannel.getId());
return checkCanBeVisible(NotificationManager.IMPORTANCE_DEFAULT) && !isDefaultChannel();
}
@Override

View File

@@ -47,7 +47,7 @@ public class VibrationPreferenceController extends NotificationPreferenceControl
return false;
}
return checkCanBeVisible(NotificationManager.IMPORTANCE_DEFAULT)
&& !NotificationChannel.DEFAULT_CHANNEL_ID.equals(mChannel.getId())
&& !isDefaultChannel()
&& mVibrator != null
&& mVibrator.hasVibrator();
}

View File

@@ -0,0 +1,106 @@
/*
* 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.notification;
import android.app.Activity;
import android.app.NotificationManager;
import android.content.Intent;
import android.os.Bundle;
import android.provider.Settings;
import android.support.annotation.VisibleForTesting;
import android.view.View;
import android.widget.CheckBox;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
public class ZenOnboardingActivity extends Activity {
private NotificationManager mNm;
private MetricsLogger mMetrics;
CheckBox mScreenOn;
CheckBox mScreenOff;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setNotificationManager(getSystemService(NotificationManager.class));
setMetricsLogger(new MetricsLogger());
setupUI();
}
@VisibleForTesting
protected void setupUI() {
setContentView(R.layout.zen_onboarding);
mScreenOn = findViewById(R.id.screen_on_option);
mScreenOff = findViewById(R.id.screen_off_option);
mScreenOn.setChecked(true);
mScreenOff.setChecked(true);
mMetrics.visible(MetricsEvent.SETTINGS_ZEN_ONBOARDING);
}
@VisibleForTesting
protected void setNotificationManager(NotificationManager nm) {
mNm = nm;
}
@VisibleForTesting
protected void setMetricsLogger(MetricsLogger ml) {
mMetrics = ml;
}
public void logClick(View view) {
CheckBox checkbox = (CheckBox) view;
switch (checkbox.getId()) {
case R.id.screen_on_option:
mMetrics.action(MetricsEvent.ACTION_ZEN_ONBOARDING_SCREEN_ON, checkbox.isChecked());
break;
case R.id.screen_off_option:
mMetrics.action(MetricsEvent.ACTION_ZEN_ONBOARDING_SCREEN_OFF,
checkbox.isChecked());
break;
}
}
public void launchSettings(View button) {
mMetrics.action(MetricsEvent.ACTION_ZEN_ONBOARDING_SETTINGS);
Intent settings = new Intent(Settings.ZEN_MODE_BLOCKED_EFFECTS_SETTINGS);
settings.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(settings);
}
public void save(View button) {
mMetrics.action(MetricsEvent.ACTION_ZEN_ONBOARDING_OK);
NotificationManager.Policy policy = mNm.getNotificationPolicy();
int currentEffects = policy.suppressedVisualEffects;
currentEffects = NotificationManager.Policy.toggleScreenOnEffectsSuppressed(
currentEffects, mScreenOn != null && mScreenOn.isChecked());
currentEffects = NotificationManager.Policy.toggleScreenOffEffectsSuppressed(
currentEffects, mScreenOff != null && mScreenOff.isChecked());
NotificationManager.Policy newPolicy = new NotificationManager.Policy(
policy.priorityCategories, policy.priorityCallSenders,
policy.priorityMessageSenders, currentEffects);
mNm.setNotificationPolicy(newPolicy);
finishAndRemoveTask();
}
}

View File

@@ -654,7 +654,6 @@ public class ChooseLockGeneric extends SettingsActivity {
}
if (quality == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
mLockPatternUtils.setSeparateProfileChallengeEnabled(mUserId, true, mUserPassword);
mChooseLockSettingsHelper.utils().clearLock(mUserPassword, mUserId);
mChooseLockSettingsHelper.utils().setLockScreenDisabled(disabled, mUserId);
getActivity().setResult(Activity.RESULT_OK);

View File

@@ -33,6 +33,10 @@ 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,
Settings.ACTION_BATTERY_SAVER_SETTINGS,
Settings.ACTION_BLUETOOTH_SETTINGS,
"android.intent.action.POWER_USAGE_SUMMARY",
Settings.ACTION_SOUND_SETTINGS,
};
String TAG = "DeviceIndex";
@@ -40,7 +44,7 @@ public interface DeviceIndexFeatureProvider {
String INDEX_VERSION = "settings:index_version";
// Increment when new items are added to ensure they get pushed to the device index.
int VERSION = 1;
int VERSION = 2;
boolean isIndexingEnabled();

View File

@@ -40,8 +40,6 @@ import com.android.settings.core.SliderPreferenceController;
import com.android.settings.core.TogglePreferenceController;
import com.android.settings.overlay.FeatureFactory;
import androidx.slice.core.SliceHints;
/**
* Responds to actions performed on slices and notifies slices of updates in state changes.
*/
@@ -64,7 +62,7 @@ public class SliceBroadcastReceiver extends BroadcastReceiver {
handleToggleAction(context, key, isPlatformDefined);
break;
case ACTION_SLIDER_CHANGED:
int newPosition = intent.getIntExtra(SliceHints.EXTRA_RANGE_VALUE, -1);
int newPosition = intent.getIntExtra(Slice.EXTRA_RANGE_VALUE, -1);
handleSliderAction(context, key, newPosition);
break;
case ACTION_WIFI_CHANGED:

View File

@@ -17,6 +17,8 @@
package com.android.settings.slices;
import static androidx.slice.builders.ListBuilder.ICON_IMAGE;
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
import static com.android.settings.core.BasePreferenceController.DISABLED_DEPENDENT_SETTING;
import static com.android.settings.core.BasePreferenceController.DISABLED_FOR_USER;
import static com.android.settings.core.BasePreferenceController.DISABLED_UNSUPPORTED;
@@ -47,6 +49,7 @@ import com.android.settings.search.DatabaseIndexingUtils;
import com.android.settingslib.core.AbstractPreferenceController;
import android.support.v4.graphics.drawable.IconCompat;
import androidx.slice.Slice;
import androidx.slice.builders.ListBuilder;
import androidx.slice.builders.SliceAction;
@@ -75,7 +78,8 @@ public class SliceBuilderUtils {
// action name).
FeatureFactory.getFactory(context).getMetricsFeatureProvider()
.action(context, MetricsEvent.ACTION_SETTINGS_SLICE_REQUESTED, sliceNamePair);
if (!controller.isAvailable()) {
if (controller.getAvailabilityStatus() != AVAILABLE) {
return buildUnavailableSlice(context, sliceData, controller);
}
@@ -145,6 +149,57 @@ public class SliceBuilderUtils {
sliceData.getKey());
}
/**
* @return {@link PendingIntent} for a non-primary {@link SliceAction}.
*/
public static PendingIntent getActionIntent(Context context, String action, SliceData data) {
final Intent intent = new Intent(action);
intent.setClass(context, SliceBroadcastReceiver.class);
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);
}
/**
* @return {@link PendingIntent} for the primary {@link SliceAction}.
*/
public static PendingIntent getContentPendingIntent(Context context, SliceData sliceData) {
final Intent intent = getContentIntent(context, sliceData);
return PendingIntent.getActivity(context, 0 /* requestCode */, intent, 0 /* flags */);
}
/**
* @return {@link PendingIntent} to the Settings home page.
*/
public 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 */);
}
/**
* @return the summary text for a {@link Slice} built for {@param sliceData}.
*/
public static CharSequence getSubtitleText(Context context,
AbstractPreferenceController controller, SliceData sliceData) {
CharSequence summaryText;
if (controller != null) {
summaryText = controller.getSummary();
if (isValidSummary(context, summaryText)) {
return summaryText;
}
}
summaryText = sliceData.getSummary();
if (isValidSummary(context, summaryText)) {
return summaryText;
}
return "";
}
public static Uri getUri(String path, boolean isPlatformSlice) {
final String authority = isPlatformSlice
? SettingsSlicesContract.AUTHORITY
@@ -156,9 +211,20 @@ public class SliceBuilderUtils {
.build();
}
@VisibleForTesting
static Intent getContentIntent(Context context, SliceData sliceData) {
final Uri contentUri = new Uri.Builder().appendPath(sliceData.getKey()).build();
final Intent intent = DatabaseIndexingUtils.buildSearchResultPageIntent(context,
sliceData.getFragmentClassName(), sliceData.getKey(), sliceData.getScreenTitle(),
0 /* TODO */);
intent.setClassName(context.getPackageName(), SubSettings.class.getName());
intent.setData(contentUri);
return intent;
}
private static Slice buildToggleSlice(Context context, SliceData sliceData,
BasePreferenceController controller) {
final PendingIntent contentIntent = getContentIntent(context, sliceData);
final PendingIntent contentIntent = getContentPendingIntent(context, sliceData);
final Icon icon = Icon.createWithResource(context, sliceData.getIconResource());
final CharSequence subtitleText = getSubtitleText(context, controller, sliceData);
final TogglePreferenceController toggleController =
@@ -178,7 +244,7 @@ public class SliceBuilderUtils {
private static Slice buildIntentSlice(Context context, SliceData sliceData,
BasePreferenceController controller) {
final PendingIntent contentIntent = getContentIntent(context, sliceData);
final PendingIntent contentIntent = getContentPendingIntent(context, sliceData);
final Icon icon = Icon.createWithResource(context, sliceData.getIconResource());
final CharSequence subtitleText = getSubtitleText(context, controller, sliceData);
@@ -227,49 +293,6 @@ public class SliceBuilderUtils {
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, data.getKey());
intent.putExtra(EXTRA_SLICE_PLATFORM_DEFINED, data.isPlatformDefined());
return PendingIntent.getBroadcast(context, 0 /* requestCode */, intent,
PendingIntent.FLAG_CANCEL_CURRENT);
}
private static PendingIntent getContentIntent(Context context, SliceData sliceData) {
Intent intent = DatabaseIndexingUtils.buildSearchResultPageIntent(context,
sliceData.getFragmentClassName(), sliceData.getKey(), sliceData.getScreenTitle(),
0 /* TODO */);
intent.setClassName("com.android.settings", SubSettings.class.getName());
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) {
CharSequence summaryText;
if (controller != null) {
summaryText = controller.getSummary();
if (isValidSummary(context, summaryText)) {
return summaryText;
}
}
summaryText = sliceData.getSummary();
if (isValidSummary(context, summaryText)) {
return summaryText;
}
return "";
}
private static boolean isValidSummary(Context context, CharSequence summary) {
if (summary == null || TextUtils.isEmpty(summary.toString().trim())) {
return false;
@@ -298,12 +321,12 @@ public class SliceBuilderUtils {
break;
case DISABLED_FOR_USER:
summary = context.getString(R.string.disabled_for_user_setting_summary);
primaryAction = new SliceAction(getContentIntent(context, data),
primaryAction = new SliceAction(getContentPendingIntent(context, data),
(IconCompat) null /* actionIcon */, null /* actionTitle */);
break;
case DISABLED_DEPENDENT_SETTING:
summary = context.getString(R.string.disabled_dependent_setting_summary);
primaryAction = new SliceAction(getContentIntent(context, data),
primaryAction = new SliceAction(getContentPendingIntent(context, data),
(IconCompat) null /* actionIcon */, null /* actionTitle */);
break;
case UNAVAILABLE_UNKNOWN:

Some files were not shown because too many files have changed in this diff Show More