Commit 81bef1d7 authored by John Spurlock's avatar John Spurlock
Browse files

VolumeZen: Sound & Notifications settings.

- Add sound settings under the newly combined Sound & Notifications
  top-level settings page.
- New slider preferences for setting audio stream volumes.
- Migrate checkbox prefs to switch prefs.
- New settings subpage for touch sounds.
- New settings subpage for "Showing notifications"
- New setting pref for displaying intercepted notifications in zen mode.
- New tri-state lockscreen notifications pref.
- Add priority + sensitivity options to app notification dialog.
- Remove badges on app notifications row, migrate to subtitle text.
- Migrate strings to common spot in strings.xml
- Remove heads up setting.
- Remove tweaks category (unused).
- Clean up notification settings, separate out into a code section per option.
- Clean up _settings.xml files, prefix each pref with option name.
- Add appropriate indexing data to each settings page.

Depends on f/b change Ic30aa575ae07650cee62c8c1d83b6bc69395cf0d

Change-Id: If700385a7d0057f6c4c4bcf6e648dcf88b8ebff2
parent ba046c03
......@@ -1722,6 +1722,53 @@
android:resource="@id/notification_settings" />
</activity>
<activity android:name="Settings$NotificationDisplaySettingsActivity"
android:label="@string/notification_display_settings"
android:exported="true"
android:taskAffinity=""
android:excludeFromRecents="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="android.settings.ACTION_NOTIFICATION_DISPLAY_SETTINGS" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<meta-data android:name="com.android.settings.FRAGMENT_CLASS"
android:value="com.android.settings.notification.NotificationDisplaySettings" />
<meta-data android:name="com.android.settings.TOP_LEVEL_HEADER_ID"
android:resource="@id/notification_settings" />
</activity>
<activity android:name="Settings$TouchSoundSettingsActivity"
android:label="@string/touch_sound_settings"
android:exported="true"
android:taskAffinity=""
android:excludeFromRecents="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="android.settings.ACTION_TOUCH_SOUND_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.TouchSoundSettings" />
<meta-data android:name="com.android.settings.TOP_LEVEL_HEADER_ID"
android:resource="@id/notification_settings" />
</activity>
<activity android:name="Settings$AppNotificationSettingsActivity"
android:label="@string/app_notifications_title"
android:exported="true"
android:taskAffinity=""
android:excludeFromRecents="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="android.settings.ACTION_APP_NOTIFICATION_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.AppNotificationSettings" />
<meta-data android:name="com.android.settings.TOP_LEVEL_HEADER_ID"
android:resource="@id/notification_settings" />
</activity>
<!-- Show regulatory info (from settings item or dialing "*#07#") -->
<activity android:name="RegulatoryInfoDisplayActivity"
......
......@@ -12,8 +12,8 @@
-keep class com.android.settings.accounts.*
-keep class com.android.settings.fuelgauge.*
-keep class com.android.settings.users.*
-keep class com.android.settings.NotificationStation
-keep class com.android.settings.nfc.*
-keep class com.android.settings.notification.*
# Keep click responders
-keepclassmembers class com.android.settings.inputmethod.UserDictionaryAddWordActivity {
......
......@@ -33,26 +33,6 @@
android:contentDescription="@null"
android:scaleType="center" />
<ImageView
android:id="@android:id/icon1"
android:layout_width="@dimen/notification_app_icon_badge_size"
android:layout_height="@dimen/notification_app_icon_badge_size"
android:layout_marginLeft="@dimen/notification_app_icon_badge_margin"
android:layout_marginTop="@dimen/notification_app_icon_badge_margin"
android:background="#bb8b0000"
android:contentDescription="@null" />
<ImageView
android:id="@android:id/icon2"
android:layout_width="@dimen/notification_app_icon_badge_size"
android:layout_height="@dimen/notification_app_icon_badge_size"
android:layout_alignBottom="@android:id/icon"
android:layout_alignEnd="@android:id/icon"
android:layout_marginBottom="@dimen/notification_app_icon_badge_margin"
android:layout_marginEnd="@dimen/notification_app_icon_badge_margin"
android:background="#bb006400"
android:contentDescription="@null" />
<TextView
android:id="@android:id/title"
android:layout_width="match_parent"
......@@ -63,6 +43,18 @@
android:singleLine="true"
android:textAlignment="viewStart"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="@android:id/text1"
android:layout_width="match_parent"
android:layout_height="@dimen/notification_app_icon_size"
android:layout_toEndOf="@android:id/icon"
android:gravity="bottom"
android:ellipsize="end"
android:singleLine="true"
android:textAlignment="viewStart"
android:textColor="#888"
android:textAppearance="?android:attr/textAppearanceMedium" />
</RelativeLayout>
<View
......
......@@ -44,4 +44,22 @@
android:text="@string/app_notifications_dialog_show"
android:textAppearance="?android:attr/textAppearanceListItem" />
<CheckBox
android:id="@android:id/button2"
android:layout_width="match_parent"
android:layout_height="@dimen/notification_app_icon_size"
android:layout_below="@android:id/button1"
android:layout_marginStart="@dimen/content_margin_left"
android:text="@string/app_notifications_dialog_priority"
android:textAppearance="?android:attr/textAppearanceListItem" />
<CheckBox
android:id="@android:id/button3"
android:layout_width="match_parent"
android:layout_height="@dimen/notification_app_icon_size"
android:layout_below="@android:id/button2"
android:layout_marginStart="@dimen/content_margin_left"
android:text="@string/app_notifications_dialog_visibility"
android:textAppearance="?android:attr/textAppearanceListItem" />
</RelativeLayout>
\ No newline at end of file
......@@ -1028,63 +1028,6 @@
<!-- Summary of preference to manage device policies -->
<string name="manage_trust_agents_summary">View or deactivate trust agents</string>
<!-- Notification access settings (part of Security) -->
<!-- Title of preference to manage notification listeners -->
<string name="manage_notification_access">Notification access</string>
<!-- Summary of preference to manage notification listeners, when none are enabled -->
<string name="manage_notification_access_summary_zero">Apps cannot read notifications</string>
<!-- Summary of preference to manage notification listeners, when one or more are enabled
and are therefore able to read the user's notifications -->
<plurals name="manage_notification_access_summary_nonzero">
<item quantity="one">%d app can read notifications</item>
<item quantity="other">%d apps can read notifications</item>
</plurals>
<!-- String to show in the list of notification listeners, when none is installed -->
<string name="no_notification_listeners">No notification listeners are installed.</string>
<!-- Title for a warning message about security implications of enabling a notification
listener, displayed as a dialog message. [CHAR LIMIT=NONE] -->
<string name="notification_listener_security_warning_title">Enable
<xliff:g id="service" example="NotificationReader">%1$s</xliff:g>?</string>
<!-- Summary for a warning message about security implications of enabling a notification
listener, displayed as a dialog message. [CHAR LIMIT=NONE] -->
<string name="notification_listener_security_warning_summary">
<xliff:g id="notification_listener_name">%1$s</xliff:g> will be able to
read all notifications posted by the system or any installed app, which may include personal
information such as contact names and the text of messages sent to you. It will also be able
to dismiss these notifications or touch action buttons within them.
</string>
<!-- Title of preference to manage condition providers -->
<string name="manage_condition_providers">Condition providers</string>
<!-- Summary of preference to manage condition providers, when none are enabled -->
<string name="manage_condition_providers_summary_zero">No apps provide conditions</string>
<!-- Summary of preference to manage condition providers, when one or more are enabled -->
<plurals name="manage_condition_providers_summary_nonzero">
<item quantity="one">%d app provides conditions</item>
<item quantity="other">%d apps provide conditions</item>
</plurals>
<!-- String to show in the list of condition providers, when none is installed -->
<string name="no_condition_providers">No condition providers are installed.</string>
<!-- Title for a warning message about security implications of enabling a condition
provider, displayed as a dialog message. [CHAR LIMIT=NONE] -->
<string name="condition_provider_security_warning_title">Enable
<xliff:g id="service" example="ConditionProvider">%1$s</xliff:g>?</string>
<!-- Summary for a warning message about security implications of enabling a condition
provider, displayed as a dialog message. [CHAR LIMIT=NONE] -->
<string name="condition_provider_security_warning_summary">
<xliff:g id="condition_provider_name">%1$s</xliff:g> will be able to
add exit conditions to Do not disturb mode.
</string>
<!-- Bluetooth settings -->
<!-- Bluetooth settings check box title on Main Settings screen -->
<string name="bluetooth_quick_toggle_title">Bluetooth</string>
......@@ -1778,8 +1721,6 @@
<string name="display_settings_title">Display</string>
<!-- Sound settings screen heading -->
<string name="sound_settings">Sound</string>
<!-- Sound settings screen, setting option name to pick ringtone (a list dialog comes up)-->
<string name="ringtone_title">Phone ringtone</string>
<!-- Sound settings screen, setting option summary text -->
<string name="ringtone_summary">""</string>
<!-- Sound settings screen, volume title -->
......@@ -1792,8 +1733,6 @@
<string name="vibrate_in_silent_title">Vibrate when silent</string>
<!-- Sound settings screen, setting option name -->
<string name="notification_sound_title">Default notification sound</string>
<!-- Sound settings screen, notification light repeat pulsing title -->
<string name="notification_pulse_title">Pulse notification light</string>
<!-- Display settings screen, notification popups are enabled [CHAR LIMIT=30] -->
<string name="heads_up_enabled_title">Pop up if high priority</string>
<!-- Sound settings screen, the title of the volume bar to adjust the incoming call volume -->
......@@ -1839,9 +1778,6 @@
<string name="volume_notification_mute">Mute notifications</string>
<!-- Image description for alarm volume mute button. -->
<string name="volume_alarm_mute">Mute alarms</string>
<!-- Sound settings screen, setting option name checkbox. About vibration setting
during incoming calls. [CHAR LIMIT=30] -->
<string name="vibrate_when_ringing_title">Vibrate when ringing</string>
<!-- Dock settings title, top level -->
<string name="dock_settings">Dock</string>
......@@ -5110,39 +5046,6 @@
<!--Search Keywords-->
<string name="keywords_wifi">wifi wi-fi network connection</string>
<!-- Notifications on lockscreen -->
<!-- Label for checkbox controlling the contents of notifications shown on
the secure lockscreen [CHAR LIMIT=25] -->
<string name="lock_screen_notifications">When device is locked</string>
<!-- Summary for lock_screen_notifications: sensitive information will be
hidden or redacted from notifications shown on a secure lock screen
[CHAR LIMIT=50] -->
<string name="lock_screen_notifications_summary_hide">Hide sensitive notification content</string>
<!-- Summary for lock_screen_notifications: all information will be
shown in notifications shown on a secure lock screen
[CHAR LIMIT=50] -->
<string name="lock_screen_notifications_summary_show">Show all notification content</string>
<!-- [CHAR LIMIT=30] Notification settings screen, setting option name -->
<string name="title_zen_mode">Do not disturb</string>
<!-- [CHAR LIMIT=30] Zen mode settings screen, activity title -->
<string name="zen_mode_settings_title">Do not disturb</string>
<!-- [CHAR LIMIT=20] Notifications settings header -->
<string name="notification_settings">Notifications</string>
<!-- [CHAR LIMIT=20] Notifications settings: Tweaks section header (eng
builds only) -->
<string name="notification_settings_tweaks">Tweaks</string>
<!-- [CHAR LIMIT=20] Notifications settings: Apps section header -->
<string name="notification_settings_apps_title">App notifications</string>
<!-- [CHAR LIMIT=NONE] Content description for per-app notification
settings button -->
<string name="notification_app_settings_button">Notification settings</string>
<!-- NFC Wi-Fi pairing/setup strings-->
<!-- Write NFC tag for Wi-Fi pairing/setup title [CHAR_LIMIT=30]-->
......@@ -5163,17 +5066,170 @@
<!-- Option title for the default sound, context based on screen -->
<string name="default_sound">Default sound</string>
<!-- [CHAR LIMIT=NONE] Text when loading app list in notification settings -->
<string name="loading_notification_apps">Loading apps...</string>
<!-- [CHAR LIMIT=40] Notification settings: App notifications screen title -->
<!-- Sounds and Notifications -->
<!-- Sounds & notifications: Settings header. [CHAR LIMIT=20] -->
<string name="notification_settings">Sounds &amp; Notifications</string>
<!-- Sounds & notifications: Title for the option managing media volume. [CHAR LIMIT=NONE] -->
<string name="media_volume_option_title">Media volume</string>
<!-- Sounds & notifications: Title for the option managing alarm volume. [CHAR LIMIT=NONE] -->
<string name="alarm_volume_option_title">Alarm volume</string>
<!-- Sounds & notifications: Title for the option managing ringer volume. [CHAR LIMIT=NONE] -->
<string name="ring_volume_option_title">Ring volume</string>
<!-- Sounds & notifications: Title for the Do not disturb option and associated settings page. [CHAR LIMIT=NONE] -->
<string name="zen_mode_settings_title">Do not disturb</string>
<!-- Sounds & notifications: Title for the ringer mode option. [CHAR LIMIT=NONE] -->
<string name="ringer_mode_title">When calls and notifications arrive</string>
<!-- Sounds & notifications: Value for the ringer mode option when audible. [CHAR LIMIT=NONE] -->
<string name="ringer_mode_audible">Ring</string>
<!-- Sounds & notifications: Value for the ringer mode option when vibrate. [CHAR LIMIT=NONE] -->
<string name="ringer_mode_vibrate">Vibrate instead of ringing</string>
<!-- Sounds & notifications: Value for the ringer mode option when silent. [CHAR LIMIT=NONE] -->
<string name="ringer_mode_silent">Don\'t ring or vibrate</string>
<!-- Sounds & notifications: Title for the option defining the phone ringtone. [CHAR LIMIT=NONE] -->
<string name="ringtone_title">Phone ringtone</string>
<!-- Sounds & notifications: Title for the option defining the default notification ringtone. [CHAR LIMIT=NONE] -->
<string name="notification_ringtone_title">Default notification ringtone</string>
<!-- Sounds & notifications: Title for the option managing whether or not to vibrate when ringing. [CHAR LIMIT=NONE] -->
<string name="vibrate_when_ringing_title">Vibrate when ringing</string>
<!-- Sounds & notifications: Title for the showing notifications option and associated settings page. [CHAR LIMIT=NONE] -->
<string name="notification_display_settings">Showing notifications</string>
<!-- Sounds & notifications > Showing notifications: Title for the pulse notification light option. [CHAR LIMIT=NONE] -->
<string name="notification_pulse_title">Pulse notification light</string>
<!-- Sounds & notifications > Showing notifications: Title for the option controlling notifications on the lockscreen. [CHAR LIMIT=NONE] -->
<string name="lock_screen_notifications_title">When device is locked</string>
<!-- Sounds & notifications > Showing notifications: Value for lockscreen notifications: all information will be
shown in notifications shown on a secure lock screen
[CHAR LIMIT=50] -->
<string name="lock_screen_notifications_summary_show">Show all notification content</string>
<!-- Sounds & notifications > Showing notifications: Value for lockscreen notifications: sensitive information will be
hidden or redacted from notifications shown on a secure lock screen
[CHAR LIMIT=50] -->
<string name="lock_screen_notifications_summary_hide">Hide sensitive notification content</string>
<!-- Sounds & notifications > Showing notifications: Value for lockscreen notifications: notifications will not appear on a secure lock screen
[CHAR LIMIT=50] -->
<string name="lock_screen_notifications_summary_disable">Don\'t show notifications at all</string>
<!-- Sounds & notifications > Showing notifications: Title for the option managing notification display in zen mode. [CHAR LIMIT=NONE] -->
<string name="zen_mode_notifications_title">When do not disturb is on</string>
<!-- Sounds & notifications > Showing notifications: Value for zen mode notifications: notifications will be suppressed in zen mode [CHAR LIMIT=50] -->
<string name="zen_mode_notifications_summary_hide">Hide new notifications from the list</string>
<!-- Sounds & notifications > Showing notifications: Value for zen mode notifications: notifications will be displayed in zen mode [CHAR LIMIT=50] -->
<string name="zen_mode_notifications_summary_show">Show all notifications in the list</string>
<!-- Sounds & notifications > Showing notifications: Title for the option managing notifications per application. [CHAR LIMIT=NONE] -->
<string name="app_notifications_title">App notifications</string>
<!-- [CHAR LIMIT=30] Notification settings: App notifications dialog show option -->
<!-- Sounds & notifications: Title for the touch sounds option and associated settings page. [CHAR LIMIT=NONE] -->
<string name="touch_sound_settings">Touch sounds</string>
<!-- Sounds & notifications > Touch sounds: Title for the option enabling touch sounds for dial pad tones. [CHAR LIMIT=NONE] -->
<string name="dial_pad_tones_title">Dial pad tones</string>
<!-- Sounds & notifications > Touch sounds: Title for the option enabling touch sounds for screen locking and unlocking. [CHAR LIMIT=NONE] -->
<string name="screen_locking_sounds_title">Screen locking &amp; unlocking</string>
<!-- Sounds & notifications > Touch sounds: Title for the option enabling other touch sounds. [CHAR LIMIT=NONE] -->
<string name="other_touch_sounds_title">Other touch sounds</string>
<!-- Sounds & notifications > Touch sounds: Title for the option enabling haptic feedback on touch. [CHAR LIMIT=NONE] -->
<string name="vibrate_on_touch_title">Vibrate on touch</string>
<!-- Sounds & notifications: Title for managing notification listeners option. [CHAR LIMIT=NONE] -->
<string name="manage_notification_access_title">Notification access</string>
<!-- Summary of preference to manage notification listeners, when none are enabled -->
<string name="manage_notification_access_summary_zero">Apps cannot read notifications</string>
<!-- Summary of preference to manage notification listeners, when one or more are enabled
and are therefore able to read the user's notifications -->
<plurals name="manage_notification_access_summary_nonzero">
<item quantity="one">%d app can read notifications</item>
<item quantity="other">%d apps can read notifications</item>
</plurals>
<!-- String to show in the list of notification listeners, when none is installed -->
<string name="no_notification_listeners">No notification listeners are installed.</string>
<!-- Title for a warning message about security implications of enabling a notification
listener, displayed as a dialog message. [CHAR LIMIT=NONE] -->
<string name="notification_listener_security_warning_title">Enable
<xliff:g id="service" example="NotificationReader">%1$s</xliff:g>?</string>
<!-- Summary for a warning message about security implications of enabling a notification
listener, displayed as a dialog message. [CHAR LIMIT=NONE] -->
<string name="notification_listener_security_warning_summary">
<xliff:g id="notification_listener_name">%1$s</xliff:g> will be able to
read all notifications posted by the system or any installed app, which may include personal
information such as contact names and the text of messages sent to you. It will also be able
to dismiss these notifications or touch action buttons within them.
</string>
<!-- Title of preference to manage condition providers -->
<string name="manage_condition_providers">Condition providers</string>
<!-- Summary of preference to manage condition providers, when none are enabled -->
<string name="manage_condition_providers_summary_zero">No apps provide conditions</string>
<!-- Summary of preference to manage condition providers, when one or more are enabled -->
<plurals name="manage_condition_providers_summary_nonzero">
<item quantity="one">%d app provides conditions</item>
<item quantity="other">%d apps provide conditions</item>
</plurals>
<!-- String to show in the list of condition providers, when none is installed -->
<string name="no_condition_providers">No condition providers are installed.</string>
<!-- Title for a warning message about security implications of enabling a condition
provider, displayed as a dialog message. [CHAR LIMIT=NONE] -->
<string name="condition_provider_security_warning_title">Enable
<xliff:g id="service" example="ConditionProvider">%1$s</xliff:g>?</string>
<!-- Summary for a warning message about security implications of enabling a condition
provider, displayed as a dialog message. [CHAR LIMIT=NONE] -->
<string name="condition_provider_security_warning_summary">
<xliff:g id="condition_provider_name">%1$s</xliff:g> will be able to
add exit conditions to Do not disturb mode.
</string>
<!-- [CHAR LIMIT=NONE] Text when loading app list in notification settings -->
<string name="loading_notification_apps">Loading apps...</string>
<!-- [CHAR LIMIT=NONE] Notification settings: App notifications dialog show option -->
<string name="app_notifications_dialog_show">Show notifications</string>
<!-- [CHAR LIMIT=30] Notification settings: App notifications dialog priority option -->
<string name="app_notifications_dialog_priority">High priority</string>
<!-- [CHAR LIMIT=NONE] Notification settings: App notifications dialog priority option -->
<string name="app_notifications_dialog_priority">Display at the top of the list</string>
<!-- [CHAR LIMIT=NONE] Notification settings: App notifications dialog visibility option -->
<string name="app_notifications_dialog_visibility">Hide sensitive content when device is locked</string>
<!-- [CHAR LIMIT=20] Notification settings: App notifications row summary when banned -->
<string name="app_notification_row_banned">Blocked</string>
<!-- [CHAR LIMIT=20] Notification settings: App notifications row summary when high priority -->
<string name="app_notification_row_priority">Top of list</string>
<!-- [CHAR LIMIT=20] Notification settings: App notifications row summary when sensitive -->
<string name="app_notification_row_sensitive">Sensitive</string>
<!-- [CHAR LIMIT=20] Notification settings: App notifications dialog dismiss button caption -->
<string name="app_notifications_dialog_done">Done</string>
......@@ -5193,8 +5249,8 @@
<!-- [CHAR LIMIT=40] Zen mode settings: Entry conditions option: title -->
<string name="zen_mode_entry_conditions_title">Automatically turn on</string>
<!-- [CHAR LIMIT=40] Zen mode settings: Entry conditions option: summary condition divider -->
<string name="zen_mode_entry_conditions_summary_divider">, </string>
<!-- [CHAR LIMIT=40] General divider text when concatenating multiple items in a text summary -->
<string name="summary_divider_text">, </string>
<!-- [CHAR LIMIT=40] Zen mode settings: Entry conditions option: value when blank -->
<string name="zen_mode_entry_conditions_summary_none">Never</string>
......@@ -5241,6 +5297,14 @@
<!-- [CHAR LIMIT=20] Zen mode settings: End time option: Summary text value format -->
<string name="zen_mode_end_time_summary_format"><xliff:g id="formatted_time">%s</xliff:g> next day</string>
<!-- [CHAR LIMIT=20] Notifications settings: Apps section header -->
<string name="notification_settings_apps_title">App notifications</string>
<!-- [CHAR LIMIT=NONE] Content description for per-app notification
settings button -->
<string name="notification_app_settings_button">Notification settings</string>
<!-- [CHAR LIMIT=35] Feedback on the device -->
<string name="device_feedback">Send feedback about this device</string>
......
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2014 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"
android:title="@string/notification_display_settings"
android:key="notification_display_settings"
xmlns:settings="http://schemas.android.com/apk/res/com.android.settings">
<!-- Pulse notification light -->
<SwitchPreference
android:key="notification_pulse"
android:title="@string/notification_pulse_title"
android:switchTextOff=""
android:switchTextOn=""
android:persistent="false" />
<!-- When device is locked -->
<com.android.settings.notification.DropDownPreference
android:key="lock_screen_notifications"
android:title="@string/lock_screen_notifications_title"
android:persistent="false" />
<!-- When do not disturb is on -->
<com.android.settings.notification.DropDownPreference
android:key="zen_mode_notifications"
android:title="@string/zen_mode_notifications_title"
android:persistent="false" />
<!-- App notifications -->
<PreferenceScreen
android:key="app_notifications"
android:title="@string/app_notifications_title"
android:fragment="com.android.settings.notification.AppNotificationSettings" />
</PreferenceScreen>
......@@ -19,41 +19,78 @@
android:key="notification_settings"
xmlns:settings="http://schemas.android.com/apk/res/com.android.settings">
<com.android.settings.DefaultRingtonePreference
android:key="notification_sound"
android:title="@string/default_sound"
android:dialogTitle="@string/notification_sound_dialog_title"
android:persistent="false"
android:ringtoneType="notification" />
<!-- Media volume -->
<com.android.settings.notification.VolumeSeekBarPreference
android:key="media_volume"
android:icon="@*android:drawable/ic_audio_vol"
android:title="@string/media_volume_option_title" />
<CheckBoxPreference
android:key="notification_pulse"
android:title="@string/notification_pulse_title"
android:persistent="false" />
<!-- 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" />
<CheckBoxPreference
android:key="heads_up"
android:title="@string/heads_up_enabled_title"
android:persistent="false" />
<!-- 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" />
<!-- Do not disturb -->
<PreferenceScreen
android:key="zen_mode"
android:title="@string/zen_mode_settings_title"
android:fragment="com.android.settings.notification.ZenModeSettings" />
<!-- When calls and notifications arrive -->
<com.android.settings.notification.DropDownPreference
android:key="toggle_lock_screen_notifications"
android:title="@string/lock_screen_notifications"
android:key="ringer_mode"
android:title="@string/ringer_mode_title"
android:persistent="false" />
<PreferenceScreen
android:key="configure"
android:title="@string/notification_settings_apps_title"
android:fragment="com.android.settings.notification.AppNotificationSettings" />
<!-- Phone ringtone -->
<com.android.settings.DefaultRingtonePreference
android:key="ringtone"
android:title="@string/ringtone_title"
android:dialogTitle="@string/ringtone_title"
android:persistent="false"
android:ringtoneType="ringtone" />
<PreferenceScreen
android:key="zen_mode"
android:title="@string/title_zen_mode"
android:fragment="com.android.settings.notification.ZenModeSettings" />
<!-- Default notification ringtone -->
<com.android.settings.DefaultRingtonePreference
android:key="notification_ringtone"
android:title="@string/notification_ringtone_title"
android:dialogTitle="@string/notification_ringtone_title"
android:persistent="false"
android:ringtoneType="notification" />
<!-- Vibrate when ringing -->
<SwitchPreference
android:key="vibrate_when_ringing"
android:title="@string/vibrate_when_ringing_title"
android:switchTextOff=""
android:switchTextOn=""
android:persistent="false" />
<!-- Showing notifications -->
<Preference
android:key="showing_notifications"
android:title="@string/notification_display_settings"
android:persistent="false"
android:fragment="com.android.settings.notification.NotificationDisplaySettings" />
<!-- Touch sounds -->
<Preference
android:key="touch_sounds"
android:title="@string/touch_sound_settings"
android:persistent="false"
android:fragment="com.android.settings.notification.TouchSoundSettings" />
<!-- Notification access -->
<Preference
android:key="manage_notification_access"
android:title="@string/manage_notification_access"
android:title="@string/manage_notification_access_title"
android:persistent="false"
android:fragment="com.android.settings.notification.NotificationAccessSettings" />
......
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2014 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"
android:title="@string/touch_sound_settings"
android:key="touch_sound_settings"
xmlns:settings="http://schemas.android.com/apk/res/com.android.settings">
<!-- Dial pad tones -->
<SwitchPreference
android:key="dial_pad_tones"
android:title="@string/dial_pad_tones_title"
android:switchTextOff=""
android:switchTextOn=""
android:persistent="false" />
<!-- Screen locking / unlocking -->
<SwitchPreference
android:key="screen_locking_sounds"
android:title="@string/screen_locking_sounds_title"
android:switchTextOff=""
android:switchTextOn=""
android:persistent="false" />
<!-- Other touch sounds -->
<SwitchPreference
android:key="other_touch_sounds"
android:title="@string/other_touch_sounds_title"
android:switchTextOff=""
android:switchTextOn=""
android:persistent="false" />
<!-- Vibrate on touch -->
<SwitchPreference
android:key="vibrate_on_touch"
android:title="@string/vibrate_on_touch_title"
android:switchTextOff=""
android:switchTextOn=""
android:persistent="false" />
</PreferenceScreen>
......@@ -34,6 +34,7 @@ import android.os.Looper;
import android.os.Message;
import android.os.Parcel;
import android.os.Parcelable;
import android.preference.SeekBarVolumizer;
import android.preference.VolumePreference;
import android.provider.Settings;
import android.provider.Settings.System;
......@@ -173,10 +174,10 @@ public class RingerVolumePreference extends VolumePreference {
mSeekBars[i] = seekBar;
if (SEEKBAR_TYPE[i] == AudioManager.STREAM_MUSIC) {
mSeekBarVolumizer[i] = new SeekBarVolumizer(getContext(), seekBar,
SEEKBAR_TYPE[i], getMediaVolumeUri(getContext()));
SEEKBAR_TYPE[i], getMediaVolumeUri(getContext()), this);
} else {
mSeekBarVolumizer[i] = new SeekBarVolumizer(getContext(), seekBar,
SEEKBAR_TYPE[i]);
SEEKBAR_TYPE[i], null, this);
}
}
......@@ -275,7 +276,7 @@ public class RingerVolumePreference extends VolumePreference {
}
@Override
protected void onSampleStarting(SeekBarVolumizer volumizer) {
public void onSampleStarting(SeekBarVolumizer volumizer) {
super.onSampleStarting(volumizer);
for (SeekBarVolumizer vol : mSeekBarVolumizer) {
if (vol != null && vol != volumizer) vol.stopSample();
......
......@@ -88,6 +88,9 @@ public class Settings extends SettingsActivity {
public static class PrintJobSettingsActivity extends SettingsActivity { /* empty */ }
public static class ZenModeSettingsActivity extends SettingsActivity { /* empty */ }
public static class NotificationSettingsActivity extends SettingsActivity { /* empty */ }
public static class NotificationDisplaySettingsActivity extends SettingsActivity { /* empty */ }
public static class AppNotificationSettingsActivity extends SettingsActivity { /* empty */ }
public static class TouchSoundSettingsActivity extends SettingsActivity { /* empty */ }
public static class TopLevelSettings extends SettingsActivity { /* empty */ }
}
......
......@@ -29,11 +29,8 @@ import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.content.pm.Signature;
import android.graphics.Paint;
import android.graphics.Path;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.PathShape;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
......@@ -57,6 +54,9 @@ import android.widget.SectionIndexer;
import android.widget.TextView;
import com.android.settings.R;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable;
import com.android.settings.search.SearchIndexableRaw;
import java.text.Collator;
import java.util.ArrayList;
......@@ -64,7 +64,7 @@ import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class AppNotificationSettings extends ListFragment {
public class AppNotificationSettings extends ListFragment implements Indexable {
private static final String TAG = "AppNotificationSettings";
private static final boolean DEBUG = true;
......@@ -187,6 +187,9 @@ public class AppNotificationSettings extends ListFragment {
final TextView title = (TextView) layout.findViewById(android.R.id.title);
title.setText(row.label);
final CheckBox showBox = (CheckBox) layout.findViewById(android.R.id.button1);
final CheckBox priBox = (CheckBox) layout.findViewById(android.R.id.button2);
final CheckBox senBox = (CheckBox) layout.findViewById(android.R.id.button3);
showBox.setChecked(!row.banned);
final OnCheckedChangeListener showListener = new OnCheckedChangeListener() {
@Override
......@@ -195,6 +198,8 @@ public class AppNotificationSettings extends ListFragment {
if (success) {
row.banned = !isChecked;
mAdapter.bindView(v, row, true /*animate*/);
priBox.setEnabled(!row.banned);
senBox.setEnabled(!row.banned);
} else {
showBox.setOnCheckedChangeListener(null);
showBox.setChecked(!isChecked);
......@@ -203,6 +208,44 @@ public class AppNotificationSettings extends ListFragment {
}
};
showBox.setOnCheckedChangeListener(showListener);
priBox.setChecked(row.priority);
final OnCheckedChangeListener priListener = new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
boolean success = mBackend.setHighPriority(row.pkg, row.uid, isChecked);
if (success) {
row.priority = isChecked;
mAdapter.bindView(v, row, true /*animate*/);
} else {
priBox.setOnCheckedChangeListener(null);
priBox.setChecked(!isChecked);
priBox.setOnCheckedChangeListener(this);
}
}
};
priBox.setOnCheckedChangeListener(priListener);
senBox.setChecked(row.sensitive);
final OnCheckedChangeListener senListener = new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
boolean success = mBackend.setSensitive(row.pkg, row.uid, isChecked);
if (success) {
row.sensitive = isChecked;
mAdapter.bindView(v, row, true /*animate*/);
} else {
senBox.setOnCheckedChangeListener(null);
senBox.setChecked(!isChecked);
senBox.setOnCheckedChangeListener(this);
}
}
};
senBox.setOnCheckedChangeListener(senListener);
priBox.setEnabled(!row.banned);
senBox.setEnabled(!row.banned);
final AlertDialog d = new AlertDialog.Builder(mContext)
.setView(layout)
.setPositiveButton(R.string.app_notifications_dialog_done, null)
......@@ -214,48 +257,16 @@ public class AppNotificationSettings extends ListFragment {
ViewGroup row;
ViewGroup appButton;
ImageView icon;
ImageView banBadge;
ImageView priBadge;
TextView title;
TextView subtitle;
View settingsDivider;
ImageView settingsButton;
View rowDivider;
}
private class NotificationAppAdapter extends ArrayAdapter<Row> implements SectionIndexer {
private final ShapeDrawable mBanShape, mPriShape;
public NotificationAppAdapter(Context context) {
super(context, 0, 0);
final int s = context.getResources()
.getDimensionPixelSize(R.dimen.notification_app_icon_badge_size);
mBanShape = shape(banPath(s), s);
mPriShape = shape(priPath(s), s);
}
private ShapeDrawable shape(Path path, int s) {
final ShapeDrawable sd = new ShapeDrawable(new PathShape(path, s, s));
sd.getPaint().setStyle(Paint.Style.STROKE);
sd.getPaint().setColor(0xffffffff);
sd.getPaint().setStrokeWidth(s / 12);
sd.setIntrinsicWidth(s);
sd.setIntrinsicHeight(s);
return sd;
}
private Path banPath(int s) {
final Path p = new Path();
final int d = s / 5;
p.moveTo(d, d); p.lineTo(s - d, s - d);
p.moveTo(d, s - d); p.lineTo(s - d, d);
return p;
}
private Path priPath(int s) {
final Path p = new Path();
final int d = s / 5;
p.moveTo(s / 2, d); p.lineTo(s / 2, s - d);
return p;
}
@Override
......@@ -302,11 +313,8 @@ public class AppNotificationSettings extends ListFragment {
vh.appButton = (ViewGroup) v.findViewById(android.R.id.button1);
vh.appButton.setLayoutTransition(new LayoutTransition());
vh.icon = (ImageView) v.findViewById(android.R.id.icon);
vh.banBadge = (ImageView) v.findViewById(android.R.id.icon1);
vh.banBadge.setImageDrawable(mBanShape);
vh.priBadge = (ImageView) v.findViewById(android.R.id.icon2);
vh.priBadge.setImageDrawable(mPriShape);
vh.title = (TextView) v.findViewById(android.R.id.title);
vh.subtitle = (TextView) v.findViewById(android.R.id.text1);
vh.settingsDivider = v.findViewById(R.id.settings_divider);
vh.settingsButton = (ImageView) v.findViewById(android.R.id.button2);
vh.rowDivider = v.findViewById(R.id.row_divider);
......@@ -326,6 +334,7 @@ public class AppNotificationSettings extends ListFragment {
public void bindView(final View view, Row r, boolean animate) {
if (!(r instanceof AppRow)) {
// it's a section row
TextView tv = (TextView)view;
tv.setText(r.section);
return;
......@@ -343,9 +352,10 @@ public class AppNotificationSettings extends ListFragment {
});
enableLayoutTransitions(vh.appButton, animate);
vh.icon.setImageDrawable(row.icon);
vh.banBadge.setVisibility(row.banned ? View.VISIBLE : View.GONE);
vh.priBadge.setVisibility(row.priority ? View.VISIBLE : View.GONE);
vh.title.setText(row.label);
final String sub = getSubtitle(row);
vh.subtitle.setText(sub);
vh.subtitle.setVisibility(!sub.isEmpty() ? View.VISIBLE : View.GONE);
final boolean showSettings = !row.banned && row.settingsIntent != null;
vh.settingsDivider.setVisibility(showSettings ? View.VISIBLE : View.GONE);
vh.settingsButton.setVisibility(showSettings ? View.VISIBLE : View.GONE);
......@@ -359,6 +369,17 @@ public class AppNotificationSettings extends ListFragment {
});
}
private String getSubtitle(AppRow row) {
if (row.banned) return mContext.getString(R.string.app_notification_row_banned);
if (!row.priority && !row.sensitive) return "";
final String priString = mContext.getString(R.string.app_notification_row_priority);
final String senString = mContext.getString(R.string.app_notification_row_sensitive);
if (row.priority != row.sensitive) {
return row.priority ? priString : senString;
}
return priString + mContext.getString(R.string.summary_divider_text) + senString;
}
@Override
public Object[] getSections() {
return mSections.toArray(new Object[mSections.size()]);
......@@ -396,7 +417,8 @@ public class AppNotificationSettings extends ListFragment {
public Intent settingsIntent;
public boolean banned;
public boolean priority;
public boolean first;
public boolean sensitive;
public boolean first; // first app in section
}
private static final Comparator<AppRow> mRowComparator = new Comparator<AppRow>() {
......@@ -435,6 +457,7 @@ public class AppNotificationSettings extends ListFragment {
row.icon = pkg.applicationInfo.loadIcon(pm);
row.banned = mBackend.getNotificationsBanned(row.pkg, row.uid);
row.priority = mBackend.getHighPriority(row.pkg, row.uid);
row.sensitive = mBackend.getSensitive(row.pkg, row.uid);
mRows.put(row.pkg, row);
}
// collect config activities
......@@ -552,5 +575,38 @@ public class AppNotificationSettings extends ListFragment {
// TODO save high-pri state to NoMan
return true;
}
public boolean getSensitive(String pkg, int uid) {
// TODO get visibility state from NoMan
return false;
}
public boolean setSensitive(String pkg, int uid, boolean sensitive) {
// TODO save visibility state to NoMan
return true;
}
}
// === Indexing ===
public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider() {
@Override
public List<SearchIndexableRaw> getRawDataToIndex(Context context, boolean enabled) {
final List<SearchIndexableRaw> result = new ArrayList<SearchIndexableRaw>();
add(result, context, R.string.app_notifications_title);
add(result, context, R.string.app_notifications_dialog_show);
add(result, context, R.string.app_notifications_dialog_priority);
add(result, context, R.string.app_notifications_dialog_visibility);
return result;
}
private void add(List<SearchIndexableRaw> result, Context context, int title) {
final Resources res = context.getResources();
final SearchIndexableRaw data = new SearchIndexableRaw(context);
data.title = res.getString(title);
data.screenTitle = res.getString(R.string.app_notifications_title);
result.add(data);
}
};
}
/*
* Copyright (C) 2014 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.content.ContentResolver;
import android.content.Context;
import android.content.res.Resources;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceChangeListener;
import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceScreen;
import android.preference.TwoStatePreference;
import android.provider.Settings;
import android.util.Log;
import com.android.settings.R;
import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable;
import com.android.settings.search.SearchIndexableRaw;
import java.util.ArrayList;
import java.util.List;
public class NotificationDisplaySettings extends SettingsPreferenceFragment implements Indexable {
private static final String TAG = "NotificationDisplaySettings";
private static final String KEY_NOTIFICATION_PULSE = "notification_pulse";
private static final String KEY_LOCK_SCREEN_NOTIFICATIONS = "lock_screen_notifications";
private static final String KEY_ZEN_MODE_NOTIFICATIONS = "zen_mode_notifications";
private final Handler mHandler = new Handler();
private final SettingsObserver mSettingsObserver = new SettingsObserver();
private TwoStatePreference mNotificationPulse;
private DropDownPreference mLockscreen;
private DropDownPreference mZenModeNotifications;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.notification_display_settings);
final PreferenceScreen root = getPreferenceScreen();
initPulse(root);
initLockscreenNotifications(root);
initZenModeNotifications(root);
}
@Override
public void onResume() {
super.onResume();
mSettingsObserver.register(true);
}
@Override
public void onPause() {
super.onPause();
mSettingsObserver.register(false);
}
// === Pulse notification light ===
private void initPulse(PreferenceScreen parent) {
mNotificationPulse = (TwoStatePreference) parent.findPreference(KEY_NOTIFICATION_PULSE);
if (mNotificationPulse == null) return;
if (!getResources()
.getBoolean(com.android.internal.R.bool.config_intrusiveNotificationLed)) {
parent.removePreference(mNotificationPulse);
} else {
updatePulse();
mNotificationPulse.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
final boolean val = (Boolean)newValue;
return Settings.System.putInt(getContentResolver(),
Settings.System.NOTIFICATION_LIGHT_PULSE,
val ? 1 : 0);
}
});
}
}
private void updatePulse() {
if (mNotificationPulse == null) return;
try {
mNotificationPulse.setChecked(Settings.System.getInt(getContentResolver(),
Settings.System.NOTIFICATION_LIGHT_PULSE) == 1);
} catch (Settings.SettingNotFoundException snfe) {
Log.e(TAG, Settings.System.NOTIFICATION_LIGHT_PULSE + " not found");
}
}
// === Lockscreen (public / private) notifications ===
private void initLockscreenNotifications(PreferenceScreen parent) {
mLockscreen = (DropDownPreference) parent.findPreference(KEY_LOCK_SCREEN_NOTIFICATIONS);
if (mLockscreen == null) return;
mLockscreen.addItem(R.string.lock_screen_notifications_summary_show,
R.string.lock_screen_notifications_summary_show);
mLockscreen.addItem(R.string.lock_screen_notifications_summary_hide,
R.string.lock_screen_notifications_summary_hide);
mLockscreen.addItem(R.string.lock_screen_notifications_summary_disable,
R.string.lock_screen_notifications_summary_disable);
updateLockscreenNotifications();
mLockscreen.setCallback(new DropDownPreference.Callback() {
@Override
public boolean onItemSelected(int pos, Object value) {
final int val = (Integer) value;
final boolean enabled = val != R.string.lock_screen_notifications_summary_disable;
final boolean show = val == R.string.lock_screen_notifications_summary_show;
Settings.Secure.putInt(getContentResolver(),
Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, show ? 1 : 0);
Settings.Global.putInt(getContentResolver(),
Settings.Global.LOCK_SCREEN_SHOW_NOTIFICATIONS, enabled ? 1 : 0);
return true;
}
});
}
private void updateLockscreenNotifications() {
if (mLockscreen == null) return;
final boolean allowPrivate = getLockscreenAllowPrivateNotifications();
final boolean enabled = getLockscreenNotificationsEnabled();
final int val = !enabled ? R.string.lock_screen_notifications_summary_disable :
allowPrivate ? R.string.lock_screen_notifications_summary_show :
R.string.lock_screen_notifications_summary_hide;
mLockscreen.setSelectedValue(val);
}
private boolean getLockscreenNotificationsEnabled() {
return Settings.Global.getInt(getContentResolver(),
Settings.Global.LOCK_SCREEN_SHOW_NOTIFICATIONS, 0) != 0;
}
private boolean getLockscreenAllowPrivateNotifications() {
return Settings.Secure.getInt(getContentResolver(),
Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0) != 0;
}
// === Zen mode notifications ===
private void initZenModeNotifications(PreferenceScreen parent) {
mZenModeNotifications = (DropDownPreference)
parent.findPreference(KEY_ZEN_MODE_NOTIFICATIONS);
if (mZenModeNotifications == null) return;
mZenModeNotifications.addItem(R.string.zen_mode_notifications_summary_hide, 0);
mZenModeNotifications.addItem(R.string.zen_mode_notifications_summary_show, 1);
updateZenModeNotifications();
mZenModeNotifications.setCallback(new DropDownPreference.Callback() {
@Override
public boolean onItemSelected(int pos, Object value) {
final int val = (Integer) value;
Settings.Secure.putInt(getContentResolver(),
Settings.Secure.DISPLAY_INTERCEPTED_NOTIFICATIONS, val);
return true;
}
});
}
private void updateZenModeNotifications() {
if (mZenModeNotifications == null) return;
mZenModeNotifications.setSelectedValue(Settings.Secure.getInt(getContentResolver(),
Settings.Secure.DISPLAY_INTERCEPTED_NOTIFICATIONS, 0));
}
// === Indexing ===
public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider() {
@Override
public List<SearchIndexableRaw> getRawDataToIndex(Context context, boolean enabled) {
final List<SearchIndexableRaw> result = new ArrayList<SearchIndexableRaw>();
add(result, context, R.string.notification_display_settings);
add(result, context, R.string.notification_pulse_title);
add(result, context, R.string.lock_screen_notifications_title);
add(result, context, R.string.zen_mode_notifications_title);
return result;
}
private void add(List<SearchIndexableRaw> result, Context context, int title) {
final Resources res = context.getResources();
final SearchIndexableRaw data = new SearchIndexableRaw(context);
data.title = res.getString(title);
data.screenTitle = res.getString(R.string.notification_display_settings);
result.add(data);
}
};
// === Callbacks ===
private final class SettingsObserver extends ContentObserver {
private final Uri NOTIFICATION_LIGHT_PULSE_URI =
Settings.System.getUriFor(Settings.System.NOTIFICATION_LIGHT_PULSE);
private final Uri LOCK_SCREEN_PRIVATE_URI =
Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS);
private final Uri LOCK_SCREEN_SHOW_URI =
Settings.Global.getUriFor(Settings.Global.LOCK_SCREEN_SHOW_NOTIFICATIONS);
private final Uri DISPLAY_INTERCEPTED_NOTIFICATIONS_URI =
Settings.Secure.getUriFor(Settings.Secure.DISPLAY_INTERCEPTED_NOTIFICATIONS);
public SettingsObserver() {
super(mHandler);
}
public void register(boolean register) {
final ContentResolver cr = getContentResolver();
if (register) {
cr.registerContentObserver(NOTIFICATION_LIGHT_PULSE_URI, false, this);
cr.registerContentObserver(LOCK_SCREEN_PRIVATE_URI, false, this);
cr.registerContentObserver(LOCK_SCREEN_SHOW_URI, false, this);
cr.registerContentObserver(DISPLAY_INTERCEPTED_NOTIFICATIONS_URI, false, this);
} else {
cr.unregisterContentObserver(this);
}
}
@Override
public void onChange(boolean selfChange, Uri uri) {
super.onChange(selfChange, uri);
if (NOTIFICATION_LIGHT_PULSE_URI.equals(uri)) {
updatePulse();
}
if (LOCK_SCREEN_PRIVATE_URI.equals(uri) || LOCK_SCREEN_SHOW_URI.equals(uri)) {
updateLockscreenNotifications();
}
if (DISPLAY_INTERCEPTED_NOTIFICATIONS_URI.equals(uri)) {
updateZenModeNotifications();
}
}
}
}
......@@ -16,209 +16,212 @@
package com.android.settings.notification;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.database.ContentObserver;
import android.media.AudioManager;
import android.media.RingtoneManager;
import android.os.Build;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceGroup;
import android.preference.Preference.OnPreferenceChangeListener;
import android.preference.PreferenceScreen;
import android.preference.SeekBarVolumizer;
import android.preference.TwoStatePreference;
import android.provider.Settings;
import android.util.Log;
import com.android.settings.R;
import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.SoundSettings;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable;
import com.android.settings.search.SearchIndexableRaw;
public class NotificationSettings extends SettingsPreferenceFragment implements
Preference.OnPreferenceChangeListener, OnPreferenceClickListener {
import java.util.ArrayList;
import java.util.List;
public class NotificationSettings extends SettingsPreferenceFragment implements Indexable {
private static final String TAG = "NotificationSettings";
private static final String KEY_NOTIFICATION_SOUND = "notification_sound";
private static final String KEY_NOTIFICATION_PULSE = "notification_pulse";
private static final String KEY_HEADS_UP = "heads_up";
private static final String KEY_LOCK_SCREEN_NOTIFICATIONS = "toggle_lock_screen_notifications";
private static final String KEY_MEDIA_VOLUME = "media_volume";
private static final String KEY_ALARM_VOLUME = "alarm_volume";
private static final String KEY_RING_VOLUME = "ring_volume";
private static final String KEY_RINGER_MODE = "ringer_mode";
private static final String KEY_PHONE_RINGTONE = "ringtone";
private static final String KEY_NOTIFICATION_RINGTONE = "notification_ringtone";
private static final String KEY_VIBRATE_WHEN_RINGING = "vibrate_when_ringing";
private static final String KEY_NOTIFICATION_ACCESS = "manage_notification_access";
private static final String KEY_TWEAKS_CATEGORY = "category_tweaks"; // power toys, eng only
private static final int SAMPLE_CUTOFF = 2000; // manually cap sample playback at 2 seconds
private static final int MSG_UPDATE_SOUND_SUMMARY = 2;
private final VolumePreferenceCallback mVolumeCallback = new VolumePreferenceCallback();
private final H mHandler = new H();
private final SettingsObserver mSettingsObserver = new SettingsObserver();
private Context mContext;
private PackageManager mPM;
private Preference mNotificationSoundPreference;
private DropDownPreference mRingerMode;
private Preference mPhoneRingtonePreference;
private Preference mNotificationRingtonePreference;
private TwoStatePreference mVibrateWhenRinging;
private Preference mNotificationAccess;
private DropDownPreference mLockscreen;
private TwoStatePreference mHeadsUp;
private TwoStatePreference mNotificationPulse;
private final Runnable mRingtoneLookupRunnable = new Runnable() {
@Override
public void run() {
if (mNotificationSoundPreference != null) {
final CharSequence summary = SoundSettings.updateRingtoneName(
mContext, RingtoneManager.TYPE_NOTIFICATION);
if (summary != null) {
mHandler.sendMessage(
mHandler.obtainMessage(MSG_UPDATE_SOUND_SUMMARY, summary));
}
}
}
};
private final Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_UPDATE_SOUND_SUMMARY:
mNotificationSoundPreference.setSummary((CharSequence) msg.obj);
break;
}
}
};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mContext = getActivity();
final ContentResolver resolver = mContext.getContentResolver();
mPM = mContext.getPackageManager();
addPreferencesFromResource(R.xml.notification_settings);
final PreferenceScreen root = getPreferenceScreen();
PreferenceGroup tweaksCategory = (PreferenceGroup)
root.findPreference(KEY_TWEAKS_CATEGORY);
if (tweaksCategory != null
&& !(Build.TYPE.equals("eng") || Build.TYPE.equals("userdebug"))) {
root.removePreference(tweaksCategory);
tweaksCategory = null;
}
mNotificationSoundPreference = findPreference(KEY_NOTIFICATION_SOUND);
initVolumePreference(KEY_MEDIA_VOLUME, AudioManager.STREAM_MUSIC);
initVolumePreference(KEY_ALARM_VOLUME, AudioManager.STREAM_ALARM);
initVolumePreference(KEY_RING_VOLUME, AudioManager.STREAM_RING);
initRingerMode(root);
initRingtones(root);
initVibrateWhenRinging(root);
mNotificationAccess = findPreference(KEY_NOTIFICATION_ACCESS);
refreshNotificationListeners();
mLockscreen = (DropDownPreference) root.findPreference(KEY_LOCK_SCREEN_NOTIFICATIONS);
if (mLockscreen != null) {
if (!getDeviceLockscreenNotificationsEnabled()) {
root.removePreference(mLockscreen);
} else {
mLockscreen.addItem(R.string.lock_screen_notifications_summary_show, 1);
mLockscreen.addItem(R.string.lock_screen_notifications_summary_hide, 0);
final int val = getLockscreenAllowPrivateNotifications() ? 1 : 0;
mLockscreen.setSelectedValue(val);
mLockscreen.setCallback(new DropDownPreference.Callback() {
@Override
public boolean onItemSelected(int pos, Object value) {
final int val = (Integer) value;
Settings.Secure.putInt(getContentResolver(),
Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, val);
return true;
}
});
}
}
mHeadsUp = (TwoStatePreference) findPreference(KEY_HEADS_UP);
if (mHeadsUp != null) {
updateHeadsUpMode(resolver);
mHeadsUp.setOnPreferenceChangeListener(this);
resolver.registerContentObserver(
Settings.Global.getUriFor(Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED),
false, new ContentObserver(mHandler) {
@Override
public void onChange(boolean selfChange) {
updateHeadsUpMode(resolver);
}
});
}
mNotificationPulse = (TwoStatePreference) findPreference(KEY_NOTIFICATION_PULSE);
if (mNotificationPulse != null
&& getResources().getBoolean(
com.android.internal.R.bool.config_intrusiveNotificationLed) == false) {
getPreferenceScreen().removePreference(mNotificationPulse);
} else {
try {
mNotificationPulse.setChecked(Settings.System.getInt(resolver,
Settings.System.NOTIFICATION_LIGHT_PULSE) == 1);
mNotificationPulse.setOnPreferenceChangeListener(this);
} catch (Settings.SettingNotFoundException snfe) {
Log.e(TAG, Settings.System.NOTIFICATION_LIGHT_PULSE + " not found");
}
}
}
@Override
public void onResume() {
super.onResume();
refreshNotificationListeners();
lookupRingtoneNames();
final IntentFilter filter = new IntentFilter(AudioManager.RINGER_MODE_CHANGED_ACTION);
mContext.registerReceiver(mReceiver, filter);
mSettingsObserver.register(true);
}
@Override
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
final String key = preference.getKey();
if (KEY_HEADS_UP.equals(key)) {
setHeadsUpMode(getContentResolver(), mHeadsUp.isChecked());
} else if (KEY_NOTIFICATION_PULSE.equals(key)) {
Settings.System.putInt(getContentResolver(),
Settings.System.NOTIFICATION_LIGHT_PULSE,
mNotificationPulse.isChecked() ? 1 : 0);
} else {
return super.onPreferenceTreeClick(preferenceScreen, preference);
}
public void onPause() {
super.onPause();
mVolumeCallback.stopSample();
mContext.unregisterReceiver(mReceiver);
mSettingsObserver.register(false);
}
// === Volumes ===
return true;
private void initVolumePreference(String key, int stream) {
final VolumeSeekBarPreference volumePref = (VolumeSeekBarPreference) findPreference(key);
volumePref.setStream(stream);
volumePref.setCallback(mVolumeCallback);
}
@Override
public boolean onPreferenceChange(Preference preference, Object objValue) {
return true;
private final class VolumePreferenceCallback implements VolumeSeekBarPreference.Callback {
private SeekBarVolumizer mCurrent;
@Override
public void onSampleStarting(SeekBarVolumizer sbv) {
if (mCurrent != null && mCurrent != sbv) {
mCurrent.stopSample();
}
mCurrent = sbv;
if (mCurrent != null) {
mHandler.removeMessages(H.STOP_SAMPLE);
mHandler.sendEmptyMessageDelayed(H.STOP_SAMPLE, SAMPLE_CUTOFF);
}
}
public void stopSample() {
if (mCurrent != null) {
mCurrent.stopSample();
}
}
};
// === Ringer mode ===
private void initRingerMode(PreferenceScreen root) {
mRingerMode = (DropDownPreference) root.findPreference(KEY_RINGER_MODE);
if (mRingerMode == null) return;
final AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
mRingerMode.addItem(R.string.ringer_mode_audible, AudioManager.RINGER_MODE_NORMAL);
mRingerMode.addItem(R.string.ringer_mode_vibrate, AudioManager.RINGER_MODE_VIBRATE);
mRingerMode.addItem(R.string.ringer_mode_silent, AudioManager.RINGER_MODE_SILENT);
updateRingerMode();
mRingerMode.setCallback(new DropDownPreference.Callback() {
@Override
public boolean onItemSelected(int pos, Object value) {
final int val = (Integer) value;
am.setRingerMode(val);
return true;
}
});
}
@Override
public boolean onPreferenceClick(Preference preference) {
return false;
private void updateRingerMode() {
final AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
mRingerMode.setSelectedValue(am.getRingerMode());
}
// === Heads-up notifications ===
// === Phone & notification ringtone ===
private void updateHeadsUpMode(ContentResolver resolver) {
mHeadsUp.setChecked(Settings.Global.HEADS_UP_ON == Settings.Global.getInt(resolver,
Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED, Settings.Global.HEADS_UP_OFF));
private void initRingtones(PreferenceScreen root) {
mPhoneRingtonePreference = root.findPreference(KEY_PHONE_RINGTONE);
mNotificationRingtonePreference = root.findPreference(KEY_NOTIFICATION_RINGTONE);
}
private void setHeadsUpMode(ContentResolver resolver, boolean value) {
Settings.Global.putInt(resolver, Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED,
value ? Settings.Global.HEADS_UP_ON : Settings.Global.HEADS_UP_OFF);
private void lookupRingtoneNames() {
AsyncTask.execute(mLookupRingtoneNames);
}
// === Lockscreen (public / private) notifications ===
private final Runnable mLookupRingtoneNames = new Runnable() {
@Override
public void run() {
if (mPhoneRingtonePreference != null) {
final CharSequence summary = SoundSettings.updateRingtoneName(
mContext, RingtoneManager.TYPE_RINGTONE);
if (summary != null) {
mHandler.obtainMessage(H.UPDATE_PHONE_RINGTONE, summary).sendToTarget();
}
}
if (mNotificationRingtonePreference != null) {
final CharSequence summary = SoundSettings.updateRingtoneName(
mContext, RingtoneManager.TYPE_NOTIFICATION);
if (summary != null) {
mHandler.obtainMessage(H.UPDATE_NOTIFICATION_RINGTONE, summary).sendToTarget();
}
}
}
};
private boolean getDeviceLockscreenNotificationsEnabled() {
return 0 != Settings.Global.getInt(getContentResolver(),
Settings.Global.LOCK_SCREEN_SHOW_NOTIFICATIONS, 0);
// === Vibrate when ringing ===
private void initVibrateWhenRinging(PreferenceScreen root) {
mVibrateWhenRinging = (TwoStatePreference) findPreference(KEY_VIBRATE_WHEN_RINGING);
if (mVibrateWhenRinging == null) return;
mVibrateWhenRinging.setPersistent(false);
updateVibrateWhenRinging();
mVibrateWhenRinging.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
final boolean val = (Boolean) newValue;
return Settings.System.putInt(getContentResolver(),
Settings.System.VIBRATE_WHEN_RINGING,
val ? 1 : 0);
}
});
}
private boolean getLockscreenAllowPrivateNotifications() {
return 0 != Settings.Secure.getInt(getContentResolver(),
Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0);
private void updateVibrateWhenRinging() {
if (mVibrateWhenRinging == null) return;
mVibrateWhenRinging.setChecked(Settings.System.getInt(getContentResolver(),
Settings.System.VIBRATE_WHEN_RINGING, 0) != 0);
}
// === Notification listeners ===
......@@ -242,9 +245,92 @@ public class NotificationSettings extends SettingsPreferenceFragment implements
}
}
// === Ringtone ===
// === Indexing ===
public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider() {
@Override
public List<SearchIndexableRaw> getRawDataToIndex(Context context, boolean enabled) {
final List<SearchIndexableRaw> result = new ArrayList<SearchIndexableRaw>();
add(result, context, R.string.notification_settings);
add(result, context, R.string.media_volume_option_title);
add(result, context, R.string.alarm_volume_option_title);
add(result, context, R.string.ring_volume_option_title);
add(result, context, R.string.ringer_mode_title);
add(result, context, R.string.ringtone_title);
add(result, context, R.string.vibrate_when_ringing_title);
add(result, context, R.string.manage_notification_access_title);
return result;
}
private void lookupRingtoneNames() {
new Thread(mRingtoneLookupRunnable).start();
private void add(List<SearchIndexableRaw> result, Context context, int title) {
final Resources res = context.getResources();
final SearchIndexableRaw data = new SearchIndexableRaw(context);
data.title = res.getString(title);
data.screenTitle = res.getString(R.string.notification_settings);
result.add(data);
}
};
// === Callbacks ===
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (AudioManager.RINGER_MODE_CHANGED_ACTION.equals(intent.getAction())) {
updateRingerMode();
}
}
};
private final class SettingsObserver extends ContentObserver {
private final Uri VIBRATE_WHEN_RINGING_URI =
Settings.System.getUriFor(Settings.System.VIBRATE_WHEN_RINGING);
public SettingsObserver() {
super(mHandler);
}
public void register(boolean register) {
final ContentResolver cr = getContentResolver();
if (register) {
cr.registerContentObserver(VIBRATE_WHEN_RINGING_URI, false, this);
} else {
cr.unregisterContentObserver(this);
}
}
@Override
public void onChange(boolean selfChange, Uri uri) {
super.onChange(selfChange, uri);
if (VIBRATE_WHEN_RINGING_URI.equals(uri)) {
updateVibrateWhenRinging();
}
}
}
private final class H extends Handler {
private static final int UPDATE_PHONE_RINGTONE = 1;
private static final int UPDATE_NOTIFICATION_RINGTONE = 2;
private static final int STOP_SAMPLE = 3;
private H() {
super(Looper.getMainLooper());
}
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case UPDATE_PHONE_RINGTONE:
mPhoneRingtonePreference.setSummary((CharSequence) msg.obj);
break;
case UPDATE_NOTIFICATION_RINGTONE:
mNotificationRingtonePreference.setSummary((CharSequence) msg.obj);
break;
case STOP_SAMPLE:
mVolumeCallback.stopSample();
break;
}
}
}
}
/*
* Copyright (C) 2014 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.content.ContentResolver;
import android.content.Context;
import android.content.res.Resources;
import android.database.ContentObserver;
import android.media.AudioManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Vibrator;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceChangeListener;
import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceScreen;
import android.preference.TwoStatePreference;
import android.provider.Settings.System;
import android.util.Log;
import com.android.settings.R;
import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.Utils;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable;
import com.android.settings.search.SearchIndexableRaw;
import java.util.ArrayList;
import java.util.List;
public class TouchSoundSettings extends SettingsPreferenceFragment implements Indexable {
private static final String TAG = "TouchSoundSettings";
private static final String KEY_DIAL_PAD_TONES = "dial_pad_tones";
private static final String KEY_SCREEN_LOCKING_SOUNDS = "screen_locking_sounds";
private static final String KEY_OTHER_TOUCH_SOUNDS = "other_touch_sounds";
private static final String KEY_VIBRATE_ON_TOUCH = "vibrate_on_touch";
private final Handler mHandler = new Handler();
private final SettingsObserver mSettingsObserver = new SettingsObserver();
private AudioManager mAudioManager;
private SystemSettingPref mDialPadTones;
private SystemSettingPref mScreenLockingSounds;
private SystemSettingPref mOtherTouchSounds;
private SystemSettingPref mVibrateOnTouch;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.touch_sound_settings);
mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
final boolean hasVoice = Utils.isVoiceCapable(getActivity());
final Vibrator vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
final boolean hasHaptic = vibrator != null && vibrator.hasVibrator();
mDialPadTones = new SystemSettingPref(hasVoice,
KEY_DIAL_PAD_TONES, System.DTMF_TONE_WHEN_DIALING);
mScreenLockingSounds = new SystemSettingPref(true,
KEY_SCREEN_LOCKING_SOUNDS, System.LOCKSCREEN_SOUNDS_ENABLED);
mOtherTouchSounds = new SystemSettingPref(true,
KEY_OTHER_TOUCH_SOUNDS,System.SOUND_EFFECTS_ENABLED) {
@Override
protected void setSetting(boolean value) {
if (value) {
mAudioManager.loadSoundEffects();
} else {
mAudioManager.unloadSoundEffects();
}
super.setSetting(value);
}
};
mVibrateOnTouch = new SystemSettingPref(hasHaptic,
KEY_VIBRATE_ON_TOUCH, System.HAPTIC_FEEDBACK_ENABLED);
}
@Override
public void onResume() {
super.onResume();
mSettingsObserver.register(true);
}
@Override
public void onPause() {
super.onPause();
mSettingsObserver.register(false);
}
// === Common system setting preference helper ===
private class SystemSettingPref {
private final String mSetting;
private final Uri mUri;
private TwoStatePreference mPref;
private SystemSettingPref(boolean applicable, String key, String setting) {
mSetting = setting;
mUri = System.getUriFor(mSetting);
if (!applicable) removePreference(key);
mPref = (TwoStatePreference) getPreferenceScreen().findPreference(key);
if (mPref == null) return;
update();
mPref.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
setSetting((Boolean)newValue);
return true;
}
});
}
protected void setSetting(boolean value) {
System.putInt(getContentResolver(), mSetting, value ? 1 : 0);
}
private Uri getUri() {
return mUri;
}
private void update() {
if (mPref == null) return;
mPref.setChecked(System.getInt(getContentResolver(), mSetting, 1) != 0);
}
}
// === Indexing ===
public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider() {
@Override
public List<SearchIndexableRaw> getRawDataToIndex(Context context, boolean enabled) {
final List<SearchIndexableRaw> result = new ArrayList<SearchIndexableRaw>();
add(result, context, R.string.touch_sound_settings);
add(result, context, R.string.dial_pad_tones_title);
add(result, context, R.string.screen_locking_sounds_title);
add(result, context, R.string.other_touch_sounds_title);
add(result, context, R.string.vibrate_on_touch_title);
return result;
}
private void add(List<SearchIndexableRaw> result, Context context, int title) {
final Resources res = context.getResources();
final SearchIndexableRaw data = new SearchIndexableRaw(context);
data.title = res.getString(title);
data.screenTitle = res.getString(R.string.touch_sound_settings);
result.add(data);
}
};
// === Callbacks ===
private final class SettingsObserver extends ContentObserver {
public SettingsObserver() {
super(mHandler);
}
public void register(boolean register) {
final ContentResolver cr = getContentResolver();
if (register) {
cr.registerContentObserver(mDialPadTones.getUri(), false, this);
cr.registerContentObserver(mScreenLockingSounds.getUri(), false, this);
cr.registerContentObserver(mOtherTouchSounds.getUri(), false, this);
cr.registerContentObserver(mVibrateOnTouch.getUri(), false, this);
} else {
cr.unregisterContentObserver(this);
}
}
@Override
public void onChange(boolean selfChange, Uri uri) {
super.onChange(selfChange, uri);
if (mDialPadTones.getUri().equals(uri)) {
mDialPadTones.update();
}
if (mScreenLockingSounds.getUri().equals(uri)) {
mScreenLockingSounds.update();
}
if (mOtherTouchSounds.getUri().equals(uri)) {
mOtherTouchSounds.update();
}
if (mVibrateOnTouch.getUri().equals(uri)) {
mVibrateOnTouch.update();
}
}
}
}
/*
* Copyright (C) 2014 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.content.ContentResolver;
import android.content.Context;
import android.media.AudioManager;
import android.net.Uri;
import android.preference.PreferenceManager;
import android.preference.SeekBarPreference;
import android.preference.SeekBarVolumizer;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.widget.SeekBar;
import com.android.settings.R;
/** A slider preference that directly controls an audio stream volume (no dialog) **/
public class VolumeSeekBarPreference extends SeekBarPreference
implements PreferenceManager.OnActivityStopListener {
private static final String TAG = "VolumeSeekBarPreference";
private final Context mContext;
private int mStream;
private SeekBar mSeekBar;
private SeekBarVolumizer mVolumizer;
private Callback mCallback;
public VolumeSeekBarPreference(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
}
public void setStream(int stream) {
mStream = stream;
}
public void setCallback(Callback callback) {
mCallback = callback;
}
@Override
public void onActivityStop() {
if (mVolumizer != null) {
mVolumizer.stop();
}
}
@Override
protected void onBindView(View view) {
super.onBindView(view);
if (mStream == 0) {
Log.w(TAG, "No stream found, not binding volumizer");
return;
}
getPreferenceManager().registerOnActivityStopListener(this);
final SeekBar seekBar = (SeekBar) view.findViewById(com.android.internal.R.id.seekbar);
if (seekBar == mSeekBar) return;
mSeekBar = seekBar;
final SeekBarVolumizer.Callback sbvc = new SeekBarVolumizer.Callback() {
@Override
public void onSampleStarting(SeekBarVolumizer sbv) {
if (mCallback != null) {
mCallback.onSampleStarting(sbv);
}
}
};
final Uri sampleUri = mStream == AudioManager.STREAM_MUSIC ? getMediaVolumeUri() : null;
mVolumizer = new SeekBarVolumizer(mContext, seekBar, mStream, sampleUri, sbvc);
}
private Uri getMediaVolumeUri() {
return Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://"
+ mContext.getPackageName()
+ "/" + R.raw.media_volume);
}
public interface Callback {
void onSampleStarting(SeekBarVolumizer sbv);
}
}
......@@ -329,7 +329,7 @@ public class ZenModeSettings extends SettingsPreferenceFragment implements Index
if (automatic == null || automatic.length == 0) {
return null;
}
final String divider = getString(R.string.zen_mode_entry_conditions_summary_divider);
final String divider = getString(R.string.summary_divider_text);
final StringBuilder sb = new StringBuilder();
for (int i = 0; i < automatic.length; i++) {
if (i > 0) sb.append(divider);
......
......@@ -36,7 +36,10 @@ import com.android.settings.deviceinfo.Memory;
import com.android.settings.fuelgauge.PowerUsageSummary;
import com.android.settings.inputmethod.InputMethodAndLanguageSettings;
import com.android.settings.location.LocationSettings;
import com.android.settings.notification.AppNotificationSettings;
import com.android.settings.notification.NotificationDisplaySettings;
import com.android.settings.notification.NotificationSettings;
import com.android.settings.notification.TouchSoundSettings;
import com.android.settings.notification.ZenModeSettings;
import com.android.settings.print.PrintSettingsFragment;
import com.android.settings.users.UserSettings;
......@@ -137,12 +140,30 @@ public final class SearchIndexableResources {
NotificationSettings.class.getName(),
R.drawable.ic_settings_notifications));
sResMap.put(NotificationDisplaySettings.class.getName(),
new SearchIndexableResource(RANK_NOTIFICATIONS,
R.xml.notification_display_settings,
NotificationDisplaySettings.class.getName(),
R.drawable.ic_settings_notifications));
sResMap.put(TouchSoundSettings.class.getName(),
new SearchIndexableResource(RANK_NOTIFICATIONS,
R.xml.touch_sound_settings,
TouchSoundSettings.class.getName(),
R.drawable.ic_settings_notifications));
sResMap.put(ZenModeSettings.class.getName(),
new SearchIndexableResource(RANK_NOTIFICATIONS,
NO_DATA_RES_ID,
ZenModeSettings.class.getName(),
R.drawable.ic_settings_notifications));
sResMap.put(AppNotificationSettings.class.getName(),
new SearchIndexableResource(RANK_NOTIFICATIONS,
NO_DATA_RES_ID,
AppNotificationSettings.class.getName(),
R.drawable.ic_settings_notifications));
sResMap.put(Memory.class.getName(),
new SearchIndexableResource(RANK_MEMORY,
NO_DATA_RES_ID,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment