Merge "Rootless GPU Debug"
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index d65d92d..0a8bcb6 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -2817,6 +2817,8 @@
</intent-filter>
<meta-data android:name="com.android.settings.category"
android:value="com.android.settings.category.ia.wireless" />
+ <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.sim.SimSettings" />
</activity>
diff --git a/proguard.flags b/proguard.flags
index d644f47..7a403a4 100644
--- a/proguard.flags
+++ b/proguard.flags
@@ -39,3 +39,21 @@
public static ** SEARCH_INDEX_DATA_PROVIDER;
public static ** SUMMARY_PROVIDER_FACTORY;
}
+
+# Keep classes, annotations and members used by Lifecycle
+-keepattributes *Annotation*
+
+-keepclassmembers enum android.arch.lifecycle.Lifecycle$Event {
+ <fields>;
+}
+
+-keep class * implements android.arch.lifecycle.LifecycleObserver {
+}
+
+-keep class * implements android.arch.lifecycle.GeneratedAdapter {
+ <init>(...);
+}
+
+-keepclassmembers class ** {
+ @android.arch.lifecycle.OnLifecycleEvent *;
+}
diff --git a/res/layout/zen_mode_button.xml b/res/layout/zen_mode_button.xml
new file mode 100644
index 0000000..af24fce
--- /dev/null
+++ b/res/layout/zen_mode_button.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:gravity="bottom"
+ android:paddingTop="4dp"
+ android:paddingStart="72dp"
+ android:paddingEnd="72dp"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <Button
+ android:id="@+id/zen_mode_button"
+ android:layout_width="0dp"
+ android:layout_weight="1"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:paddingEnd="8dp" />
+
+</LinearLayout>
\ No newline at end of file
diff --git a/res/layout/zen_mode_settings_button.xml b/res/layout/zen_mode_settings_button.xml
new file mode 100644
index 0000000..4d4b7d6
--- /dev/null
+++ b/res/layout/zen_mode_settings_button.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:gravity="bottom"
+ android:paddingTop="4dp"
+ android:paddingStart="72dp"
+ android:paddingEnd="72dp"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <Button
+ android:id="@+id/zen_mode_settings_turn_on_button"
+ style="@style/ActionPrimaryButton"
+ android:layout_width="0dp"
+ android:layout_weight="1"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:text="@string/zen_mode_button_turn_on"
+ android:paddingEnd="8dp" />
+
+ <Button
+ android:id="@+id/zen_mode_settings_turn_off_button"
+ style="@style/ActionSecondaryButton"
+ android:layout_width="0dp"
+ android:layout_weight="1"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:text="@string/zen_mode_button_turn_off"
+ android:paddingEnd="8dp" />
+
+</LinearLayout>
\ No newline at end of file
diff --git a/res/values/arrays.xml b/res/values/arrays.xml
index 84f3722..aa8a586 100644
--- a/res/values/arrays.xml
+++ b/res/values/arrays.xml
@@ -1031,4 +1031,18 @@
<item>never</item>
</string-array>
+ <string-array name="zen_mode_contacts_entries" translatable="false">
+ <item>@string/zen_mode_from_anyone</item>
+ <item>@string/zen_mode_from_contacts</item>
+ <item>@string/zen_mode_from_starred</item>
+ <item>@string/zen_mode_from_none</item>
+ </string-array>
+
+ <string-array name="zen_mode_contacts_values" translatable="false">
+ <item>zen_mode_from_anyone</item>
+ <item>zen_mode_from_contacts</item>
+ <item>zen_mode_from_starred</item>
+ <item>zen_mode_from_none</item>
+ </string-array>
+
</resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index bc43892..43827e3 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -6475,6 +6475,8 @@
<string name="sim_calls_ask_first_prefs_title">Ask every time</string>
<!-- When a SIM preference hasn't been selected yet, this string is displayed as the pref summary until the user chooses a SIM subscription from the preference list [CHAR LIMIT=50] -->
<string name="sim_selection_required_pref">Selection required</string>
+ <!-- Title for SIM selection notification channel -->
+ <string name="sim_selection_channel_title">SIM selection</string>
<!--Dashboard strings-->
<!-- Text to describe the dashboard fragment title [CHAR LIMIT=16] -->
@@ -6573,7 +6575,10 @@
<string name="keywords_payment_settings">pay, tap, payments</string>
<string name="keywords_backup">backup, back up</string>
<string name="keywords_assist_gesture_launch">gesture</string>
- <string name="keywords_imei_info">imei, meid</string>
+ <string name="keywords_imei_info">imei, meid, min, prl version, imei sv</string>
+ <string name="keywords_sim_status">network, mobile network state, service state, signal strength, mobile network type, roaming, iccid</string>
+ <string name="keywords_model_and_hardware">serial number, hardware version</string>
+ <string name="keywords_android_version">android security patch level, baseband version, kernel version, </string>
<!-- NFC Wi-Fi pairing/setup strings-->
@@ -6752,6 +6757,27 @@
<!-- Do not disturb: Button to add new automatic rule to DND. [CHAR LIMIT=30] -->
<string name="zen_mode_add">Add</string>
+ <!-- Do not disturb: Label for button that will turn on zen mode. [CHAR LIMIT=30] -->
+ <string name="zen_mode_button_turn_on">TURN ON NOW</string>
+
+ <!-- Do not disturb: Label for button that will turn off zen mode. [CHAR LIMIT=30] -->
+ <string name="zen_mode_button_turn_off">TURN OFF NOW</string>
+
+ <!-- [CHAR LIMIT=110] Zen mode settings footer: Footer showing end time of DND -->
+ <string name="zen_mode_settings_dnd_manual_end_time_next_day">Do Not Disturb is on until <xliff:g id="formatted_time" example="7:00 AM">%s</xliff:g></string>
+
+ <!-- [CHAR LIMIT=110] Zen mode settings footer: Footer showing length of DND -->
+ <string name="zen_mode_settings_dnd_manual_indefinite">Do Not Disturb will stay on until you turn it off.</string>
+
+ <!-- [CHAR LIMIT=110] Zen mode settings footer: Footer showing how DND was triggered by an automatic DND rule -->
+ <string name="zen_mode_settings_dnd_automatic_rule">Do Not Disturb was automatically turned on by a rule <xliff:g id="rule_name" example="Weeknights">%s</xliff:g></string>
+
+ <!-- [CHAR LIMIT=110] Zen mode settings footer: Footer how DND was triggered by an app -->
+ <string name="zen_mode_settings_dnd_automatic_rule_app">Do Not Disturb was automatically turned on by an app <xliff:g id="app_name" example="Pixel Services">%s</xliff:g></string>
+
+ <!-- [CHAR LIMIT=110] Zen mode settings footer: Footer how DND was triggered by multiple rules and/or apps -->
+ <string name="zen_mode_settings_dnd_automatic_rule_multiple">Do Not Disturb was automatically turned on by a rule or app</string>
+
<!-- Work Sounds: Work sound settings section header. [CHAR LIMIT=50] -->
<string name="sound_work_settings">Work profile sounds</string>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index f3b67e2..e2b6d44 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -218,6 +218,7 @@
<item name="android:paddingStart">4dip</item>
<item name="android:layout_marginStart">4dip</item>
<item name="android:textSize">18sp</item>
+ <item name="android:textAlignment">viewStart</item>
</style>
<style name="wifi_section">
diff --git a/res/xml/data_usage_metered_prefs.xml b/res/xml/data_usage_metered_prefs.xml
index ef0faf2..9764ad3 100644
--- a/res/xml/data_usage_metered_prefs.xml
+++ b/res/xml/data_usage_metered_prefs.xml
@@ -14,8 +14,10 @@
limitations under the License.
-->
-<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
- android:title="@string/network_restrictions">
+<PreferenceScreen
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:key="data_usage_metered_prefs"
+ android:title="@string/network_restrictions">
<PreferenceCategory
android:key="mobile"
@@ -37,6 +39,7 @@
<com.android.settingslib.widget.FooterPreference
android:title="@string/data_usage_metered_body"
+ android:key="footer_preference"
android:selectable="false" />
</PreferenceScreen>
diff --git a/res/xml/device_info_settings_v2.xml b/res/xml/device_info_settings_v2.xml
index 9a48e96..bf4b47b 100644
--- a/res/xml/device_info_settings_v2.xml
+++ b/res/xml/device_info_settings_v2.xml
@@ -19,8 +19,7 @@
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res/com.android.settings"
android:key="device_info_pref_screen"
- android:title="@string/about_settings"
- settings:initialExpandedChildrenCount="6">
+ android:title="@string/about_settings">
<!-- Phone number -->
<Preference
@@ -34,6 +33,7 @@
android:key="sim_status"
android:order="10"
android:title="@string/sim_status_title"
+ settings:keywords="@string/keywords_sim_status"
android:summary="@string/summary_placeholder"/>
<!-- Model & hardware -->
@@ -41,6 +41,7 @@
android:key="device_model"
android:order="21"
android:title="@string/hardware_info"
+ settings:keywords="@string/keywords_model_and_hardware"
android:summary="@string/summary_placeholder"/>
<!-- IMEI -->
@@ -56,12 +57,20 @@
android:key="firmware_version"
android:order="32"
android:title="@string/firmware_version"
+ settings:keywords="@string/keywords_android_version"
+ android:summary="@string/summary_placeholder"/>
+
+ <!-- IMS registration -->
+ <Preference
+ android:key="ims_reg_state"
+ android:order="33"
+ android:title="@string/ims_reg_title"
android:summary="@string/summary_placeholder"/>
<!--IP address -->
<Preference
android:key="wifi_ip_address"
- android:order="33"
+ android:order="34"
android:title="@string/wifi_ip_address"
android:summary="@string/summary_placeholder"
settings:allowDividerAbove="true"/>
@@ -69,14 +78,14 @@
<!-- Wi-Fi MAC address -->
<Preference
android:key="wifi_mac_address"
- android:order="34"
+ android:order="35"
android:title="@string/status_wifi_mac_address"
android:summary="@string/summary_placeholder"/>
<!-- Bluetooth address -->
<Preference
android:key="bt_address"
- android:order="35"
+ android:order="36"
android:title="@string/status_bt_address"
android:summary="@string/summary_placeholder"/>
@@ -84,7 +93,7 @@
<!-- Legal information -->
<Preference
android:key="legal_container"
- android:order="36"
+ android:order="37"
android:title="@string/legal_information"
android:fragment="com.android.settings.LegalSettings"
settings:allowDividerAbove="true"/>
@@ -92,7 +101,7 @@
<!-- Regulatory labels -->
<Preference
android:key="regulatory_info"
- android:order="37"
+ android:order="38"
android:title="@string/regulatory_labels">
<intent android:action="android.settings.SHOW_REGULATORY_INFO"/>
</Preference>
@@ -100,15 +109,36 @@
<!-- Safety & regulatory manual -->
<Preference
android:key="safety_info"
- android:order="38"
+ android:order="39"
android:title="@string/safety_and_regulatory_info">
<intent android:action="android.settings.SHOW_SAFETY_AND_REGULATORY_INFO"/>
</Preference>
+ <!-- Manual -->
+ <Preference
+ android:key="manual"
+ android:order="40"
+ android:title="@string/manual">
+ <intent android:action="android.settings.SHOW_MANUAL"/>
+ </Preference>
+
+ <!-- Feedback on the device -->
+ <Preference
+ android:key="device_feedback"
+ android:order="41"
+ android:title="@string/device_feedback"/>
+
+ <!-- Device FCC equipment id -->
+ <Preference
+ android:key="fcc_equipment_id"
+ android:order="42"
+ android:title="@string/fcc_equipment_id"
+ android:summary="@string/summary_placeholder"/>
+
<!-- Build number -->
<Preference
android:key="build_number"
- android:order="39"
+ android:order="43"
android:title="@string/build_number"
android:summary="@string/summary_placeholder"
settings:allowDividerAbove="true"/>
diff --git a/res/xml/location_mode.xml b/res/xml/location_mode.xml
index e6dc067..ac8e584 100644
--- a/res/xml/location_mode.xml
+++ b/res/xml/location_mode.xml
@@ -14,20 +14,22 @@
limitations under the License.
-->
-<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
- android:title="@string/location_mode_screen_title">
+<PreferenceScreen
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:key="location_mode_settings"
+ android:title="@string/location_mode_screen_title">
- <com.android.settings.widget.RadioButtonPreference
- android:key="high_accuracy"
- android:title="@string/location_mode_high_accuracy_title"
- android:summary="@string/location_mode_high_accuracy_description" />
- <com.android.settings.widget.RadioButtonPreference
- android:key="battery_saving"
- android:title="@string/location_mode_battery_saving_title"
- android:summary="@string/location_mode_battery_saving_description" />
- <com.android.settings.widget.RadioButtonPreference
- android:key="sensors_only"
- android:title="@string/location_mode_sensors_only_title"
- android:summary="@string/location_mode_sensors_only_description" />
+ <com.android.settings.widget.RadioButtonPreference
+ android:key="high_accuracy"
+ android:title="@string/location_mode_high_accuracy_title"
+ android:summary="@string/location_mode_high_accuracy_description" />
+ <com.android.settings.widget.RadioButtonPreference
+ android:key="battery_saving"
+ android:title="@string/location_mode_battery_saving_title"
+ android:summary="@string/location_mode_battery_saving_description" />
+ <com.android.settings.widget.RadioButtonPreference
+ android:key="sensors_only"
+ android:title="@string/location_mode_sensors_only_title"
+ android:summary="@string/location_mode_sensors_only_description" />
</PreferenceScreen>
diff --git a/res/xml/screen_pinning_settings.xml b/res/xml/screen_pinning_settings.xml
index 229c4ea..f27e4aa 100644
--- a/res/xml/screen_pinning_settings.xml
+++ b/res/xml/screen_pinning_settings.xml
@@ -14,11 +14,13 @@
limitations under the License.
-->
-<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
- android:title="@string/screen_pinning_title">
+<PreferenceScreen
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:key="screen_pinning_settings_screen"
+ android:title="@string/screen_pinning_title">
- <SwitchPreference
- android:key="use_screen_lock"
- android:title="@string/screen_pinning_unlock_none" />
+ <SwitchPreference
+ android:key="use_screen_lock"
+ android:title="@string/screen_pinning_unlock_none" />
</PreferenceScreen>
diff --git a/res/xml/security_settings_misc.xml b/res/xml/security_settings_misc.xml
index bc737b0..730686c 100644
--- a/res/xml/security_settings_misc.xml
+++ b/res/xml/security_settings_misc.xml
@@ -75,7 +75,7 @@
android:key="screen_pinning_settings"
android:title="@string/screen_pinning_title"
android:summary="@string/switch_off_text"
- android:fragment="com.android.settings.ScreenPinningSettings"/>
+ android:fragment="com.android.settings.security.ScreenPinningSettings"/>
<Preference android:key="security_misc_usage_access"
android:title="@string/usage_access_title"
diff --git a/res/xml/zen_mode_automation_settings.xml b/res/xml/zen_mode_automation_settings.xml
index 33842ec..99826ea 100644
--- a/res/xml/zen_mode_automation_settings.xml
+++ b/res/xml/zen_mode_automation_settings.xml
@@ -19,5 +19,15 @@
android:key="zen_mode_automation_settings_page"
android:title="@string/zen_mode_automation_settings_page_title" >
- <!-- Rules added at runtime -->
+
+ <PreferenceCategory
+ android:key="zen_mode_automatic_rules">
+ <!-- Rules added at runtime -->
+ </PreferenceCategory>
+
+ <Preference
+ android:key="zen_mode_add_automatic_rule"
+ android:icon="@drawable/ic_menu_add"
+ android:title="@string/zen_mode_add_rule"/>
+
</PreferenceScreen>
diff --git a/res/xml/zen_mode_behavior_settings.xml b/res/xml/zen_mode_behavior_settings.xml
index 999d6b4..7b5ed91 100644
--- a/res/xml/zen_mode_behavior_settings.xml
+++ b/res/xml/zen_mode_behavior_settings.xml
@@ -46,17 +46,16 @@
android:key="zen_mode_events"
android:title="@string/zen_mode_events"/>
- <!-- Messages -->
- <DropDownPreference
+ <Preference
android:key="zen_mode_messages"
android:title="@string/zen_mode_messages"
- android:summary="%s" />
+ android:fragment="com.android.settings.notification.ZenModeMessagesSettings" />
<!-- Calls -->
- <DropDownPreference
+ <Preference
android:key="zen_mode_calls"
android:title="@string/zen_mode_calls"
- android:summary="%s" />
+ android:fragment="com.android.settings.notification.ZenModeCallsSettings" />
<!-- Repeat callers -->
<SwitchPreference
diff --git a/res/xml/zen_mode_calls_settings.xml b/res/xml/zen_mode_calls_settings.xml
new file mode 100644
index 0000000..aa84216
--- /dev/null
+++ b/res/xml/zen_mode_calls_settings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<PreferenceScreen
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:key="zen_mode_calls_settings"
+ android:title="@string/zen_mode_calls" />
diff --git a/res/xml/zen_mode_messages_settings.xml b/res/xml/zen_mode_messages_settings.xml
new file mode 100644
index 0000000..4b4a1e2
--- /dev/null
+++ b/res/xml/zen_mode_messages_settings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<PreferenceScreen
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:key="zen_mode_messages_settings"
+ android:title="@string/zen_mode_messages" />
diff --git a/res/xml/zen_mode_settings.xml b/res/xml/zen_mode_settings.xml
index 92e2b7f..82bef4d 100644
--- a/res/xml/zen_mode_settings.xml
+++ b/res/xml/zen_mode_settings.xml
@@ -19,6 +19,7 @@
android:key="zen_mode_settings"
android:title="@string/zen_mode_settings_title">
+ <!-- Priority behavior settings -->
<Preference
android:key="zen_mode_behavior_settings"
android:title="@string/zen_mode_behavior_settings_title"
@@ -29,4 +30,14 @@
android:key="zen_mode_automation_settings"
android:title="@string/zen_mode_automation_settings_title"
android:fragment="com.android.settings.notification.ZenModeAutomationSettings" />
+
+ <!-- Turn on DND button -->
+ <!-- Layout preference doesn't obey allowDividerAbove, so put it in a PreferenceCategory -->
+ <PreferenceCategory>
+ <com.android.settings.applications.LayoutPreference
+ android:key="zen_mode_settings_button_container"
+ android:selectable="false"
+ android:layout="@layout/zen_mode_settings_button" />
+ </PreferenceCategory>
+
</PreferenceScreen>
diff --git a/src/com/android/settings/DeviceInfoSettings.java b/src/com/android/settings/DeviceInfoSettings.java
index 6c6c9e9..e5c3e06 100644
--- a/src/com/android/settings/DeviceInfoSettings.java
+++ b/src/com/android/settings/DeviceInfoSettings.java
@@ -22,8 +22,11 @@
import android.app.Fragment;
import android.content.Context;
import android.content.Intent;
+import android.os.Bundle;
import android.provider.SearchIndexableResource;
+import android.telephony.TelephonyManager;
import android.util.FeatureFlagUtils;
+import android.support.annotation.VisibleForTesting;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.dashboard.DashboardFragment;
@@ -35,6 +38,7 @@
import com.android.settings.deviceinfo.FccEquipmentIdPreferenceController;
import com.android.settings.deviceinfo.FeedbackPreferenceController;
import com.android.settings.deviceinfo.FirmwareVersionPreferenceController;
+import com.android.settings.deviceinfo.ImsStatusPreferenceController;
import com.android.settings.deviceinfo.IpAddressPreferenceController;
import com.android.settings.deviceinfo.KernelVersionPreferenceController;
import com.android.settings.deviceinfo.ManualPreferenceController;
@@ -61,6 +65,11 @@
private static final String KEY_LEGAL_CONTAINER = "legal_container";
+ @VisibleForTesting
+ static final int SIM_PREFERENCES_COUNT = 3;
+ @VisibleForTesting
+ static final int NON_SIM_PREFERENCES_COUNT = 2;
+
@Override
public int getMetricsCategory() {
return MetricsEvent.DEVICEINFO;
@@ -72,6 +81,21 @@
}
@Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ if (FeatureFlagUtils.isEnabled(getContext(), DEVICE_INFO_V2)) {
+ // Increase the number of children when the device contains more than 1 sim.
+ final TelephonyManager telephonyManager = (TelephonyManager) getSystemService(
+ Context.TELEPHONY_SERVICE);
+ final int numberOfChildren = Math.max(SIM_PREFERENCES_COUNT,
+ SIM_PREFERENCES_COUNT * telephonyManager.getPhoneCount())
+ + NON_SIM_PREFERENCES_COUNT;
+ getPreferenceScreen().setInitialExpandedChildrenCount(numberOfChildren);
+ }
+ }
+
+ @Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
final BuildNumberPreferenceController buildNumberPreferenceController =
getPreferenceController(BuildNumberPreferenceController.class);
@@ -139,6 +163,8 @@
controllers.add(new FirmwareVersionPreferenceControllerV2(context, fragment));
+ controllers.add(new ImsStatusPreferenceController(context, lifecycle));
+
controllers.add(new IpAddressPreferenceController(context, lifecycle));
controllers.add(new WifiMacAddressPreferenceController(context, lifecycle));
@@ -149,6 +175,12 @@
controllers.add(new SafetyInfoPreferenceController(context));
+ controllers.add(new ManualPreferenceController(context));
+
+ controllers.add(new FeedbackPreferenceController(fragment, context));
+
+ controllers.add(new FccEquipmentIdPreferenceController(context));
+
controllers.add(
new BuildNumberPreferenceController(context, activity, fragment, lifecycle));
diff --git a/src/com/android/settings/datausage/DataUsageMeteredSettings.java b/src/com/android/settings/datausage/DataUsageMeteredSettings.java
index 0afb894..8bc7e04 100644
--- a/src/com/android/settings/datausage/DataUsageMeteredSettings.java
+++ b/src/com/android/settings/datausage/DataUsageMeteredSettings.java
@@ -14,27 +14,26 @@
package com.android.settings.datausage;
-import static android.net.wifi.WifiInfo.removeDoubleQuotes;
-
import android.app.backup.BackupManager;
import android.content.Context;
-import android.content.res.Resources;
import android.net.NetworkPolicyManager;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.os.Bundle;
+import android.provider.SearchIndexableResource;
import android.support.v7.preference.DropDownPreference;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceCategory;
import android.text.TextUtils;
+
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
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 com.android.settingslib.NetworkPolicyEditor;
-import java.util.ArrayList;
+
+import java.util.Arrays;
import java.util.List;
/**
@@ -134,49 +133,11 @@
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>();
- final Resources res = context.getResources();
-
- // Add fragment title
- SearchIndexableRaw data = new SearchIndexableRaw(context);
- data.title = res.getString(R.string.data_usage_menu_metered);
- data.screenTitle = res.getString(R.string.data_usage_menu_metered);
- result.add(data);
-
- // Body
- data = new SearchIndexableRaw(context);
- data.title = res.getString(R.string.data_usage_metered_body);
- data.screenTitle = res.getString(R.string.data_usage_menu_metered);
- result.add(data);
-
- // Wi-Fi networks category
- data = new SearchIndexableRaw(context);
- data.title = res.getString(R.string.data_usage_metered_wifi);
- data.screenTitle = res.getString(R.string.data_usage_menu_metered);
- result.add(data);
-
- final WifiManager wifiManager =
- (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
- if (DataUsageUtils.hasWifiRadio(context) && wifiManager.isWifiEnabled()) {
- for (WifiConfiguration config : wifiManager.getConfiguredNetworks()) {
- if (config.SSID != null) {
- final String networkId = config.SSID;
-
- data = new SearchIndexableRaw(context);
- data.title = removeDoubleQuotes(networkId);
- data.screenTitle = res.getString(R.string.data_usage_menu_metered);
- result.add(data);
- }
- }
- } else {
- data = new SearchIndexableRaw(context);
- data.title = res.getString(R.string.data_usage_metered_wifi_disabled);
- data.screenTitle = res.getString(R.string.data_usage_menu_metered);
- result.add(data);
- }
-
- return result;
+ public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
+ boolean enabled) {
+ final SearchIndexableResource sir = new SearchIndexableResource(context);
+ sir.xmlResId = R.xml.data_usage_metered_prefs;
+ return Arrays.asList(sir);
}
@Override
diff --git a/src/com/android/settings/deviceinfo/PhoneNumberPreferenceController.java b/src/com/android/settings/deviceinfo/PhoneNumberPreferenceController.java
index 5edac0f..802d774 100644
--- a/src/com/android/settings/deviceinfo/PhoneNumberPreferenceController.java
+++ b/src/com/android/settings/deviceinfo/PhoneNumberPreferenceController.java
@@ -26,13 +26,15 @@
import android.text.TextUtils;
import com.android.settings.R;
+import com.android.settings.core.PreferenceControllerMixin;
import com.android.settingslib.DeviceInfoUtils;
import com.android.settingslib.core.AbstractPreferenceController;
import java.util.ArrayList;
import java.util.List;
-public class PhoneNumberPreferenceController extends AbstractPreferenceController {
+public class PhoneNumberPreferenceController extends AbstractPreferenceController implements
+ PreferenceControllerMixin {
private final static String KEY_PHONE_NUMBER = "phone_number";
diff --git a/src/com/android/settings/deviceinfo/StorageSettings.java b/src/com/android/settings/deviceinfo/StorageSettings.java
index a3ed940..e9d3c85 100644
--- a/src/com/android/settings/deviceinfo/StorageSettings.java
+++ b/src/com/android/settings/deviceinfo/StorageSettings.java
@@ -16,7 +16,8 @@
package com.android.settings.deviceinfo;
-import android.app.Activity;
+import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
+
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.Fragment;
@@ -63,8 +64,6 @@
import java.util.Collections;
import java.util.List;
-import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
-
/**
* Panel showing both internal storage (both built-in storage and private
* volumes) and removable storage (public volumes).
@@ -545,13 +544,7 @@
public static final SummaryLoader.SummaryProviderFactory SUMMARY_PROVIDER_FACTORY
- = new SummaryLoader.SummaryProviderFactory() {
- @Override
- public SummaryLoader.SummaryProvider createSummaryProvider(Activity activity,
- SummaryLoader summaryLoader) {
- return new SummaryProvider(activity, summaryLoader);
- }
- };
+ = (activity, summaryLoader) -> new SummaryProvider(activity, summaryLoader);
/** Enable indexing of searchable data */
public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
@@ -559,15 +552,17 @@
@Override
public List<SearchIndexableRaw> getRawDataToIndex(
Context context, boolean enabled) {
- final List<SearchIndexableRaw> result = new ArrayList<SearchIndexableRaw>();
+ final List<SearchIndexableRaw> result = new ArrayList<>();
SearchIndexableRaw data = new SearchIndexableRaw(context);
data.title = context.getString(R.string.storage_settings);
+ data.key = "storage_settings";
data.screenTitle = context.getString(R.string.storage_settings);
result.add(data);
data = new SearchIndexableRaw(context);
data.title = context.getString(R.string.internal_storage);
+ data.key = "storage_settings_internal_storage";
data.screenTitle = context.getString(R.string.storage_settings);
result.add(data);
@@ -577,6 +572,7 @@
for (VolumeInfo vol : vols) {
if (isInteresting(vol)) {
data.title = storage.getBestVolumeDescription(vol);
+ data.key = "storage_settings_volume_" +vol.id;
data.screenTitle = context.getString(R.string.storage_settings);
result.add(data);
}
@@ -584,36 +580,43 @@
data = new SearchIndexableRaw(context);
data.title = context.getString(R.string.memory_size);
+ data.key = "storage_settings_memory_size";
data.screenTitle = context.getString(R.string.storage_settings);
result.add(data);
data = new SearchIndexableRaw(context);
data.title = context.getString(R.string.memory_available);
+ data.key = "storage_settings_memory_available";
data.screenTitle = context.getString(R.string.storage_settings);
result.add(data);
data = new SearchIndexableRaw(context);
data.title = context.getString(R.string.memory_apps_usage);
+ data.key = "storage_settings_apps_space";
data.screenTitle = context.getString(R.string.storage_settings);
result.add(data);
data = new SearchIndexableRaw(context);
data.title = context.getString(R.string.memory_dcim_usage);
+ data.key = "storage_settings_dcim_space";
data.screenTitle = context.getString(R.string.storage_settings);
result.add(data);
data = new SearchIndexableRaw(context);
data.title = context.getString(R.string.memory_music_usage);
+ data.key = "storage_settings_music_space";
data.screenTitle = context.getString(R.string.storage_settings);
result.add(data);
data = new SearchIndexableRaw(context);
data.title = context.getString(R.string.memory_media_misc_usage);
+ data.key = "storage_settings_misc_space";
data.screenTitle = context.getString(R.string.storage_settings);
result.add(data);
data = new SearchIndexableRaw(context);
data.title = context.getString(R.string.storage_menu_free);
+ data.key = "storage_settings_free_space";
data.screenTitle = context.getString(R.string.storage_menu_free);
// We need to define all three in order for this to trigger properly.
data.intentAction = StorageManager.ACTION_MANAGE_STORAGE;
diff --git a/src/com/android/settings/display/ScreenZoomSettings.java b/src/com/android/settings/display/ScreenZoomSettings.java
index a77782f..6b5216e 100644
--- a/src/com/android/settings/display/ScreenZoomSettings.java
+++ b/src/com/android/settings/display/ScreenZoomSettings.java
@@ -22,6 +22,7 @@
import android.content.res.Resources;
import android.os.Bundle;
import android.view.Display;
+
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.PreviewSeekBarPreferenceFragment;
import com.android.settings.R;
@@ -48,7 +49,7 @@
mActivityLayoutResId = R.layout.screen_zoom_activity;
// This should be replaced once the final preview sample screen is in place.
- mPreviewSampleResIds = new int[]{R.layout.screen_zoom_preview_1,
+ mPreviewSampleResIds = new int[] {R.layout.screen_zoom_preview_1,
R.layout.screen_zoom_preview_2,
R.layout.screen_zoom_preview_settings};
@@ -60,8 +61,8 @@
// connect to the window manager service. Just use the current
// density and don't let the user change anything.
final int densityDpi = getResources().getDisplayMetrics().densityDpi;
- mValues = new int[] { densityDpi };
- mEntries = new String[] { getString(DisplayDensityUtils.SUMMARY_DEFAULT) };
+ mValues = new int[] {densityDpi};
+ mEntries = new String[] {getString(DisplayDensityUtils.SUMMARY_DEFAULT)};
mInitialIndex = 0;
mDefaultDensity = densityDpi;
} else {
@@ -109,10 +110,12 @@
public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider() {
@Override
- public List<SearchIndexableRaw> getRawDataToIndex(Context context, boolean enabled) {
+ public List<SearchIndexableRaw> getRawDataToIndex(Context context,
+ boolean enabled) {
final Resources res = context.getResources();
final SearchIndexableRaw data = new SearchIndexableRaw(context);
data.title = res.getString(R.string.screen_zoom_title);
+ data.key = "screen_zoom_settings";
data.screenTitle = res.getString(R.string.screen_zoom_title);
data.keywords = res.getString(R.string.screen_zoom_keywords);
diff --git a/src/com/android/settings/network/PrivateDnsModeDialogFragment.java b/src/com/android/settings/network/PrivateDnsModeDialogFragment.java
index cb3079e..5704fb9 100644
--- a/src/com/android/settings/network/PrivateDnsModeDialogFragment.java
+++ b/src/com/android/settings/network/PrivateDnsModeDialogFragment.java
@@ -32,6 +32,7 @@
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
+import android.widget.Button;
import android.widget.EditText;
import android.widget.RadioGroup;
@@ -68,6 +69,8 @@
@VisibleForTesting
RadioGroup mRadioGroup;
@VisibleForTesting
+ Button mSaveButton;
+ @VisibleForTesting
String mMode;
public static void show(FragmentManager fragmentManager) {
@@ -81,17 +84,23 @@
public Dialog onCreateDialog(Bundle savedInstanceState) {
final Context context = getContext();
- return new AlertDialog.Builder(context)
+ final AlertDialog dialog = new AlertDialog.Builder(context)
.setTitle(R.string.select_private_dns_configuration_title)
.setView(buildPrivateDnsView(context))
.setPositiveButton(R.string.save, this)
.setNegativeButton(R.string.dlg_cancel, null)
.create();
+
+ dialog.setOnShowListener(dialogInterface -> {
+ mSaveButton = dialog.getButton(DialogInterface.BUTTON_POSITIVE);
+ updateDialogInfo();
+ });
+ return dialog;
}
private View buildPrivateDnsView(final Context context) {
final ContentResolver contentResolver = context.getContentResolver();
- final String mode = Settings.Global.getString(contentResolver, MODE_KEY);
+ mMode = Settings.Global.getString(contentResolver, MODE_KEY);
final View view = LayoutInflater.from(context).inflate(R.layout.private_dns_mode_dialog,
null);
@@ -101,7 +110,7 @@
mRadioGroup = view.findViewById(R.id.private_dns_radio_group);
mRadioGroup.setOnCheckedChangeListener(this);
- mRadioGroup.check(PRIVATE_DNS_MAP.getOrDefault(mode, R.id.private_dns_mode_opportunistic));
+ mRadioGroup.check(PRIVATE_DNS_MAP.getOrDefault(mMode, R.id.private_dns_mode_opportunistic));
return view;
}
@@ -129,17 +138,15 @@
switch (checkedId) {
case R.id.private_dns_mode_off:
mMode = PRIVATE_DNS_MODE_OFF;
- mEditText.setEnabled(false);
break;
case R.id.private_dns_mode_opportunistic:
mMode = PRIVATE_DNS_MODE_OPPORTUNISTIC;
- mEditText.setEnabled(false);
break;
case R.id.private_dns_mode_provider:
mMode = PRIVATE_DNS_MODE_PROVIDER_HOSTNAME;
- mEditText.setEnabled(true);
break;
}
+ updateDialogInfo();
}
@Override
@@ -152,8 +159,9 @@
@Override
public void afterTextChanged(Editable s) {
- // TODO(b/68030013): Disable the "positive button" ("Save") when appearsValid is false.
- final boolean valid = isWeaklyValidatedHostname(s.toString());
+ if (mSaveButton != null) {
+ mSaveButton.setEnabled(isWeaklyValidatedHostname(mEditText.getText().toString()));
+ }
}
private boolean isWeaklyValidatedHostname(String hostname) {
@@ -165,4 +173,17 @@
return hostname.matches(WEAK_HOSTNAME_REGEX);
}
+ private void updateDialogInfo() {
+ final boolean modeProvider = PRIVATE_DNS_MODE_PROVIDER_HOSTNAME.equals(mMode);
+ if (mEditText != null) {
+ mEditText.setEnabled(modeProvider);
+ }
+ if (mSaveButton != null) {
+ mSaveButton.setEnabled(
+ modeProvider
+ ? isWeaklyValidatedHostname(mEditText.getText().toString())
+ : true);
+ }
+ }
+
}
diff --git a/src/com/android/settings/notification/AbstractZenModeAutomaticRulePreferenceController.java b/src/com/android/settings/notification/AbstractZenModeAutomaticRulePreferenceController.java
new file mode 100644
index 0000000..ec9cf2a
--- /dev/null
+++ b/src/com/android/settings/notification/AbstractZenModeAutomaticRulePreferenceController.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.notification;
+
+import android.app.AutomaticZenRule;
+import android.app.Fragment;
+import android.app.NotificationManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ServiceInfo;
+import android.provider.Settings;
+import android.service.notification.ConditionProviderService;
+import android.service.notification.ZenModeConfig;
+import android.support.v7.preference.Preference;
+
+import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settingslib.core.AbstractPreferenceController;
+
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Map;
+import java.util.Set;
+
+abstract public class AbstractZenModeAutomaticRulePreferenceController extends
+ AbstractPreferenceController implements PreferenceControllerMixin {
+
+ private static final String TAG = "ZenModeAutomaticRule";
+ protected ZenModeBackend mBackend;
+ protected Fragment mParent;
+ protected Set<Map.Entry<String, AutomaticZenRule>> mRules;
+ protected PackageManager mPm;
+
+ public AbstractZenModeAutomaticRulePreferenceController(Context context, Fragment parent) {
+ super(context);
+ mBackend = ZenModeBackend.getInstance(context);
+ mParent = parent;
+ mPm = mContext.getPackageManager();
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ super.updateState(preference);
+ mRules = getZenModeRules();
+ }
+
+ private Set<Map.Entry<String, AutomaticZenRule>> getZenModeRules() {
+ Map<String, AutomaticZenRule> ruleMap =
+ NotificationManager.from(mContext).getAutomaticZenRules();
+ return ruleMap.entrySet();
+ }
+
+ protected void showNameRuleDialog(final ZenRuleInfo ri) {
+ new ZenRuleNameDialog(mContext, null, ri.defaultConditionId) {
+ @Override
+ public void onOk(String ruleName) {
+ AutomaticZenRule rule = new AutomaticZenRule(ruleName, ri.serviceComponent,
+ ri.defaultConditionId, NotificationManager.INTERRUPTION_FILTER_PRIORITY,
+ true);
+ String savedRuleId = mBackend.addZenRule(rule);
+ if (savedRuleId != null) {
+ mParent.startActivity(getRuleIntent(ri.settingsAction, null, savedRuleId));
+ }
+ }
+ }.show();
+ }
+
+ protected Map.Entry<String, AutomaticZenRule>[] sortedRules() {
+ if (mRules == null) {
+ mRules = getZenModeRules();
+ }
+ final Map.Entry<String, AutomaticZenRule>[] rt =
+ mRules.toArray(new Map.Entry[mRules.size()]);
+ Arrays.sort(rt, RULE_COMPARATOR);
+ return rt;
+ }
+
+ protected static Intent getRuleIntent(String settingsAction,
+ ComponentName configurationActivity, String ruleId) {
+ final Intent intent = new Intent()
+ .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
+ .putExtra(ConditionProviderService.EXTRA_RULE_ID, ruleId);
+ if (configurationActivity != null) {
+ intent.setComponent(configurationActivity);
+ } else {
+ intent.setAction(settingsAction);
+ }
+ return intent;
+ }
+
+ private static final Comparator<Map.Entry<String, AutomaticZenRule>> RULE_COMPARATOR =
+ new Comparator<Map.Entry<String, AutomaticZenRule>>() {
+ @Override
+ public int compare(Map.Entry<String, AutomaticZenRule> lhs,
+ Map.Entry<String, AutomaticZenRule> rhs) {
+ int byDate = Long.compare(lhs.getValue().getCreationTime(),
+ rhs.getValue().getCreationTime());
+ if (byDate != 0) {
+ return byDate;
+ } else {
+ return key(lhs.getValue()).compareTo(key(rhs.getValue()));
+ }
+ }
+
+ private String key(AutomaticZenRule rule) {
+ final int type = ZenModeConfig.isValidScheduleConditionId(rule.getConditionId())
+ ? 1 : ZenModeConfig.isValidEventConditionId(rule.getConditionId())
+ ? 2 : 3;
+ return type + rule.getName().toString();
+ }
+ };
+
+ public static ZenRuleInfo getRuleInfo(PackageManager pm, ServiceInfo si) {
+ if (si == null || si.metaData == null) {
+ return null;
+ }
+ final String ruleType = si.metaData.getString(ConditionProviderService.META_DATA_RULE_TYPE);
+ final ComponentName configurationActivity = getSettingsActivity(si);
+ if (ruleType != null && !ruleType.trim().isEmpty() && configurationActivity != null) {
+ final ZenRuleInfo ri = new ZenRuleInfo();
+ ri.serviceComponent = new ComponentName(si.packageName, si.name);
+ ri.settingsAction = Settings.ACTION_ZEN_MODE_EXTERNAL_RULE_SETTINGS;
+ ri.title = ruleType;
+ ri.packageName = si.packageName;
+ ri.configurationActivity = getSettingsActivity(si);
+ ri.packageLabel = si.applicationInfo.loadLabel(pm);
+ ri.ruleInstanceLimit =
+ si.metaData.getInt(ConditionProviderService.META_DATA_RULE_INSTANCE_LIMIT, -1);
+ return ri;
+ }
+ return null;
+ }
+
+ protected static ComponentName getSettingsActivity(ServiceInfo si) {
+ if (si == null || si.metaData == null) {
+ return null;
+ }
+ final String configurationActivity =
+ si.metaData.getString(ConditionProviderService.META_DATA_CONFIGURATION_ACTIVITY);
+ if (configurationActivity != null) {
+ return ComponentName.unflattenFromString(configurationActivity);
+ }
+ return null;
+ }
+}
diff --git a/src/com/android/settings/notification/AbstractZenModePreferenceController.java b/src/com/android/settings/notification/AbstractZenModePreferenceController.java
new file mode 100644
index 0000000..ec275b2
--- /dev/null
+++ b/src/com/android/settings/notification/AbstractZenModePreferenceController.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.notification;
+
+import android.app.NotificationManager;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Handler;
+import android.provider.Settings;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settings.core.PreferenceControllerMixin;
+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.OnPause;
+import com.android.settingslib.core.lifecycle.events.OnResume;
+
+abstract public class AbstractZenModePreferenceController extends
+ AbstractPreferenceController implements PreferenceControllerMixin, LifecycleObserver,
+ OnResume, OnPause {
+
+ private SettingObserver mSettingObserver;
+ private final String KEY;
+ final private NotificationManager mNotificationManager;
+
+ public AbstractZenModePreferenceController(Context context, String key,
+ Lifecycle lifecycle) {
+ super(context);
+ if (lifecycle != null) {
+ lifecycle.addObserver(this);
+ }
+ KEY = key;
+ mNotificationManager = (NotificationManager) context.getSystemService(
+ Context.NOTIFICATION_SERVICE);
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+ mSettingObserver = new SettingObserver(screen.findPreference(KEY));
+ }
+
+ @Override
+ public void onResume() {
+ if (mSettingObserver != null) {
+ mSettingObserver.register(mContext.getContentResolver());
+ }
+ }
+
+ @Override
+ public void onPause() {
+ if (mSettingObserver != null) {
+ mSettingObserver.unregister(mContext.getContentResolver());
+ }
+ }
+
+ protected NotificationManager.Policy getPolicy() {
+ return mNotificationManager.getNotificationPolicy();
+ }
+
+ protected int getZenMode() {
+ return Settings.Global.getInt(mContext.getContentResolver(),
+ Settings.Global.ZEN_MODE, 0);
+ }
+
+ class SettingObserver extends ContentObserver {
+ private final Uri ZEN_MODE_URI = Settings.Global.getUriFor(Settings.Global.ZEN_MODE);
+ private final Uri ZEN_MODE_CONFIG_ETAG_URI = Settings.Global.getUriFor(
+ Settings.Global.ZEN_MODE_CONFIG_ETAG);
+
+ private final Preference mPreference;
+
+ public SettingObserver(Preference preference) {
+ super(new Handler());
+ mPreference = preference;
+ }
+
+ public void register(ContentResolver cr) {
+ cr.registerContentObserver(ZEN_MODE_URI, false, this);
+ cr.registerContentObserver(ZEN_MODE_CONFIG_ETAG_URI, false, this);
+ }
+
+ public void unregister(ContentResolver cr) {
+ cr.unregisterContentObserver(this);
+ }
+
+ @Override
+ public void onChange(boolean selfChange, Uri uri) {
+ super.onChange(selfChange, uri);
+ if (ZEN_MODE_URI.equals(uri)) {
+ updateState(mPreference);
+ }
+
+ if (ZEN_MODE_CONFIG_ETAG_URI.equals(uri)) {
+ updateState(mPreference);
+ }
+ }
+ }
+}
diff --git a/src/com/android/settings/notification/ZenModeAddAutomaticRulePreferenceController.java b/src/com/android/settings/notification/ZenModeAddAutomaticRulePreferenceController.java
new file mode 100644
index 0000000..a15536c
--- /dev/null
+++ b/src/com/android/settings/notification/ZenModeAddAutomaticRulePreferenceController.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.notification;
+
+import android.app.Fragment;
+import android.content.Context;
+import android.content.Intent;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settings.utils.ZenServiceListing;
+
+public class ZenModeAddAutomaticRulePreferenceController extends
+ AbstractZenModeAutomaticRulePreferenceController implements
+ Preference.OnPreferenceClickListener {
+
+ private final String KEY_ADD_RULE;
+ private final ZenServiceListing mZenServiceListing;
+
+ public ZenModeAddAutomaticRulePreferenceController(Context context, String key,
+ Fragment parent, ZenServiceListing serviceListing) {
+ super(context, parent);
+ KEY_ADD_RULE = key;
+ mZenServiceListing = serviceListing;
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY_ADD_RULE;
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return true;
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+ Preference pref = screen.findPreference(KEY_ADD_RULE);
+ pref.setPersistent(false);
+ pref.setOnPreferenceClickListener(this);
+ }
+
+ @Override
+ public boolean onPreferenceClick(Preference preference) {
+ new ZenRuleSelectionDialog(mContext, mZenServiceListing) {
+ @Override
+ public void onSystemRuleSelected(ZenRuleInfo ri) {
+ showNameRuleDialog(ri);
+ }
+
+ @Override
+ public void onExternalRuleSelected(ZenRuleInfo ri) {
+ Intent intent = new Intent().setComponent(ri.configurationActivity);
+ mParent.startActivity(intent);
+ }
+ }.show();
+ return true;
+ }
+}
diff --git a/src/com/android/settings/notification/ZenModeAlarmsPreferenceController.java b/src/com/android/settings/notification/ZenModeAlarmsPreferenceController.java
new file mode 100644
index 0000000..ef8d026
--- /dev/null
+++ b/src/com/android/settings/notification/ZenModeAlarmsPreferenceController.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.notification;
+
+import android.app.NotificationManager.Policy;
+import android.content.Context;
+import android.provider.Settings;
+import android.support.v14.preference.SwitchPreference;
+import android.support.v7.preference.Preference;
+import android.util.Log;
+
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+public class ZenModeAlarmsPreferenceController extends
+ AbstractZenModePreferenceController implements Preference.OnPreferenceChangeListener {
+
+ protected static final String KEY = "zen_mode_alarms";
+ private final ZenModeBackend mBackend;
+
+ public ZenModeAlarmsPreferenceController(Context context, Lifecycle lifecycle) {
+ super(context, KEY, lifecycle);
+ mBackend = ZenModeBackend.getInstance(context);
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY;
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return true;
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ super.updateState(preference);
+
+ SwitchPreference pref = (SwitchPreference) preference;
+ switch (getZenMode()) {
+ case Settings.Global.ZEN_MODE_NO_INTERRUPTIONS:
+ pref.setEnabled(false);
+ pref.setChecked(false);
+ break;
+ case Settings.Global.ZEN_MODE_ALARMS:
+ pref.setEnabled(false);
+ pref.setChecked(true);
+ break;
+ default:
+ pref.setEnabled(true);
+ pref.setChecked(mBackend.isPriorityCategoryEnabled(
+ Policy.PRIORITY_CATEGORY_ALARMS));
+ }
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ final boolean allowAlarms = (Boolean) newValue;
+ if (ZenModeSettingsBase.DEBUG) {
+ Log.d(TAG, "onPrefChange allowAlarms=" + allowAlarms);
+ }
+ mBackend.saveSoundPolicy(Policy.PRIORITY_CATEGORY_ALARMS, allowAlarms);
+ return true;
+ }
+}
diff --git a/src/com/android/settings/notification/ZenModeAutomaticRulesPreferenceController.java b/src/com/android/settings/notification/ZenModeAutomaticRulesPreferenceController.java
new file mode 100644
index 0000000..f91bdd6
--- /dev/null
+++ b/src/com/android/settings/notification/ZenModeAutomaticRulesPreferenceController.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.notification;
+
+import android.app.AutomaticZenRule;
+import android.app.Fragment;
+import android.content.Context;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceCategory;
+import android.support.v7.preference.PreferenceScreen;
+import java.util.Map;
+
+public class ZenModeAutomaticRulesPreferenceController extends
+ AbstractZenModeAutomaticRulePreferenceController {
+
+ private final String KEY_AUTOMATIC_RULES;
+ private PreferenceCategory mPreferenceCategory;
+ Map.Entry<String, AutomaticZenRule>[] mSortedRules;
+
+ public ZenModeAutomaticRulesPreferenceController(Context context, String key,
+ Fragment parent) {
+ super(context, parent);
+ KEY_AUTOMATIC_RULES = key;
+ mSortedRules = sortedRules();
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY_AUTOMATIC_RULES;
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return true;
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+ mPreferenceCategory = (PreferenceCategory) screen.findPreference(getPreferenceKey());
+ mPreferenceCategory.setPersistent(false);
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ super.updateState(preference);
+
+ // no need to update AutomaticRule if a rule was deleted
+ // (on rule deletion, the preference removes itself from its parent)
+ int oldRuleLength = mSortedRules.length;
+ mSortedRules = sortedRules();
+ if (!wasRuleDeleted(oldRuleLength)) {
+ updateAutomaticRules();
+ }
+ }
+
+ private boolean wasRuleDeleted(int oldRuleLength) {
+ int newRuleLength = mSortedRules.length;
+ int prefCount = mPreferenceCategory.getPreferenceCount();
+
+ return (prefCount == oldRuleLength -1) && (prefCount == newRuleLength);
+ }
+
+ private void updateAutomaticRules() {
+ for (Map.Entry<String, AutomaticZenRule> sortedRule : mSortedRules) {
+ ZenRulePreference currPref = (ZenRulePreference)
+ mPreferenceCategory.findPreference(sortedRule.getKey());
+ if (currPref != null && currPref.appExists) {
+ // rule already exists in preferences, update it
+ currPref.setAttributes(sortedRule.getValue());
+ } else {
+ // rule doesn't exist in preferences, add it
+ ZenRulePreference pref = new ZenRulePreference(mPreferenceCategory.getContext(),
+ sortedRule, mPreferenceCategory);
+ if (pref.appExists) {
+ mPreferenceCategory.addPreference(pref);
+ }
+ }
+ }
+
+ }
+}
+
+
+
diff --git a/src/com/android/settings/notification/ZenModeAutomationPreferenceController.java b/src/com/android/settings/notification/ZenModeAutomationPreferenceController.java
new file mode 100644
index 0000000..aa46d4e
--- /dev/null
+++ b/src/com/android/settings/notification/ZenModeAutomationPreferenceController.java
@@ -0,0 +1,34 @@
+package com.android.settings.notification;
+
+import android.content.Context;
+import android.support.v7.preference.Preference;
+
+import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settingslib.core.AbstractPreferenceController;
+
+public class ZenModeAutomationPreferenceController extends
+ AbstractPreferenceController implements PreferenceControllerMixin {
+
+ protected static final String KEY_ZEN_MODE_AUTOMATION = "zen_mode_automation_settings";
+ private final ZenModeSettings.SummaryBuilder mSummaryBuilder;
+
+ public ZenModeAutomationPreferenceController(Context context) {
+ super(context);
+ mSummaryBuilder = new ZenModeSettings.SummaryBuilder(context);
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY_ZEN_MODE_AUTOMATION;
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return true;
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ preference.setSummary(mSummaryBuilder.getAutomaticRulesSummary());
+ }
+}
diff --git a/src/com/android/settings/notification/ZenModeAutomationSettings.java b/src/com/android/settings/notification/ZenModeAutomationSettings.java
index 07e9228..d096e8c 100644
--- a/src/com/android/settings/notification/ZenModeAutomationSettings.java
+++ b/src/com/android/settings/notification/ZenModeAutomationSettings.java
@@ -16,167 +16,47 @@
package com.android.settings.notification;
-import android.app.AlertDialog;
-import android.app.AutomaticZenRule;
-import android.app.NotificationManager;
-import android.content.ComponentName;
+import android.app.Fragment;
import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.ServiceInfo;
-import android.content.res.Resources;
-import android.os.Bundle;
-import android.provider.SearchIndexableResource;
-import android.provider.Settings;
import android.service.notification.ConditionProviderService;
-import android.service.notification.ZenModeConfig;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.Preference.OnPreferenceClickListener;
-import android.support.v7.preference.PreferenceScreen;
-import android.support.v7.preference.PreferenceViewHolder;
-import android.view.View;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable;
-import com.android.settings.utils.ManagedServiceSettings.Config;
+import com.android.settings.utils.ManagedServiceSettings;
import com.android.settings.utils.ZenServiceListing;
-import com.android.settingslib.TwoTargetPreference;
+import com.android.settingslib.core.AbstractPreferenceController;
-import java.util.Arrays;
-import java.util.Comparator;
+import java.util.ArrayList;
import java.util.List;
-import java.util.Map;
-public class ZenModeAutomationSettings extends ZenModeSettingsBase implements Indexable {
-
- static final Config CONFIG = getConditionProviderConfig();
-
- private PackageManager mPm;
- private ZenServiceListing mServiceListing;
+public class ZenModeAutomationSettings extends ZenModeSettingsBase {
+ private static final String KEY_ADD_RULE = "zen_mode_add_automatic_rule";
+ private static final String KEY_AUTOMATIC_RULES = "zen_mode_automatic_rules";
+ protected static final ManagedServiceSettings.Config CONFIG = getConditionProviderConfig();
@Override
- public void onCreate(Bundle icicle) {
- super.onCreate(icicle);
- addPreferencesFromResource(R.xml.zen_mode_automation_settings);
+ protected List<AbstractPreferenceController> getPreferenceControllers(Context context) {
+ ZenServiceListing serviceListing = new ZenServiceListing(getContext(), CONFIG);
+ serviceListing.reloadApprovedServices();
+ return buildPreferenceControllers(context, this, serviceListing);
+ }
- mPm = mContext.getPackageManager();
- mServiceListing = new ZenServiceListing(mContext, CONFIG);
- mServiceListing.reloadApprovedServices();
+ private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
+ Fragment parent, ZenServiceListing serviceListing) {
+ List<AbstractPreferenceController> controllers = new ArrayList<>();
+ controllers.add(new ZenModeAddAutomaticRulePreferenceController(context, KEY_ADD_RULE,
+ parent, serviceListing));
+ controllers.add(new ZenModeAutomaticRulesPreferenceController(context,
+ KEY_AUTOMATIC_RULES, parent));
+
+ return controllers;
}
@Override
- protected void onZenModeChanged() {
- // don't care
- }
-
- @Override
- protected void onZenModeConfigChanged() {
- updateControls();
- }
-
- @Override
- public void onResume() {
- super.onResume();
- if (isUiRestricted()) {
- return;
- }
- updateControls();
- }
-
- private void showAddRuleDialog() {
- new ZenRuleSelectionDialog(mContext, mServiceListing) {
- @Override
- public void onSystemRuleSelected(ZenRuleInfo ri) {
- showNameRuleDialog(ri);
- }
-
- @Override
- public void onExternalRuleSelected(ZenRuleInfo ri) {
- Intent intent = new Intent().setComponent(ri.configurationActivity);
- startActivity(intent);
- }
- }.show();
- }
-
- private void showNameRuleDialog(final ZenRuleInfo ri) {
- new ZenRuleNameDialog(mContext, null, ri.defaultConditionId) {
- @Override
- public void onOk(String ruleName) {
- mMetricsFeatureProvider.action(mContext, MetricsEvent.ACTION_ZEN_ADD_RULE_OK);
- AutomaticZenRule rule = new AutomaticZenRule(ruleName, ri.serviceComponent,
- ri.defaultConditionId, NotificationManager.INTERRUPTION_FILTER_PRIORITY,
- true);
- String savedRuleId = addZenRule(rule);
- if (savedRuleId != null) {
- startActivity(getRuleIntent(ri.settingsAction, null, savedRuleId));
- }
- }
- }.show();
- }
-
- private void showDeleteRuleDialog(final String ruleId, final CharSequence ruleName) {
- new AlertDialog.Builder(mContext)
- .setMessage(getString(R.string.zen_mode_delete_rule_confirmation, ruleName))
- .setNegativeButton(R.string.cancel, null)
- .setPositiveButton(R.string.zen_mode_delete_rule_button,
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- mMetricsFeatureProvider.action(mContext,
- MetricsEvent.ACTION_ZEN_DELETE_RULE_OK);
- removeZenRule(ruleId);
- }
- })
- .show();
- }
-
- private Intent getRuleIntent(String settingsAction, ComponentName configurationActivity,
- String ruleId) {
- final Intent intent = new Intent()
- .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
- .putExtra(ConditionProviderService.EXTRA_RULE_ID, ruleId);
- if (configurationActivity != null) {
- intent.setComponent(configurationActivity);
- } else {
- intent.setAction(settingsAction);
- }
- return intent;
- }
-
- private Map.Entry<String,AutomaticZenRule>[] sortedRules() {
- final Map.Entry<String,AutomaticZenRule>[] rt =
- mRules.toArray(new Map.Entry[mRules.size()]);
- Arrays.sort(rt, RULE_COMPARATOR);
- return rt;
- }
-
- private void updateControls() {
- final PreferenceScreen root = getPreferenceScreen();
- root.removeAll();
- final Map.Entry<String,AutomaticZenRule>[] sortedRules = sortedRules();
- for (Map.Entry<String,AutomaticZenRule> sortedRule : sortedRules) {
- ZenRulePreference pref = new ZenRulePreference(getPrefContext(), sortedRule);
- if (pref.appExists) {
- root.addPreference(pref);
- }
- }
- final Preference p = new Preference(getPrefContext());
- p.setIcon(R.drawable.ic_menu_add);
- p.setTitle(R.string.zen_mode_add_rule);
- p.setPersistent(false);
- p.setOnPreferenceClickListener(new OnPreferenceClickListener() {
- @Override
- public boolean onPreferenceClick(Preference preference) {
- mMetricsFeatureProvider.action(mContext, MetricsEvent.ACTION_ZEN_ADD_RULE);
- showAddRuleDialog();
- return true;
- }
- });
- root.addPreference(p);
+ protected int getPreferenceScreenResId() {
+ return R.xml.zen_mode_automation_settings;
}
@Override
@@ -184,18 +64,8 @@
return MetricsEvent.NOTIFICATION_ZEN_MODE_AUTOMATION;
}
- private String computeRuleSummary(AutomaticZenRule rule, boolean isSystemRule,
- CharSequence providerLabel) {
- final String mode = computeZenModeCaption(getResources(), rule.getInterruptionFilter());
- final String ruleState = (rule == null || !rule.isEnabled())
- ? getString(R.string.switch_off_text)
- : getString(R.string.zen_mode_rule_summary_enabled_combination, mode);
-
- return ruleState;
- }
-
- private static Config getConditionProviderConfig() {
- final Config c = new Config();
+ protected static ManagedServiceSettings.Config getConditionProviderConfig() {
+ final ManagedServiceSettings.Config c = new ManagedServiceSettings.Config();
c.tag = TAG;
c.intentAction = ConditionProviderService.SERVICE_INTERFACE;
c.permission = android.Manifest.permission.BIND_CONDITION_PROVIDER_SERVICE;
@@ -203,146 +73,22 @@
return c;
}
- private static String computeZenModeCaption(Resources res, int zenMode) {
- switch (zenMode) {
- case NotificationManager.INTERRUPTION_FILTER_ALARMS:
- return res.getString(R.string.zen_mode_option_alarms);
- case NotificationManager.INTERRUPTION_FILTER_PRIORITY:
- return res.getString(R.string.zen_mode_option_important_interruptions);
- case NotificationManager.INTERRUPTION_FILTER_NONE:
- return res.getString(R.string.zen_mode_option_no_interruptions);
- default:
- return null;
- }
- }
-
- public static ZenRuleInfo getRuleInfo(PackageManager pm, ServiceInfo si) {
- if (si == null || si.metaData == null) {
- return null;
- }
- final String ruleType = si.metaData.getString(ConditionProviderService.META_DATA_RULE_TYPE);
- final ComponentName configurationActivity = getSettingsActivity(si);
- if (ruleType != null && !ruleType.trim().isEmpty() && configurationActivity != null) {
- final ZenRuleInfo ri = new ZenRuleInfo();
- ri.serviceComponent = new ComponentName(si.packageName, si.name);
- ri.settingsAction = Settings.ACTION_ZEN_MODE_EXTERNAL_RULE_SETTINGS;
- ri.title = ruleType;
- ri.packageName = si.packageName;
- ri.configurationActivity = getSettingsActivity(si);
- ri.packageLabel = si.applicationInfo.loadLabel(pm);
- ri.ruleInstanceLimit =
- si.metaData.getInt(ConditionProviderService.META_DATA_RULE_INSTANCE_LIMIT, -1);
- return ri;
- }
- return null;
- }
-
- private static ComponentName getSettingsActivity(ServiceInfo si) {
- if (si == null || si.metaData == null) {
- return null;
- }
- final String configurationActivity =
- si.metaData.getString(ConditionProviderService.META_DATA_CONFIGURATION_ACTIVITY);
- if (configurationActivity != null) {
- return ComponentName.unflattenFromString(configurationActivity);
- }
- return null;
- }
-
- private static final Comparator<Map.Entry<String,AutomaticZenRule>> RULE_COMPARATOR =
- new Comparator<Map.Entry<String,AutomaticZenRule>>() {
- @Override
- public int compare(Map.Entry<String,AutomaticZenRule> lhs,
- Map.Entry<String,AutomaticZenRule> rhs) {
- int byDate = Long.compare(lhs.getValue().getCreationTime(),
- rhs.getValue().getCreationTime());
- if (byDate != 0) {
- return byDate;
- } else {
- return key(lhs.getValue()).compareTo(key(rhs.getValue()));
- }
- }
-
- private String key(AutomaticZenRule rule) {
- final int type = ZenModeConfig.isValidScheduleConditionId(rule.getConditionId())
- ? 1 : ZenModeConfig.isValidEventConditionId(rule.getConditionId())
- ? 2 : 3;
- return type + rule.getName().toString();
- }
- };
-
- private class ZenRulePreference extends TwoTargetPreference {
- final CharSequence mName;
- final String mId;
- final boolean appExists;
-
- public ZenRulePreference(Context context,
- final Map.Entry<String, AutomaticZenRule> ruleEntry) {
- super(context);
-
- final AutomaticZenRule rule = ruleEntry.getValue();
- mName = rule.getName();
- mId = ruleEntry.getKey();
-
- final boolean isSchedule = ZenModeConfig.isValidScheduleConditionId(
- rule.getConditionId());
- final boolean isEvent = ZenModeConfig.isValidEventConditionId(rule.getConditionId());
- final boolean isSystemRule = isSchedule || isEvent;
-
- try {
- ApplicationInfo info = mPm.getApplicationInfo(rule.getOwner().getPackageName(), 0);
- setSummary(computeRuleSummary(rule, isSystemRule, info.loadLabel(mPm)));
- } catch (PackageManager.NameNotFoundException e) {
- appExists = false;
- return;
- }
-
- appExists = true;
- setTitle(rule.getName());
- setPersistent(false);
-
- final String action = isSchedule ? ZenModeScheduleRuleSettings.ACTION
- : isEvent ? ZenModeEventRuleSettings.ACTION : "";
- ServiceInfo si = mServiceListing.findService(rule.getOwner());
- ComponentName settingsActivity = getSettingsActivity(si);
- setIntent(getRuleIntent(action, settingsActivity, mId));
- setSelectable(settingsActivity != null || isSystemRule);
- }
-
- @Override
- protected int getSecondTargetResId() {
- return R.layout.zen_rule_widget;
- }
-
- @Override
- public void onBindViewHolder(PreferenceViewHolder view) {
- super.onBindViewHolder(view);
-
- View v = view.findViewById(R.id.delete_zen_rule);
- if (v != null) {
- v.setOnClickListener(mDeleteListener);
- }
- }
-
- private final View.OnClickListener mDeleteListener = new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- showDeleteRuleDialog(mId, mName);
- }
- };
- }
-
/**
* For Search.
*/
public static final Indexable.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.zen_mode_automation_settings;
- return Arrays.asList(sir);
- }
- };
+ @Override
+ public List<String> getNonIndexableKeys(Context context) {
+ final List<String> keys = super.getNonIndexableKeys(context);
+ keys.add(KEY_ADD_RULE);
+ keys.add(KEY_AUTOMATIC_RULES);
+ return keys;
+ }
+
+ @Override
+ public List<AbstractPreferenceController> getPreferenceControllers(Context context) {
+ return buildPreferenceControllers(context, null, null);
+ }
+ };
}
diff --git a/src/com/android/settings/notification/ZenModeBackend.java b/src/com/android/settings/notification/ZenModeBackend.java
new file mode 100644
index 0000000..945da0b
--- /dev/null
+++ b/src/com/android/settings/notification/ZenModeBackend.java
@@ -0,0 +1,274 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.notification;
+
+import android.app.AutomaticZenRule;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.provider.Settings;
+import android.service.notification.ZenModeConfig;
+import android.support.annotation.VisibleForTesting;
+import android.util.Log;
+
+import com.android.settings.R;
+
+public class ZenModeBackend {
+ @VisibleForTesting
+ protected static final String ZEN_MODE_FROM_ANYONE = "zen_mode_from_anyone";
+ @VisibleForTesting
+ protected static final String ZEN_MODE_FROM_CONTACTS = "zen_mode_from_contacts";
+ @VisibleForTesting
+ protected static final String ZEN_MODE_FROM_STARRED = "zen_mode_from_starred";
+ @VisibleForTesting
+ protected static final String ZEN_MODE_FROM_NONE = "zen_mode_from_none";
+ protected static final int SOURCE_NONE = -1;
+
+ private static ZenModeBackend sInstance;
+
+ protected int mZenMode;
+ /** gets policy last set by updatePolicy **/
+ protected NotificationManager.Policy mPolicy;
+ private final NotificationManager mNotificationManager;
+
+ private String TAG = "ZenModeSettingsBackend";
+ private final Context mContext;
+
+ public static ZenModeBackend getInstance(Context context) {
+ if (sInstance == null) {
+ sInstance = new ZenModeBackend(context);
+ }
+ return sInstance;
+ }
+
+ public ZenModeBackend(Context context) {
+ mContext = context;
+ mNotificationManager = (NotificationManager) context.getSystemService(
+ Context.NOTIFICATION_SERVICE);
+ updateZenMode();
+ updatePolicy();
+ }
+
+ protected void updatePolicy() {
+ if (mNotificationManager != null) {
+ mPolicy = mNotificationManager.getNotificationPolicy();
+ }
+ }
+
+ protected void updateZenMode() {
+ mZenMode = Settings.Global.getInt(mContext.getContentResolver(),
+ Settings.Global.ZEN_MODE, mZenMode);
+ }
+
+ protected boolean setZenRule(String id, AutomaticZenRule rule) {
+ return NotificationManager.from(mContext).updateAutomaticZenRule(id, rule);
+ }
+
+ protected void setZenMode(int zenMode) {
+ NotificationManager.from(mContext).setZenMode(zenMode, null, TAG);
+ mZenMode = zenMode;
+ }
+
+ /** gets last zen mode set by setZenMode or updateZenMode **/
+ protected int getZenMode() {
+ mZenMode = Settings.Global.getInt(mContext.getContentResolver(),
+ Settings.Global.ZEN_MODE, mZenMode);
+ return mZenMode;
+ }
+
+ protected boolean isPriorityCategoryEnabled(int categoryType) {
+ return (mPolicy.priorityCategories & categoryType) != 0;
+ }
+
+ protected int getNewPriorityCategories(boolean allow, int categoryType) {
+ int priorityCategories = mPolicy.priorityCategories;
+ if (allow) {
+ priorityCategories |= categoryType;
+ } else {
+ priorityCategories &= ~categoryType;
+ }
+ return priorityCategories;
+ }
+
+ protected int getPriorityCallSenders() {
+ return mPolicy.priorityCallSenders;
+ }
+
+ protected int getPriorityMessageSenders() {
+ return mPolicy.priorityMessageSenders;
+ }
+
+ protected void saveVisualEffectsPolicy(int category, boolean canBypass) {
+ int suppressedEffects = getNewSuppressedEffects(!canBypass, category);
+ savePolicy(mPolicy.priorityCategories, mPolicy.priorityCallSenders,
+ mPolicy.priorityMessageSenders, suppressedEffects);
+ }
+
+ protected void saveSoundPolicy(int category, boolean allow) {
+ int priorityCategories = getNewPriorityCategories(allow, category);
+ savePolicy(priorityCategories, mPolicy.priorityCallSenders,
+ mPolicy.priorityMessageSenders, mPolicy.suppressedVisualEffects);
+ }
+
+ protected void savePolicy(int priorityCategories, int priorityCallSenders,
+ int priorityMessageSenders, int suppressedVisualEffects) {
+ mPolicy = new NotificationManager.Policy(priorityCategories, priorityCallSenders,
+ priorityMessageSenders,
+ suppressedVisualEffects);
+ mNotificationManager.setNotificationPolicy(mPolicy);
+ }
+
+ protected int getNewSuppressedEffects(boolean suppress, int effectType) {
+ int effects = mPolicy.suppressedVisualEffects;
+ if (suppress) {
+ effects |= effectType;
+ } else {
+ effects &= ~effectType;
+ }
+ return effects;
+ }
+
+ protected boolean isEffectAllowed(int effect) {
+ return (mPolicy.suppressedVisualEffects & effect) == 0;
+ }
+
+ protected void saveSenders(int category, int val) {
+ int priorityCallSenders = getPriorityCallSenders();
+ int priorityMessagesSenders = getPriorityMessageSenders();
+ int categorySenders = getPrioritySenders(category);
+
+ final boolean allowSenders = val != SOURCE_NONE;
+ final int allowSendersFrom = val == SOURCE_NONE ? categorySenders : val;
+
+ String stringCategory = "";
+ if (category == NotificationManager.Policy.PRIORITY_CATEGORY_CALLS) {
+ stringCategory = "Calls";
+ priorityCallSenders = allowSendersFrom;
+ }
+
+ if (category == NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES) {
+ stringCategory = "Messages";
+ priorityMessagesSenders = allowSendersFrom;
+ }
+
+ savePolicy(getNewPriorityCategories(allowSenders, category),
+ priorityCallSenders, priorityMessagesSenders, mPolicy.suppressedVisualEffects);
+
+ if (ZenModeSettingsBase.DEBUG) Log.d(TAG, "onPrefChange allow=" +
+ stringCategory + allowSenders + " allow" + stringCategory + "From="
+ + ZenModeConfig.sourceToString(allowSendersFrom));
+ }
+
+ protected String getSendersKey(int category) {
+ switch (getZenMode()) {
+ case Settings.Global.ZEN_MODE_NO_INTERRUPTIONS:
+ case Settings.Global.ZEN_MODE_ALARMS:
+ return getKeyFromSetting(SOURCE_NONE);
+ default:
+ int prioritySenders = getPrioritySenders(category);
+ return getKeyFromSetting(isPriorityCategoryEnabled(category)
+ ? prioritySenders : SOURCE_NONE);
+ }
+ }
+
+ private int getPrioritySenders(int category) {
+ int categorySenders = -1;
+
+ if (category == NotificationManager.Policy.PRIORITY_CATEGORY_CALLS) {
+ return getPriorityCallSenders();
+ }
+
+ if (category == NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES) {
+ return getPriorityMessageSenders();
+ }
+
+ return categorySenders;
+ }
+
+ protected static String getKeyFromSetting(int contactType) {
+ switch (contactType) {
+ case NotificationManager.Policy.PRIORITY_SENDERS_ANY:
+ return ZEN_MODE_FROM_ANYONE;
+ case NotificationManager.Policy.PRIORITY_SENDERS_CONTACTS:
+ return ZEN_MODE_FROM_CONTACTS;
+ case NotificationManager.Policy.PRIORITY_SENDERS_STARRED:
+ return ZEN_MODE_FROM_STARRED;
+ case SOURCE_NONE:
+ default:
+ return ZEN_MODE_FROM_NONE;
+ }
+ }
+
+ protected int getContactsSummary(int category) {
+ int contactType = -1;
+
+ // SOURCE_NONE can be used when in total silence or alarms only
+ // (policy is based on user's preferences but the UI displayed is based on zenMode)
+ if (category == SOURCE_NONE) {
+ return R.string.zen_mode_from_none;
+ }
+
+ if (category == NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES) {
+ if (isPriorityCategoryEnabled(category)) {
+ contactType = getPriorityMessageSenders();
+ }
+ } else if (category == NotificationManager.Policy.PRIORITY_CATEGORY_CALLS) {
+ if (isPriorityCategoryEnabled(category)) {
+ contactType = getPriorityCallSenders();
+ }
+ }
+
+ switch (contactType) {
+ case NotificationManager.Policy.PRIORITY_SENDERS_ANY:
+ return R.string.zen_mode_from_anyone;
+ case NotificationManager.Policy.PRIORITY_SENDERS_CONTACTS:
+ return R.string.zen_mode_from_contacts;
+ case NotificationManager.Policy.PRIORITY_SENDERS_STARRED:
+ return R.string.zen_mode_from_starred;
+ case SOURCE_NONE:
+ default:
+ return R.string.zen_mode_from_none;
+ }
+ }
+
+ protected static int getSettingFromPrefKey(String key) {
+ switch (key) {
+ case ZEN_MODE_FROM_ANYONE:
+ return NotificationManager.Policy.PRIORITY_SENDERS_ANY;
+ case ZEN_MODE_FROM_CONTACTS:
+ return NotificationManager.Policy.PRIORITY_SENDERS_CONTACTS;
+ case ZEN_MODE_FROM_STARRED:
+ return NotificationManager.Policy.PRIORITY_SENDERS_STARRED;
+ case ZEN_MODE_FROM_NONE:
+ default:
+ return SOURCE_NONE;
+ }
+ }
+
+ public boolean removeZenRule(String ruleId) {
+ return NotificationManager.from(mContext).removeAutomaticZenRule(ruleId);
+ }
+
+ protected String addZenRule(AutomaticZenRule rule) {
+ try {
+ String id = NotificationManager.from(mContext).addAutomaticZenRule(rule);
+ NotificationManager.from(mContext).getAutomaticZenRule(id);
+ return id;
+ } catch (Exception e) {
+ return null;
+ }
+ }
+}
diff --git a/src/com/android/settings/notification/ZenModeBehaviorPreferenceController.java b/src/com/android/settings/notification/ZenModeBehaviorPreferenceController.java
new file mode 100644
index 0000000..0e1f066
--- /dev/null
+++ b/src/com/android/settings/notification/ZenModeBehaviorPreferenceController.java
@@ -0,0 +1,37 @@
+package com.android.settings.notification;
+
+import android.content.Context;
+import android.support.v7.preference.Preference;
+
+import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+public class ZenModeBehaviorPreferenceController extends
+ AbstractZenModePreferenceController implements PreferenceControllerMixin {
+
+ protected static final String KEY_BEHAVIOR_SETTINGS = "zen_mode_behavior_settings";
+ private final ZenModeSettings.SummaryBuilder mSummaryBuilder;
+
+ public ZenModeBehaviorPreferenceController(Context context, Lifecycle lifecycle) {
+ super(context, KEY_BEHAVIOR_SETTINGS, lifecycle);
+ mSummaryBuilder = new ZenModeSettings.SummaryBuilder(context);
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY_BEHAVIOR_SETTINGS;
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return true;
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ super.updateState(preference);
+
+ preference.setSummary(mSummaryBuilder.getBehaviorSettingSummary(getPolicy(),
+ getZenMode()));
+ }
+}
diff --git a/src/com/android/settings/notification/ZenModeBehaviorSettings.java b/src/com/android/settings/notification/ZenModeBehaviorSettings.java
index 6fc97cf..dfe6786 100644
--- a/src/com/android/settings/notification/ZenModeBehaviorSettings.java
+++ b/src/com/android/settings/notification/ZenModeBehaviorSettings.java
@@ -16,303 +16,43 @@
package com.android.settings.notification;
-import android.app.NotificationManager;
-import android.app.NotificationManager.Policy;
import android.content.Context;
-import android.os.Bundle;
-import android.provider.SearchIndexableResource;
-import android.provider.Settings;
-import android.service.notification.ZenModeConfig;
-import android.support.v14.preference.SwitchPreference;
-import android.support.v7.preference.DropDownPreference;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.Preference.OnPreferenceChangeListener;
-import android.support.v7.preference.PreferenceScreen;
-import android.util.Log;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable;
+import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.lifecycle.Lifecycle;
-import java.util.Arrays;
+import java.util.ArrayList;
import java.util.List;
public class ZenModeBehaviorSettings extends ZenModeSettingsBase implements Indexable {
- private static final String KEY_ALARMS = "zen_mode_alarms";
- private static final String KEY_MEDIA = "zen_mode_media";
- private static final String KEY_REMINDERS = "zen_mode_reminders";
- private static final String KEY_EVENTS = "zen_mode_events";
- private static final String KEY_MESSAGES = "zen_mode_messages";
- private static final String KEY_CALLS = "zen_mode_calls";
- private static final String KEY_REPEAT_CALLERS = "zen_mode_repeat_callers";
- private static final String KEY_SCREEN_OFF = "zen_mode_screen_off";
- private static final String KEY_SCREEN_ON = "zen_mode_screen_on";
-
- private SwitchPreference mScreenOff;
- private SwitchPreference mScreenOn;
-
- private static final int SOURCE_NONE = -1;
-
- private boolean mDisableListeners;
- private SwitchPreference mReminders;
- private SwitchPreference mEvents;
- private DropDownPreference mMessages;
- private DropDownPreference mCalls;
- private SwitchPreference mRepeatCallers;
- private SwitchPreference mAlarms;
- private SwitchPreference mMediaSystemOther;
-
- private Policy mPolicy;
@Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- addPreferencesFromResource(R.xml.zen_mode_behavior_settings);
- final PreferenceScreen root = getPreferenceScreen();
+ protected List<AbstractPreferenceController> getPreferenceControllers(Context context) {
+ return buildPreferenceControllers(context, getLifecycle());
+ }
- mPolicy = NotificationManager.from(mContext).getNotificationPolicy();
-
- mReminders = (SwitchPreference) root.findPreference(KEY_REMINDERS);
- mReminders.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- if (mDisableListeners) return true;
- final boolean val = (Boolean) newValue;
- mMetricsFeatureProvider.action(mContext, MetricsEvent.ACTION_ZEN_ALLOW_REMINDERS,
- val);
- if (DEBUG) Log.d(TAG, "onPrefChange allowReminders=" + val);
- savePolicy(getNewPriorityCategories(val, Policy.PRIORITY_CATEGORY_REMINDERS),
- mPolicy.priorityCallSenders, mPolicy.priorityMessageSenders,
- mPolicy.suppressedVisualEffects);
- return true;
- }
- });
-
- mEvents = (SwitchPreference) root.findPreference(KEY_EVENTS);
- mEvents.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- if (mDisableListeners) return true;
- final boolean val = (Boolean) newValue;
- mMetricsFeatureProvider.action(mContext, MetricsEvent.ACTION_ZEN_ALLOW_EVENTS, val);
- if (DEBUG) Log.d(TAG, "onPrefChange allowEvents=" + val);
- savePolicy(getNewPriorityCategories(val, Policy.PRIORITY_CATEGORY_EVENTS),
- mPolicy.priorityCallSenders, mPolicy.priorityMessageSenders,
- mPolicy.suppressedVisualEffects);
- return true;
- }
- });
-
- mMessages = (DropDownPreference) root.findPreference(KEY_MESSAGES);
- addSources(mMessages);
- mMessages.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- if (mDisableListeners) return false;
- final int val = Integer.parseInt((String) newValue);
- final boolean allowMessages = val != SOURCE_NONE;
- final int allowMessagesFrom =
- val == SOURCE_NONE ? mPolicy.priorityMessageSenders : val;
- mMetricsFeatureProvider.action(mContext, MetricsEvent.ACTION_ZEN_ALLOW_MESSAGES, val);
- if (DEBUG) Log.d(TAG, "onPrefChange allowMessages=" + allowMessages
- + " allowMessagesFrom=" + ZenModeConfig.sourceToString(allowMessagesFrom));
- savePolicy(
- getNewPriorityCategories(allowMessages, Policy.PRIORITY_CATEGORY_MESSAGES),
- mPolicy.priorityCallSenders, allowMessagesFrom,
- mPolicy.suppressedVisualEffects);
- return true;
- }
- });
-
- mCalls = (DropDownPreference) root.findPreference(KEY_CALLS);
- addSources(mCalls);
- mCalls.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- if (mDisableListeners) return false;
- final int val = Integer.parseInt((String) newValue);
- final boolean allowCalls = val != SOURCE_NONE;
- final int allowCallsFrom = val == SOURCE_NONE ? mPolicy.priorityCallSenders : val;
- mMetricsFeatureProvider.action(mContext, MetricsEvent.ACTION_ZEN_ALLOW_CALLS, val);
- if (DEBUG) Log.d(TAG, "onPrefChange allowCalls=" + allowCalls
- + " allowCallsFrom=" + ZenModeConfig.sourceToString(allowCallsFrom));
- savePolicy(getNewPriorityCategories(allowCalls, Policy.PRIORITY_CATEGORY_CALLS),
- allowCallsFrom, mPolicy.priorityMessageSenders,
- mPolicy.suppressedVisualEffects);
- return true;
- }
- });
-
- mRepeatCallers = (SwitchPreference) root.findPreference(KEY_REPEAT_CALLERS);
- mRepeatCallers.setSummary(mContext.getString(R.string.zen_mode_repeat_callers_summary,
- mContext.getResources().getInteger(com.android.internal.R.integer
- .config_zen_repeat_callers_threshold)));
- mRepeatCallers.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- if (mDisableListeners) return true;
- final boolean val = (Boolean) newValue;
- mMetricsFeatureProvider.action(mContext, MetricsEvent.ACTION_ZEN_ALLOW_REPEAT_CALLS,
- val);
- if (DEBUG) Log.d(TAG, "onPrefChange allowRepeatCallers=" + val);
- int priorityCategories = getNewPriorityCategories(val,
- Policy.PRIORITY_CATEGORY_REPEAT_CALLERS);
- savePolicy(priorityCategories, mPolicy.priorityCallSenders,
- mPolicy.priorityMessageSenders, mPolicy.suppressedVisualEffects);
- return true;
- }
- });
-
- mAlarms = (SwitchPreference) root.findPreference(KEY_ALARMS);
- mAlarms.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- if (mDisableListeners) return true;
- final boolean val = (Boolean) newValue;
- mMetricsFeatureProvider.action(mContext, MetricsEvent.ACTION_ZEN_ALLOW_ALARMS, val);
- if (DEBUG) Log.d(TAG, "onPrefChange allowAlarms=" + val);
- savePolicy(getNewPriorityCategories(val, Policy.PRIORITY_CATEGORY_ALARMS),
- mPolicy.priorityCallSenders, mPolicy.priorityMessageSenders,
- mPolicy.suppressedVisualEffects);
- return true;
- }
- });
-
- mMediaSystemOther = (SwitchPreference) root.findPreference(KEY_MEDIA);
- mMediaSystemOther.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- if (mDisableListeners) return true;
- final boolean val = (Boolean) newValue;
- mMetricsFeatureProvider.action(mContext, MetricsEvent.ACTION_ZEN_ALLOW_MEDIA, val);
- if (DEBUG) Log.d(TAG, "onPrefChange allowMediaSystemOther=" + val);
- savePolicy(getNewPriorityCategories(val,
- Policy.PRIORITY_CATEGORY_MEDIA_SYSTEM_OTHER),
- mPolicy.priorityCallSenders, mPolicy.priorityMessageSenders,
- mPolicy.suppressedVisualEffects);
- return true;
- }
- });
-
- mScreenOff = (SwitchPreference) root.findPreference(KEY_SCREEN_OFF);
- if (!getResources()
- .getBoolean(com.android.internal.R.bool.config_intrusiveNotificationLed)) {
- mScreenOff.setSummary(R.string.zen_mode_screen_off_summary_no_led);
- }
-
- mScreenOff.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- if (mDisableListeners) return true;
- final boolean bypass = (Boolean) newValue;
- mMetricsFeatureProvider.action(mContext,
- MetricsEvent.ACTION_ZEN_ALLOW_WHEN_SCREEN_OFF, !bypass);
- if (DEBUG) Log.d(TAG, "onPrefChange suppressWhenScreenOff=" + !bypass);
- savePolicy(mPolicy.priorityCategories,
- mPolicy.priorityCallSenders, mPolicy.priorityMessageSenders,
- getNewSuppressedEffects(!bypass, Policy.SUPPRESSED_EFFECT_SCREEN_OFF));
- return true;
- }
- });
-
- mScreenOn = (SwitchPreference) root.findPreference(KEY_SCREEN_ON);
- mScreenOn.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- if (mDisableListeners) return true;
- final boolean bypass = (Boolean) newValue;
- mMetricsFeatureProvider.action(mContext,
- MetricsEvent.ACTION_ZEN_ALLOW_WHEN_SCREEN_ON, bypass);
- if (DEBUG) Log.d(TAG, "onPrefChange allowWhenScreenOn=" + !bypass);
- savePolicy(mPolicy.priorityCategories,
- mPolicy.priorityCallSenders, mPolicy.priorityMessageSenders,
- getNewSuppressedEffects(!bypass, Policy.SUPPRESSED_EFFECT_SCREEN_ON));
- return true;
- }
- });
-
- updateControls();
+ private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
+ Lifecycle lifecycle) {
+ List<AbstractPreferenceController> controllers = new ArrayList<>();
+ controllers.add(new ZenModeAlarmsPreferenceController(context, lifecycle));
+ controllers.add(new ZenModeMediaSystemOtherPreferenceController(context, lifecycle));
+ controllers.add(new ZenModeEventsPreferenceController(context, lifecycle));
+ controllers.add(new ZenModeRemindersPreferenceController(context, lifecycle));
+ controllers.add(new ZenModeMessagesPreferenceController(context, lifecycle));
+ controllers.add(new ZenModeCallsPreferenceController(context, lifecycle));
+ controllers.add(new ZenModeRepeatCallersPreferenceController(context, lifecycle));
+ controllers.add(new ZenModeScreenOnPreferenceController(context, lifecycle));
+ controllers.add(new ZenModeScreenOffPreferenceController(context, lifecycle));
+ return controllers;
}
@Override
- protected void onZenModeChanged() {
- updateControls();
- }
-
- @Override
- protected void onZenModeConfigChanged() {
- mPolicy = NotificationManager.from(mContext).getNotificationPolicy();
- updateControls();
- }
-
- private void updateControlsPolicy() {
- if (mCalls != null) {
- mCalls.setValue(Integer.toString(
- isPriorityCategoryEnabled(Policy.PRIORITY_CATEGORY_CALLS)
- ? mPolicy.priorityCallSenders : SOURCE_NONE));
- }
- mMessages.setValue(Integer.toString(
- isPriorityCategoryEnabled(Policy.PRIORITY_CATEGORY_MESSAGES)
- ? mPolicy.priorityMessageSenders : SOURCE_NONE));
- mAlarms.setChecked(isPriorityCategoryEnabled(Policy.PRIORITY_CATEGORY_ALARMS));
- mMediaSystemOther.setChecked(isPriorityCategoryEnabled(
- Policy.PRIORITY_CATEGORY_MEDIA_SYSTEM_OTHER));
- mReminders.setChecked(isPriorityCategoryEnabled(Policy.PRIORITY_CATEGORY_REMINDERS));
- mEvents.setChecked(isPriorityCategoryEnabled(Policy.PRIORITY_CATEGORY_EVENTS));
- mRepeatCallers.setChecked(
- isPriorityCategoryEnabled(Policy.PRIORITY_CATEGORY_REPEAT_CALLERS));
- mRepeatCallers.setVisible(!isPriorityCategoryEnabled(Policy.PRIORITY_CATEGORY_CALLS)
- || mPolicy.priorityCallSenders != Policy.PRIORITY_SENDERS_ANY);
-
- }
-
- private void updateControls() {
- mDisableListeners = true;
- switch(mZenMode) {
- case Settings.Global.ZEN_MODE_NO_INTERRUPTIONS:
- toggleBasicNoInterruptions();
- mAlarms.setChecked(false);
- mMediaSystemOther.setChecked(false);
- setTogglesEnabled(false);
- break;
- case Settings.Global.ZEN_MODE_ALARMS:
- toggleBasicNoInterruptions();
- mAlarms.setChecked(true);
- mMediaSystemOther.setChecked(true);
- setTogglesEnabled(false);
- break;
- default:
- updateControlsPolicy();
- setTogglesEnabled(true);
- }
-
- mScreenOff.setChecked(isEffectAllowed(Policy.SUPPRESSED_EFFECT_SCREEN_OFF));
- mScreenOn.setChecked(isEffectAllowed(Policy.SUPPRESSED_EFFECT_SCREEN_ON));
-
- mDisableListeners = false;
- }
-
- private void toggleBasicNoInterruptions() {
- if (mCalls != null) {
- mCalls.setValue(Integer.toString(SOURCE_NONE));
- }
- mMessages.setValue(Integer.toString(SOURCE_NONE));
- mReminders.setChecked(false);
- mEvents.setChecked(false);
- mRepeatCallers.setChecked(false);
- }
-
- private void setTogglesEnabled(boolean enable) {
- if (mCalls != null) {
- mCalls.setEnabled(enable);
- }
- mMessages.setEnabled(enable);
- mReminders.setEnabled(enable);
- mEvents.setEnabled(enable);
- mRepeatCallers.setEnabled(enable);
- mAlarms.setEnabled(enable);
- mMediaSystemOther.setEnabled(enable);
+ protected int getPreferenceScreenResId() {
+ return R.xml.zen_mode_behavior_settings;
}
@Override
@@ -320,67 +60,29 @@
return MetricsEvent.NOTIFICATION_ZEN_MODE_PRIORITY;
}
- private static void addSources(DropDownPreference pref) {
- pref.setEntries(new CharSequence[]{
- pref.getContext().getString(R.string.zen_mode_from_anyone),
- pref.getContext().getString(R.string.zen_mode_from_contacts),
- pref.getContext().getString(R.string.zen_mode_from_starred),
- pref.getContext().getString(R.string.zen_mode_from_none),
- });
- pref.setEntryValues(new CharSequence[] {
- Integer.toString(Policy.PRIORITY_SENDERS_ANY),
- Integer.toString(Policy.PRIORITY_SENDERS_CONTACTS),
- Integer.toString(Policy.PRIORITY_SENDERS_STARRED),
- Integer.toString(SOURCE_NONE),
- });
- }
-
- private boolean isPriorityCategoryEnabled(int categoryType) {
- return (mPolicy.priorityCategories & categoryType) != 0;
- }
-
- private int getNewPriorityCategories(boolean allow, int categoryType) {
- int priorityCategories = mPolicy.priorityCategories;
- if (allow) {
- priorityCategories |= categoryType;
- } else {
- priorityCategories &= ~categoryType;
- }
- return priorityCategories;
- }
-
- private void savePolicy(int priorityCategories, int priorityCallSenders,
- int priorityMessageSenders, int suppressedVisualEffects) {
- mPolicy = new Policy(priorityCategories, priorityCallSenders, priorityMessageSenders,
- suppressedVisualEffects);
- NotificationManager.from(mContext).setNotificationPolicy(mPolicy);
- }
-
/**
* For Search.
*/
public static final Indexable.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.zen_mode_behavior_settings;
- return Arrays.asList(sir);
+ public List<String> getNonIndexableKeys(Context context) {
+ final List<String> keys = super.getNonIndexableKeys(context);
+ keys.add(ZenModeAlarmsPreferenceController.KEY);
+ keys.add(ZenModeMediaSystemOtherPreferenceController.KEY);
+ keys.add(ZenModeEventsPreferenceController.KEY);
+ keys.add(ZenModeRemindersPreferenceController.KEY);
+ keys.add(ZenModeMessagesPreferenceController.KEY);
+ keys.add(ZenModeCallsPreferenceController.KEY);
+ keys.add(ZenModeRepeatCallersPreferenceController.KEY);
+ keys.add(ZenModeScreenOnPreferenceController.KEY);
+ keys.add(ZenModeScreenOffPreferenceController.KEY);
+ return keys;
}
- };
- private int getNewSuppressedEffects(boolean suppress, int effectType) {
- int effects = mPolicy.suppressedVisualEffects;
- if (suppress) {
- effects |= effectType;
- } else {
- effects &= ~effectType;
- }
- return effects;
- }
-
- private boolean isEffectAllowed(int effect) {
- return (mPolicy.suppressedVisualEffects & effect) == 0;
- }
+ @Override
+ public List<AbstractPreferenceController> getPreferenceControllers(Context context) {
+ return buildPreferenceControllers(context, null);
+ }
+ };
}
diff --git a/src/com/android/settings/notification/ZenModeButtonPreferenceController.java b/src/com/android/settings/notification/ZenModeButtonPreferenceController.java
new file mode 100644
index 0000000..79115f2
--- /dev/null
+++ b/src/com/android/settings/notification/ZenModeButtonPreferenceController.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.notification;
+
+import android.content.Context;
+import android.provider.Settings;
+import android.support.v7.preference.Preference;
+import android.view.View;
+import android.widget.Button;
+
+import com.android.settings.R;
+import com.android.settings.applications.LayoutPreference;
+import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+public class ZenModeButtonPreferenceController extends AbstractZenModePreferenceController
+ implements PreferenceControllerMixin {
+
+ protected static final String KEY = "zen_mode_settings_button_container";
+ private Button mZenButtonOn;
+ private Button mZenButtonOff;
+ private ZenModeBackend mBackend;
+
+ public ZenModeButtonPreferenceController(Context context, Lifecycle lifecycle) {
+ super(context, KEY, lifecycle);
+ mBackend = ZenModeBackend.getInstance(context);
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return true;
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY;
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ super.updateState(preference);
+
+ if (null == mZenButtonOn) {
+ mZenButtonOn = (Button) ((LayoutPreference) preference)
+ .findViewById(R.id.zen_mode_settings_turn_on_button);
+ mZenButtonOn.setOnClickListener(v ->
+ mBackend.setZenMode(Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS));
+ }
+
+ if (null == mZenButtonOff) {
+ mZenButtonOff = (Button) ((LayoutPreference) preference)
+ .findViewById(R.id.zen_mode_settings_turn_off_button);
+ mZenButtonOff.setOnClickListener(v ->
+ mBackend.setZenMode(Settings.Global.ZEN_MODE_OFF));
+ }
+
+ updateButtons();
+ }
+
+ private void updateButtons() {
+ switch (getZenMode()) {
+ case Settings.Global.ZEN_MODE_ALARMS:
+ case Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS:
+ case Settings.Global.ZEN_MODE_NO_INTERRUPTIONS:
+ mZenButtonOff.setVisibility(View.VISIBLE);
+ mZenButtonOn.setVisibility(View.GONE);
+ break;
+ case Settings.Global.ZEN_MODE_OFF:
+ default:
+ mZenButtonOff.setVisibility(View.GONE);
+ mZenButtonOn.setVisibility(View.VISIBLE);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/com/android/settings/notification/ZenModeCallsPreferenceController.java b/src/com/android/settings/notification/ZenModeCallsPreferenceController.java
new file mode 100644
index 0000000..d952c11
--- /dev/null
+++ b/src/com/android/settings/notification/ZenModeCallsPreferenceController.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.notification;
+
+import android.app.NotificationManager;
+import android.content.Context;
+import android.provider.Settings;
+import android.support.v7.preference.Preference;
+
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+public class ZenModeCallsPreferenceController extends AbstractZenModePreferenceController {
+
+ protected static final String KEY = "zen_mode_calls";
+ private final ZenModeBackend mBackend;
+
+ public ZenModeCallsPreferenceController(Context context, Lifecycle lifecycle) {
+ super(context, KEY, lifecycle);
+ mBackend = ZenModeBackend.getInstance(context);
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY;
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return true;
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ super.updateState(preference);
+
+ switch (getZenMode()) {
+ case Settings.Global.ZEN_MODE_NO_INTERRUPTIONS:
+ case Settings.Global.ZEN_MODE_ALARMS:
+ preference.setEnabled(false);
+ preference.setSummary(mBackend.getContactsSummary(mBackend.SOURCE_NONE));
+ break;
+ default:
+ preference.setEnabled(true);
+ preference.setSummary(mBackend.getContactsSummary(
+ NotificationManager.Policy.PRIORITY_CATEGORY_CALLS));
+ }
+
+ }
+}
diff --git a/src/com/android/settings/notification/ZenModeCallsSettings.java b/src/com/android/settings/notification/ZenModeCallsSettings.java
new file mode 100644
index 0000000..6874dc0
--- /dev/null
+++ b/src/com/android/settings/notification/ZenModeCallsSettings.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.notification;
+
+import android.app.NotificationManager;
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+
+import com.android.internal.logging.nano.MetricsProto;
+import com.android.settings.R;
+import com.android.settings.widget.RadioButtonPickerFragment;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ZenModeCallsSettings extends RadioButtonPickerFragment {
+ private ZenModeBackend mBackend;
+
+ @Override
+ public void onAttach(Context context) {
+ super.onAttach(context);
+ mBackend = ZenModeBackend.getInstance(context);
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return MetricsProto.MetricsEvent.NOTIFICATION_ZEN_MODE_CALLS;
+ }
+
+ @Override
+ protected int getPreferenceScreenResId() {
+ return R.xml.zen_mode_calls_settings;
+ }
+
+ @Override
+ protected List<? extends RadioButtonPickerFragment.CandidateInfo> getCandidates() {
+ final String[] entries = entries();
+ final String[] values = keys();
+ final List<CallsCandidateInfo> candidates = new ArrayList<>();
+
+ if (entries == null || entries.length <= 0) return null;
+ if (values == null || values.length != entries.length) {
+ throw new IllegalArgumentException("Entries and values must be of the same length.");
+ }
+
+ for (int i = 0; i < entries.length; i++) {
+ candidates.add(new CallsCandidateInfo(entries[i], values[i]));
+ }
+
+ return candidates;
+ }
+
+ private String[] entries() {
+ return getResources().getStringArray(R.array.zen_mode_contacts_entries);
+ }
+
+ private String[] keys() {
+ return getResources().getStringArray(R.array.zen_mode_contacts_values);
+ }
+
+ @Override
+ protected String getDefaultKey() {
+ return mBackend.getSendersKey(NotificationManager.Policy.PRIORITY_CATEGORY_CALLS);
+ }
+
+ @Override
+ protected boolean setDefaultKey(String key) {
+ mBackend.saveSenders(NotificationManager.Policy.PRIORITY_CATEGORY_CALLS,
+ mBackend.getSettingFromPrefKey(key));
+ return true;
+ }
+
+ private static final class CallsCandidateInfo extends RadioButtonPickerFragment.CandidateInfo {
+ private final String name;
+ private final String key;
+
+ CallsCandidateInfo(String title, String value) {
+ super(true);
+
+ name = title;
+ key = value;
+ }
+
+ @Override
+ public CharSequence loadLabel() {
+ return name;
+ }
+
+ @Override
+ public Drawable loadIcon() {
+ return null;
+ }
+
+ @Override
+ public String getKey() {
+ return key;
+ }
+ }
+}
diff --git a/src/com/android/settings/notification/ZenModeEventRuleSettings.java b/src/com/android/settings/notification/ZenModeEventRuleSettings.java
index 3361734..aa2cc3f 100644
--- a/src/com/android/settings/notification/ZenModeEventRuleSettings.java
+++ b/src/com/android/settings/notification/ZenModeEventRuleSettings.java
@@ -33,6 +33,7 @@
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
+import com.android.settingslib.core.AbstractPreferenceController;
import java.util.ArrayList;
import java.util.Collections;
@@ -81,6 +82,16 @@
mCreate = false;
}
+ @Override
+ protected int getPreferenceScreenResId() {
+ return R.xml.zen_mode_event_rule_settings;
+ }
+
+ @Override
+ protected List<AbstractPreferenceController> getPreferenceControllers(Context context) {
+ return null;
+ }
+
private void reloadCalendar() {
mCalendars = getCalendars(mContext);
ArrayList<CharSequence> entries = new ArrayList<>();
@@ -107,7 +118,6 @@
@Override
protected void onCreateInternal() {
mCreate = true;
- addPreferencesFromResource(R.xml.zen_mode_event_rule_settings);
final PreferenceScreen root = getPreferenceScreen();
mCalendar = (DropDownPreference) root.findPreference(KEY_CALENDAR);
@@ -243,5 +253,4 @@
public String name;
public int userId;
}
-
}
diff --git a/src/com/android/settings/notification/ZenModeEventsPreferenceController.java b/src/com/android/settings/notification/ZenModeEventsPreferenceController.java
new file mode 100644
index 0000000..3763fed
--- /dev/null
+++ b/src/com/android/settings/notification/ZenModeEventsPreferenceController.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.notification;
+
+import android.app.NotificationManager.Policy;
+import android.content.Context;
+import android.provider.Settings;
+import android.support.v14.preference.SwitchPreference;
+import android.support.v7.preference.Preference;
+import android.util.Log;
+
+
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+public class ZenModeEventsPreferenceController extends AbstractZenModePreferenceController
+ implements Preference.OnPreferenceChangeListener {
+
+ protected static final String KEY = "zen_mode_events";
+ private final ZenModeBackend mBackend;
+
+ public ZenModeEventsPreferenceController(Context context, Lifecycle lifecycle) {
+ super(context, KEY, lifecycle);
+ mBackend = ZenModeBackend.getInstance(context);
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY;
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return true;
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ super.updateState(preference);
+
+ SwitchPreference pref = (SwitchPreference) preference;
+ switch (getZenMode()) {
+ case Settings.Global.ZEN_MODE_NO_INTERRUPTIONS:
+ case Settings.Global.ZEN_MODE_ALARMS:
+ pref.setEnabled(false);
+ pref.setChecked(false);
+ break;
+ default:
+ pref.setChecked(mBackend.isPriorityCategoryEnabled(
+ Policy.PRIORITY_CATEGORY_EVENTS));
+ pref.setEnabled(true);
+ }
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ final boolean allowEvents = (Boolean) newValue;
+ if (ZenModeSettingsBase.DEBUG) {
+ Log.d(TAG, "onPrefChange allowEvents=" + allowEvents);
+ }
+ mBackend.saveSoundPolicy(Policy.PRIORITY_CATEGORY_EVENTS, allowEvents);
+ return true;
+ }
+}
diff --git a/src/com/android/settings/notification/ZenModeMediaSystemOtherPreferenceController.java b/src/com/android/settings/notification/ZenModeMediaSystemOtherPreferenceController.java
new file mode 100644
index 0000000..8afe881
--- /dev/null
+++ b/src/com/android/settings/notification/ZenModeMediaSystemOtherPreferenceController.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.notification;
+
+import android.app.NotificationManager.Policy;
+import android.content.Context;
+import android.provider.Settings;
+import android.support.v14.preference.SwitchPreference;
+import android.support.v7.preference.Preference;
+import android.util.Log;
+
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+public class ZenModeMediaSystemOtherPreferenceController extends AbstractZenModePreferenceController
+ implements Preference.OnPreferenceChangeListener {
+
+ protected static final String KEY = "zen_mode_media";
+ private final ZenModeBackend mBackend;
+
+ public ZenModeMediaSystemOtherPreferenceController(Context context, Lifecycle lifecycle) {
+ super(context, KEY, lifecycle);
+ mBackend = ZenModeBackend.getInstance(context);
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY;
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return true;
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ super.updateState(preference);
+
+ SwitchPreference pref = (SwitchPreference) preference;
+ switch (getZenMode()) {
+ case Settings.Global.ZEN_MODE_NO_INTERRUPTIONS:
+ pref.setEnabled(false);
+ pref.setChecked(false);
+ break;
+ case Settings.Global.ZEN_MODE_ALARMS:
+ pref.setEnabled(false);
+ pref.setChecked(true);
+ break;
+ default:
+ pref.setEnabled(true);
+ pref.setChecked(mBackend.isPriorityCategoryEnabled(
+ Policy.PRIORITY_CATEGORY_MEDIA_SYSTEM_OTHER));
+ }
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ final boolean allowMedia = (Boolean) newValue;
+ if (ZenModeSettingsBase.DEBUG) {
+ Log.d(TAG, "onPrefChange allowMediaSystemOther=" + allowMedia);
+ }
+ mBackend.saveSoundPolicy(Policy.PRIORITY_CATEGORY_MEDIA_SYSTEM_OTHER, allowMedia);
+ return true;
+ }
+}
diff --git a/src/com/android/settings/notification/ZenModeMessagesPreferenceController.java b/src/com/android/settings/notification/ZenModeMessagesPreferenceController.java
new file mode 100644
index 0000000..dad6cf1
--- /dev/null
+++ b/src/com/android/settings/notification/ZenModeMessagesPreferenceController.java
@@ -0,0 +1,46 @@
+package com.android.settings.notification;
+
+import android.app.NotificationManager;
+import android.content.Context;
+import android.provider.Settings;
+import android.support.v7.preference.Preference;
+
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+public class ZenModeMessagesPreferenceController extends AbstractZenModePreferenceController {
+
+ protected static final String KEY = "zen_mode_messages";
+ private final ZenModeBackend mBackend;
+
+ public ZenModeMessagesPreferenceController(Context context, Lifecycle lifecycle) {
+ super(context, KEY, lifecycle);
+ mBackend = ZenModeBackend.getInstance(context);
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY;
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return true;
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ super.updateState(preference);
+
+ switch (getZenMode()) {
+ case Settings.Global.ZEN_MODE_NO_INTERRUPTIONS:
+ case Settings.Global.ZEN_MODE_ALARMS:
+ preference.setEnabled(false);
+ preference.setSummary(mBackend.getContactsSummary(mBackend.SOURCE_NONE));
+ break;
+ default:
+ preference.setEnabled(true);
+ preference.setSummary(mBackend.getContactsSummary(
+ NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES));
+ }
+ }
+}
diff --git a/src/com/android/settings/notification/ZenModeMessagesSettings.java b/src/com/android/settings/notification/ZenModeMessagesSettings.java
new file mode 100644
index 0000000..9cbf248
--- /dev/null
+++ b/src/com/android/settings/notification/ZenModeMessagesSettings.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.notification;
+
+import android.app.NotificationManager;
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+
+import com.android.internal.logging.nano.MetricsProto;
+import com.android.settings.R;
+import com.android.settings.widget.RadioButtonPickerFragment;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ZenModeMessagesSettings extends RadioButtonPickerFragment {
+ private ZenModeBackend mBackend;
+
+ @Override
+ public void onAttach(Context context) {
+ super.onAttach(context);
+ mBackend = ZenModeBackend.getInstance(context);
+ }
+ @Override
+ public int getMetricsCategory() {
+ return MetricsProto.MetricsEvent.NOTIFICATION_ZEN_MODE_MESSAGES;
+ }
+
+ @Override
+ protected int getPreferenceScreenResId() {
+ return R.xml.zen_mode_messages_settings;
+ }
+
+ @Override
+ protected List<? extends RadioButtonPickerFragment.CandidateInfo> getCandidates() {
+ final String[] entries = entries();
+ final String[] values = keys();
+ final List<MessagesCandidateInfo> candidates = new ArrayList<>();
+
+ if (entries == null || entries.length <= 0) return null;
+ if (values == null || values.length != entries.length) {
+ throw new IllegalArgumentException("Entries and values must be of the same length.");
+ }
+
+ for (int i = 0; i < entries.length; i++) {
+ candidates.add(new MessagesCandidateInfo(entries[i], values[i]));
+ }
+
+ return candidates;
+ }
+
+ private String[] entries() {
+ return getResources().getStringArray(R.array.zen_mode_contacts_entries);
+ }
+
+ private String[] keys() {
+ return getResources().getStringArray(R.array.zen_mode_contacts_values);
+ }
+
+ @Override
+ protected String getDefaultKey() {
+ return mBackend.getSendersKey(NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES);
+ }
+
+ @Override
+ protected boolean setDefaultKey(String key) {
+ mBackend.saveSenders(NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES,
+ mBackend.getSettingFromPrefKey(key));
+ return true;
+ }
+
+ private final class MessagesCandidateInfo extends RadioButtonPickerFragment.CandidateInfo {
+ private final String name;
+ private final String key;
+
+ MessagesCandidateInfo(String title, String value) {
+ super(true);
+
+ name = title;
+ key = value;
+ }
+
+ @Override
+ public CharSequence loadLabel() {
+ return name;
+ }
+
+ @Override
+ public Drawable loadIcon() {
+ return null;
+ }
+
+ @Override
+ public String getKey() {
+ return key;
+ }
+ }
+}
diff --git a/src/com/android/settings/notification/ZenModeRemindersPreferenceController.java b/src/com/android/settings/notification/ZenModeRemindersPreferenceController.java
new file mode 100644
index 0000000..edc7cf9
--- /dev/null
+++ b/src/com/android/settings/notification/ZenModeRemindersPreferenceController.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.notification;
+
+import android.app.NotificationManager;
+import android.content.Context;
+import android.provider.Settings;
+import android.support.v14.preference.SwitchPreference;
+import android.support.v7.preference.Preference;
+import android.util.Log;
+
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+public class ZenModeRemindersPreferenceController extends AbstractZenModePreferenceController
+ implements Preference.OnPreferenceChangeListener {
+
+ protected static final String KEY = "zen_mode_reminders";
+ private final ZenModeBackend mBackend;
+
+ public ZenModeRemindersPreferenceController(Context context, Lifecycle lifecycle) {
+ super(context, KEY, lifecycle);
+ mBackend = ZenModeBackend.getInstance(context);
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY;
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return true;
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ super.updateState(preference);
+
+ SwitchPreference pref = (SwitchPreference) preference;
+ switch (getZenMode()) {
+ case Settings.Global.ZEN_MODE_NO_INTERRUPTIONS:
+ case Settings.Global.ZEN_MODE_ALARMS:
+ pref.setEnabled(false);
+ pref.setChecked(false);
+ break;
+ default:
+ pref.setEnabled(true);
+ pref.setChecked(mBackend.isPriorityCategoryEnabled(
+ NotificationManager.Policy.PRIORITY_CATEGORY_REMINDERS));
+ }
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ final boolean allowReminders = (Boolean) newValue;
+ if (ZenModeSettingsBase.DEBUG) Log.d(TAG, "onPrefChange allowReminders=" + allowReminders);
+ mBackend.saveSoundPolicy(NotificationManager.Policy.PRIORITY_CATEGORY_REMINDERS,
+ allowReminders);
+ return true;
+ }
+}
diff --git a/src/com/android/settings/notification/ZenModeRepeatCallersPreferenceController.java b/src/com/android/settings/notification/ZenModeRepeatCallersPreferenceController.java
new file mode 100644
index 0000000..1d18409
--- /dev/null
+++ b/src/com/android/settings/notification/ZenModeRepeatCallersPreferenceController.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.notification;
+
+import android.app.NotificationManager.Policy;
+import android.content.Context;
+import android.provider.Settings;
+import android.support.v14.preference.SwitchPreference;
+import android.support.v7.preference.Preference;
+import android.util.Log;
+
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+public class ZenModeRepeatCallersPreferenceController extends AbstractZenModePreferenceController
+ implements Preference.OnPreferenceChangeListener {
+
+ protected static final String KEY = "zen_mode_repeat_callers";
+ private final ZenModeBackend mBackend;
+
+ public ZenModeRepeatCallersPreferenceController(Context context, Lifecycle lifecycle) {
+ super(context, KEY, lifecycle);
+ mBackend = ZenModeBackend.getInstance(context);
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY;
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return true;
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ super.updateState(preference);
+
+ SwitchPreference pref = (SwitchPreference) preference;
+
+ switch (getZenMode()) {
+ case Settings.Global.ZEN_MODE_NO_INTERRUPTIONS:
+ case Settings.Global.ZEN_MODE_ALARMS:
+ pref.setEnabled(false);
+ pref.setChecked(false);
+ break;
+ default:
+ boolean anyCallersCanBypassDnd = (mBackend.isPriorityCategoryEnabled(
+ Policy.PRIORITY_CATEGORY_CALLS)
+ && mBackend.getPriorityCallSenders() == Policy.PRIORITY_SENDERS_ANY);
+ // if any caller can bypass dnd then repeat callers preference is disabled
+ if (anyCallersCanBypassDnd) {
+ pref.setEnabled(false);
+ pref.setChecked(true);
+ } else {
+ pref.setEnabled(true);
+ pref.setChecked(mBackend.isPriorityCategoryEnabled(
+ Policy.PRIORITY_CATEGORY_REPEAT_CALLERS));
+ }
+ }
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ final boolean allowRepeatCallers = (Boolean) newValue;
+ if (ZenModeSettingsBase.DEBUG) Log.d(TAG, "onPrefChange allowRepeatCallers="
+ + allowRepeatCallers);
+ mBackend.saveSoundPolicy(Policy.PRIORITY_CATEGORY_REPEAT_CALLERS, allowRepeatCallers);
+ return true;
+ }
+}
diff --git a/src/com/android/settings/notification/ZenModeRuleSettingsBase.java b/src/com/android/settings/notification/ZenModeRuleSettingsBase.java
index 83c6753..9eccfdc 100644
--- a/src/com/android/settings/notification/ZenModeRuleSettingsBase.java
+++ b/src/com/android/settings/notification/ZenModeRuleSettingsBase.java
@@ -26,6 +26,7 @@
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
+import android.provider.SearchIndexableResource;
import android.service.notification.ConditionProviderService;
import android.support.v7.preference.DropDownPreference;
import android.support.v7.preference.Preference;
@@ -43,7 +44,16 @@
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.SettingsActivity;
+import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settings.search.Indexable;
import com.android.settings.widget.SwitchBar;
+import com.android.settingslib.core.AbstractPreferenceController;
+
+import java.util.Arrays;
+import java.util.List;
+
+import java.util.Arrays;
+import java.util.List;
public abstract class ZenModeRuleSettingsBase extends ZenModeSettingsBase
implements SwitchBar.OnSwitchChangeListener {
@@ -52,6 +62,8 @@
private static final String KEY_RULE_NAME = "rule_name";
private static final String KEY_ZEN_MODE = "zen_mode";
+ private static final String KEY_EVENT_RULE_SETTINGS = "zen_mode_event_rule_settings";
+ private static final String KEY_SCHEDULE_RULE_SETTINGS = "zen_mode_schedule_rule_settings";
protected Context mContext;
protected boolean mDisableListeners;
@@ -72,8 +84,6 @@
@Override
public void onCreate(Bundle icicle) {
- super.onCreate(icicle);
-
mContext = getActivity();
final Intent intent = getActivity().getIntent();
@@ -96,6 +106,8 @@
return;
}
+ super.onCreate(icicle);
+
setHasOptionsMenu(true);
onCreateInternal();
@@ -129,7 +141,7 @@
if (zenMode == mRule.getInterruptionFilter()) return false;
if (DEBUG) Log.d(TAG, "onPrefChange zenMode=" + zenMode);
mRule.setInterruptionFilter(zenMode);
- setZenRule(mId, mRule);
+ mBackend.setZenRule(mId, mRule);
return true;
}
});
@@ -138,6 +150,11 @@
}
@Override
+ protected List<AbstractPreferenceController> getPreferenceControllers(Context context) {
+ return null;
+ }
+
+ @Override
public void onResume() {
super.onResume();
if (isUiRestricted()) {
@@ -172,7 +189,7 @@
mMetricsFeatureProvider.action(mContext, MetricsEvent.ACTION_ZEN_ENABLE_RULE, enabled);
if (DEBUG) Log.d(TAG, "onSwitchChanged enabled=" + enabled);
mRule.setEnabled(enabled);
- setZenRule(mId, mRule);
+ mBackend.setZenRule(mId, mRule);
if (enabled) {
final int toastText = getEnabledToastText();
if (toastText != 0) {
@@ -188,16 +205,12 @@
protected void updateRule(Uri newConditionId) {
mRule.setConditionId(newConditionId);
- setZenRule(mId, mRule);
- }
-
- @Override
- protected void onZenModeChanged() {
- // noop
+ mBackend.setZenRule(mId, mRule);
}
@Override
protected void onZenModeConfigChanged() {
+ super.onZenModeConfigChanged();
if (!refreshRuleOrFinish()) {
updateControls();
}
@@ -225,7 +238,7 @@
@Override
public void onOk(String ruleName) {
mRule.setName(ruleName);
- setZenRule(mId, mRule);
+ mBackend.setZenRule(mId, mRule);
}
}.show();
}
@@ -250,7 +263,7 @@
mMetricsFeatureProvider.action(mContext,
MetricsEvent.ACTION_ZEN_DELETE_RULE_OK);
mDeleting = true;
- removeZenRule(mId);
+ mBackend.removeZenRule(mId);
}
})
.show();
@@ -294,4 +307,25 @@
mDisableListeners = false;
}
+ /**
+ * For Search.
+ */
+ public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+ new BaseSearchIndexProvider() {
+ @Override
+ public List<SearchIndexableResource> getXmlResourcesToIndex(
+ Context context, boolean enabled) {
+ final SearchIndexableResource sir = new SearchIndexableResource(context);
+ // not indexable
+ return Arrays.asList(sir);
+ }
+
+ @Override
+ public List<String> getNonIndexableKeys(Context context) {
+ final List<String> keys = super.getNonIndexableKeys(context);
+ keys.add(KEY_SCHEDULE_RULE_SETTINGS);
+ keys.add(KEY_EVENT_RULE_SETTINGS);
+ return keys;
+ }
+ };
}
diff --git a/src/com/android/settings/notification/ZenModeScheduleRuleSettings.java b/src/com/android/settings/notification/ZenModeScheduleRuleSettings.java
index 72f6567..ab0349e 100644
--- a/src/com/android/settings/notification/ZenModeScheduleRuleSettings.java
+++ b/src/com/android/settings/notification/ZenModeScheduleRuleSettings.java
@@ -19,7 +19,6 @@
import android.app.AlertDialog;
import android.app.AutomaticZenRule;
import android.app.Dialog;
-import android.app.DialogFragment;
import android.app.FragmentManager;
import android.app.TimePickerDialog;
import android.content.Context;
@@ -40,10 +39,12 @@
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
+import com.android.settingslib.core.AbstractPreferenceController;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Calendar;
+import java.util.List;
public class ZenModeScheduleRuleSettings extends ZenModeRuleSettingsBase {
private static final String KEY_DAYS = "days";
@@ -71,6 +72,16 @@
}
@Override
+ protected int getPreferenceScreenResId() {
+ return R.xml.zen_mode_schedule_rule_settings;
+ }
+
+ @Override
+ protected List<AbstractPreferenceController> getPreferenceControllers(Context context) {
+ return null;
+ }
+
+ @Override
protected String getZenModeDependency() {
return mDays.getKey();
}
@@ -82,7 +93,6 @@
@Override
protected void onCreateInternal() {
- addPreferencesFromResource(R.xml.zen_mode_schedule_rule_settings);
final PreferenceScreen root = getPreferenceScreen();
mDays = root.findPreference(KEY_DAYS);
@@ -306,5 +316,4 @@
boolean onSetTime(int hour, int minute);
}
}
-
}
diff --git a/src/com/android/settings/notification/ZenModeScreenOffPreferenceController.java b/src/com/android/settings/notification/ZenModeScreenOffPreferenceController.java
new file mode 100644
index 0000000..2b70706
--- /dev/null
+++ b/src/com/android/settings/notification/ZenModeScreenOffPreferenceController.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.notification;
+
+import android.app.NotificationManager.Policy;
+import android.content.Context;
+import android.support.v14.preference.SwitchPreference;
+import android.support.v7.preference.Preference;
+import android.util.Log;
+
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+public class ZenModeScreenOffPreferenceController extends
+ AbstractZenModePreferenceController implements Preference.OnPreferenceChangeListener {
+
+ protected static final String KEY = "zen_mode_screen_off";
+ private final ZenModeBackend mBackend;
+
+ public ZenModeScreenOffPreferenceController(Context context, Lifecycle lifecycle) {
+ super(context, KEY, lifecycle);
+ mBackend = ZenModeBackend.getInstance(context);
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY;
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return true;
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ super.updateState(preference);
+
+ SwitchPreference pref = (SwitchPreference) preference;
+ pref.setChecked(mBackend.isEffectAllowed(Policy.SUPPRESSED_EFFECT_SCREEN_OFF));
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ final boolean bypass = (Boolean) newValue;
+ if (ZenModeSettingsBase.DEBUG) Log.d(TAG, "onPrefChange allowWhenScreenOff="
+ + !bypass);
+ mBackend.saveVisualEffectsPolicy(Policy.SUPPRESSED_EFFECT_SCREEN_OFF, bypass);
+ return true;
+ }
+}
diff --git a/src/com/android/settings/notification/ZenModeScreenOnPreferenceController.java b/src/com/android/settings/notification/ZenModeScreenOnPreferenceController.java
new file mode 100644
index 0000000..8e0b348
--- /dev/null
+++ b/src/com/android/settings/notification/ZenModeScreenOnPreferenceController.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.notification;
+
+import android.app.NotificationManager.Policy;
+import android.content.Context;
+import android.support.v14.preference.SwitchPreference;
+import android.support.v7.preference.Preference;
+import android.util.Log;
+
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+public class ZenModeScreenOnPreferenceController extends
+ AbstractZenModePreferenceController implements Preference.OnPreferenceChangeListener {
+
+ protected static final String KEY = "zen_mode_screen_on";
+ private final ZenModeBackend mBackend;
+
+ public ZenModeScreenOnPreferenceController(Context context, Lifecycle lifecycle) {
+ super(context, KEY, lifecycle);
+ mBackend = ZenModeBackend.getInstance(context);
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY;
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return true;
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ super.updateState(preference);
+
+ SwitchPreference pref = (SwitchPreference) preference;
+ pref.setChecked(mBackend.isEffectAllowed(Policy.SUPPRESSED_EFFECT_SCREEN_ON));
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ final boolean bypass = (Boolean) newValue;
+ if (ZenModeSettingsBase.DEBUG) Log.d(TAG, "onPrefChange allowWhenScreenOn="
+ + !bypass);
+
+ mBackend.saveVisualEffectsPolicy(Policy.SUPPRESSED_EFFECT_SCREEN_ON, bypass);
+ return true;
+ }
+}
diff --git a/src/com/android/settings/notification/ZenModeSettings.java b/src/com/android/settings/notification/ZenModeSettings.java
index 2699cfd..fbc9f7d 100644
--- a/src/com/android/settings/notification/ZenModeSettings.java
+++ b/src/com/android/settings/notification/ZenModeSettings.java
@@ -20,56 +20,27 @@
import android.app.NotificationManager;
import android.app.NotificationManager.Policy;
import android.content.Context;
-import android.os.Bundle;
import android.provider.SearchIndexableResource;
import android.provider.Settings;
-import android.service.notification.ZenModeConfig;
import android.support.annotation.VisibleForTesting;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.PreferenceScreen;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable;
+import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.lifecycle.Lifecycle;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
-public class ZenModeSettings extends ZenModeSettingsBase implements Indexable {
-
- private static final String KEY_BEHAVIOR_SETTINGS = "zen_mode_behavior_settings";
- private static final String KEY_AUTOMATION_SETTINGS = "zen_mode_automation_settings";
-
- private Preference mBehaviorSettings;
- private Preference mAutomationSettings;
- private Policy mPolicy;
- private SummaryBuilder mSummaryBuilder;
-
+public class ZenModeSettings extends ZenModeSettingsBase {
@Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- addPreferencesFromResource(R.xml.zen_mode_settings);
- final PreferenceScreen root = getPreferenceScreen();
-
- mBehaviorSettings = root.findPreference(KEY_BEHAVIOR_SETTINGS);
- mAutomationSettings = root.findPreference(KEY_AUTOMATION_SETTINGS);
- mPolicy = NotificationManager.from(mContext).getNotificationPolicy();
- mSummaryBuilder = new SummaryBuilder(getContext());
- }
-
- @Override
- public void onResume() {
- super.onResume();
- if (isUiRestricted()) {
- return;
- }
- updateControls();
+ protected int getPreferenceScreenResId() {
+ return R.xml.zen_mode_settings;
}
@Override
@@ -78,27 +49,8 @@
}
@Override
- protected void onZenModeChanged() {
- updateControls();
- }
-
- @Override
- protected void onZenModeConfigChanged() {
- mPolicy = NotificationManager.from(mContext).getNotificationPolicy();
- updateControls();
- }
-
- private void updateControls() {
- updateBehaviorSettingsSummary();
- updateAutomationSettingsSummary();
- }
-
- private void updateBehaviorSettingsSummary() {
- mBehaviorSettings.setSummary(mSummaryBuilder.getBehaviorSettingSummary(mPolicy, mZenMode));
- }
-
- private void updateAutomationSettingsSummary() {
- mAutomationSettings.setSummary(mSummaryBuilder.getAutomaticRulesSummary());
+ protected List<AbstractPreferenceController> getPreferenceControllers(Context context) {
+ return buildPreferenceControllers(context, getLifecycle());
}
@Override
@@ -106,6 +58,15 @@
return R.string.help_uri_interruptions;
}
+ private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
+ Lifecycle lifecycle) {
+ List<AbstractPreferenceController> controllers = new ArrayList<>();
+ controllers.add(new ZenModeBehaviorPreferenceController(context, lifecycle));
+ controllers.add(new ZenModeAutomationPreferenceController(context));
+ controllers.add(new ZenModeButtonPreferenceController(context, lifecycle));
+ return controllers;
+ }
+
public static class SummaryBuilder {
private Context mContext;
@@ -227,42 +188,31 @@
}
}
- private static final Comparator<Entry<String,AutomaticZenRule>> RULE_COMPARATOR =
- new Comparator<Map.Entry<String,AutomaticZenRule>>() {
- @Override
- public int compare(Map.Entry<String,AutomaticZenRule> lhs,
- Map.Entry<String,AutomaticZenRule> rhs) {
- int byDate = Long.compare(lhs.getValue().getCreationTime(),
- rhs.getValue().getCreationTime());
- if (byDate != 0) {
- return byDate;
- } else {
- return key(lhs.getValue()).compareTo(key(rhs.getValue()));
- }
- }
-
- private String key(AutomaticZenRule rule) {
- final int type = ZenModeConfig.isValidScheduleConditionId(rule.getConditionId())
- ? 1
- : ZenModeConfig.isValidEventConditionId(rule.getConditionId())
- ? 2
- : 3;
- return type + rule.getName().toString();
- }
- };
-
/**
* For Search.
*/
public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider() {
+
@Override
- public List<SearchIndexableResource> getXmlResourcesToIndex(
- Context context, boolean enabled) {
+ public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
+ boolean enabled) {
final SearchIndexableResource sir = new SearchIndexableResource(context);
sir.xmlResId = R.xml.zen_mode_settings;
return Arrays.asList(sir);
}
- };
+ @Override
+ public List<String> getNonIndexableKeys(Context context) {
+ List<String> keys = super.getNonIndexableKeys(context);
+ keys.add(ZenModeButtonPreferenceController.KEY);
+ return keys;
+ }
+
+ @Override
+ public List<AbstractPreferenceController> getPreferenceControllers(Context
+ context) {
+ return buildPreferenceControllers(context, null);
+ }
+ };
}
diff --git a/src/com/android/settings/notification/ZenModeSettingsBase.java b/src/com/android/settings/notification/ZenModeSettingsBase.java
index 6a9431e..2aecae4 100644
--- a/src/com/android/settings/notification/ZenModeSettingsBase.java
+++ b/src/com/android/settings/notification/ZenModeSettingsBase.java
@@ -16,8 +16,6 @@
package com.android.settings.notification;
-import android.app.AutomaticZenRule;
-import android.app.NotificationManager;
import android.content.Context;
import android.database.ContentObserver;
import android.net.Uri;
@@ -26,17 +24,11 @@
import android.os.UserManager;
import android.provider.Settings;
import android.provider.Settings.Global;
-import android.service.notification.ZenModeConfig;
import android.util.Log;
-import com.android.settings.RestrictedSettingsFragment;
+import com.android.settings.dashboard.RestrictedDashboardFragment;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-abstract public class ZenModeSettingsBase extends RestrictedSettingsFragment {
+abstract public class ZenModeSettingsBase extends RestrictedDashboardFragment {
protected static final String TAG = "ZenModeSettings";
protected static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
@@ -44,30 +36,33 @@
private final SettingsObserver mSettingsObserver = new SettingsObserver();
protected Context mContext;
- protected Set<Map.Entry<String, AutomaticZenRule>> mRules;
protected int mZenMode;
- abstract protected void onZenModeChanged();
- abstract protected void onZenModeConfigChanged();
+ protected ZenModeBackend mBackend;
+
+ protected void onZenModeConfigChanged() {};
public ZenModeSettingsBase() {
super(UserManager.DISALLOW_ADJUST_VOLUME);
}
@Override
+ protected String getLogTag() {
+ return TAG;
+ }
+
+ @Override
public void onCreate(Bundle icicle) {
- super.onCreate(icicle);
mContext = getActivity();
+ mBackend = ZenModeBackend.getInstance(mContext);
+ super.onCreate(icicle);
updateZenMode(false /*fireChanged*/);
- maybeRefreshRules(true, false /*fireChanged*/);
- if (DEBUG) Log.d(TAG, "Loaded mRules=" + mRules);
}
@Override
public void onResume() {
super.onResume();
updateZenMode(true /*fireChanged*/);
- maybeRefreshRules(true, true /*fireChanged*/);
mSettingsObserver.register();
if (isUiRestricted()) {
if (isUiRestrictedByOnlyAdmin()) {
@@ -89,56 +84,7 @@
final int zenMode = Settings.Global.getInt(getContentResolver(), Global.ZEN_MODE, mZenMode);
if (zenMode == mZenMode) return;
mZenMode = zenMode;
- if (DEBUG) Log.d(TAG, "updateZenMode mZenMode=" + mZenMode);
- if (fireChanged) {
- onZenModeChanged();
- }
- }
-
- protected String addZenRule(AutomaticZenRule rule) {
- try {
- String id = NotificationManager.from(mContext).addAutomaticZenRule(rule);
- final AutomaticZenRule savedRule =
- NotificationManager.from(mContext).getAutomaticZenRule(id);
- maybeRefreshRules(savedRule != null, true);
- return id;
- } catch (Exception e) {
- return null;
- }
- }
-
- protected boolean setZenRule(String id, AutomaticZenRule rule) {
- final boolean success =
- NotificationManager.from(mContext).updateAutomaticZenRule(id, rule);
- maybeRefreshRules(success, true);
- return success;
- }
-
- protected boolean removeZenRule(String id) {
- final boolean success =
- NotificationManager.from(mContext).removeAutomaticZenRule(id);
- maybeRefreshRules(success, true);
- return success;
- }
-
- protected void maybeRefreshRules(boolean success, boolean fireChanged) {
- if (success) {
- mRules = getZenModeRules();
- if (DEBUG) Log.d(TAG, "Refreshed mRules=" + mRules);
- if (fireChanged) {
- onZenModeConfigChanged();
- }
- }
- }
-
- protected void setZenMode(int zenMode, Uri conditionId) {
- NotificationManager.from(mContext).setZenMode(zenMode, conditionId, TAG);
- }
-
- private Set<Map.Entry<String, AutomaticZenRule>> getZenModeRules() {
- Map<String, AutomaticZenRule> ruleMap
- = NotificationManager.from(mContext).getAutomaticZenRules();
- return ruleMap.entrySet();
+ if (DEBUG) Log.d(TAG, "updateZenMode mZenMode=" + mZenMode + " " + fireChanged);
}
private final class SettingsObserver extends ContentObserver {
@@ -165,7 +111,8 @@
updateZenMode(true /*fireChanged*/);
}
if (ZEN_MODE_CONFIG_ETAG_URI.equals(uri)) {
- maybeRefreshRules(true, true /*fireChanged*/);
+ mBackend.updatePolicy();
+ onZenModeConfigChanged();
}
}
}
diff --git a/src/com/android/settings/notification/ZenRulePreference.java b/src/com/android/settings/notification/ZenRulePreference.java
new file mode 100644
index 0000000..4d7181a
--- /dev/null
+++ b/src/com/android/settings/notification/ZenRulePreference.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.notification;
+
+import android.app.AlertDialog;
+import android.app.AutomaticZenRule;
+import android.app.NotificationManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ServiceInfo;
+import android.content.res.Resources;
+import android.service.notification.ZenModeConfig;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceCategory;
+import android.support.v7.preference.PreferenceViewHolder;
+import android.view.View;
+
+import com.android.settings.R;
+import com.android.settings.utils.ManagedServiceSettings;
+import com.android.settings.utils.ZenServiceListing;
+import com.android.settingslib.TwoTargetPreference;
+
+import java.util.Map;
+
+public class ZenRulePreference extends TwoTargetPreference {
+ private static final ManagedServiceSettings.Config CONFIG =
+ ZenModeAutomationSettings.getConditionProviderConfig();
+ final CharSequence mName;
+ final String mId;
+ boolean appExists;
+ final PreferenceCategory mParent;
+ final Preference mPref;
+ final Context mContext;
+ final ZenModeBackend mBackend;
+ final ZenServiceListing mServiceListing;
+ final PackageManager mPm;
+
+ public ZenRulePreference(Context context,
+ final Map.Entry<String, AutomaticZenRule> ruleEntry,
+ PreferenceCategory prefCategory) {
+ super(context);
+
+ mBackend = ZenModeBackend.getInstance(context);
+ mContext = context;
+ final AutomaticZenRule rule = ruleEntry.getValue();
+ mName = rule.getName();
+ mId = ruleEntry.getKey();
+ mParent = prefCategory;
+ mPm = mContext.getPackageManager();
+ mServiceListing = new ZenServiceListing(mContext, CONFIG);
+ mServiceListing.reloadApprovedServices();
+ mPref = this;
+
+ setAttributes(rule);
+ }
+
+ @Override
+ protected int getSecondTargetResId() {
+ return R.layout.zen_rule_widget;
+ }
+
+ @Override
+ public void onBindViewHolder(PreferenceViewHolder view) {
+ super.onBindViewHolder(view);
+
+ View v = view.findViewById(R.id.delete_zen_rule);
+ if (v != null) {
+ v.setOnClickListener(mDeleteListener);
+ }
+ }
+
+ private final View.OnClickListener mDeleteListener = new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ showDeleteRuleDialog(mId, mName, mParent, mPref);
+ }
+ };
+
+ private void showDeleteRuleDialog(final String ruleId, final CharSequence ruleName,
+ PreferenceCategory parent, Preference pref) {
+ new AlertDialog.Builder(mContext)
+ .setMessage(mContext.getResources().getString(
+ R.string.zen_mode_delete_rule_confirmation, ruleName))
+ .setNegativeButton(R.string.cancel, null)
+ .setPositiveButton(R.string.zen_mode_delete_rule_button,
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ mBackend.removeZenRule(ruleId);
+ parent.removePreference(pref);
+ }
+ })
+ .show();
+ }
+
+ protected void setAttributes(AutomaticZenRule rule) {
+ final boolean isSchedule = ZenModeConfig.isValidScheduleConditionId(
+ rule.getConditionId());
+ final boolean isEvent = ZenModeConfig.isValidEventConditionId(rule.getConditionId());
+ final boolean isSystemRule = isSchedule || isEvent;
+
+ try {
+ ApplicationInfo info = mPm.getApplicationInfo(rule.getOwner().getPackageName(), 0);
+ setSummary(computeRuleSummary(rule, isSystemRule, info.loadLabel(mPm)));
+ } catch (PackageManager.NameNotFoundException e) {
+ appExists = false;
+ return;
+ }
+
+ appExists = true;
+ setTitle(rule.getName());
+ setPersistent(false);
+
+ final String action = isSchedule ? ZenModeScheduleRuleSettings.ACTION
+ : isEvent ? ZenModeEventRuleSettings.ACTION : "";
+ ServiceInfo si = mServiceListing.findService(rule.getOwner());
+ ComponentName settingsActivity = AbstractZenModeAutomaticRulePreferenceController.
+ getSettingsActivity(si);
+ setIntent(AbstractZenModeAutomaticRulePreferenceController.getRuleIntent(action,
+ settingsActivity, mId));
+ setSelectable(settingsActivity != null || isSystemRule);
+ setKey(mId);
+ }
+
+ private String computeRuleSummary(AutomaticZenRule rule, boolean isSystemRule,
+ CharSequence providerLabel) {
+ final String mode = computeZenModeCaption(mContext.getResources(),
+ rule.getInterruptionFilter());
+ final String ruleState = (rule == null || !rule.isEnabled())
+ ? mContext.getResources().getString(R.string.switch_off_text)
+ : mContext.getResources().getString(
+ R.string.zen_mode_rule_summary_enabled_combination, mode);
+
+ return ruleState;
+ }
+
+ private static String computeZenModeCaption(Resources res, int zenMode) {
+ switch (zenMode) {
+ case NotificationManager.INTERRUPTION_FILTER_ALARMS:
+ return res.getString(R.string.zen_mode_option_alarms);
+ case NotificationManager.INTERRUPTION_FILTER_PRIORITY:
+ return res.getString(R.string.zen_mode_option_important_interruptions);
+ case NotificationManager.INTERRUPTION_FILTER_NONE:
+ return res.getString(R.string.zen_mode_option_no_interruptions);
+ default:
+ return null;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/com/android/settings/notification/ZenRuleSelectionDialog.java b/src/com/android/settings/notification/ZenRuleSelectionDialog.java
index 3c49dcb..0c725ed 100644
--- a/src/com/android/settings/notification/ZenRuleSelectionDialog.java
+++ b/src/com/android/settings/notification/ZenRuleSelectionDialog.java
@@ -164,7 +164,8 @@
if (DEBUG) Log.d(TAG, "Services reloaded: count=" + services.size());
Set<ZenRuleInfo> externalRuleTypes = new TreeSet<>(RULE_TYPE_COMPARATOR);
for (ServiceInfo serviceInfo : services) {
- final ZenRuleInfo ri = ZenModeAutomationSettings.getRuleInfo(mPm, serviceInfo);
+ final ZenRuleInfo ri = AbstractZenModeAutomaticRulePreferenceController.
+ getRuleInfo(mPm, serviceInfo);
if (ri != null && ri.configurationActivity != null
&& mNm.isNotificationPolicyAccessGrantedForPackage(ri.packageName)
&& (ri.ruleInstanceLimit <= 0 || ri.ruleInstanceLimit
diff --git a/src/com/android/settings/print/PrintSettingsFragment.java b/src/com/android/settings/print/PrintSettingsFragment.java
index 3d63000..6bdce48 100644
--- a/src/com/android/settings/print/PrintSettingsFragment.java
+++ b/src/com/android/settings/print/PrintSettingsFragment.java
@@ -55,7 +55,6 @@
import com.android.settings.dashboard.SummaryLoader;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable;
-import com.android.settings.search.SearchIndexableRaw;
import com.android.settings.utils.ProfileSettingsPreferenceFragment;
import java.text.DateFormat;
@@ -616,49 +615,11 @@
public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider() {
- @Override
- public List<SearchIndexableRaw> getRawDataToIndex(Context context, boolean enabled) {
- List<SearchIndexableRaw> indexables = new ArrayList<SearchIndexableRaw>();
-
- PackageManager packageManager = context.getPackageManager();
- PrintManager printManager = (PrintManager) context.getSystemService(
- Context.PRINT_SERVICE);
-
- String screenTitle = context.getResources().getString(R.string.print_settings);
- SearchIndexableRaw data = new SearchIndexableRaw(context);
- data.title = screenTitle;
- data.screenTitle = screenTitle;
- indexables.add(data);
-
- // Indexing all services, regardless if enabled. Please note that the index will not be
- // updated until this function is called again
- List<PrintServiceInfo> services =
- printManager.getPrintServices(PrintManager.ALL_SERVICES);
-
- if (services != null) {
- final int serviceCount = services.size();
- for (int i = 0; i < serviceCount; i++) {
- PrintServiceInfo service = services.get(i);
-
- ComponentName componentName = new ComponentName(
- service.getResolveInfo().serviceInfo.packageName,
- service.getResolveInfo().serviceInfo.name);
-
- data = new SearchIndexableRaw(context);
- data.key = componentName.flattenToString();
- data.title = service.getResolveInfo().loadLabel(packageManager).toString();
- data.screenTitle = screenTitle;
- indexables.add(data);
- }
- }
-
- return indexables;
- }
@Override
public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
boolean enabled) {
- List<SearchIndexableResource> indexables = new ArrayList<SearchIndexableResource>();
+ List<SearchIndexableResource> indexables = new ArrayList<>();
SearchIndexableResource indexable = new SearchIndexableResource(context);
indexable.xmlResId = R.xml.print_settings;
indexables.add(indexable);
diff --git a/src/com/android/settings/search/SearchIndexableResources.java b/src/com/android/settings/search/SearchIndexableResources.java
index 46e693d..c0cfc46 100644
--- a/src/com/android/settings/search/SearchIndexableResources.java
+++ b/src/com/android/settings/search/SearchIndexableResources.java
@@ -22,7 +22,6 @@
import com.android.settings.DeviceInfoSettings;
import com.android.settings.DisplaySettings;
import com.android.settings.LegalSettings;
-import com.android.settings.ScreenPinningSettings;
import com.android.settings.accessibility.AccessibilitySettings;
import com.android.settings.accessibility.AccessibilityShortcutPreferenceFragment;
import com.android.settings.accessibility.MagnificationPreferenceFragment;
@@ -69,10 +68,13 @@
import com.android.settings.notification.SoundSettings;
import com.android.settings.notification.ZenModeAutomationSettings;
import com.android.settings.notification.ZenModeBehaviorSettings;
+import com.android.settings.notification.ZenModeEventRuleSettings;
+import com.android.settings.notification.ZenModeScheduleRuleSettings;
import com.android.settings.notification.ZenModeSettings;
import com.android.settings.print.PrintSettingsFragment;
import com.android.settings.security.EncryptionAndCredential;
import com.android.settings.security.LockscreenDashboardFragment;
+import com.android.settings.security.ScreenPinningSettings;
import com.android.settings.security.SecuritySettings;
import com.android.settings.security.screenlock.ScreenLockSettings;
import com.android.settings.sim.SimSettings;
@@ -168,6 +170,8 @@
addIndex(LockscreenDashboardFragment.class);
addIndex(ZenModeBehaviorSettings.class);
addIndex(ZenModeAutomationSettings.class);
+ addIndex(ZenModeEventRuleSettings.class);
+ addIndex(ZenModeScheduleRuleSettings.class);
}
private SearchIndexableResources() {
diff --git a/src/com/android/settings/ScreenPinningSettings.java b/src/com/android/settings/security/ScreenPinningSettings.java
similarity index 84%
rename from src/com/android/settings/ScreenPinningSettings.java
rename to src/com/android/settings/security/ScreenPinningSettings.java
index b3b6868..488e0c8 100644
--- a/src/com/android/settings/ScreenPinningSettings.java
+++ b/src/com/android/settings/security/ScreenPinningSettings.java
@@ -13,14 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.settings;
+package com.android.settings.security;
import android.app.admin.DevicePolicyManager;
import android.content.Context;
import android.content.Intent;
-import android.content.res.Resources;
import android.os.Bundle;
import android.os.UserHandle;
+import android.provider.SearchIndexableResource;
import android.provider.Settings;
import android.support.v14.preference.SwitchPreference;
import android.support.v7.preference.Preference;
@@ -33,13 +33,15 @@
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.widget.LockPatternUtils;
+import com.android.settings.R;
+import com.android.settings.SettingsActivity;
+import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.password.ChooseLockGeneric;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable;
-import com.android.settings.search.SearchIndexableRaw;
import com.android.settings.widget.SwitchBar;
-import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
/**
@@ -210,33 +212,13 @@
*/
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.title = res.getString(R.string.screen_pinning_title);
- data.screenTitle = res.getString(R.string.screen_pinning_title);
- result.add(data);
-
- if (isLockToAppEnabled(context)) {
- // Screen lock option
- data = new SearchIndexableRaw(context);
- data.title = res.getString(R.string.screen_pinning_unlock_none);
- data.screenTitle = res.getString(R.string.screen_pinning_title);
- result.add(data);
- } else {
- // Screen pinning description.
- data = new SearchIndexableRaw(context);
- data.title = res.getString(R.string.screen_pinning_description);
- data.screenTitle = res.getString(R.string.screen_pinning_title);
- result.add(data);
- }
-
- return result;
+ public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
+ boolean enabled) {
+ final SearchIndexableResource sir = new SearchIndexableResource(context);
+ sir.xmlResId = R.xml.screen_pinning_settings;
+ return Arrays.asList(sir);
}
};
}
diff --git a/src/com/android/settings/security/SecuritySettings.java b/src/com/android/settings/security/SecuritySettings.java
index 35ce909..01c138a 100644
--- a/src/com/android/settings/security/SecuritySettings.java
+++ b/src/com/android/settings/security/SecuritySettings.java
@@ -823,6 +823,7 @@
SearchIndexableRaw data = new SearchIndexableRaw(context);
data.title = screenTitle;
+ data.key = "security_settings_screen";
data.screenTitle = screenTitle;
result.add(data);
@@ -834,11 +835,13 @@
// This catches the title which can be overloaded in an overlay
data = new SearchIndexableRaw(context);
data.title = res.getString(R.string.security_settings_fingerprint_preference_title);
+ data.key = "security_fingerprint";
data.screenTitle = screenTitle;
result.add(data);
// Fallback for when the above doesn't contain "fingerprint"
data = new SearchIndexableRaw(context);
data.title = res.getString(R.string.fingerprint_manage_category_title);
+ data.key = "security_managed_fingerprint";
data.screenTitle = screenTitle;
result.add(data);
}
@@ -853,22 +856,7 @@
profileUserId)) {
data = new SearchIndexableRaw(context);
data.title = res.getString(R.string.lock_settings_profile_unification_title);
- data.screenTitle = screenTitle;
- result.add(data);
- }
- }
-
- // Advanced
- if (lockPatternUtils.isSecure(MY_USER_ID)) {
- final TrustAgentManager trustAgentManager =
- FeatureFactory.getFactory(context).getSecurityFeatureProvider()
- .getTrustAgentManager();
- final List<TrustAgentComponentInfo> agents =
- trustAgentManager.getActiveTrustAgents(context, lockPatternUtils);
- for (int i = 0; i < agents.size(); i++) {
- final TrustAgentComponentInfo agent = agents.get(i);
- data = new SearchIndexableRaw(context);
- data.title = agent.title;
+ data.key = "security_use_one_lock";
data.screenTitle = screenTitle;
result.add(data);
}
diff --git a/src/com/android/settings/sim/SimSelectNotification.java b/src/com/android/settings/sim/SimSelectNotification.java
index 67e423b..2dd2dcf 100644
--- a/src/com/android/settings/sim/SimSelectNotification.java
+++ b/src/com/android/settings/sim/SimSelectNotification.java
@@ -16,6 +16,7 @@
package com.android.settings.sim;
+import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
@@ -40,6 +41,9 @@
private static final String TAG = "SimSelectNotification";
private static final int NOTIFICATION_ID = 1;
+ private static final String SIM_SELECT_NOTIFICATION_CHANNEL =
+ "sim_select_notification_channel";
+
@Override
public void onReceive(Context context, Intent intent) {
final TelephonyManager telephonyManager = (TelephonyManager)
@@ -117,8 +121,14 @@
private void createNotification(Context context){
final Resources resources = context.getResources();
+
+ NotificationChannel notificationChannel = new NotificationChannel(
+ SIM_SELECT_NOTIFICATION_CHANNEL,
+ resources.getString(R.string.sim_selection_channel_title),
+ NotificationManager.IMPORTANCE_LOW);
+
NotificationCompat.Builder builder =
- new NotificationCompat.Builder(context)
+ new NotificationCompat.Builder(context, SIM_SELECT_NOTIFICATION_CHANNEL)
.setSmallIcon(R.drawable.ic_sim_card_alert_white_48dp)
.setColor(context.getColor(R.color.sim_noitification))
.setContentTitle(resources.getString(R.string.sim_notification_title))
@@ -130,6 +140,7 @@
builder.setContentIntent(resultPendingIntent);
NotificationManager notificationManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
+ notificationManager.createNotificationChannel(notificationChannel);
notificationManager.notify(NOTIFICATION_ID, builder.build());
}
diff --git a/src/com/android/settings/users/UserSettings.java b/src/com/android/settings/users/UserSettings.java
index 906c9d4..9f510d2 100644
--- a/src/com/android/settings/users/UserSettings.java
+++ b/src/com/android/settings/users/UserSettings.java
@@ -1136,6 +1136,7 @@
final Resources res = context.getResources();
SearchIndexableRaw data = new SearchIndexableRaw(context);
data.title = res.getString(R.string.user_settings_title);
+ data.key = "users_settings";
data.screenTitle = res.getString(R.string.user_settings_title);
result.add(data);
@@ -1145,6 +1146,7 @@
R.string.user_add_user_or_profile_menu
: R.string.user_add_user_menu);
data.screenTitle = res.getString(R.string.user_settings_title);
+ data.key = "user_settings_add_users";
result.add(data);
}
return result;
diff --git a/src/com/android/settings/wallpaper/WallpaperTypeSettings.java b/src/com/android/settings/wallpaper/WallpaperTypeSettings.java
index 3c95785..a87249e 100644
--- a/src/com/android/settings/wallpaper/WallpaperTypeSettings.java
+++ b/src/com/android/settings/wallpaper/WallpaperTypeSettings.java
@@ -16,7 +16,6 @@
package com.android.settings.wallpaper;
-import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -113,6 +112,7 @@
SearchIndexableRaw data = new SearchIndexableRaw(context);
data.title = label.toString();
+ data.key = "wallpaper_type_settings";
data.screenTitle = context.getResources().getString(
R.string.wallpaper_settings_fragment_title);
data.intentAction = Intent.ACTION_SET_WALLPAPER;
diff --git a/src/com/android/settings/wifi/WifiSettings.java b/src/com/android/settings/wifi/WifiSettings.java
index 14db3d3..4c87bac 100644
--- a/src/com/android/settings/wifi/WifiSettings.java
+++ b/src/com/android/settings/wifi/WifiSettings.java
@@ -68,7 +68,6 @@
import com.android.settingslib.wifi.AccessPoint;
import com.android.settingslib.wifi.AccessPoint.AccessPointListener;
import com.android.settingslib.wifi.AccessPointPreference;
-import com.android.settingslib.wifi.WifiSavedConfigUtils;
import com.android.settingslib.wifi.WifiTracker;
import com.android.settingslib.wifi.WifiTrackerFactory;
@@ -1117,18 +1116,6 @@
data.key = DATA_KEY_REFERENCE;
result.add(data);
- // Add saved Wi-Fi access points
- final List<AccessPoint> accessPoints =
- WifiSavedConfigUtils.getAllConfigs(context,
- context.getSystemService(WifiManager.class));
- for (AccessPoint accessPoint : accessPoints) {
- data = new SearchIndexableRaw(context);
- data.title = accessPoint.getSsidStr();
- data.screenTitle = res.getString(R.string.wifi_settings);
- data.enabled = enabled;
- result.add(data);
- }
-
return result;
}
};
diff --git a/src/com/android/settings/wifi/tether/WifiTetherSettings.java b/src/com/android/settings/wifi/tether/WifiTetherSettings.java
index 1569bfc..d06ad4a 100644
--- a/src/com/android/settings/wifi/tether/WifiTetherSettings.java
+++ b/src/com/android/settings/wifi/tether/WifiTetherSettings.java
@@ -28,6 +28,7 @@
import android.os.Bundle;
import android.os.UserManager;
import android.support.annotation.VisibleForTesting;
+import android.text.TextUtils;
import android.util.Log;
import com.android.internal.logging.nano.MetricsProto;
@@ -40,6 +41,7 @@
import java.util.ArrayList;
import java.util.List;
+import java.util.UUID;
public class WifiTetherSettings extends RestrictedDashboardFragment
implements WifiTetherBasePreferenceController.OnTetherConfigUpdateListener {
@@ -156,6 +158,7 @@
config.SSID = mSSIDPreferenceController.getSSID();
config.preSharedKey = mPasswordPreferenceController.getPassword();
+ ensureWifiConfigHasPassword(config);
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA2_PSK);
config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
config.apBand = mApBandPreferenceController.getBandIndex();
@@ -177,6 +180,15 @@
}
@VisibleForTesting
+ static void ensureWifiConfigHasPassword(WifiConfiguration config) {
+ if (TextUtils.isEmpty(config.preSharedKey)) {
+ String randomUUID = UUID.randomUUID().toString();
+ //first 12 chars from xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx
+ config.preSharedKey = randomUUID.substring(0, 8) + randomUUID.substring(9, 13);
+ }
+ }
+
+ @VisibleForTesting
class TetherChangeReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context content, Intent intent) {
diff --git a/tests/robotests/assets/grandfather_not_implementing_indexable b/tests/robotests/assets/grandfather_not_implementing_indexable
index 8c44112..46414c7 100644
--- a/tests/robotests/assets/grandfather_not_implementing_indexable
+++ b/tests/robotests/assets/grandfather_not_implementing_indexable
@@ -3,7 +3,6 @@
com.android.settings.deviceinfo.PrivateVolumeForget
com.android.settings.inputmethod.SpellCheckersSettings
com.android.settings.inputmethod.KeyboardLayoutPickerFragment
-com.android.settings.notification.ZenModeEventRuleSettings
com.android.settings.fuelgauge.InactiveApps
com.android.settings.accessibility.CaptionPropertiesFragment
com.android.settings.accessibility.AccessibilitySettingsForSetupWizard
@@ -30,7 +29,6 @@
com.android.settings.accessibility.ToggleAutoclickPreferenceFragment
com.android.settings.applications.AppLaunchSettings
com.android.settings.applications.ProcessStatsUi
-com.android.settings.notification.ZenModeScheduleRuleSettings
com.android.settings.datausage.BillingCycleSettings
com.android.settings.notification.NotificationStation
com.android.settings.print.PrintJobSettingsFragment
diff --git a/tests/robotests/src/com/android/settings/DeviceInfoSettingsTest.java b/tests/robotests/src/com/android/settings/DeviceInfoSettingsTest.java
index 8cedaf1..9f2415b 100644
--- a/tests/robotests/src/com/android/settings/DeviceInfoSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/DeviceInfoSettingsTest.java
@@ -16,19 +16,32 @@
package com.android.settings;
+import static com.android.settings.DeviceInfoSettings.NON_SIM_PREFERENCES_COUNT;
+import static com.android.settings.DeviceInfoSettings.SIM_PREFERENCES_COUNT;
+
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
+import android.app.Activity;
import android.content.Context;
import android.os.Build;
+import android.os.SystemProperties;
import android.support.v7.preference.PreferenceScreen;
+import android.telephony.TelephonyManager;
+import android.util.FeatureFlagUtils;
+import android.view.View;
+import com.android.settings.core.FeatureFlags;
import com.android.settings.dashboard.SummaryLoader;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.XmlTestUtils;
+import com.android.settings.testutils.shadow.SettingsShadowResources;
+import com.android.settings.testutils.shadow.SettingsShadowSystemProperties;
import com.android.settings.testutils.shadow.ShadowConnectivityManager;
import com.android.settings.testutils.shadow.ShadowUtils;
import com.android.settingslib.DeviceInfoUtils;
@@ -40,29 +53,43 @@
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
+import org.robolectric.util.ReflectionHelpers;
import java.util.List;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(
- manifest = TestConfig.MANIFEST_PATH,
- sdk = TestConfig.SDK_VERSION_O,
- shadows = {ShadowUtils.class, ShadowConnectivityManager.class}
+ manifest = TestConfig.MANIFEST_PATH,
+ sdk = TestConfig.SDK_VERSION_O,
+ shadows = {ShadowUtils.class, ShadowConnectivityManager.class}
)
public class DeviceInfoSettingsTest {
@Mock
+ private Activity mActivity;
+ @Mock
private PreferenceScreen mScreen;
@Mock
private SummaryLoader mSummaryLoader;
+ @Mock
+ private TelephonyManager mTelephonyManager;
+ private Context mContext;
private DeviceInfoSettings mSettings;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
+ mContext = RuntimeEnvironment.application;
mSettings = spy(new DeviceInfoSettings());
+
+ doReturn(mActivity).when(mSettings).getActivity();
+ doReturn(mContext.getTheme()).when(mActivity).getTheme();
+ doReturn(mContext.getResources()).when(mSettings).getResources();
+ doNothing().when(mSettings).onCreatePreferences(any(), any());
+
doReturn(mScreen).when(mSettings).getPreferenceScreen();
+ doReturn(mTelephonyManager).when(mSettings).getSystemService(Context.TELEPHONY_SERVICE);
}
@Test
@@ -91,4 +118,32 @@
assertThat(keys).containsAllIn(niks);
}
+
+ @Test
+ @Config(shadows = {SettingsShadowResources.SettingsShadowTheme.class,
+ SettingsShadowSystemProperties.class})
+ public void onCreate_singleSim_shouldAddSingleSimCount() {
+ SystemProperties.set(FeatureFlagUtils.FFLAG_OVERRIDE_PREFIX + FeatureFlags.DEVICE_INFO_V2,
+ "true");
+ doReturn(1).when(mTelephonyManager).getPhoneCount();
+
+ mSettings.onCreate(null /* icicle */);
+
+ verify(mScreen).setInitialExpandedChildrenCount(
+ SIM_PREFERENCES_COUNT + NON_SIM_PREFERENCES_COUNT);
+ }
+
+ @Test
+ @Config(shadows = {SettingsShadowResources.SettingsShadowTheme.class,
+ SettingsShadowSystemProperties.class})
+ public void onCreate_dualeSim_shouldAddDualSimCount() {
+ SystemProperties.set(FeatureFlagUtils.FFLAG_OVERRIDE_PREFIX + FeatureFlags.DEVICE_INFO_V2,
+ "true");
+ doReturn(2).when(mTelephonyManager).getPhoneCount();
+
+ mSettings.onCreate(null /* icicle */);
+
+ verify(mScreen).setInitialExpandedChildrenCount(
+ 2 * SIM_PREFERENCES_COUNT + NON_SIM_PREFERENCES_COUNT);
+ }
}
diff --git a/tests/robotests/src/com/android/settings/network/PrivateDnsModeDialogFragmentTest.java b/tests/robotests/src/com/android/settings/network/PrivateDnsModeDialogFragmentTest.java
index 3468702..f1d7a73 100644
--- a/tests/robotests/src/com/android/settings/network/PrivateDnsModeDialogFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/network/PrivateDnsModeDialogFragmentTest.java
@@ -27,6 +27,7 @@
import android.content.Context;
import android.provider.Settings;
+import android.widget.Button;
import com.android.settings.R;
import com.android.settings.TestConfig;
@@ -43,9 +44,11 @@
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class PrivateDnsModeDialogFragmentTest {
private static final String HOST_NAME = "192.168.1.1";
+ private static final String INVALID_HOST_NAME = "...,";
private Context mContext;
private PrivateDnsModeDialogFragment mFragment;
+ private Button mSaveButton;
@Before
@@ -53,9 +56,12 @@
MockitoAnnotations.initMocks(this);
mContext = RuntimeEnvironment.application;
+ mSaveButton = new Button(mContext);
+
mFragment = spy(new PrivateDnsModeDialogFragment());
doReturn(mContext).when(mFragment).getContext();
mFragment.onCreateDialog(null);
+ mFragment.mSaveButton = mSaveButton;
}
@Test
@@ -96,4 +102,19 @@
R.id.private_dns_mode_opportunistic);
}
+ @Test
+ public void testOnCheckedChanged_switchMode_saveButtonHasCorrectState() {
+ // Set invalid hostname
+ mFragment.mEditText.setText(INVALID_HOST_NAME);
+
+ mFragment.onCheckedChanged(null, R.id.private_dns_mode_opportunistic);
+ assertThat(mSaveButton.isEnabled()).isTrue();
+
+ mFragment.onCheckedChanged(null, R.id.private_dns_mode_provider);
+ assertThat(mSaveButton.isEnabled()).isFalse();
+
+ mFragment.onCheckedChanged(null, R.id.private_dns_mode_off);
+ assertThat(mSaveButton.isEnabled()).isTrue();
+ }
+
}
diff --git a/tests/robotests/src/com/android/settings/notification/ZenModeAlarmsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/ZenModeAlarmsPreferenceControllerTest.java
new file mode 100644
index 0000000..06ca70a
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/ZenModeAlarmsPreferenceControllerTest.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.notification;
+
+import static android.provider.Settings.Global.ZEN_MODE;
+import static android.provider.Settings.Global.ZEN_MODE_ALARMS;
+import static android.provider.Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+import static android.provider.Settings.Global.ZEN_MODE_NO_INTERRUPTIONS;
+
+import static junit.framework.Assert.assertEquals;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.NotificationManager;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.provider.Settings;
+import android.support.v14.preference.SwitchPreference;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowApplication;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.util.ReflectionHelpers;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
+public class ZenModeAlarmsPreferenceControllerTest {
+ private ZenModeAlarmsPreferenceController mController;
+
+ @Mock
+ private ZenModeBackend mBackend;
+ @Mock
+ private NotificationManager mNotificationManager;
+ @Mock
+ private SwitchPreference mockPref;
+ @Mock
+ private NotificationManager.Policy mPolicy;
+ @Mock
+ private PreferenceScreen mPreferenceScreen;
+
+ private Context mContext;
+ private ContentResolver mContentResolver;
+
+ private final boolean ALARMS_SETTINGS = true;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ ShadowApplication shadowApplication = ShadowApplication.getInstance();
+ shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNotificationManager);
+
+ mContext = shadowApplication.getApplicationContext();
+ mContentResolver = RuntimeEnvironment.application.getContentResolver();
+ when(mNotificationManager.getNotificationPolicy()).thenReturn(mPolicy);
+ mController = new ZenModeAlarmsPreferenceController(mContext, mock(Lifecycle.class));
+ ReflectionHelpers.setField(mController, "mBackend", mBackend);
+
+ when(mPreferenceScreen.findPreference(mController.getPreferenceKey())).thenReturn(
+ mockPref);
+ mController.displayPreference(mPreferenceScreen);
+ }
+
+ @Test
+ public void updateState_TotalSilence() {
+ Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_NO_INTERRUPTIONS);
+
+ final SwitchPreference mockPref = mock(SwitchPreference.class);
+ mController.updateState(mockPref);
+
+ verify(mockPref).setEnabled(false);
+ verify(mockPref).setChecked(false);
+ }
+
+ @Test
+ public void updateState_AlarmsOnly() {
+ Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_ALARMS);
+
+ final SwitchPreference mockPref = mock(SwitchPreference.class);
+ mController.updateState(mockPref);
+
+ verify(mockPref).setEnabled(false);
+ verify(mockPref).setChecked(true);
+ }
+
+ @Test
+ public void updateState_Priority() {
+ Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_IMPORTANT_INTERRUPTIONS);
+
+ when(mBackend.isPriorityCategoryEnabled(
+ NotificationManager.Policy.PRIORITY_CATEGORY_ALARMS)).thenReturn(ALARMS_SETTINGS);
+
+ mController.updateState(mockPref);
+
+ verify(mockPref).setEnabled(true);
+ verify(mockPref).setChecked(ALARMS_SETTINGS);
+ }
+
+ @Test
+ public void onPreferenceChanged_EnableAlarms() {
+ boolean allowAlarms = true;
+ mController.onPreferenceChange(mockPref, allowAlarms);
+
+ verify(mBackend).saveSoundPolicy(NotificationManager.Policy.PRIORITY_CATEGORY_ALARMS,
+ allowAlarms);
+ }
+
+ @Test
+ public void onPreferenceChanged_DisableAlarms() {
+ boolean allowAlarms = false;
+ mController.onPreferenceChange(mockPref, allowAlarms);
+
+ verify(mBackend).saveSoundPolicy(NotificationManager.Policy.PRIORITY_CATEGORY_ALARMS,
+ allowAlarms);
+ }
+}
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/notification/ZenModeButtonPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/ZenModeButtonPreferenceControllerTest.java
new file mode 100644
index 0000000..a1b4dab
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/ZenModeButtonPreferenceControllerTest.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.notification;
+
+import static android.provider.Settings.Global.ZEN_MODE;
+import static android.provider.Settings.Global.ZEN_MODE_ALARMS;
+import static android.provider.Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+import static android.provider.Settings.Global.ZEN_MODE_NO_INTERRUPTIONS;
+import static android.provider.Settings.Global.ZEN_MODE_OFF;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.NotificationManager;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.provider.Settings;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+import android.view.View;
+import android.widget.Button;
+
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowApplication;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.util.ReflectionHelpers;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
+public class ZenModeButtonPreferenceControllerTest {
+ private ZenModeButtonPreferenceController mController;
+
+ @Mock
+ private ZenModeBackend mBackend;
+ @Mock
+ private NotificationManager mNotificationManager;
+ @Mock
+ private Preference mockPref;
+ @Mock
+ private NotificationManager.Policy mPolicy;
+ @Mock
+ private Button mZenButtonOn;
+ @Mock
+ private Button mZenButtonOff;
+ @Mock
+ private PreferenceScreen mPreferenceScreen;
+ private ContentResolver mContentResolver;
+ private Context mContext;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ ShadowApplication shadowApplication = ShadowApplication.getInstance();
+ shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNotificationManager);
+
+ mContext = shadowApplication.getApplicationContext();
+ mContentResolver = RuntimeEnvironment.application.getContentResolver();
+ mController = new ZenModeButtonPreferenceController(mContext, mock(Lifecycle.class));
+ when(mNotificationManager.getNotificationPolicy()).thenReturn(mPolicy);
+ ReflectionHelpers.setField(mController, "mBackend", mBackend);
+ ReflectionHelpers.setField(mController, "mZenButtonOn", mZenButtonOn);
+ ReflectionHelpers.setField(mController, "mZenButtonOff", mZenButtonOff);
+
+ when(mPreferenceScreen.findPreference(mController.getPreferenceKey())).thenReturn(
+ mockPref);
+ mController.displayPreference(mPreferenceScreen);
+ }
+
+ @Test
+ public void updateState_TotalSilence() {
+ Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_NO_INTERRUPTIONS);
+ final Preference mockPref = mock(Preference.class);
+ mController.updateState(mockPref);
+
+ verify(mZenButtonOn).setVisibility(View.GONE);
+ verify(mZenButtonOff).setVisibility(View.VISIBLE);
+ }
+
+ @Test
+ public void updateState_AlarmsOnly() {
+ Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_ALARMS);
+ final Preference mockPref = mock(Preference.class);
+ mController.updateState(mockPref);
+
+ verify(mZenButtonOn).setVisibility(View.GONE);
+ verify(mZenButtonOff).setVisibility(View.VISIBLE);
+ }
+
+ @Test
+ public void updateState_Priority() {
+ Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_IMPORTANT_INTERRUPTIONS);
+ final Preference mockPref = mock(Preference.class);
+ mController.updateState(mockPref);
+
+ verify(mZenButtonOn).setVisibility(View.GONE);
+ verify(mZenButtonOff).setVisibility(View.VISIBLE);
+ }
+
+ @Test
+ public void updateState_ZenOff() {
+ Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_OFF);
+ final Preference mockPref = mock(Preference.class);
+ mController.updateState(mockPref);
+
+ verify(mZenButtonOn).setVisibility(View.VISIBLE);
+ verify(mZenButtonOff).setVisibility(View.GONE);
+ }
+}
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/notification/ZenModeCallsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/ZenModeCallsPreferenceControllerTest.java
new file mode 100644
index 0000000..ea7e9f5
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/ZenModeCallsPreferenceControllerTest.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.notification;
+
+import static android.provider.Settings.Global.ZEN_MODE;
+import static android.provider.Settings.Global.ZEN_MODE_ALARMS;
+import static android.provider.Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+import static android.provider.Settings.Global.ZEN_MODE_NO_INTERRUPTIONS;
+
+import static junit.framework.Assert.assertEquals;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.NotificationManager;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.provider.Settings;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settings.R;
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowApplication;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.util.ReflectionHelpers;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
+public class ZenModeCallsPreferenceControllerTest {
+ private ZenModeCallsPreferenceController mController;
+
+ @Mock
+ private ZenModeBackend mBackend;
+ @Mock
+ private NotificationManager mNotificationManager;
+ @Mock
+ private Preference mockPref;
+ @Mock
+ private NotificationManager.Policy mPolicy;
+ @Mock
+ private PreferenceScreen mPreferenceScreen;
+ private ContentResolver mContentResolver;
+ private Context mContext;
+
+ private final boolean CALLS_SETTINGS = true;
+ private final int MOCK_CALLS_SENDERS = NotificationManager.Policy.PRIORITY_SENDERS_STARRED;
+ private final int SUMMARY_ID_MOCK_CALLS_SENDERS = R.string.zen_mode_from_starred;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ ShadowApplication shadowApplication = ShadowApplication.getInstance();
+ shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNotificationManager);
+
+ mContext = shadowApplication.getApplicationContext();
+ mContentResolver = RuntimeEnvironment.application.getContentResolver();
+ when(mNotificationManager.getNotificationPolicy()).thenReturn(mPolicy);
+ when(mBackend.getContactsSummary(ZenModeBackend.SOURCE_NONE))
+ .thenCallRealMethod();
+ when(mBackend.getContactsSummary(NotificationManager.Policy.PRIORITY_CATEGORY_CALLS))
+ .thenCallRealMethod();
+
+ mController = new ZenModeCallsPreferenceController(mContext, mock(Lifecycle.class));
+ ReflectionHelpers.setField(mController, "mBackend", mBackend);
+
+ when(mPreferenceScreen.findPreference(mController.getPreferenceKey())).thenReturn(
+ mockPref);
+ mController.displayPreference(mPreferenceScreen);
+ }
+
+ @Test
+ public void updateState_TotalSilence() {
+ Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_NO_INTERRUPTIONS);
+ when(mBackend.isPriorityCategoryEnabled(
+ NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES))
+ .thenReturn(false);
+ final Preference mockPref = mock(Preference.class);
+ mController.updateState(mockPref);
+
+ verify(mockPref).setEnabled(false);
+ verify(mockPref).setSummary(R.string.zen_mode_from_none);
+ }
+
+ @Test
+ public void updateState_AlarmsOnly() {
+ Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_ALARMS);
+
+ final Preference mockPref = mock(Preference.class);
+ mController.updateState(mockPref);
+
+ verify(mockPref).setEnabled(false);
+ verify(mockPref).setSummary(R.string.zen_mode_from_none);
+ }
+
+ @Test
+ public void updateState_Priority() {
+ Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_IMPORTANT_INTERRUPTIONS);
+ when(mBackend.isPriorityCategoryEnabled(
+ NotificationManager.Policy.PRIORITY_CATEGORY_CALLS))
+ .thenReturn(CALLS_SETTINGS);
+ when(mBackend.getPriorityCallSenders()).thenReturn(MOCK_CALLS_SENDERS);
+
+ mController.updateState(mockPref);
+
+ verify(mockPref).setEnabled(true);
+ verify(mockPref).setSummary(SUMMARY_ID_MOCK_CALLS_SENDERS);
+ }
+}
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/notification/ZenModeCallsTest.java b/tests/robotests/src/com/android/settings/notification/ZenModeCallsTest.java
new file mode 100644
index 0000000..3cc87a8
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/ZenModeCallsTest.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.notification;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.Activity;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.os.UserManager;
+import android.provider.Settings;
+
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.FakeFeatureFactory;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+import org.robolectric.util.ReflectionHelpers;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class ZenModeCallsTest {
+ private ZenModeCallsSettings mCalls;
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+ private ZenModeBackend mBackend;
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+ private Activity mActivity;
+ @Mock
+ private UserManager mUserManager;
+ @Mock
+ private NotificationManager mNotificationManager;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ when(mActivity.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
+ when(mActivity.getSystemService(Context.NOTIFICATION_SERVICE))
+ .thenReturn(mNotificationManager);
+ FakeFeatureFactory.setupForTest(mActivity);
+
+ mCalls = new ZenModeCallsSettings();
+ mCalls.onAttach((Context)mActivity);
+
+ ReflectionHelpers.setField(mCalls, "mBackend", mBackend);
+ }
+
+ @Test
+ public void getDefaultKeyReturnsBasedOnZen() {
+ when(mBackend.getSendersKey(NotificationManager.Policy.PRIORITY_CATEGORY_CALLS))
+ .thenCallRealMethod();
+ when(mBackend.getZenMode()).thenReturn(Settings.Global.ZEN_MODE_NO_INTERRUPTIONS);
+ assertThat(mCalls.getDefaultKey())
+ .isEqualTo(mBackend.getKeyFromSetting(mBackend.SOURCE_NONE));
+
+ when(mBackend.getZenMode()).thenReturn(Settings.Global.ZEN_MODE_ALARMS);
+ assertThat(mCalls.getDefaultKey())
+ .isEqualTo(mBackend.getKeyFromSetting(mBackend.SOURCE_NONE));
+
+ when(mBackend.getZenMode()).thenReturn(Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS);
+ when(mBackend.isPriorityCategoryEnabled(
+ NotificationManager.Policy.PRIORITY_CATEGORY_CALLS))
+ .thenReturn(true);
+ when(mBackend.getPriorityMessageSenders())
+ .thenReturn(NotificationManager.Policy.PRIORITY_SENDERS_ANY);
+ assertThat(mCalls.getDefaultKey())
+ .isEqualTo(mBackend.getKeyFromSetting(
+ NotificationManager.Policy.PRIORITY_SENDERS_ANY));
+ }
+
+ @Test
+ public void setAnySender() {
+ String key = mBackend.getKeyFromSetting(NotificationManager.Policy.PRIORITY_SENDERS_ANY);
+ mCalls.setDefaultKey(key);
+ verify(mBackend).saveSenders(NotificationManager.Policy.PRIORITY_CATEGORY_CALLS,
+ mBackend.getSettingFromPrefKey(key));
+ }
+
+ @Test
+ public void setNoSender() {
+ String key = mBackend.getKeyFromSetting(ZenModeBackend.SOURCE_NONE);
+ mCalls.setDefaultKey(key);
+ verify(mBackend).saveSenders(NotificationManager.Policy.PRIORITY_CATEGORY_CALLS,
+ mBackend.getSettingFromPrefKey(key));
+ }
+
+ @Test
+ public void setStarredSenders() {
+ String key = mBackend.getKeyFromSetting(
+ NotificationManager.Policy.PRIORITY_SENDERS_STARRED);
+ mCalls.setDefaultKey(key);
+ verify(mBackend).saveSenders(NotificationManager.Policy.PRIORITY_CATEGORY_CALLS,
+ mBackend.getSettingFromPrefKey(key));
+ }
+
+ @Test
+ public void setContactsOnlySenders() {
+ String key = mBackend.getKeyFromSetting(
+ NotificationManager.Policy.PRIORITY_SENDERS_CONTACTS);
+ mCalls.setDefaultKey(key);
+ verify(mBackend).saveSenders(NotificationManager.Policy.PRIORITY_CATEGORY_CALLS,
+ mBackend.getSettingFromPrefKey(key));
+ }
+}
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/notification/ZenModeEventsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/ZenModeEventsPreferenceControllerTest.java
new file mode 100644
index 0000000..b527abf
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/ZenModeEventsPreferenceControllerTest.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.notification;
+
+import static android.provider.Settings.Global.ZEN_MODE;
+import static android.provider.Settings.Global.ZEN_MODE_ALARMS;
+import static android.provider.Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+import static android.provider.Settings.Global.ZEN_MODE_NO_INTERRUPTIONS;
+
+import static junit.framework.Assert.assertEquals;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.NotificationManager;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.provider.Settings;
+import android.support.v14.preference.SwitchPreference;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.shadows.ShadowApplication;
+import org.robolectric.annotation.Config;
+import org.robolectric.util.ReflectionHelpers;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
+public class ZenModeEventsPreferenceControllerTest {
+ private ZenModeEventsPreferenceController mController;
+
+ @Mock
+ private ZenModeBackend mBackend;
+ @Mock
+ private NotificationManager mNotificationManager;
+ @Mock
+ private SwitchPreference mockPref;
+ @Mock
+ private NotificationManager.Policy mPolicy;
+ @Mock
+ private PreferenceScreen mPreferenceScreen;
+ private ContentResolver mContentResolver;
+ private Context mContext;
+
+ private final boolean EVENTS_SETTINGS = true;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ ShadowApplication shadowApplication = ShadowApplication.getInstance();
+ shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNotificationManager);
+
+ mContext = shadowApplication.getApplicationContext();
+ mContentResolver = RuntimeEnvironment.application.getContentResolver();
+ when(mNotificationManager.getNotificationPolicy()).thenReturn(mPolicy);
+
+ mController = new ZenModeEventsPreferenceController(mContext, mock(Lifecycle.class));
+ ReflectionHelpers.setField(mController, "mBackend", mBackend);
+
+ when(mPreferenceScreen.findPreference(mController.getPreferenceKey())).thenReturn(
+ mockPref);
+ mController.displayPreference(mPreferenceScreen);
+ }
+
+ @Test
+ public void updateState_TotalSilence() {
+ Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_NO_INTERRUPTIONS);
+
+ final SwitchPreference mockPref = mock(SwitchPreference.class);
+ mController.updateState(mockPref);
+
+ verify(mockPref).setEnabled(false);
+ verify(mockPref).setChecked(false);
+ }
+
+ @Test
+ public void updateState_AlarmsOnly() {
+ Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_ALARMS);
+
+ final SwitchPreference mockPref = mock(SwitchPreference.class);
+ mController.updateState(mockPref);
+
+ verify(mockPref).setEnabled(false);
+ verify(mockPref).setChecked(false);
+ }
+
+ @Test
+ public void updateState_Priority() {
+ Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_IMPORTANT_INTERRUPTIONS);
+
+ when(mBackend.isPriorityCategoryEnabled(
+ NotificationManager.Policy.PRIORITY_CATEGORY_EVENTS)).thenReturn(EVENTS_SETTINGS);
+
+ mController.updateState(mockPref);
+
+ verify(mockPref).setEnabled(true);
+ verify(mockPref).setChecked(EVENTS_SETTINGS);
+ }
+
+ @Test
+ public void onPreferenceChanged_EnableEvents() {
+ boolean allow = true;
+ mController.onPreferenceChange(mockPref, allow);
+
+ verify(mBackend).saveSoundPolicy(NotificationManager.Policy.PRIORITY_CATEGORY_EVENTS,
+ allow);
+ }
+
+ @Test
+ public void onPreferenceChanged_DisableEvents() {
+ boolean allow = false;
+ mController.onPreferenceChange(mockPref, allow);
+
+ verify(mBackend).saveSoundPolicy(NotificationManager.Policy.PRIORITY_CATEGORY_EVENTS,
+ allow);
+ }
+}
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/notification/ZenModeMediaPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/ZenModeMediaPreferenceControllerTest.java
new file mode 100644
index 0000000..976d6d4
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/ZenModeMediaPreferenceControllerTest.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.notification;
+
+import static android.provider.Settings.Global.ZEN_MODE;
+import static android.provider.Settings.Global.ZEN_MODE_ALARMS;
+import static android.provider.Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+import static android.provider.Settings.Global.ZEN_MODE_NO_INTERRUPTIONS;
+
+import static junit.framework.Assert.assertEquals;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.NotificationManager;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.provider.Settings;
+import android.support.v14.preference.SwitchPreference;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowApplication;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.util.ReflectionHelpers;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
+public class ZenModeMediaPreferenceControllerTest {
+ private ZenModeMediaSystemOtherPreferenceController mController;
+
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+ private Context mContext;
+ @Mock
+ private ZenModeBackend mBackend;
+ @Mock
+ private NotificationManager mNotificationManager;
+ @Mock
+ private SwitchPreference mockPref;
+ @Mock
+ private NotificationManager.Policy mPolicy;
+ @Mock
+ private PreferenceScreen mPreferenceScreen;
+ private ContentResolver mContentResolver;
+
+ private final boolean MEDIA_SETTINGS = true;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ ShadowApplication shadowApplication = ShadowApplication.getInstance();
+ shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNotificationManager);
+
+ mContext = shadowApplication.getApplicationContext();
+ mContentResolver = RuntimeEnvironment.application.getContentResolver();
+ when(mNotificationManager.getNotificationPolicy()).thenReturn(mPolicy);
+
+ mController = new ZenModeMediaSystemOtherPreferenceController(mContext,
+ mock(Lifecycle.class));
+ ReflectionHelpers.setField(mController, "mBackend", mBackend);
+
+ when(mPreferenceScreen.findPreference(mController.getPreferenceKey())).thenReturn(
+ mockPref);
+ mController.displayPreference(mPreferenceScreen);
+ }
+
+ @Test
+ public void updateState_TotalSilence() {
+ Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_NO_INTERRUPTIONS);
+
+ final SwitchPreference mockPref = mock(SwitchPreference.class);
+ mController.updateState(mockPref);
+
+ verify(mockPref).setEnabled(false);
+ verify(mockPref).setChecked(false);
+ }
+
+ @Test
+ public void updateState_AlarmsOnly() {
+ Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_ALARMS);
+
+ final SwitchPreference mockPref = mock(SwitchPreference.class);
+ mController.updateState(mockPref);
+
+ verify(mockPref).setEnabled(false);
+ verify(mockPref).setChecked(true);
+ }
+
+ @Test
+ public void updateState_Priority() {
+ Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_IMPORTANT_INTERRUPTIONS);
+
+ when(mBackend.isPriorityCategoryEnabled(
+ NotificationManager.Policy.PRIORITY_CATEGORY_MEDIA_SYSTEM_OTHER)).
+ thenReturn(MEDIA_SETTINGS);
+
+ mController.updateState(mockPref);
+
+ verify(mockPref).setEnabled(true);
+ verify(mockPref).setChecked(MEDIA_SETTINGS);
+ }
+
+ @Test
+ public void onPreferenceChanged_EnableEvents() {
+ boolean allow = true;
+ mController.onPreferenceChange(mockPref, allow);
+
+ verify(mBackend).saveSoundPolicy(
+ NotificationManager.Policy.PRIORITY_CATEGORY_MEDIA_SYSTEM_OTHER, allow);
+ }
+
+ @Test
+ public void onPreferenceChanged_DisableEvents() {
+ boolean allow = false;
+ mController.onPreferenceChange(mockPref, allow);
+
+ verify(mBackend).saveSoundPolicy(
+ NotificationManager.Policy.PRIORITY_CATEGORY_MEDIA_SYSTEM_OTHER, allow);
+ }
+}
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/notification/ZenModeMessagesPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/ZenModeMessagesPreferenceControllerTest.java
new file mode 100644
index 0000000..c06f93f
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/ZenModeMessagesPreferenceControllerTest.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.notification;
+
+import static android.provider.Settings.Global.ZEN_MODE;
+import static android.provider.Settings.Global.ZEN_MODE_ALARMS;
+import static android.provider.Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+import static android.provider.Settings.Global.ZEN_MODE_NO_INTERRUPTIONS;
+
+import static junit.framework.Assert.assertEquals;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.NotificationManager;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.provider.Settings;
+import android.support.v14.preference.SwitchPreference;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settings.R;
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowApplication;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.util.ReflectionHelpers;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
+public class ZenModeMessagesPreferenceControllerTest {
+ private ZenModeMessagesPreferenceController mController;
+
+ @Mock
+ private ZenModeBackend mBackend;
+ @Mock
+ private NotificationManager mNotificationManager;
+ @Mock
+ private Preference mockPref;
+ @Mock
+ private NotificationManager.Policy mPolicy;
+ @Mock
+ private PreferenceScreen mPreferenceScreen;
+ private ContentResolver mContentResolver;
+ private Context mContext;
+
+ private final boolean MESSAGES_SETTINGS = true;
+ private final int MOCK_MESSAGES_SENDERS = NotificationManager.Policy.PRIORITY_SENDERS_STARRED;
+ private final int SUMMARY_ID_MOCK_MESSAGES_SENDERS = R.string.zen_mode_from_starred;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ ShadowApplication shadowApplication = ShadowApplication.getInstance();
+ shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNotificationManager);
+
+ mContext = shadowApplication.getApplicationContext();
+ mContentResolver = RuntimeEnvironment.application.getContentResolver();
+ when(mNotificationManager.getNotificationPolicy()).thenReturn(mPolicy);
+
+ when(mBackend.getPriorityMessageSenders()).thenReturn(MOCK_MESSAGES_SENDERS);
+ when(mBackend.getContactsSummary(ZenModeBackend.SOURCE_NONE))
+ .thenCallRealMethod();
+ when(mBackend.getContactsSummary(NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES))
+ .thenCallRealMethod();
+
+ mController = new ZenModeMessagesPreferenceController(mContext, mock(Lifecycle.class));
+ ReflectionHelpers.setField(mController, "mBackend", mBackend);
+
+ when(mPreferenceScreen.findPreference(mController.getPreferenceKey())).thenReturn(
+ mockPref);
+ mController.displayPreference(mPreferenceScreen);
+ }
+
+ @Test
+ public void updateState_TotalSilence() {
+ Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_NO_INTERRUPTIONS);
+
+ when(mBackend.isPriorityCategoryEnabled(
+ NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES))
+ .thenReturn(false);
+ final Preference mockPref = mock(Preference.class);
+ mController.updateState(mockPref);
+
+ verify(mockPref).setEnabled(false);
+ verify(mockPref).setSummary(R.string.zen_mode_from_none);
+ }
+
+ @Test
+ public void updateState_AlarmsOnly() {
+ Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_ALARMS);
+
+ final Preference mockPref = mock(Preference.class);
+ mController.updateState(mockPref);
+
+ verify(mockPref).setEnabled(false);
+ verify(mockPref).setSummary(R.string.zen_mode_from_none);
+ }
+
+ @Test
+ public void updateState_Priority() {
+ Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_IMPORTANT_INTERRUPTIONS);
+
+ when(mBackend.isPriorityCategoryEnabled(
+ NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES))
+ .thenReturn(MESSAGES_SETTINGS);
+
+ mController.updateState(mockPref);
+
+ verify(mockPref).setEnabled(true);
+ verify(mockPref).setSummary(SUMMARY_ID_MOCK_MESSAGES_SENDERS);
+ }
+}
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/notification/ZenModeMessagesTest.java b/tests/robotests/src/com/android/settings/notification/ZenModeMessagesTest.java
new file mode 100644
index 0000000..fe92570
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/ZenModeMessagesTest.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.notification;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.Activity;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.os.UserManager;
+import android.provider.Settings;
+
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.FakeFeatureFactory;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+import org.robolectric.util.ReflectionHelpers;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class ZenModeMessagesTest {
+ private ZenModeMessagesSettings mMessages;
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+ private ZenModeBackend mBackend;
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+ private Activity mActivity;
+ @Mock
+ private UserManager mUserManager;
+ @Mock
+ private NotificationManager mNotificationManager;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ when(mActivity.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
+ when(mActivity.getSystemService(Context.NOTIFICATION_SERVICE))
+ .thenReturn(mNotificationManager);
+ FakeFeatureFactory.setupForTest(mActivity);
+
+ mMessages = new ZenModeMessagesSettings();
+ mMessages.onAttach((Context)mActivity);
+
+ ReflectionHelpers.setField(mMessages, "mBackend", mBackend);
+ }
+
+ @Test
+ public void getDefaultKeyReturnsBasedOnZen() {
+ when(mBackend.getSendersKey(NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES))
+ .thenCallRealMethod();
+ when(mBackend.getZenMode()).thenReturn(Settings.Global.ZEN_MODE_NO_INTERRUPTIONS);
+ assertThat(mMessages.getDefaultKey())
+ .isEqualTo(mBackend.getKeyFromSetting(mBackend.SOURCE_NONE));
+
+ when(mBackend.getZenMode()).thenReturn(Settings.Global.ZEN_MODE_ALARMS);
+ assertThat(mMessages.getDefaultKey())
+ .isEqualTo(mBackend.getKeyFromSetting(mBackend.SOURCE_NONE));
+
+ when(mBackend.getZenMode()).thenReturn(Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS);
+ when(mBackend.isPriorityCategoryEnabled(
+ NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES))
+ .thenReturn(true);
+ when(mBackend.getPriorityMessageSenders())
+ .thenReturn(NotificationManager.Policy.PRIORITY_SENDERS_ANY);
+ assertThat(mMessages.getDefaultKey())
+ .isEqualTo(mBackend.getKeyFromSetting(
+ NotificationManager.Policy.PRIORITY_SENDERS_ANY));
+ }
+
+ @Test
+ public void setAnySender() {
+ String key = mBackend.getKeyFromSetting(NotificationManager.Policy.PRIORITY_SENDERS_ANY);
+ mMessages.setDefaultKey(key);
+ verify(mBackend).saveSenders(NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES,
+ mBackend.getSettingFromPrefKey(key));
+ }
+
+ @Test
+ public void setNoSender() {
+ String key = mBackend.getKeyFromSetting(ZenModeBackend.SOURCE_NONE);
+ mMessages.setDefaultKey(key);
+ verify(mBackend).saveSenders(NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES,
+ mBackend.getSettingFromPrefKey(key));
+ }
+
+ @Test
+ public void setStarredSenders() {
+ String key = mBackend.getKeyFromSetting(
+ NotificationManager.Policy.PRIORITY_SENDERS_STARRED);
+ mMessages.setDefaultKey(key);
+ verify(mBackend).saveSenders(NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES,
+ mBackend.getSettingFromPrefKey(key));
+ }
+
+ @Test
+ public void setContactsOnlySenders() {
+ String key = mBackend.getKeyFromSetting(
+ NotificationManager.Policy.PRIORITY_SENDERS_CONTACTS);
+ mMessages.setDefaultKey(key);
+ verify(mBackend).saveSenders(NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES,
+ mBackend.getSettingFromPrefKey(key));
+ }
+}
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/notification/ZenModePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/ZenModePreferenceControllerTest.java
index 1d71a8a..0a28673 100644
--- a/tests/robotests/src/com/android/settings/notification/ZenModePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/ZenModePreferenceControllerTest.java
@@ -43,7 +43,7 @@
import static org.mockito.Mockito.when;
@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
public class ZenModePreferenceControllerTest {
@Mock
diff --git a/tests/robotests/src/com/android/settings/notification/ZenModeRemindersPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/ZenModeRemindersPreferenceControllerTest.java
new file mode 100644
index 0000000..9d8b011
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/ZenModeRemindersPreferenceControllerTest.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.notification;
+
+import static android.provider.Settings.Global.ZEN_MODE;
+import static android.provider.Settings.Global.ZEN_MODE_ALARMS;
+import static android.provider.Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+import static android.provider.Settings.Global.ZEN_MODE_NO_INTERRUPTIONS;
+
+import static junit.framework.Assert.assertEquals;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.NotificationManager;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.provider.Settings;
+import android.support.v14.preference.SwitchPreference;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowApplication;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.util.ReflectionHelpers;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
+public class ZenModeRemindersPreferenceControllerTest {
+ private ZenModeRemindersPreferenceController mController;
+
+ @Mock
+ private ZenModeBackend mBackend;
+ @Mock
+ private NotificationManager mNotificationManager;
+ @Mock
+ private SwitchPreference mockPref;
+ @Mock
+ private NotificationManager.Policy mPolicy;
+ @Mock
+ private PreferenceScreen mPreferenceScreen;
+
+ private ContentResolver mContentResolver;
+ private Context mContext;
+ private final boolean REMINDERS_SETTINGS = true;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ ShadowApplication shadowApplication = ShadowApplication.getInstance();
+ shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNotificationManager);
+
+ mContext = shadowApplication.getApplicationContext();
+ mContentResolver = RuntimeEnvironment.application.getContentResolver();
+ when(mNotificationManager.getNotificationPolicy()).thenReturn(mPolicy);
+
+ mController = new ZenModeRemindersPreferenceController(mContext, mock(Lifecycle.class));
+ ReflectionHelpers.setField(mController, "mBackend", mBackend);
+
+ when(mPreferenceScreen.findPreference(mController.getPreferenceKey())).thenReturn(
+ mockPref);
+ mController.displayPreference(mPreferenceScreen);
+ }
+
+
+ @Test
+ public void updateState_TotalSilence() {
+ Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_NO_INTERRUPTIONS);
+
+ final SwitchPreference mockPref = mock(SwitchPreference.class);
+ mController.updateState(mockPref);
+
+ verify(mockPref).setEnabled(false);
+ verify(mockPref).setChecked(false);
+ }
+
+ @Test
+ public void updateState_AlarmsOnly() {
+ Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_ALARMS);
+
+ final SwitchPreference mockPref = mock(SwitchPreference.class);
+ mController.updateState(mockPref);
+
+ verify(mockPref).setEnabled(false);
+ verify(mockPref).setChecked(false);
+ }
+
+ @Test
+ public void updateState_Priority() {
+ Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_IMPORTANT_INTERRUPTIONS);
+
+ when(mBackend.isPriorityCategoryEnabled(
+ NotificationManager.Policy.PRIORITY_CATEGORY_REMINDERS)).
+ thenReturn(REMINDERS_SETTINGS);
+
+ mController.updateState(mockPref);
+
+ verify(mockPref).setEnabled(true);
+ verify(mockPref).setChecked(REMINDERS_SETTINGS);
+ }
+
+ @Test
+ public void onPreferenceChanged_EnableReminders() {
+ boolean allow = true;
+ mController.onPreferenceChange(mockPref, allow);
+
+ verify(mBackend).saveSoundPolicy(NotificationManager.Policy.PRIORITY_CATEGORY_REMINDERS,
+ allow);
+ }
+
+ @Test
+ public void onPreferenceChanged_DisableReminders() {
+ boolean allow = false;
+ mController.onPreferenceChange(mockPref, allow);
+
+ verify(mBackend).saveSoundPolicy(NotificationManager.Policy.PRIORITY_CATEGORY_REMINDERS,
+ allow);
+ }
+}
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/notification/ZenModeRepeatCallersPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/ZenModeRepeatCallersPreferenceControllerTest.java
new file mode 100644
index 0000000..d4ee9bc
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/ZenModeRepeatCallersPreferenceControllerTest.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.notification;
+
+import static android.provider.Settings.Global.ZEN_MODE;
+import static android.provider.Settings.Global.ZEN_MODE_ALARMS;
+import static android.provider.Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+import static android.provider.Settings.Global.ZEN_MODE_NO_INTERRUPTIONS;
+
+import static junit.framework.Assert.assertEquals;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.NotificationManager;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.provider.Settings;
+import android.support.v14.preference.SwitchPreference;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowApplication;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.util.ReflectionHelpers;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
+public class ZenModeRepeatCallersPreferenceControllerTest {
+ private ZenModeRepeatCallersPreferenceController mController;
+
+ @Mock
+ private ZenModeBackend mBackend;
+ @Mock
+ private NotificationManager mNotificationManager;
+ @Mock
+ private SwitchPreference mockPref;
+ @Mock
+ private NotificationManager.Policy mPolicy;
+ @Mock
+ private PreferenceScreen mPreferenceScreen;
+ private ContentResolver mContentResolver;
+ private Context mContext;
+
+ private final boolean REPEAT_CALLERS_SETTINGS = true;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ ShadowApplication shadowApplication = ShadowApplication.getInstance();
+ shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNotificationManager);
+
+ mContext = shadowApplication.getApplicationContext();
+ mContentResolver = RuntimeEnvironment.application.getContentResolver();
+ when(mNotificationManager.getNotificationPolicy()).thenReturn(mPolicy);
+
+ mController = new ZenModeRepeatCallersPreferenceController(mContext, mock(Lifecycle.class));
+ ReflectionHelpers.setField(mController, "mBackend", mBackend);
+
+ when(mPreferenceScreen.findPreference(mController.getPreferenceKey())).thenReturn(
+ mockPref);
+ mController.displayPreference(mPreferenceScreen);
+ }
+
+ @Test
+ public void updateState_TotalSilence() {
+ Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_NO_INTERRUPTIONS);
+ final SwitchPreference mockPref = mock(SwitchPreference.class);
+ mController.updateState(mockPref);
+
+ verify(mockPref).setEnabled(false);
+ verify(mockPref).setChecked(false);
+ }
+
+ @Test
+ public void updateState_AlarmsOnly() {
+ Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_ALARMS);
+
+ final SwitchPreference mockPref = mock(SwitchPreference.class);
+ mController.updateState(mockPref);
+
+ verify(mockPref).setEnabled(false);
+ verify(mockPref).setChecked(false);
+ }
+
+ @Test
+ public void updateState_Priority() {
+ Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_IMPORTANT_INTERRUPTIONS);
+
+ when(mBackend.isPriorityCategoryEnabled(
+ NotificationManager.Policy.PRIORITY_CATEGORY_REPEAT_CALLERS)).
+ thenReturn(REPEAT_CALLERS_SETTINGS);
+
+ mController.updateState(mockPref);
+
+ verify(mockPref).setEnabled(true);
+ verify(mockPref).setChecked(REPEAT_CALLERS_SETTINGS);
+ }
+
+ @Test
+ public void updateState_Priority_anyCallers() {
+ boolean mockPriorityState = false;
+ Settings.Global.putInt(mContentResolver, ZEN_MODE, ZEN_MODE_IMPORTANT_INTERRUPTIONS);
+ when(mBackend.isPriorityCategoryEnabled(NotificationManager.Policy.PRIORITY_CATEGORY_CALLS))
+ .thenReturn(true);
+ when(mBackend.getPriorityCallSenders()).thenReturn(
+ NotificationManager.Policy.PRIORITY_SENDERS_ANY);
+ when(mBackend.isPriorityCategoryEnabled(
+ NotificationManager.Policy.PRIORITY_CATEGORY_REPEAT_CALLERS))
+ .thenReturn(mockPriorityState);
+
+ mController.updateState(mockPref);
+
+ verify(mockPref).setEnabled(false);
+ verify(mockPref).setChecked(true);
+ }
+
+ @Test
+ public void onPreferenceChanged_EnableRepeatCallers() {
+ boolean allow = true;
+ mController.onPreferenceChange(mockPref, allow);
+
+ verify(mBackend).saveSoundPolicy(
+ NotificationManager.Policy.PRIORITY_CATEGORY_REPEAT_CALLERS, allow);
+ }
+
+ @Test
+ public void onPreferenceChanged_DisableRepeatCallers() {
+ boolean allow = false;
+ mController.onPreferenceChange(mockPref, allow);
+
+ verify(mBackend).saveSoundPolicy(
+ NotificationManager.Policy.PRIORITY_CATEGORY_REPEAT_CALLERS, allow);
+ }
+}
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/notification/ZenModeScheduleRuleSettingsTest.java b/tests/robotests/src/com/android/settings/notification/ZenModeScheduleRuleSettingsTest.java
index f8e5775..89b3f2a 100644
--- a/tests/robotests/src/com/android/settings/notification/ZenModeScheduleRuleSettingsTest.java
+++ b/tests/robotests/src/com/android/settings/notification/ZenModeScheduleRuleSettingsTest.java
@@ -105,11 +105,6 @@
protected Object getSystemService(final String name) {
return null;
}
-
- @Override
- protected void maybeRefreshRules(boolean success, boolean fireChanged) {
- //do nothing
- }
}
}
diff --git a/tests/robotests/src/com/android/settings/notification/ZenModeScreenOffPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/ZenModeScreenOffPreferenceControllerTest.java
new file mode 100644
index 0000000..3fe1eab
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/ZenModeScreenOffPreferenceControllerTest.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.notification;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.NotificationManager;
+import android.content.Context;
+import android.provider.Settings;
+import android.support.v14.preference.SwitchPreference;
+
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowApplication;
+import org.robolectric.util.ReflectionHelpers;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
+public class ZenModeScreenOffPreferenceControllerTest {
+ private ZenModeScreenOffPreferenceController mController;
+
+ @Mock
+ private ZenModeBackend mBackend;
+ @Mock
+ private NotificationManager mNotificationManager;
+ @Mock
+ private SwitchPreference mockPref;
+ @Mock
+ private NotificationManager.Policy mPolicy;
+
+ private Context mContext;
+ private final boolean MOCK_PRIORITY_SCREEN_OFF_SETTING = false;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ ShadowApplication shadowApplication = ShadowApplication.getInstance();
+ shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNotificationManager);
+
+ mContext = shadowApplication.getApplicationContext();
+ when(mNotificationManager.getNotificationPolicy()).thenReturn(mPolicy);
+
+ mController = new ZenModeScreenOffPreferenceController(mContext, mock(Lifecycle.class));
+ ReflectionHelpers.setField(mController, "mBackend", mBackend);
+ }
+
+ @Test
+ public void updateState() {
+ final SwitchPreference mockPref = mock(SwitchPreference.class);
+ when(mBackend.isEffectAllowed(NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_OFF))
+ .thenReturn(MOCK_PRIORITY_SCREEN_OFF_SETTING);
+ mController.updateState(mockPref);
+
+ verify(mockPref).setChecked(MOCK_PRIORITY_SCREEN_OFF_SETTING);
+ }
+
+ @Test
+ public void onPreferenceChanged_EnableScreenOff() {
+ boolean allow = true;
+ mController.onPreferenceChange(mockPref, allow);
+
+ verify(mBackend).saveVisualEffectsPolicy(
+ NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_OFF, allow);
+ }
+
+ @Test
+ public void onPreferenceChanged_DisableScreenOff() {
+ boolean allow = false;
+ mController.onPreferenceChange(mockPref, allow);
+
+ verify(mBackend).saveVisualEffectsPolicy(
+ NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_OFF, allow);
+ }
+}
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/notification/ZenModeScreenOnPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/ZenModeScreenOnPreferenceControllerTest.java
new file mode 100644
index 0000000..24e3ce3
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/notification/ZenModeScreenOnPreferenceControllerTest.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.notification;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.NotificationManager;
+import android.content.Context;
+import android.provider.Settings;
+import android.support.v14.preference.SwitchPreference;
+
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowApplication;
+import org.robolectric.util.ReflectionHelpers;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
+public class ZenModeScreenOnPreferenceControllerTest {
+ private ZenModeScreenOnPreferenceController mController;
+
+ @Mock
+ private ZenModeBackend mBackend;
+ @Mock
+ private NotificationManager mNotificationManager;
+ @Mock
+ private SwitchPreference mockPref;
+ @Mock
+ private NotificationManager.Policy mPolicy;
+
+ private Context mContext;
+ private final boolean MOCK_PRIORITY_SCREEN_ON_SETTING = false;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ ShadowApplication shadowApplication = ShadowApplication.getInstance();
+ shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNotificationManager);
+
+ mContext = shadowApplication.getApplicationContext();
+ when(mNotificationManager.getNotificationPolicy()).thenReturn(mPolicy);
+
+ mController = new ZenModeScreenOnPreferenceController(mContext, mock(Lifecycle.class));
+ ReflectionHelpers.setField(mController, "mBackend", mBackend);
+ }
+
+ @Test
+ public void updateState() {
+ final SwitchPreference mockPref = mock(SwitchPreference.class);
+ when(mBackend.isEffectAllowed(NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_ON))
+ .thenReturn(MOCK_PRIORITY_SCREEN_ON_SETTING);
+ mController.updateState(mockPref);
+
+ verify(mockPref).setChecked(MOCK_PRIORITY_SCREEN_ON_SETTING);
+ }
+
+ @Test
+ public void onPreferenceChanged_EnableScreenOn() {
+ boolean allow = true;
+ mController.onPreferenceChange(mockPref, allow);
+
+ verify(mBackend).saveVisualEffectsPolicy(
+ NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_ON, allow);
+ }
+
+ @Test
+ public void onPreferenceChanged_DisableScreenOn() {
+ boolean allow = false;
+ mController.onPreferenceChange(mockPref, allow);
+
+ verify(mBackend).saveVisualEffectsPolicy(
+ NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_ON, allow);
+ }
+}
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherApBandPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherApBandPreferenceControllerTest.java
index 6832ca8..bb33f93 100644
--- a/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherApBandPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherApBandPreferenceControllerTest.java
@@ -42,7 +42,7 @@
import org.robolectric.annotation.Config;
@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
public class WifiTetherApBandPreferenceControllerTest {
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
diff --git a/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherPasswordPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherPasswordPreferenceControllerTest.java
index a6d536d..044efad 100644
--- a/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherPasswordPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherPasswordPreferenceControllerTest.java
@@ -43,7 +43,7 @@
@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
public class WifiTetherPasswordPreferenceControllerTest {
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
diff --git a/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherPreferenceControllerTest.java
index 9d24e78..44c70f6 100644
--- a/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherPreferenceControllerTest.java
@@ -63,7 +63,7 @@
import java.util.ArrayList;
@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION,
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O,
shadows = {
WifiTetherPreferenceControllerTest.ShadowWifiTetherSettings.class,
WifiTetherPreferenceControllerTest.ShadowWifiTetherSwitchBarController.class,
diff --git a/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherSSIDPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherSSIDPreferenceControllerTest.java
index 1cba30e..e058eed 100644
--- a/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherSSIDPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherSSIDPreferenceControllerTest.java
@@ -42,7 +42,7 @@
import org.robolectric.annotation.Config;
@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
public class WifiTetherSSIDPreferenceControllerTest {
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
diff --git a/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherSettingsTest.java b/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherSettingsTest.java
new file mode 100644
index 0000000..76a8e23
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherSettingsTest.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.wifi.tether;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.net.wifi.WifiConfiguration;
+
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.annotation.Config;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O)
+public class WifiTetherSettingsTest {
+
+ @Test
+ public void ensureWifiConfigHasPassword_shouldGeneratePassword() {
+ WifiConfiguration config = new WifiConfiguration();
+ WifiTetherSettings.ensureWifiConfigHasPassword(config);
+
+ assertThat(config.preSharedKey).isNotEmpty();
+ }
+}
diff --git a/tests/unit/src/com/android/settings/core/UniquePreferenceTest.java b/tests/unit/src/com/android/settings/core/UniquePreferenceTest.java
index 5f3e512..ce3fe01 100644
--- a/tests/unit/src/com/android/settings/core/UniquePreferenceTest.java
+++ b/tests/unit/src/com/android/settings/core/UniquePreferenceTest.java
@@ -33,6 +33,7 @@
import com.android.settings.search.DatabaseIndexingUtils;
import com.android.settings.search.Indexable;
+import com.android.settings.search.SearchIndexableRaw;
import com.android.settings.search.SearchIndexableResources;
import com.android.settings.search.XmlParserUtils;
@@ -64,7 +65,7 @@
"dashboard_tile_placeholder" // This is the placeholder pref for injecting dynamic
// tiles.
- );
+ );
private Context mContext;
@@ -91,13 +92,13 @@
final Set<String> nullKeyClasses = new HashSet<>();
final Set<String> duplicatedKeys = new HashSet<>();
for (Class<?> clazz : SearchIndexableResources.providerValues()) {
- verifyPreferenceIdInXml(uniqueKeys, duplicatedKeys, nullKeyClasses, clazz);
+ verifyPreferenceKeys(uniqueKeys, duplicatedKeys, nullKeyClasses, clazz);
}
if (!nullKeyClasses.isEmpty()) {
final StringBuilder nullKeyErrors = new StringBuilder()
- .append("Each preference must have a key, ")
- .append("the following classes have pref without keys:\n");
+ .append("Each preference/SearchIndexableData must have a key, ")
+ .append("the following classes have null keys:\n");
for (String c : nullKeyClasses) {
nullKeyErrors.append(c).append("\n");
}
@@ -114,7 +115,7 @@
}
}
- private void verifyPreferenceIdInXml(Set<String> uniqueKeys, Set<String> duplicatedKeys,
+ private void verifyPreferenceKeys(Set<String> uniqueKeys, Set<String> duplicatedKeys,
Set<String> nullKeyClasses, Class<?> clazz)
throws IOException, XmlPullParserException, Resources.NotFoundException {
if (clazz == null) {
@@ -123,8 +124,16 @@
final String className = clazz.getName();
final Indexable.SearchIndexProvider provider =
DatabaseIndexingUtils.getSearchIndexProvider(clazz);
+ final List<SearchIndexableRaw> rawsToIndex = provider.getRawDataToIndex(mContext, true);
final List<SearchIndexableResource> resourcesToIndex =
provider.getXmlResourcesToIndex(mContext, true);
+ verifyResources(className, resourcesToIndex, uniqueKeys, duplicatedKeys, nullKeyClasses);
+ verifyRaws(className, rawsToIndex, uniqueKeys, duplicatedKeys, nullKeyClasses);
+ }
+
+ private void verifyResources(String className, List<SearchIndexableResource> resourcesToIndex,
+ Set<String> uniqueKeys, Set<String> duplicatedKeys, Set<String> nullKeyClasses)
+ throws IOException, XmlPullParserException, Resources.NotFoundException {
if (resourcesToIndex == null) {
Log.d(TAG, className + "is not providing SearchIndexableResource, skipping");
return;
@@ -172,4 +181,25 @@
&& (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth));
}
}
+
+ private void verifyRaws(String className, List<SearchIndexableRaw> rawsToIndex,
+ Set<String> uniqueKeys, Set<String> duplicatedKeys, Set<String> nullKeyClasses) {
+ if (rawsToIndex == null) {
+ Log.d(TAG, className + "is not providing SearchIndexableRaw, skipping");
+ return;
+ }
+ for (SearchIndexableRaw raw : rawsToIndex) {
+ if (TextUtils.isEmpty(raw.key)) {
+ Log.e(TAG, "Every SearchIndexableRaw must have an key; found null key"
+ + " in " + className);
+ nullKeyClasses.add(className);
+ continue;
+ }
+ if (uniqueKeys.contains(raw.key) && !WHITELISTED_DUPLICATE_KEYS.contains(raw.key)) {
+ Log.e(TAG, "Every SearchIndexableRaw key must unique; found " + raw.key
+ + " in " + className);
+ duplicatedKeys.add(raw.key);
+ }
+ }
+ }
}