Snap for 4489599 from e677f49328 to pi-release
Change-Id: Iafc4a1036c6b050b2a6424fa3effb73ececbc6e3
This commit is contained in:
35
res/layout/preference_dropdown_material_settings.xml
Normal file
35
res/layout/preference_dropdown_material_settings.xml
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
Copyright (C) 2016 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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Based off frameworks/base/core/res/res/layout/preference_dropdown_material.xml
|
||||||
|
except that icon space in this layout is always reserved -->
|
||||||
|
<FrameLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<Spinner
|
||||||
|
android:id="@+id/spinner"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="@dimen/preference_no_icon_padding_start"
|
||||||
|
android:visibility="invisible" />
|
||||||
|
|
||||||
|
<include layout="@layout/preference_material"/>
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
@@ -6741,6 +6741,9 @@
|
|||||||
<!-- Do not disturb: Title for the zen mode automatic rules page in settings. [CHAR LIMIT=30] -->
|
<!-- Do not disturb: Title for the zen mode automatic rules page in settings. [CHAR LIMIT=30] -->
|
||||||
<string name="zen_mode_automation_settings_page_title">Automatic rules</string>
|
<string name="zen_mode_automation_settings_page_title">Automatic rules</string>
|
||||||
|
|
||||||
|
<!-- Do not disturb: Title for a specific zen mode automatic rule in settings. [CHAR LIMIT=30] -->
|
||||||
|
<string name="zen_mode_automatic_rule_settings_page_title">Automatic rule</string>
|
||||||
|
|
||||||
<!-- Do not disturb: Title for the zen mode automation option Suggestion. [CHAR LIMIT=50] -->
|
<!-- Do not disturb: Title for the zen mode automation option Suggestion. [CHAR LIMIT=50] -->
|
||||||
<string name="zen_mode_automation_suggestion_title">Set Do Not Disturb rules</string>
|
<string name="zen_mode_automation_suggestion_title">Set Do Not Disturb rules</string>
|
||||||
|
|
||||||
|
|||||||
@@ -20,19 +20,19 @@
|
|||||||
<resources>
|
<resources>
|
||||||
|
|
||||||
<!-- Fragment style -->
|
<!-- Fragment style -->
|
||||||
<style name="SettingsPreferenceFragmentStyle" parent="@style/PreferenceFragment.Material">
|
<style name="SettingsPreferenceFragmentStyle" parent="@style/PreferenceFragmentStyle.SettingsBase">
|
||||||
<item name="android:layout">@layout/preference_list_fragment</item>
|
<item name="android:layout">@layout/preference_list_fragment</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="ApnPreference" parent="@style/Preference.Material">
|
<style name="ApnPreference" parent="Preference.SettingsBase">
|
||||||
<item name="android:layout">@layout/apn_preference_layout</item>
|
<item name="android:layout">@layout/apn_preference_layout</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="SettingsSeekBarPreference" parent="@style/Preference.Material">
|
<style name="SettingsSeekBarPreference" parent="Preference.SettingsBase">
|
||||||
<item name="android:layout">@layout/preference_widget_seekbar_settings</item>
|
<item name="android:layout">@layout/preference_widget_seekbar_settings</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="SyncSwitchPreference" parent="@style/Preference.Material">
|
<style name="SyncSwitchPreference" parent="Preference.SettingsBase">
|
||||||
<item name="android:widgetLayout">@layout/preference_widget_sync_toggle</item>
|
<item name="android:widgetLayout">@layout/preference_widget_sync_toggle</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|||||||
@@ -15,8 +15,18 @@
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
<PreferenceScreen
|
||||||
android:key="zen_mode_event_rule_settings" >
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:key="zen_mode_event_rule_settings"
|
||||||
|
android:title="@string/zen_mode_automatic_rule_settings_page_title">
|
||||||
|
|
||||||
|
<com.android.settings.applications.LayoutPreference
|
||||||
|
android:key="pref_app_header"
|
||||||
|
android:layout="@layout/settings_entity_header" />
|
||||||
|
|
||||||
|
<com.android.settings.applications.LayoutPreference
|
||||||
|
android:key="zen_automatic_rule_switch"
|
||||||
|
android:layout="@layout/styled_switch_bar" />
|
||||||
|
|
||||||
<!-- Rule name -->
|
<!-- Rule name -->
|
||||||
<Preference
|
<Preference
|
||||||
@@ -36,10 +46,4 @@
|
|||||||
android:title="@string/zen_mode_event_rule_reply"
|
android:title="@string/zen_mode_event_rule_reply"
|
||||||
android:summary="%s" />
|
android:summary="%s" />
|
||||||
|
|
||||||
<!-- Zen mode -->
|
|
||||||
<DropDownPreference
|
|
||||||
android:key="zen_mode"
|
|
||||||
android:title="@string/zen_mode_settings_title"
|
|
||||||
android:summary="%s" />
|
|
||||||
|
|
||||||
</PreferenceScreen>
|
</PreferenceScreen>
|
||||||
|
|||||||
@@ -15,8 +15,18 @@
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
<PreferenceScreen
|
||||||
android:key="zen_mode_schedule_rule_settings" >
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:key="zen_mode_schedule_rule_settings"
|
||||||
|
android:title="@string/zen_mode_automatic_rule_settings_page_title">
|
||||||
|
|
||||||
|
<com.android.settings.applications.LayoutPreference
|
||||||
|
android:key="pref_app_header"
|
||||||
|
android:layout="@layout/settings_entity_header" />
|
||||||
|
|
||||||
|
<com.android.settings.applications.LayoutPreference
|
||||||
|
android:key="zen_automatic_rule_switch"
|
||||||
|
android:layout="@layout/styled_switch_bar" />
|
||||||
|
|
||||||
<!-- Rule name -->
|
<!-- Rule name -->
|
||||||
<Preference
|
<Preference
|
||||||
@@ -39,11 +49,4 @@
|
|||||||
android:summary="@string/zen_mode_schedule_alarm_summary"
|
android:summary="@string/zen_mode_schedule_alarm_summary"
|
||||||
android:order="99" />
|
android:order="99" />
|
||||||
|
|
||||||
<!-- Zen mode -->
|
|
||||||
<DropDownPreference
|
|
||||||
android:key="zen_mode"
|
|
||||||
android:title="@string/zen_mode_settings_title"
|
|
||||||
android:order="100"
|
|
||||||
android:summary="%s" />
|
|
||||||
|
|
||||||
</PreferenceScreen>
|
</PreferenceScreen>
|
||||||
|
|||||||
@@ -83,15 +83,22 @@ public class DeviceInfoSettings extends DashboardFragment implements Indexable {
|
|||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle icicle) {
|
public void onCreate(Bundle icicle) {
|
||||||
super.onCreate(icicle);
|
super.onCreate(icicle);
|
||||||
|
final Bundle arguments = getArguments();
|
||||||
if (FeatureFlagUtils.isEnabled(getContext(), DEVICE_INFO_V2) || true) {
|
if (FeatureFlagUtils.isEnabled(getContext(), DEVICE_INFO_V2) || true) {
|
||||||
// Increase the number of children when the device contains more than 1 sim.
|
// Do not override initial expand children count if we come from
|
||||||
final TelephonyManager telephonyManager = (TelephonyManager) getSystemService(
|
// search (EXTRA_FRAGMENT_ARG_KEY is set) - we need to display every if entry point
|
||||||
Context.TELEPHONY_SERVICE);
|
// is search.
|
||||||
final int numberOfChildren = Math.max(SIM_PREFERENCES_COUNT,
|
if (arguments == null
|
||||||
SIM_PREFERENCES_COUNT * telephonyManager.getPhoneCount())
|
|| !arguments.containsKey(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY)) {
|
||||||
+ NON_SIM_PREFERENCES_COUNT;
|
|
||||||
getPreferenceScreen().setInitialExpandedChildrenCount(numberOfChildren);
|
// 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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
package com.android.settings.accessibility;
|
package com.android.settings.accessibility;
|
||||||
|
|
||||||
import android.accessibilityservice.AccessibilityServiceInfo;
|
import android.accessibilityservice.AccessibilityServiceInfo;
|
||||||
|
import android.annotation.Nullable;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.ContentResolver;
|
import android.content.ContentResolver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
@@ -27,6 +28,7 @@ import android.support.v7.preference.Preference;
|
|||||||
import android.view.accessibility.AccessibilityManager;
|
import android.view.accessibility.AccessibilityManager;
|
||||||
import android.widget.Switch;
|
import android.widget.Switch;
|
||||||
|
|
||||||
|
import com.android.internal.accessibility.AccessibilityShortcutController;
|
||||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.search.BaseSearchIndexProvider;
|
import com.android.settings.search.BaseSearchIndexProvider;
|
||||||
@@ -87,7 +89,7 @@ public class AccessibilityShortcutPreferenceFragment extends ToggleFeaturePrefer
|
|||||||
super.onInstallSwitchBarToggleSwitch();
|
super.onInstallSwitchBarToggleSwitch();
|
||||||
mSwitchBar.addOnSwitchChangeListener((Switch switchView, boolean enabled) -> {
|
mSwitchBar.addOnSwitchChangeListener((Switch switchView, boolean enabled) -> {
|
||||||
Context context = getContext();
|
Context context = getContext();
|
||||||
if (enabled && (getServiceInfo(context) == null)) {
|
if (enabled && !shortcutFeatureAvailable(context)) {
|
||||||
// If no service is configured, we'll disable the shortcut shortly. Give the
|
// If no service is configured, we'll disable the shortcut shortly. Give the
|
||||||
// user a chance to select a service. We'll update the preferences when we resume.
|
// user a chance to select a service. We'll update the preferences when we resume.
|
||||||
Settings.Secure.putInt(
|
Settings.Secure.putInt(
|
||||||
@@ -110,7 +112,7 @@ public class AccessibilityShortcutPreferenceFragment extends ToggleFeaturePrefer
|
|||||||
ContentResolver cr = getContentResolver();
|
ContentResolver cr = getContentResolver();
|
||||||
Context context = getContext();
|
Context context = getContext();
|
||||||
mServicePreference.setSummary(getServiceName(context));
|
mServicePreference.setSummary(getServiceName(context));
|
||||||
if (getServiceInfo(context) == null) {
|
if (!shortcutFeatureAvailable(context)) {
|
||||||
// If no service is configured, make sure the overall shortcut is turned off
|
// If no service is configured, make sure the overall shortcut is turned off
|
||||||
Settings.Secure.putInt(
|
Settings.Secure.putInt(
|
||||||
getContentResolver(), Settings.Secure.ACCESSIBILITY_SHORTCUT_ENABLED, 0);
|
getContentResolver(), Settings.Secure.ACCESSIBILITY_SHORTCUT_ENABLED, 0);
|
||||||
@@ -132,19 +134,38 @@ public class AccessibilityShortcutPreferenceFragment extends ToggleFeaturePrefer
|
|||||||
* @return The name of the service or a string saying that none is selected.
|
* @return The name of the service or a string saying that none is selected.
|
||||||
*/
|
*/
|
||||||
public static CharSequence getServiceName(Context context) {
|
public static CharSequence getServiceName(Context context) {
|
||||||
|
if (!shortcutFeatureAvailable(context)) {
|
||||||
|
return context.getString(R.string.accessibility_no_service_selected);
|
||||||
|
}
|
||||||
AccessibilityServiceInfo shortcutServiceInfo = getServiceInfo(context);
|
AccessibilityServiceInfo shortcutServiceInfo = getServiceInfo(context);
|
||||||
if (shortcutServiceInfo != null) {
|
if (shortcutServiceInfo != null) {
|
||||||
return shortcutServiceInfo.getResolveInfo().loadLabel(context.getPackageManager());
|
return shortcutServiceInfo.getResolveInfo().loadLabel(context.getPackageManager());
|
||||||
}
|
}
|
||||||
return context.getString(R.string.accessibility_no_service_selected);
|
return AccessibilityShortcutController.getFrameworkShortcutFeaturesMap()
|
||||||
|
.get(getShortcutComponent(context)).getLabel(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static AccessibilityServiceInfo getServiceInfo(Context context) {
|
private static AccessibilityServiceInfo getServiceInfo(Context context) {
|
||||||
ComponentName shortcutServiceName = ComponentName.unflattenFromString(
|
|
||||||
AccessibilityUtils.getShortcutTargetServiceComponentNameString(
|
|
||||||
context, UserHandle.myUserId()));
|
|
||||||
return AccessibilityManager.getInstance(context)
|
return AccessibilityManager.getInstance(context)
|
||||||
.getInstalledServiceInfoWithComponentName(shortcutServiceName);
|
.getInstalledServiceInfoWithComponentName(getShortcutComponent(context));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean shortcutFeatureAvailable(Context context) {
|
||||||
|
ComponentName shortcutFeature = getShortcutComponent(context);
|
||||||
|
if (shortcutFeature == null) return false;
|
||||||
|
|
||||||
|
if (AccessibilityShortcutController.getFrameworkShortcutFeaturesMap()
|
||||||
|
.containsKey(shortcutFeature)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return getServiceInfo(context) != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static @Nullable ComponentName getShortcutComponent(Context context) {
|
||||||
|
String componentNameString = AccessibilityUtils.getShortcutTargetServiceComponentNameString(
|
||||||
|
context, UserHandle.myUserId());
|
||||||
|
if (componentNameString == null) return null;
|
||||||
|
return ComponentName.unflattenFromString(componentNameString);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
|
public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
|
||||||
|
|||||||
@@ -25,29 +25,40 @@ import android.app.Fragment;
|
|||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
|
import android.content.pm.ApplicationInfo;
|
||||||
|
import android.content.pm.ComponentInfo;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
import android.util.IconDrawableFactory;
|
||||||
import android.view.accessibility.AccessibilityManager;
|
import android.view.accessibility.AccessibilityManager;
|
||||||
|
|
||||||
|
import com.android.internal.accessibility.AccessibilityShortcutController;
|
||||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||||
|
import com.android.internal.accessibility.AccessibilityShortcutController.ToggleableFrameworkFeatureInfo;
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.applications.defaultapps.DefaultAppInfo;
|
import com.android.settings.applications.defaultapps.DefaultAppInfo;
|
||||||
import com.android.settings.applications.defaultapps.DefaultAppPickerFragment;
|
import com.android.settings.applications.defaultapps.DefaultAppPickerFragment;
|
||||||
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
|
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
|
||||||
|
import com.android.settings.widget.RadioButtonPickerFragment;
|
||||||
import com.android.settings.widget.RadioButtonPreference;
|
import com.android.settings.widget.RadioButtonPreference;
|
||||||
|
import com.android.settings.wrapper.IPackageManagerWrapper;
|
||||||
import com.android.settingslib.accessibility.AccessibilityUtils;
|
import com.android.settingslib.accessibility.AccessibilityUtils;
|
||||||
|
import com.android.settingslib.wrapper.PackageManagerWrapper;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fragment for picking accessibility shortcut service
|
* Fragment for picking accessibility shortcut service
|
||||||
*/
|
*/
|
||||||
public class ShortcutServicePickerFragment extends DefaultAppPickerFragment {
|
public class ShortcutServicePickerFragment extends RadioButtonPickerFragment {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMetricsCategory() {
|
public int getMetricsCategory() {
|
||||||
@@ -60,22 +71,29 @@ public class ShortcutServicePickerFragment extends DefaultAppPickerFragment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected List<? extends DefaultAppInfo> getCandidates() {
|
protected List<? extends CandidateInfo> getCandidates() {
|
||||||
final Context context = getContext();
|
final Context context = getContext();
|
||||||
|
final PackageManager pm = context.getPackageManager();
|
||||||
final AccessibilityManager accessibilityManager = context
|
final AccessibilityManager accessibilityManager = context
|
||||||
.getSystemService(AccessibilityManager.class);
|
.getSystemService(AccessibilityManager.class);
|
||||||
final List<AccessibilityServiceInfo> installedServices =
|
final List<AccessibilityServiceInfo> installedServices =
|
||||||
accessibilityManager.getInstalledAccessibilityServiceList();
|
accessibilityManager.getInstalledAccessibilityServiceList();
|
||||||
final int numInstalledServices = installedServices.size();
|
final int numInstalledServices = installedServices.size();
|
||||||
|
final PackageManagerWrapper pmw = new PackageManagerWrapper(context.getPackageManager());
|
||||||
|
|
||||||
List<DefaultAppInfo> candidates = new ArrayList<>(numInstalledServices);
|
final List<CandidateInfo> candidates = new ArrayList<>(numInstalledServices);
|
||||||
|
Map<ComponentName, ToggleableFrameworkFeatureInfo> frameworkFeatureInfoMap =
|
||||||
|
AccessibilityShortcutController.getFrameworkShortcutFeaturesMap();
|
||||||
|
for (ComponentName componentName : frameworkFeatureInfoMap.keySet()) {
|
||||||
|
// Lookup icon
|
||||||
|
candidates.add(new FrameworkCandidateInfo(frameworkFeatureInfoMap.get(componentName),
|
||||||
|
R.drawable.empty_icon, componentName.flattenToString()));
|
||||||
|
}
|
||||||
for (int i = 0; i < numInstalledServices; i++) {
|
for (int i = 0; i < numInstalledServices; i++) {
|
||||||
AccessibilityServiceInfo installedServiceInfo = installedServices.get(i);
|
final AccessibilityServiceInfo installedServiceInfo = installedServices.get(i);
|
||||||
candidates.add(new DefaultAppInfo(context, mPm,
|
candidates.add(new DefaultAppInfo(context, pmw, UserHandle.myUserId(),
|
||||||
UserHandle.myUserId(),
|
|
||||||
installedServiceInfo.getComponentName(),
|
installedServiceInfo.getComponentName(),
|
||||||
(String) installedServiceInfo.loadSummary(mPm.getPackageManager()),
|
(String) installedServiceInfo.loadSummary(pm), true /* enabled */));
|
||||||
true /* enabled */));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return candidates;
|
return candidates;
|
||||||
@@ -105,13 +123,21 @@ public class ShortcutServicePickerFragment extends DefaultAppPickerFragment {
|
|||||||
public void onRadioButtonClicked(RadioButtonPreference selected) {
|
public void onRadioButtonClicked(RadioButtonPreference selected) {
|
||||||
final String selectedKey = selected.getKey();
|
final String selectedKey = selected.getKey();
|
||||||
|
|
||||||
final Activity activity = getActivity();
|
|
||||||
if (TextUtils.isEmpty(selectedKey)) {
|
if (TextUtils.isEmpty(selectedKey)) {
|
||||||
super.onRadioButtonClicked(selected);
|
super.onRadioButtonClicked(selected);
|
||||||
} else if (activity != null) {
|
} else {
|
||||||
final DialogFragment fragment = ConfirmationDialogFragment.newInstance(
|
final ComponentName selectedComponent = ComponentName.unflattenFromString(selectedKey);
|
||||||
this, selectedKey);
|
if (AccessibilityShortcutController.getFrameworkShortcutFeaturesMap()
|
||||||
fragment.show(activity.getFragmentManager(), ConfirmationDialogFragment.TAG);
|
.containsKey(selectedComponent)) {
|
||||||
|
// This is a framework feature. It doesn't need to be confirmed.
|
||||||
|
onRadioButtonConfirmed(selectedKey);
|
||||||
|
} else {
|
||||||
|
final Activity activity = getActivity();
|
||||||
|
if (activity != null) {
|
||||||
|
ConfirmationDialogFragment.newInstance(this, selectedKey)
|
||||||
|
.show(activity.getFragmentManager(), ConfirmationDialogFragment.TAG);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,11 +182,40 @@ public class ShortcutServicePickerFragment extends DefaultAppPickerFragment {
|
|||||||
@Override
|
@Override
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
final Fragment fragment = getTargetFragment();
|
final Fragment fragment = getTargetFragment();
|
||||||
if ((which == BUTTON_POSITIVE) && (fragment instanceof DefaultAppPickerFragment)) {
|
if ((which == BUTTON_POSITIVE) && (fragment instanceof ShortcutServicePickerFragment)) {
|
||||||
final Bundle bundle = getArguments();
|
final Bundle bundle = getArguments();
|
||||||
((ShortcutServicePickerFragment) fragment).onServiceConfirmed(
|
((ShortcutServicePickerFragment) fragment).onServiceConfirmed(
|
||||||
bundle.getString(EXTRA_KEY));
|
bundle.getString(EXTRA_KEY));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class FrameworkCandidateInfo extends CandidateInfo {
|
||||||
|
ToggleableFrameworkFeatureInfo mToggleableFrameworkFeatureInfo;
|
||||||
|
int mIconResId;
|
||||||
|
String mKey;
|
||||||
|
|
||||||
|
public FrameworkCandidateInfo(
|
||||||
|
ToggleableFrameworkFeatureInfo frameworkFeatureInfo, int iconResId, String key) {
|
||||||
|
super(true /* enabled */);
|
||||||
|
mToggleableFrameworkFeatureInfo = frameworkFeatureInfo;
|
||||||
|
mIconResId = iconResId;
|
||||||
|
mKey = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CharSequence loadLabel() {
|
||||||
|
return mToggleableFrameworkFeatureInfo.getLabel(getContext());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Drawable loadIcon() {
|
||||||
|
return getContext().getDrawable(mIconResId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getKey() {
|
||||||
|
return mKey;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,18 +16,26 @@
|
|||||||
|
|
||||||
package com.android.settings.deviceinfo;
|
package com.android.settings.deviceinfo;
|
||||||
|
|
||||||
|
import static com.android.settings.deviceinfo.StorageSettings.TAG;
|
||||||
|
|
||||||
import android.app.ActivityManager;
|
import android.app.ActivityManager;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.os.AsyncTask;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.Environment;
|
||||||
import android.os.UserManager;
|
import android.os.UserManager;
|
||||||
import android.os.storage.DiskInfo;
|
import android.os.storage.DiskInfo;
|
||||||
import android.os.storage.VolumeInfo;
|
import android.os.storage.VolumeInfo;
|
||||||
|
import android.util.DebugUtils;
|
||||||
|
import android.util.Log;
|
||||||
import android.widget.CompoundButton;
|
import android.widget.CompoundButton;
|
||||||
import android.widget.CompoundButton.OnCheckedChangeListener;
|
import android.widget.CompoundButton.OnCheckedChangeListener;
|
||||||
import android.widget.RadioButton;
|
import android.widget.RadioButton;
|
||||||
|
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
public class StorageWizardInit extends StorageWizardBase {
|
public class StorageWizardInit extends StorageWizardBase {
|
||||||
private RadioButton mRadioExternal;
|
private RadioButton mRadioExternal;
|
||||||
private RadioButton mRadioInternal;
|
private RadioButton mRadioInternal;
|
||||||
@@ -69,12 +77,15 @@ public class StorageWizardInit extends StorageWizardBase {
|
|||||||
mRadioExternal.setChecked(true);
|
mRadioExternal.setChecked(true);
|
||||||
onNavigateNext();
|
onNavigateNext();
|
||||||
finish();
|
finish();
|
||||||
}
|
} else if (!mIsPermittedToAdopt) {
|
||||||
|
// TODO: Show a message about why this is disabled for guest and
|
||||||
// TODO: Show a message about why this is disabled for guest and that only an admin user
|
// that only an admin user can adopt an sd card.
|
||||||
// can adopt an sd card.
|
|
||||||
if (!mIsPermittedToAdopt) {
|
|
||||||
mRadioInternal.setEnabled(false);
|
mRadioInternal.setEnabled(false);
|
||||||
|
} else if (mVolume != null && mVolume.getType() == VolumeInfo.TYPE_PUBLIC
|
||||||
|
&& mVolume.isMountedReadable()) {
|
||||||
|
// Device is mounted, so classify contents to possibly pick a
|
||||||
|
// recommended default operation.
|
||||||
|
new ClassifyTask().execute(mVolume.getPath());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,4 +132,29 @@ public class StorageWizardInit extends StorageWizardBase {
|
|||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Task that classifies the contents of a mounted storage device, and sets a
|
||||||
|
* recommended default operation based on result.
|
||||||
|
*/
|
||||||
|
public class ClassifyTask extends AsyncTask<File, Void, Integer> {
|
||||||
|
@Override
|
||||||
|
protected Integer doInBackground(File... params) {
|
||||||
|
int classes = Environment.classifyExternalStorageDirectory(params[0]);
|
||||||
|
Log.v(TAG, "Classified " + params[0] + " as "
|
||||||
|
+ DebugUtils.flagsToString(Environment.class, "HAS_", classes));
|
||||||
|
return classes;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPostExecute(Integer classes) {
|
||||||
|
if (classes == 0) {
|
||||||
|
// Empty is strong signal for adopt
|
||||||
|
mRadioInternal.setChecked(true);
|
||||||
|
} else if ((classes & (Environment.HAS_PICTURES | Environment.HAS_DCIM)) != 0) {
|
||||||
|
// Photos is strong signal for portable
|
||||||
|
mRadioExternal.setChecked(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,28 +29,31 @@ import android.service.notification.ConditionProviderService;
|
|||||||
import android.service.notification.ZenModeConfig;
|
import android.service.notification.ZenModeConfig;
|
||||||
import android.support.v7.preference.Preference;
|
import android.support.v7.preference.Preference;
|
||||||
|
|
||||||
|
import com.android.internal.logging.nano.MetricsProto;
|
||||||
import com.android.settings.core.PreferenceControllerMixin;
|
import com.android.settings.core.PreferenceControllerMixin;
|
||||||
import com.android.settingslib.core.AbstractPreferenceController;
|
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
abstract public class AbstractZenModeAutomaticRulePreferenceController extends
|
abstract public class AbstractZenModeAutomaticRulePreferenceController extends
|
||||||
AbstractPreferenceController implements PreferenceControllerMixin {
|
AbstractZenModePreferenceController implements PreferenceControllerMixin {
|
||||||
|
|
||||||
private static final String TAG = "ZenModeAutomaticRule";
|
|
||||||
protected ZenModeBackend mBackend;
|
protected ZenModeBackend mBackend;
|
||||||
protected Fragment mParent;
|
protected Fragment mParent;
|
||||||
protected Set<Map.Entry<String, AutomaticZenRule>> mRules;
|
protected Set<Map.Entry<String, AutomaticZenRule>> mRules;
|
||||||
protected PackageManager mPm;
|
protected PackageManager mPm;
|
||||||
|
private static List<String> mDefaultRuleIds;
|
||||||
|
|
||||||
public AbstractZenModeAutomaticRulePreferenceController(Context context, Fragment parent) {
|
public AbstractZenModeAutomaticRulePreferenceController(Context context, String key, Fragment
|
||||||
super(context);
|
parent, Lifecycle lifecycle) {
|
||||||
|
super(context, key, lifecycle);
|
||||||
mBackend = ZenModeBackend.getInstance(context);
|
mBackend = ZenModeBackend.getInstance(context);
|
||||||
mParent = parent;
|
|
||||||
mPm = mContext.getPackageManager();
|
mPm = mContext.getPackageManager();
|
||||||
|
mParent = parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -59,25 +62,22 @@ abstract public class AbstractZenModeAutomaticRulePreferenceController extends
|
|||||||
mRules = getZenModeRules();
|
mRules = getZenModeRules();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static List<String> getDefaultRuleIds() {
|
||||||
|
if (mDefaultRuleIds == null) {
|
||||||
|
mDefaultRuleIds = ZenModeConfig.DEFAULT_RULE_IDS;
|
||||||
|
}
|
||||||
|
return mDefaultRuleIds;
|
||||||
|
}
|
||||||
|
|
||||||
private Set<Map.Entry<String, AutomaticZenRule>> getZenModeRules() {
|
private Set<Map.Entry<String, AutomaticZenRule>> getZenModeRules() {
|
||||||
Map<String, AutomaticZenRule> ruleMap =
|
Map<String, AutomaticZenRule> ruleMap =
|
||||||
NotificationManager.from(mContext).getAutomaticZenRules();
|
NotificationManager.from(mContext).getAutomaticZenRules();
|
||||||
return ruleMap.entrySet();
|
return ruleMap.entrySet();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void showNameRuleDialog(final ZenRuleInfo ri) {
|
protected void showNameRuleDialog(final ZenRuleInfo ri, Fragment parent) {
|
||||||
new ZenRuleNameDialog(mContext, null, ri.defaultConditionId) {
|
ZenRuleNameDialog.show(parent, null, ri.defaultConditionId, new
|
||||||
@Override
|
RuleNameChangeListener(ri));
|
||||||
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() {
|
protected Map.Entry<String, AutomaticZenRule>[] sortedRules() {
|
||||||
@@ -108,6 +108,13 @@ abstract public class AbstractZenModeAutomaticRulePreferenceController extends
|
|||||||
@Override
|
@Override
|
||||||
public int compare(Map.Entry<String, AutomaticZenRule> lhs,
|
public int compare(Map.Entry<String, AutomaticZenRule> lhs,
|
||||||
Map.Entry<String, AutomaticZenRule> rhs) {
|
Map.Entry<String, AutomaticZenRule> rhs) {
|
||||||
|
// if it's a default rule, should be at the top of automatic rules
|
||||||
|
boolean lhsIsDefaultRule = getDefaultRuleIds().contains(lhs.getKey());
|
||||||
|
boolean rhsIsDefaultRule = getDefaultRuleIds().contains(rhs.getKey());
|
||||||
|
if (lhsIsDefaultRule != rhsIsDefaultRule) {
|
||||||
|
return lhsIsDefaultRule ? -1 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
int byDate = Long.compare(lhs.getValue().getCreationTime(),
|
int byDate = Long.compare(lhs.getValue().getCreationTime(),
|
||||||
rhs.getValue().getCreationTime());
|
rhs.getValue().getCreationTime());
|
||||||
if (byDate != 0) {
|
if (byDate != 0) {
|
||||||
@@ -157,4 +164,26 @@ abstract public class AbstractZenModeAutomaticRulePreferenceController extends
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class RuleNameChangeListener implements ZenRuleNameDialog.PositiveClickListener {
|
||||||
|
ZenRuleInfo mRuleInfo;
|
||||||
|
|
||||||
|
public RuleNameChangeListener(ZenRuleInfo ruleInfo) {
|
||||||
|
mRuleInfo = ruleInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onOk(String ruleName, Fragment parent) {
|
||||||
|
mMetricsFeatureProvider.action(mContext,
|
||||||
|
MetricsProto.MetricsEvent.ACTION_ZEN_MODE_RULE_NAME_CHANGE_OK);
|
||||||
|
AutomaticZenRule rule = new AutomaticZenRule(ruleName, mRuleInfo.serviceComponent,
|
||||||
|
mRuleInfo.defaultConditionId,
|
||||||
|
NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
|
||||||
|
String savedRuleId = mBackend.addZenRule(rule);
|
||||||
|
if (savedRuleId != null) {
|
||||||
|
parent.startActivity(getRuleIntent(mRuleInfo.settingsAction, null,
|
||||||
|
savedRuleId));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,6 +35,8 @@ import android.util.Slog;
|
|||||||
|
|
||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
import com.android.settings.core.PreferenceControllerMixin;
|
import com.android.settings.core.PreferenceControllerMixin;
|
||||||
|
import com.android.settings.core.instrumentation.MetricsFeatureProvider;
|
||||||
|
import com.android.settings.overlay.FeatureFactory;
|
||||||
import com.android.settingslib.core.AbstractPreferenceController;
|
import com.android.settingslib.core.AbstractPreferenceController;
|
||||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||||
import com.android.settingslib.core.lifecycle.LifecycleObserver;
|
import com.android.settingslib.core.lifecycle.LifecycleObserver;
|
||||||
@@ -51,6 +53,7 @@ abstract public class AbstractZenModePreferenceController extends
|
|||||||
private final String KEY;
|
private final String KEY;
|
||||||
final private NotificationManager mNotificationManager;
|
final private NotificationManager mNotificationManager;
|
||||||
protected static ZenModeConfigWrapper mZenModeConfigWrapper;
|
protected static ZenModeConfigWrapper mZenModeConfigWrapper;
|
||||||
|
protected MetricsFeatureProvider mMetricsFeatureProvider;
|
||||||
|
|
||||||
public AbstractZenModePreferenceController(Context context, String key,
|
public AbstractZenModePreferenceController(Context context, String key,
|
||||||
Lifecycle lifecycle) {
|
Lifecycle lifecycle) {
|
||||||
@@ -62,6 +65,9 @@ abstract public class AbstractZenModePreferenceController extends
|
|||||||
KEY = key;
|
KEY = key;
|
||||||
mNotificationManager = (NotificationManager) context.getSystemService(
|
mNotificationManager = (NotificationManager) context.getSystemService(
|
||||||
Context.NOTIFICATION_SERVICE);
|
Context.NOTIFICATION_SERVICE);
|
||||||
|
|
||||||
|
final FeatureFactory featureFactory = FeatureFactory.getFactory(mContext);
|
||||||
|
mMetricsFeatureProvider = featureFactory.getMetricsFeatureProvider();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -0,0 +1,104 @@
|
|||||||
|
/*
|
||||||
|
* 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.android.settings.widget.EntityHeaderController.PREF_KEY_APP_HEADER;
|
||||||
|
|
||||||
|
import android.app.AutomaticZenRule;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.pm.ApplicationInfo;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.support.v14.preference.PreferenceFragment;
|
||||||
|
import android.support.v7.preference.Preference;
|
||||||
|
import android.util.Slog;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import com.android.settings.R;
|
||||||
|
import com.android.settings.applications.LayoutPreference;
|
||||||
|
import com.android.settings.core.PreferenceControllerMixin;
|
||||||
|
import com.android.settings.widget.EntityHeaderController;
|
||||||
|
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||||
|
|
||||||
|
public class ZenAutomaticRuleHeaderPreferenceController extends AbstractZenModePreferenceController
|
||||||
|
implements PreferenceControllerMixin {
|
||||||
|
|
||||||
|
private final String KEY = PREF_KEY_APP_HEADER;
|
||||||
|
private final PreferenceFragment mFragment;
|
||||||
|
private AutomaticZenRule mRule;
|
||||||
|
private EntityHeaderController mController;
|
||||||
|
|
||||||
|
public ZenAutomaticRuleHeaderPreferenceController(Context context, PreferenceFragment fragment,
|
||||||
|
Lifecycle lifecycle) {
|
||||||
|
super(context, PREF_KEY_APP_HEADER, lifecycle);
|
||||||
|
mFragment = fragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPreferenceKey() {
|
||||||
|
return KEY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAvailable() {
|
||||||
|
return mRule != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateState(Preference preference) {
|
||||||
|
if (mRule == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mFragment != null) {
|
||||||
|
LayoutPreference pref = (LayoutPreference) preference;
|
||||||
|
|
||||||
|
if (mController == null) {
|
||||||
|
mController = EntityHeaderController
|
||||||
|
.newInstance(mFragment.getActivity(), mFragment,
|
||||||
|
pref.findViewById(R.id.entity_header));
|
||||||
|
}
|
||||||
|
|
||||||
|
pref = mController.setIcon(getIcon())
|
||||||
|
.setLabel(mRule.getName())
|
||||||
|
.setPackageName(mRule.getOwner().getPackageName())
|
||||||
|
.setUid(mContext.getUserId())
|
||||||
|
.setHasAppInfoLink(false)
|
||||||
|
.setButtonActions(EntityHeaderController.ActionType.ACTION_NONE,
|
||||||
|
EntityHeaderController.ActionType.ACTION_NONE)
|
||||||
|
.done(mFragment.getActivity(), mContext);
|
||||||
|
|
||||||
|
pref.findViewById(R.id.entity_header).setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Drawable getIcon() {
|
||||||
|
try {
|
||||||
|
PackageManager packageManager = mContext.getPackageManager();
|
||||||
|
ApplicationInfo info = packageManager.getApplicationInfo(
|
||||||
|
mRule.getOwner().getPackageName(), 0);
|
||||||
|
return info.loadIcon(packageManager);
|
||||||
|
} catch (PackageManager.NameNotFoundException e) {
|
||||||
|
Slog.w(TAG, "Unable to load icon - PackageManager.NameNotFoundException");
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void onResume(AutomaticZenRule rule) {
|
||||||
|
mRule = rule;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,97 @@
|
|||||||
|
/*
|
||||||
|
* 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.widget.Switch;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import com.android.settings.R;
|
||||||
|
import com.android.settings.applications.LayoutPreference;
|
||||||
|
import com.android.settings.widget.SwitchBar;
|
||||||
|
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||||
|
|
||||||
|
public class ZenAutomaticRuleSwitchPreferenceController extends
|
||||||
|
AbstractZenModeAutomaticRulePreferenceController implements
|
||||||
|
SwitchBar.OnSwitchChangeListener {
|
||||||
|
|
||||||
|
private static final String KEY = "zen_automatic_rule_switch";
|
||||||
|
private AutomaticZenRule mRule;
|
||||||
|
private String mId;
|
||||||
|
private Toast mEnabledToast;
|
||||||
|
private int mToastTextResource;
|
||||||
|
|
||||||
|
public ZenAutomaticRuleSwitchPreferenceController(Context context, Fragment parent,
|
||||||
|
int toastTextResource, Lifecycle lifecycle) {
|
||||||
|
super(context, KEY, parent, lifecycle);
|
||||||
|
mToastTextResource = toastTextResource;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPreferenceKey() {
|
||||||
|
return KEY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAvailable() {
|
||||||
|
return mRule != null && mId != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onResume(AutomaticZenRule rule, String id) {
|
||||||
|
mRule = rule;
|
||||||
|
mId = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateState(Preference preference) {
|
||||||
|
LayoutPreference pref = (LayoutPreference) preference;
|
||||||
|
SwitchBar bar = pref.findViewById(R.id.switch_bar);
|
||||||
|
if (mRule != null) {
|
||||||
|
bar.setChecked(mRule.isEnabled());
|
||||||
|
}
|
||||||
|
if (bar != null) {
|
||||||
|
bar.show();
|
||||||
|
try {
|
||||||
|
bar.addOnSwitchChangeListener(this);
|
||||||
|
} catch (IllegalStateException e) {
|
||||||
|
// an exception is thrown if you try to add the listener twice
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bar.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSwitchChanged(Switch switchView, boolean isChecked) {
|
||||||
|
final boolean enabled = isChecked;
|
||||||
|
if (enabled == mRule.isEnabled()) return;
|
||||||
|
mRule.setEnabled(enabled);
|
||||||
|
mBackend.setZenRule(mId, mRule);
|
||||||
|
if (enabled) {
|
||||||
|
final int toastText = mToastTextResource;
|
||||||
|
if (toastText != 0) {
|
||||||
|
mEnabledToast = Toast.makeText(mContext, toastText, Toast.LENGTH_SHORT);
|
||||||
|
mEnabledToast.show();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (mEnabledToast != null) {
|
||||||
|
mEnabledToast.cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
/*
|
||||||
|
* 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.Dialog;
|
||||||
|
import android.app.Fragment;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import com.android.internal.logging.nano.MetricsProto;
|
||||||
|
import com.android.settings.R;
|
||||||
|
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
|
||||||
|
|
||||||
|
public class ZenDeleteRuleDialog extends InstrumentedDialogFragment {
|
||||||
|
protected static final String TAG = "ZenDeleteRuleDialog";
|
||||||
|
private static final String EXTRA_ZEN_RULE_NAME = "zen_rule_name";
|
||||||
|
private static final String EXTRA_ZEN_RULE_ID = "zen_rule_id";
|
||||||
|
protected static PositiveClickListener mPositiveClickListener;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The interface we expect a listener to implement.
|
||||||
|
*/
|
||||||
|
public interface PositiveClickListener {
|
||||||
|
void onOk(String id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void show(Fragment parent, String ruleName, String id, PositiveClickListener
|
||||||
|
listener) {
|
||||||
|
final Bundle args = new Bundle();
|
||||||
|
args.putString(EXTRA_ZEN_RULE_NAME, ruleName);
|
||||||
|
args.putString(EXTRA_ZEN_RULE_ID, id);
|
||||||
|
mPositiveClickListener = listener;
|
||||||
|
|
||||||
|
ZenDeleteRuleDialog dialog = new ZenDeleteRuleDialog();
|
||||||
|
dialog.setArguments(args);
|
||||||
|
dialog.setTargetFragment(parent, 0);
|
||||||
|
dialog.show(parent.getFragmentManager(), TAG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMetricsCategory() {
|
||||||
|
return MetricsProto.MetricsEvent.NOTIFICATION_ZEN_MODE_DELETE_RULE_DIALOG;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||||
|
Bundle arguments = getArguments();
|
||||||
|
String ruleName = arguments.getString(EXTRA_ZEN_RULE_NAME);
|
||||||
|
String id = arguments.getString(EXTRA_ZEN_RULE_ID);
|
||||||
|
|
||||||
|
final AlertDialog dialog = new AlertDialog.Builder(getContext())
|
||||||
|
.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) {
|
||||||
|
if (arguments != null) {
|
||||||
|
mPositiveClickListener.onOk(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).create();
|
||||||
|
final View messageView = dialog.findViewById(android.R.id.message);
|
||||||
|
if (messageView != null) {
|
||||||
|
messageView.setTextDirection(View.TEXT_DIRECTION_LOCALE);
|
||||||
|
}
|
||||||
|
return dialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -21,6 +21,7 @@ import android.content.Context;
|
|||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.support.v7.preference.Preference;
|
import android.support.v7.preference.Preference;
|
||||||
import android.support.v7.preference.PreferenceScreen;
|
import android.support.v7.preference.PreferenceScreen;
|
||||||
|
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||||
|
|
||||||
import com.android.settings.utils.ZenServiceListing;
|
import com.android.settings.utils.ZenServiceListing;
|
||||||
|
|
||||||
@@ -28,19 +29,18 @@ public class ZenModeAddAutomaticRulePreferenceController extends
|
|||||||
AbstractZenModeAutomaticRulePreferenceController implements
|
AbstractZenModeAutomaticRulePreferenceController implements
|
||||||
Preference.OnPreferenceClickListener {
|
Preference.OnPreferenceClickListener {
|
||||||
|
|
||||||
private final String KEY_ADD_RULE;
|
protected static final String KEY = "zen_mode_add_automatic_rule";
|
||||||
private final ZenServiceListing mZenServiceListing;
|
private final ZenServiceListing mZenServiceListing;
|
||||||
|
|
||||||
public ZenModeAddAutomaticRulePreferenceController(Context context, String key,
|
public ZenModeAddAutomaticRulePreferenceController(Context context, Fragment parent,
|
||||||
Fragment parent, ZenServiceListing serviceListing) {
|
ZenServiceListing serviceListing, Lifecycle lifecycle) {
|
||||||
super(context, parent);
|
super(context, KEY, parent, lifecycle);
|
||||||
KEY_ADD_RULE = key;
|
|
||||||
mZenServiceListing = serviceListing;
|
mZenServiceListing = serviceListing;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getPreferenceKey() {
|
public String getPreferenceKey() {
|
||||||
return KEY_ADD_RULE;
|
return KEY;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -51,25 +51,30 @@ public class ZenModeAddAutomaticRulePreferenceController extends
|
|||||||
@Override
|
@Override
|
||||||
public void displayPreference(PreferenceScreen screen) {
|
public void displayPreference(PreferenceScreen screen) {
|
||||||
super.displayPreference(screen);
|
super.displayPreference(screen);
|
||||||
Preference pref = screen.findPreference(KEY_ADD_RULE);
|
Preference pref = screen.findPreference(KEY);
|
||||||
pref.setPersistent(false);
|
pref.setPersistent(false);
|
||||||
pref.setOnPreferenceClickListener(this);
|
pref.setOnPreferenceClickListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onPreferenceClick(Preference preference) {
|
public boolean onPreferenceClick(Preference preference) {
|
||||||
new ZenRuleSelectionDialog(mContext, mZenServiceListing) {
|
ZenRuleSelectionDialog.show(mContext, mParent, new RuleSelectionListener(),
|
||||||
@Override
|
mZenServiceListing);
|
||||||
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class RuleSelectionListener implements ZenRuleSelectionDialog.PositiveClickListener {
|
||||||
|
public RuleSelectionListener() {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSystemRuleSelected(ZenRuleInfo ri, Fragment parent) {
|
||||||
|
showNameRuleDialog(ri, parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onExternalRuleSelected(ZenRuleInfo ri, Fragment parent) {
|
||||||
|
Intent intent = new Intent().setComponent(ri.configurationActivity);
|
||||||
|
parent.startActivity(intent);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import android.support.v14.preference.SwitchPreference;
|
|||||||
import android.support.v7.preference.Preference;
|
import android.support.v7.preference.Preference;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.android.internal.logging.nano.MetricsProto;
|
||||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||||
|
|
||||||
public class ZenModeAlarmsPreferenceController extends
|
public class ZenModeAlarmsPreferenceController extends
|
||||||
@@ -73,6 +74,9 @@ public class ZenModeAlarmsPreferenceController extends
|
|||||||
if (ZenModeSettingsBase.DEBUG) {
|
if (ZenModeSettingsBase.DEBUG) {
|
||||||
Log.d(TAG, "onPrefChange allowAlarms=" + allowAlarms);
|
Log.d(TAG, "onPrefChange allowAlarms=" + allowAlarms);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mMetricsFeatureProvider.action(mContext, MetricsProto.MetricsEvent.ACTION_ZEN_ALLOW_ALARMS,
|
||||||
|
allowAlarms);
|
||||||
mBackend.saveSoundPolicy(Policy.PRIORITY_CATEGORY_ALARMS, allowAlarms);
|
mBackend.saveSoundPolicy(Policy.PRIORITY_CATEGORY_ALARMS, allowAlarms);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,28 +19,31 @@ package com.android.settings.notification;
|
|||||||
import android.app.AutomaticZenRule;
|
import android.app.AutomaticZenRule;
|
||||||
import android.app.Fragment;
|
import android.app.Fragment;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.support.annotation.VisibleForTesting;
|
||||||
import android.support.v7.preference.Preference;
|
import android.support.v7.preference.Preference;
|
||||||
import android.support.v7.preference.PreferenceCategory;
|
import android.support.v7.preference.PreferenceCategory;
|
||||||
import android.support.v7.preference.PreferenceScreen;
|
import android.support.v7.preference.PreferenceScreen;
|
||||||
|
|
||||||
|
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class ZenModeAutomaticRulesPreferenceController extends
|
public class ZenModeAutomaticRulesPreferenceController extends
|
||||||
AbstractZenModeAutomaticRulePreferenceController {
|
AbstractZenModeAutomaticRulePreferenceController {
|
||||||
|
|
||||||
private final String KEY_AUTOMATIC_RULES;
|
protected static final String KEY = "zen_mode_automatic_rules";
|
||||||
private PreferenceCategory mPreferenceCategory;
|
|
||||||
Map.Entry<String, AutomaticZenRule>[] mSortedRules;
|
|
||||||
|
|
||||||
public ZenModeAutomaticRulesPreferenceController(Context context, String key,
|
@VisibleForTesting
|
||||||
Fragment parent) {
|
protected PreferenceCategory mPreferenceCategory;
|
||||||
super(context, parent);
|
|
||||||
KEY_AUTOMATIC_RULES = key;
|
public ZenModeAutomaticRulesPreferenceController(Context context, Fragment parent, Lifecycle
|
||||||
mSortedRules = sortedRules();
|
lifecycle) {
|
||||||
|
super(context, KEY, parent, lifecycle);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getPreferenceKey() {
|
public String getPreferenceKey() {
|
||||||
return KEY_AUTOMATIC_RULES;
|
return KEY;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -59,40 +62,14 @@ public class ZenModeAutomaticRulesPreferenceController extends
|
|||||||
public void updateState(Preference preference) {
|
public void updateState(Preference preference) {
|
||||||
super.updateState(preference);
|
super.updateState(preference);
|
||||||
|
|
||||||
// no need to update AutomaticRule if a rule was deleted
|
mPreferenceCategory.removeAll();
|
||||||
// (on rule deletion, the preference removes itself from its parent)
|
Map.Entry<String, AutomaticZenRule>[] sortedRules = sortedRules();
|
||||||
int oldRuleLength = mSortedRules.length;
|
for (Map.Entry<String, AutomaticZenRule> sortedRule : sortedRules) {
|
||||||
mSortedRules = sortedRules();
|
ZenRulePreference pref = new ZenRulePreference(mPreferenceCategory.getContext(),
|
||||||
if (!wasRuleDeleted(oldRuleLength)) {
|
sortedRule, mParent, mMetricsFeatureProvider);
|
||||||
updateAutomaticRules();
|
mPreferenceCategory.addPreference(pref);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -28,29 +28,27 @@ import com.android.settings.search.Indexable;
|
|||||||
import com.android.settings.utils.ManagedServiceSettings;
|
import com.android.settings.utils.ManagedServiceSettings;
|
||||||
import com.android.settings.utils.ZenServiceListing;
|
import com.android.settings.utils.ZenServiceListing;
|
||||||
import com.android.settingslib.core.AbstractPreferenceController;
|
import com.android.settingslib.core.AbstractPreferenceController;
|
||||||
|
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class ZenModeAutomationSettings extends ZenModeSettingsBase {
|
public class ZenModeAutomationSettings extends ZenModeSettingsBase {
|
||||||
private static final String KEY_ADD_RULE = "zen_mode_add_automatic_rule";
|
protected final ManagedServiceSettings.Config CONFIG = getConditionProviderConfig();
|
||||||
private static final String KEY_AUTOMATIC_RULES = "zen_mode_automatic_rules";
|
|
||||||
protected static final ManagedServiceSettings.Config CONFIG = getConditionProviderConfig();
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected List<AbstractPreferenceController> getPreferenceControllers(Context context) {
|
protected List<AbstractPreferenceController> getPreferenceControllers(Context context) {
|
||||||
ZenServiceListing serviceListing = new ZenServiceListing(getContext(), CONFIG);
|
ZenServiceListing serviceListing = new ZenServiceListing(getContext(), CONFIG);
|
||||||
serviceListing.reloadApprovedServices();
|
serviceListing.reloadApprovedServices();
|
||||||
return buildPreferenceControllers(context, this, serviceListing);
|
return buildPreferenceControllers(context, this, serviceListing, getLifecycle());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
|
private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
|
||||||
Fragment parent, ZenServiceListing serviceListing) {
|
Fragment parent, ZenServiceListing serviceListing, Lifecycle lifecycle) {
|
||||||
List<AbstractPreferenceController> controllers = new ArrayList<>();
|
List<AbstractPreferenceController> controllers = new ArrayList<>();
|
||||||
controllers.add(new ZenModeAddAutomaticRulePreferenceController(context, KEY_ADD_RULE,
|
controllers.add(new ZenModeAddAutomaticRulePreferenceController(context, parent,
|
||||||
parent, serviceListing));
|
serviceListing, lifecycle));
|
||||||
controllers.add(new ZenModeAutomaticRulesPreferenceController(context,
|
controllers.add(new ZenModeAutomaticRulesPreferenceController(context, parent, lifecycle));
|
||||||
KEY_AUTOMATIC_RULES, parent));
|
|
||||||
|
|
||||||
return controllers;
|
return controllers;
|
||||||
}
|
}
|
||||||
@@ -94,15 +92,15 @@ public class ZenModeAutomationSettings extends ZenModeSettingsBase {
|
|||||||
@Override
|
@Override
|
||||||
public List<String> getNonIndexableKeys(Context context) {
|
public List<String> getNonIndexableKeys(Context context) {
|
||||||
final List<String> keys = super.getNonIndexableKeys(context);
|
final List<String> keys = super.getNonIndexableKeys(context);
|
||||||
keys.add(KEY_ADD_RULE);
|
keys.add(ZenModeAddAutomaticRulePreferenceController.KEY);
|
||||||
keys.add(KEY_AUTOMATIC_RULES);
|
keys.add(ZenModeAutomaticRulesPreferenceController.KEY);
|
||||||
return keys;
|
return keys;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<AbstractPreferenceController> getPreferenceControllers(
|
public List<AbstractPreferenceController> getPreferenceControllers(
|
||||||
Context context) {
|
Context context) {
|
||||||
return buildPreferenceControllers(context, null, null);
|
return buildPreferenceControllers(context, null, null, null);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import android.support.v7.preference.Preference;
|
|||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
|
|
||||||
|
import com.android.internal.logging.nano.MetricsProto;
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.applications.LayoutPreference;
|
import com.android.settings.applications.LayoutPreference;
|
||||||
import com.android.settings.core.PreferenceControllerMixin;
|
import com.android.settings.core.PreferenceControllerMixin;
|
||||||
@@ -57,15 +58,21 @@ public class ZenModeButtonPreferenceController extends AbstractZenModePreference
|
|||||||
if (null == mZenButtonOn) {
|
if (null == mZenButtonOn) {
|
||||||
mZenButtonOn = (Button) ((LayoutPreference) preference)
|
mZenButtonOn = (Button) ((LayoutPreference) preference)
|
||||||
.findViewById(R.id.zen_mode_settings_turn_on_button);
|
.findViewById(R.id.zen_mode_settings_turn_on_button);
|
||||||
mZenButtonOn.setOnClickListener(v ->
|
mZenButtonOn.setOnClickListener(v -> {
|
||||||
mBackend.setZenMode(Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS));
|
mMetricsFeatureProvider.action(mContext,
|
||||||
|
MetricsProto.MetricsEvent.ACTION_ZEN_TOGGLE_DND_BUTTON, true);
|
||||||
|
mBackend.setZenMode(Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (null == mZenButtonOff) {
|
if (null == mZenButtonOff) {
|
||||||
mZenButtonOff = (Button) ((LayoutPreference) preference)
|
mZenButtonOff = (Button) ((LayoutPreference) preference)
|
||||||
.findViewById(R.id.zen_mode_settings_turn_off_button);
|
.findViewById(R.id.zen_mode_settings_turn_off_button);
|
||||||
mZenButtonOff.setOnClickListener(v ->
|
mZenButtonOff.setOnClickListener(v -> {
|
||||||
mBackend.setZenMode(Settings.Global.ZEN_MODE_OFF));
|
mMetricsFeatureProvider.action(mContext,
|
||||||
|
MetricsProto.MetricsEvent.ACTION_ZEN_TOGGLE_DND_BUTTON, false);
|
||||||
|
mBackend.setZenMode(Settings.Global.ZEN_MODE_OFF);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
updateButtons();
|
updateButtons();
|
||||||
|
|||||||
@@ -60,16 +60,6 @@ public class ZenModeEventRuleSettings extends ZenModeRuleSettingsBase {
|
|||||||
return mEvent != null;
|
return mEvent != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String getZenModeDependency() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected int getEnabledToastText() {
|
|
||||||
return R.string.zen_event_rule_enabled_toast;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onResume() {
|
public void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
@@ -89,7 +79,14 @@ public class ZenModeEventRuleSettings extends ZenModeRuleSettingsBase {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected List<AbstractPreferenceController> getPreferenceControllers(Context context) {
|
protected List<AbstractPreferenceController> getPreferenceControllers(Context context) {
|
||||||
return null;
|
List<AbstractPreferenceController> controllers = new ArrayList<>();
|
||||||
|
mHeader = new ZenAutomaticRuleHeaderPreferenceController(context, this,
|
||||||
|
getLifecycle());
|
||||||
|
mSwitch = new ZenAutomaticRuleSwitchPreferenceController(context, this,
|
||||||
|
R.string.zen_event_rule_enabled_toast, getLifecycle());
|
||||||
|
controllers.add(mHeader);
|
||||||
|
controllers.add(mSwitch);
|
||||||
|
return controllers;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void reloadCalendar() {
|
private void reloadCalendar() {
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import android.support.v7.preference.Preference;
|
|||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
|
||||||
|
import com.android.internal.logging.nano.MetricsProto;
|
||||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||||
|
|
||||||
public class ZenModeEventsPreferenceController extends AbstractZenModePreferenceController
|
public class ZenModeEventsPreferenceController extends AbstractZenModePreferenceController
|
||||||
@@ -71,6 +72,8 @@ public class ZenModeEventsPreferenceController extends AbstractZenModePreference
|
|||||||
if (ZenModeSettingsBase.DEBUG) {
|
if (ZenModeSettingsBase.DEBUG) {
|
||||||
Log.d(TAG, "onPrefChange allowEvents=" + allowEvents);
|
Log.d(TAG, "onPrefChange allowEvents=" + allowEvents);
|
||||||
}
|
}
|
||||||
|
mMetricsFeatureProvider.action(mContext, MetricsProto.MetricsEvent.ACTION_ZEN_ALLOW_EVENTS,
|
||||||
|
allowEvents);
|
||||||
mBackend.saveSoundPolicy(Policy.PRIORITY_CATEGORY_EVENTS, allowEvents);
|
mBackend.saveSoundPolicy(Policy.PRIORITY_CATEGORY_EVENTS, allowEvents);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import android.support.v14.preference.SwitchPreference;
|
|||||||
import android.support.v7.preference.Preference;
|
import android.support.v7.preference.Preference;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.android.internal.logging.nano.MetricsProto;
|
||||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||||
|
|
||||||
public class ZenModeRemindersPreferenceController extends AbstractZenModePreferenceController
|
public class ZenModeRemindersPreferenceController extends AbstractZenModePreferenceController
|
||||||
@@ -67,7 +68,11 @@ public class ZenModeRemindersPreferenceController extends AbstractZenModePrefere
|
|||||||
@Override
|
@Override
|
||||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||||
final boolean allowReminders = (Boolean) newValue;
|
final boolean allowReminders = (Boolean) newValue;
|
||||||
if (ZenModeSettingsBase.DEBUG) Log.d(TAG, "onPrefChange allowReminders=" + allowReminders);
|
if (ZenModeSettingsBase.DEBUG) {
|
||||||
|
Log.d(TAG, "onPrefChange allowReminders=" + allowReminders);
|
||||||
|
}
|
||||||
|
mMetricsFeatureProvider.action(mContext,
|
||||||
|
MetricsProto.MetricsEvent.ACTION_ZEN_ALLOW_REMINDERS, allowReminders);
|
||||||
mBackend.saveSoundPolicy(NotificationManager.Policy.PRIORITY_CATEGORY_REMINDERS,
|
mBackend.saveSoundPolicy(NotificationManager.Policy.PRIORITY_CATEGORY_REMINDERS,
|
||||||
allowReminders);
|
allowReminders);
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import android.support.v14.preference.SwitchPreference;
|
|||||||
import android.support.v7.preference.Preference;
|
import android.support.v7.preference.Preference;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.android.internal.logging.nano.MetricsProto;
|
||||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||||
|
|
||||||
public class ZenModeRepeatCallersPreferenceController extends AbstractZenModePreferenceController
|
public class ZenModeRepeatCallersPreferenceController extends AbstractZenModePreferenceController
|
||||||
@@ -77,8 +78,11 @@ public class ZenModeRepeatCallersPreferenceController extends AbstractZenModePre
|
|||||||
@Override
|
@Override
|
||||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||||
final boolean allowRepeatCallers = (Boolean) newValue;
|
final boolean allowRepeatCallers = (Boolean) newValue;
|
||||||
if (ZenModeSettingsBase.DEBUG) Log.d(TAG, "onPrefChange allowRepeatCallers="
|
if (ZenModeSettingsBase.DEBUG) {
|
||||||
+ allowRepeatCallers);
|
Log.d(TAG, "onPrefChange allowRepeatCallers=" + allowRepeatCallers);
|
||||||
|
}
|
||||||
|
mMetricsFeatureProvider.action(mContext,
|
||||||
|
MetricsProto.MetricsEvent.ACTION_ZEN_ALLOW_REPEAT_CALLS, allowRepeatCallers);
|
||||||
mBackend.saveSoundPolicy(Policy.PRIORITY_CATEGORY_REPEAT_CALLERS, allowRepeatCallers);
|
mBackend.saveSoundPolicy(Policy.PRIORITY_CATEGORY_REPEAT_CALLERS, allowRepeatCallers);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,62 +16,43 @@
|
|||||||
|
|
||||||
package com.android.settings.notification;
|
package com.android.settings.notification;
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.app.AlertDialog;
|
|
||||||
import android.app.AutomaticZenRule;
|
import android.app.AutomaticZenRule;
|
||||||
|
import android.app.Fragment;
|
||||||
import android.app.NotificationManager;
|
import android.app.NotificationManager;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
|
||||||
import android.content.DialogInterface.OnClickListener;
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.service.notification.ConditionProviderService;
|
import android.service.notification.ConditionProviderService;
|
||||||
import android.support.v7.preference.DropDownPreference;
|
|
||||||
import android.support.v7.preference.Preference;
|
import android.support.v7.preference.Preference;
|
||||||
import android.support.v7.preference.Preference.OnPreferenceChangeListener;
|
|
||||||
import android.support.v7.preference.Preference.OnPreferenceClickListener;
|
import android.support.v7.preference.Preference.OnPreferenceClickListener;
|
||||||
import android.support.v7.preference.PreferenceScreen;
|
import android.support.v7.preference.PreferenceScreen;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.Menu;
|
|
||||||
import android.view.MenuInflater;
|
|
||||||
import android.view.MenuItem;
|
|
||||||
import android.view.View;
|
|
||||||
import android.widget.Switch;
|
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
import com.android.internal.logging.nano.MetricsProto;
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.SettingsActivity;
|
|
||||||
import com.android.settings.widget.SwitchBar;
|
|
||||||
import com.android.settingslib.core.AbstractPreferenceController;
|
import com.android.settingslib.core.AbstractPreferenceController;
|
||||||
|
|
||||||
import java.util.List;
|
public abstract class ZenModeRuleSettingsBase extends ZenModeSettingsBase {
|
||||||
|
|
||||||
public abstract class ZenModeRuleSettingsBase extends ZenModeSettingsBase
|
|
||||||
implements SwitchBar.OnSwitchChangeListener {
|
|
||||||
protected static final String TAG = ZenModeSettingsBase.TAG;
|
protected static final String TAG = ZenModeSettingsBase.TAG;
|
||||||
protected static final boolean DEBUG = ZenModeSettingsBase.DEBUG;
|
protected static final boolean DEBUG = ZenModeSettingsBase.DEBUG;
|
||||||
|
|
||||||
private static final String KEY_RULE_NAME = "rule_name";
|
private static final String KEY_RULE_NAME = "rule_name";
|
||||||
private static final String KEY_ZEN_MODE = "zen_mode";
|
|
||||||
|
|
||||||
protected Context mContext;
|
protected Context mContext;
|
||||||
protected boolean mDisableListeners;
|
protected boolean mDisableListeners;
|
||||||
protected AutomaticZenRule mRule;
|
protected AutomaticZenRule mRule;
|
||||||
protected String mId;
|
protected String mId;
|
||||||
|
|
||||||
private boolean mDeleting;
|
|
||||||
private Preference mRuleName;
|
private Preference mRuleName;
|
||||||
private SwitchBar mSwitchBar;
|
protected ZenAutomaticRuleHeaderPreferenceController mHeader;
|
||||||
private DropDownPreference mZenMode;
|
protected ZenAutomaticRuleSwitchPreferenceController mSwitch;
|
||||||
private Toast mEnabledToast;
|
|
||||||
|
|
||||||
abstract protected void onCreateInternal();
|
abstract protected void onCreateInternal();
|
||||||
abstract protected boolean setRule(AutomaticZenRule rule);
|
abstract protected boolean setRule(AutomaticZenRule rule);
|
||||||
abstract protected String getZenModeDependency();
|
|
||||||
abstract protected void updateControlsInternal();
|
abstract protected void updateControlsInternal();
|
||||||
abstract protected int getEnabledToastText();
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle icicle) {
|
public void onCreate(Bundle icicle) {
|
||||||
@@ -99,8 +80,6 @@ public abstract class ZenModeRuleSettingsBase extends ZenModeSettingsBase
|
|||||||
|
|
||||||
super.onCreate(icicle);
|
super.onCreate(icicle);
|
||||||
|
|
||||||
setHasOptionsMenu(true);
|
|
||||||
|
|
||||||
onCreateInternal();
|
onCreateInternal();
|
||||||
|
|
||||||
final PreferenceScreen root = getPreferenceScreen();
|
final PreferenceScreen root = getPreferenceScreen();
|
||||||
@@ -112,37 +91,6 @@ public abstract class ZenModeRuleSettingsBase extends ZenModeSettingsBase
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
mZenMode = (DropDownPreference) root.findPreference(KEY_ZEN_MODE);
|
|
||||||
mZenMode.setEntries(new CharSequence[] {
|
|
||||||
getString(R.string.zen_mode_option_important_interruptions),
|
|
||||||
getString(R.string.zen_mode_option_alarms),
|
|
||||||
getString(R.string.zen_mode_option_no_interruptions),
|
|
||||||
});
|
|
||||||
mZenMode.setEntryValues(new CharSequence[] {
|
|
||||||
Integer.toString(NotificationManager.INTERRUPTION_FILTER_PRIORITY),
|
|
||||||
Integer.toString(NotificationManager.INTERRUPTION_FILTER_ALARMS),
|
|
||||||
Integer.toString(NotificationManager.INTERRUPTION_FILTER_NONE),
|
|
||||||
});
|
|
||||||
mZenMode.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
|
|
||||||
@Override
|
|
||||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
|
||||||
if (mDisableListeners) return false;
|
|
||||||
final int zenMode = Integer.parseInt((String) newValue);
|
|
||||||
if (zenMode == mRule.getInterruptionFilter()) return false;
|
|
||||||
if (DEBUG) Log.d(TAG, "onPrefChange zenMode=" + zenMode);
|
|
||||||
mRule.setInterruptionFilter(zenMode);
|
|
||||||
mBackend.setZenRule(mId, mRule);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
mZenMode.setOrder(10); // sort at the bottom of the category
|
|
||||||
mZenMode.setDependency(getZenModeDependency());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected List<AbstractPreferenceController> getPreferenceControllers(Context context) {
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -155,43 +103,39 @@ public abstract class ZenModeRuleSettingsBase extends ZenModeSettingsBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onActivityCreated(Bundle savedInstanceState) {
|
public int getHelpResource() {
|
||||||
super.onActivityCreated(savedInstanceState);
|
return R.string.help_uri_interruptions;
|
||||||
|
|
||||||
final SettingsActivity activity = (SettingsActivity) getActivity();
|
|
||||||
mSwitchBar = activity.getSwitchBar();
|
|
||||||
mSwitchBar.addOnSwitchChangeListener(this);
|
|
||||||
mSwitchBar.show();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
public void onDestroyView() {
|
* Update state of header preference managed by PreferenceController.
|
||||||
super.onDestroyView();
|
*/
|
||||||
mSwitchBar.removeOnSwitchChangeListener(this);
|
protected void updateHeader() {
|
||||||
mSwitchBar.hide();
|
final PreferenceScreen screen = getPreferenceScreen();
|
||||||
|
|
||||||
|
mSwitch.onResume(mRule,mId);
|
||||||
|
mSwitch.displayPreference(screen);
|
||||||
|
updatePreference(mSwitch);
|
||||||
|
|
||||||
|
mHeader.onResume(mRule);
|
||||||
|
mHeader.displayPreference(screen);
|
||||||
|
updatePreference(mHeader);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private void updatePreference(AbstractPreferenceController controller) {
|
||||||
public void onSwitchChanged(Switch switchView, boolean isChecked) {
|
final PreferenceScreen screen = getPreferenceScreen();
|
||||||
if (DEBUG) Log.d(TAG, "onSwitchChanged " + isChecked);
|
if (!controller.isAvailable()) {
|
||||||
if (mDisableListeners) return;
|
return;
|
||||||
final boolean enabled = isChecked;
|
|
||||||
if (enabled == mRule.isEnabled()) return;
|
|
||||||
mMetricsFeatureProvider.action(mContext, MetricsEvent.ACTION_ZEN_ENABLE_RULE, enabled);
|
|
||||||
if (DEBUG) Log.d(TAG, "onSwitchChanged enabled=" + enabled);
|
|
||||||
mRule.setEnabled(enabled);
|
|
||||||
mBackend.setZenRule(mId, mRule);
|
|
||||||
if (enabled) {
|
|
||||||
final int toastText = getEnabledToastText();
|
|
||||||
if (toastText != 0) {
|
|
||||||
mEnabledToast = Toast.makeText(mContext, toastText, Toast.LENGTH_SHORT);
|
|
||||||
mEnabledToast.show();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (mEnabledToast != null) {
|
|
||||||
mEnabledToast.cancel();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
final String key = controller.getPreferenceKey();
|
||||||
|
|
||||||
|
final Preference preference = screen.findPreference(key);
|
||||||
|
if (preference == null) {
|
||||||
|
Log.d(TAG, String.format("Cannot find preference with key %s in Controller %s",
|
||||||
|
key, controller.getClass().getSimpleName()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
controller.updateState(preference);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void updateRule(Uri newConditionId) {
|
protected void updateRule(Uri newConditionId) {
|
||||||
@@ -207,33 +151,6 @@ public abstract class ZenModeRuleSettingsBase extends ZenModeSettingsBase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
|
||||||
if (DEBUG) Log.d(TAG, "onCreateOptionsMenu");
|
|
||||||
inflater.inflate(R.menu.zen_mode_rule, menu);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
|
||||||
if (DEBUG) Log.d(TAG, "onOptionsItemSelected " + item.getItemId());
|
|
||||||
if (item.getItemId() == R.id.delete) {
|
|
||||||
mMetricsFeatureProvider.action(mContext, MetricsEvent.ACTION_ZEN_DELETE_RULE);
|
|
||||||
showDeleteRuleDialog();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return super.onOptionsItemSelected(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void showRuleNameDialog() {
|
|
||||||
new ZenRuleNameDialog(mContext, mRule.getName(), null) {
|
|
||||||
@Override
|
|
||||||
public void onOk(String ruleName) {
|
|
||||||
mRule.setName(ruleName);
|
|
||||||
mBackend.setZenRule(mId, mRule);
|
|
||||||
}
|
|
||||||
}.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean refreshRuleOrFinish() {
|
private boolean refreshRuleOrFinish() {
|
||||||
mRule = getZenRule();
|
mRule = getZenRule();
|
||||||
if (DEBUG) Log.d(TAG, "mRule=" + mRule);
|
if (DEBUG) Log.d(TAG, "mRule=" + mRule);
|
||||||
@@ -244,42 +161,22 @@ public abstract class ZenModeRuleSettingsBase extends ZenModeSettingsBase
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showDeleteRuleDialog() {
|
private void showRuleNameDialog() {
|
||||||
final AlertDialog dialog = new AlertDialog.Builder(mContext)
|
ZenRuleNameDialog.show(this, mRule.getName(), null, new RuleNameChangeListener());
|
||||||
.setMessage(getString(R.string.zen_mode_delete_rule_confirmation, mRule.getName()))
|
|
||||||
.setNegativeButton(R.string.cancel, null)
|
|
||||||
.setPositiveButton(R.string.zen_mode_delete_rule_button, new OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
|
||||||
mMetricsFeatureProvider.action(mContext,
|
|
||||||
MetricsEvent.ACTION_ZEN_DELETE_RULE_OK);
|
|
||||||
mDeleting = true;
|
|
||||||
mBackend.removeZenRule(mId);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.show();
|
|
||||||
final View messageView = dialog.findViewById(android.R.id.message);
|
|
||||||
if (messageView != null) {
|
|
||||||
messageView.setTextDirection(View.TEXT_DIRECTION_LOCALE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void toastAndFinish() {
|
private void toastAndFinish() {
|
||||||
if (!mDeleting) {
|
Toast.makeText(mContext, R.string.zen_mode_rule_not_found_text, Toast.LENGTH_SHORT)
|
||||||
Toast.makeText(mContext, R.string.zen_mode_rule_not_found_text, Toast.LENGTH_SHORT)
|
|
||||||
.show();
|
.show();
|
||||||
}
|
|
||||||
getActivity().finish();
|
getActivity().finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateRuleName() {
|
private void updateRuleName() {
|
||||||
Activity activity = getActivity();
|
if (mRule != null) {
|
||||||
if (activity != null) {
|
|
||||||
activity.setTitle(mRule.getName());
|
|
||||||
mRuleName.setSummary(mRule.getName());
|
mRuleName.setSummary(mRule.getName());
|
||||||
} else {
|
} else {
|
||||||
if (DEBUG) Log.d(TAG, "updateRuleName - activity title and mRuleName "
|
if (DEBUG) Log.d(TAG, "updateRuleName - mRuleName "
|
||||||
+ "not updated; getActivity() returned null");
|
+ "not updated; mRuleName returned null");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -291,10 +188,19 @@ public abstract class ZenModeRuleSettingsBase extends ZenModeSettingsBase
|
|||||||
mDisableListeners = true;
|
mDisableListeners = true;
|
||||||
updateRuleName();
|
updateRuleName();
|
||||||
updateControlsInternal();
|
updateControlsInternal();
|
||||||
mZenMode.setValue(Integer.toString(mRule.getInterruptionFilter()));
|
updateHeader();
|
||||||
if (mSwitchBar != null) {
|
|
||||||
mSwitchBar.setChecked(mRule.isEnabled());
|
|
||||||
}
|
|
||||||
mDisableListeners = false;
|
mDisableListeners = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class RuleNameChangeListener implements ZenRuleNameDialog.PositiveClickListener {
|
||||||
|
public RuleNameChangeListener() {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onOk(String ruleName, Fragment parent) {
|
||||||
|
mMetricsFeatureProvider.action(mContext,
|
||||||
|
MetricsProto.MetricsEvent.ACTION_ZEN_MODE_RULE_NAME_CHANGE_OK);
|
||||||
|
mRule.setName(ruleName);
|
||||||
|
mBackend.setZenRule(mId, mRule);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
|
|||||||
import com.android.settingslib.core.AbstractPreferenceController;
|
import com.android.settingslib.core.AbstractPreferenceController;
|
||||||
|
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -76,21 +77,6 @@ public class ZenModeScheduleRuleSettings extends ZenModeRuleSettingsBase {
|
|||||||
return R.xml.zen_mode_schedule_rule_settings;
|
return R.xml.zen_mode_schedule_rule_settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected List<AbstractPreferenceController> getPreferenceControllers(Context context) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String getZenModeDependency() {
|
|
||||||
return mDays.getKey();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected int getEnabledToastText() {
|
|
||||||
return R.string.zen_schedule_rule_enabled_toast;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreateInternal() {
|
protected void onCreateInternal() {
|
||||||
final PreferenceScreen root = getPreferenceScreen();
|
final PreferenceScreen root = getPreferenceScreen();
|
||||||
@@ -208,6 +194,20 @@ public class ZenModeScheduleRuleSettings extends ZenModeRuleSettingsBase {
|
|||||||
updateEndSummary();
|
updateEndSummary();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected List<AbstractPreferenceController> getPreferenceControllers(Context context) {
|
||||||
|
List<AbstractPreferenceController> controllers = new ArrayList<>();
|
||||||
|
mHeader = new ZenAutomaticRuleHeaderPreferenceController(context, this,
|
||||||
|
getLifecycle());
|
||||||
|
mSwitch = new ZenAutomaticRuleSwitchPreferenceController(context, this,
|
||||||
|
R.string.zen_schedule_rule_enabled_toast, getLifecycle());
|
||||||
|
|
||||||
|
controllers.add(mHeader);
|
||||||
|
controllers.add(mSwitch);
|
||||||
|
return controllers;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMetricsCategory() {
|
public int getMetricsCategory() {
|
||||||
return MetricsEvent.NOTIFICATION_ZEN_MODE_SCHEDULE_RULE;
|
return MetricsEvent.NOTIFICATION_ZEN_MODE_SCHEDULE_RULE;
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import android.support.v14.preference.SwitchPreference;
|
|||||||
import android.support.v7.preference.Preference;
|
import android.support.v7.preference.Preference;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.android.internal.logging.nano.MetricsProto;
|
||||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||||
|
|
||||||
public class ZenModeScreenOffPreferenceController extends
|
public class ZenModeScreenOffPreferenceController extends
|
||||||
@@ -56,8 +57,11 @@ public class ZenModeScreenOffPreferenceController extends
|
|||||||
@Override
|
@Override
|
||||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||||
final boolean bypass = (Boolean) newValue;
|
final boolean bypass = (Boolean) newValue;
|
||||||
if (ZenModeSettingsBase.DEBUG) Log.d(TAG, "onPrefChange allowWhenScreenOff="
|
if (ZenModeSettingsBase.DEBUG) {
|
||||||
+ !bypass);
|
Log.d(TAG, "onPrefChange allowWhenScreenOff=" + bypass);
|
||||||
|
}
|
||||||
|
mMetricsFeatureProvider.action(mContext,
|
||||||
|
MetricsProto.MetricsEvent.ACTION_ZEN_ALLOW_WHEN_SCREEN_OFF, bypass);
|
||||||
mBackend.saveVisualEffectsPolicy(Policy.SUPPRESSED_EFFECT_SCREEN_OFF, bypass);
|
mBackend.saveVisualEffectsPolicy(Policy.SUPPRESSED_EFFECT_SCREEN_OFF, bypass);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import android.support.v14.preference.SwitchPreference;
|
|||||||
import android.support.v7.preference.Preference;
|
import android.support.v7.preference.Preference;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.android.internal.logging.nano.MetricsProto;
|
||||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||||
|
|
||||||
public class ZenModeScreenOnPreferenceController extends
|
public class ZenModeScreenOnPreferenceController extends
|
||||||
@@ -57,8 +58,9 @@ public class ZenModeScreenOnPreferenceController extends
|
|||||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||||
final boolean bypass = (Boolean) newValue;
|
final boolean bypass = (Boolean) newValue;
|
||||||
if (ZenModeSettingsBase.DEBUG) Log.d(TAG, "onPrefChange allowWhenScreenOn="
|
if (ZenModeSettingsBase.DEBUG) Log.d(TAG, "onPrefChange allowWhenScreenOn="
|
||||||
+ !bypass);
|
+ bypass);
|
||||||
|
mMetricsFeatureProvider.action(mContext,
|
||||||
|
MetricsProto.MetricsEvent.ACTION_ZEN_ALLOW_WHEN_SCREEN_ON, bypass);
|
||||||
mBackend.saveVisualEffectsPolicy(Policy.SUPPRESSED_EFFECT_SCREEN_ON, bypass);
|
mBackend.saveVisualEffectsPolicy(Policy.SUPPRESSED_EFFECT_SCREEN_ON, bypass);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,73 +17,103 @@
|
|||||||
package com.android.settings.notification;
|
package com.android.settings.notification;
|
||||||
|
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
|
import android.app.Dialog;
|
||||||
|
import android.app.Fragment;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
import android.os.Bundle;
|
||||||
import android.service.notification.ZenModeConfig;
|
import android.service.notification.ZenModeConfig;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
|
|
||||||
|
import com.android.internal.logging.nano.MetricsProto;
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
|
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
|
||||||
|
|
||||||
public abstract class ZenRuleNameDialog {
|
public class ZenRuleNameDialog extends InstrumentedDialogFragment {
|
||||||
private static final String TAG = "ZenRuleNameDialog";
|
protected static final String TAG = "ZenRuleNameDialog";
|
||||||
private static final boolean DEBUG = ZenModeSettings.DEBUG;
|
private static final String EXTRA_ZEN_RULE_NAME = "zen_rule_name";
|
||||||
|
private static final String EXTRA_CONDITION_ID = "extra_zen_condition_id";
|
||||||
|
protected static PositiveClickListener mPositiveClickListener;
|
||||||
|
|
||||||
private final AlertDialog mDialog;
|
@Override
|
||||||
private final EditText mEditText;
|
public int getMetricsCategory() {
|
||||||
private final CharSequence mOriginalRuleName;
|
return MetricsProto.MetricsEvent.NOTIFICATION_ZEN_MODE_RULE_NAME_DIALOG;
|
||||||
private final boolean mIsNew;
|
}
|
||||||
|
|
||||||
public ZenRuleNameDialog(Context context, CharSequence ruleName, Uri conditionId) {
|
/**
|
||||||
mIsNew = ruleName == null;
|
* The interface we expect a listener to implement.
|
||||||
mOriginalRuleName = ruleName;
|
*/
|
||||||
|
public interface PositiveClickListener {
|
||||||
|
void onOk(String newName, Fragment parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void show(Fragment parent, String ruleName, Uri conditionId, PositiveClickListener
|
||||||
|
listener) {
|
||||||
|
final Bundle args = new Bundle();
|
||||||
|
args.putString(EXTRA_ZEN_RULE_NAME, ruleName);
|
||||||
|
args.putParcelable(EXTRA_CONDITION_ID, conditionId);
|
||||||
|
mPositiveClickListener = listener;
|
||||||
|
|
||||||
|
ZenRuleNameDialog dialog = new ZenRuleNameDialog();
|
||||||
|
dialog.setArguments(args);
|
||||||
|
dialog.setTargetFragment(parent, 0);
|
||||||
|
dialog.show(parent.getFragmentManager(), TAG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||||
|
Bundle arguments = getArguments();
|
||||||
|
Uri conditionId = arguments.getParcelable(EXTRA_CONDITION_ID);
|
||||||
|
String ruleName = arguments.getString(EXTRA_ZEN_RULE_NAME);
|
||||||
|
|
||||||
|
boolean isNew = ruleName == null;
|
||||||
|
CharSequence originalRuleName = ruleName;
|
||||||
|
Context context = getContext();
|
||||||
final View v = LayoutInflater.from(context).inflate(R.layout.zen_rule_name, null,
|
final View v = LayoutInflater.from(context).inflate(R.layout.zen_rule_name, null,
|
||||||
false);
|
false);
|
||||||
mEditText = (EditText) v.findViewById(R.id.zen_mode_rule_name);
|
EditText editText = (EditText) v.findViewById(R.id.zen_mode_rule_name);
|
||||||
if (!mIsNew) {
|
if (!isNew) {
|
||||||
mEditText.setText(ruleName);
|
// set text to current rule name
|
||||||
|
editText.setText(ruleName);
|
||||||
|
// move cursor to end of text
|
||||||
|
editText.setSelection(editText.getText().length());
|
||||||
}
|
}
|
||||||
mEditText.setSelectAllOnFocus(true);
|
editText.setSelectAllOnFocus(true);
|
||||||
mDialog = new AlertDialog.Builder(context)
|
return new AlertDialog.Builder(context)
|
||||||
.setTitle(getTitleResource(conditionId))
|
.setTitle(getTitleResource(conditionId, isNew))
|
||||||
.setView(v)
|
.setView(v)
|
||||||
.setPositiveButton(mIsNew ? R.string.zen_mode_add : R.string.okay,
|
.setPositiveButton(isNew ? R.string.zen_mode_add : R.string.okay,
|
||||||
new DialogInterface.OnClickListener() {
|
new DialogInterface.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
final String newName = trimmedText();
|
final String newName = trimmedText(editText);
|
||||||
if (TextUtils.isEmpty(newName)) {
|
if (TextUtils.isEmpty(newName)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!mIsNew && mOriginalRuleName != null
|
if (!isNew && originalRuleName != null
|
||||||
&& mOriginalRuleName.equals(newName)) {
|
&& originalRuleName.equals(newName)) {
|
||||||
return; // no change to an existing rule, just dismiss
|
return; // no change to an existing rule, just dismiss
|
||||||
}
|
}
|
||||||
onOk(newName);
|
mPositiveClickListener.onOk(newName, getTargetFragment());
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.setNegativeButton(R.string.cancel, null)
|
.setNegativeButton(R.string.cancel, null)
|
||||||
.create();
|
.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract public void onOk(String ruleName);
|
private String trimmedText(EditText editText) {
|
||||||
|
return editText.getText() == null ? null : editText.getText().toString().trim();
|
||||||
public void show() {
|
|
||||||
mDialog.show();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String trimmedText() {
|
private int getTitleResource(Uri conditionId, boolean isNew) {
|
||||||
return mEditText.getText() == null ? null : mEditText.getText().toString().trim();
|
|
||||||
}
|
|
||||||
|
|
||||||
private int getTitleResource(Uri conditionId) {
|
|
||||||
final boolean isEvent = ZenModeConfig.isValidEventConditionId(conditionId);
|
final boolean isEvent = ZenModeConfig.isValidEventConditionId(conditionId);
|
||||||
final boolean isTime = ZenModeConfig.isValidScheduleConditionId(conditionId);
|
final boolean isTime = ZenModeConfig.isValidScheduleConditionId(conditionId);
|
||||||
int titleResource = R.string.zen_mode_rule_name;
|
int titleResource = R.string.zen_mode_rule_name;
|
||||||
if (mIsNew) {
|
if (isNew) {
|
||||||
if (isEvent) {
|
if (isEvent) {
|
||||||
titleResource = R.string.zen_mode_add_event_rule;
|
titleResource = R.string.zen_mode_add_event_rule;
|
||||||
} else if (isTime) {
|
} else if (isTime) {
|
||||||
|
|||||||
@@ -16,23 +16,21 @@
|
|||||||
|
|
||||||
package com.android.settings.notification;
|
package com.android.settings.notification;
|
||||||
|
|
||||||
import android.app.AlertDialog;
|
|
||||||
import android.app.AutomaticZenRule;
|
import android.app.AutomaticZenRule;
|
||||||
import android.app.NotificationManager;
|
import android.app.Fragment;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
|
||||||
import android.content.pm.ApplicationInfo;
|
import android.content.pm.ApplicationInfo;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.pm.ServiceInfo;
|
import android.content.pm.ServiceInfo;
|
||||||
import android.content.res.Resources;
|
|
||||||
import android.service.notification.ZenModeConfig;
|
import android.service.notification.ZenModeConfig;
|
||||||
import android.support.v7.preference.Preference;
|
import android.support.v7.preference.Preference;
|
||||||
import android.support.v7.preference.PreferenceCategory;
|
|
||||||
import android.support.v7.preference.PreferenceViewHolder;
|
import android.support.v7.preference.PreferenceViewHolder;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
|
import com.android.internal.logging.nano.MetricsProto;
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
|
import com.android.settings.core.instrumentation.MetricsFeatureProvider;
|
||||||
import com.android.settings.utils.ManagedServiceSettings;
|
import com.android.settings.utils.ManagedServiceSettings;
|
||||||
import com.android.settings.utils.ZenServiceListing;
|
import com.android.settings.utils.ZenServiceListing;
|
||||||
import com.android.settingslib.TwoTargetPreference;
|
import com.android.settingslib.TwoTargetPreference;
|
||||||
@@ -45,16 +43,17 @@ public class ZenRulePreference extends TwoTargetPreference {
|
|||||||
final CharSequence mName;
|
final CharSequence mName;
|
||||||
final String mId;
|
final String mId;
|
||||||
boolean appExists;
|
boolean appExists;
|
||||||
final PreferenceCategory mParent;
|
final Fragment mParent;
|
||||||
final Preference mPref;
|
final Preference mPref;
|
||||||
final Context mContext;
|
final Context mContext;
|
||||||
final ZenModeBackend mBackend;
|
final ZenModeBackend mBackend;
|
||||||
final ZenServiceListing mServiceListing;
|
final ZenServiceListing mServiceListing;
|
||||||
final PackageManager mPm;
|
final PackageManager mPm;
|
||||||
|
final MetricsFeatureProvider mMetricsFeatureProvider;
|
||||||
|
|
||||||
public ZenRulePreference(Context context,
|
public ZenRulePreference(Context context,
|
||||||
final Map.Entry<String, AutomaticZenRule> ruleEntry,
|
final Map.Entry<String, AutomaticZenRule> ruleEntry,
|
||||||
PreferenceCategory prefCategory) {
|
Fragment parent, MetricsFeatureProvider metricsProvider) {
|
||||||
super(context);
|
super(context);
|
||||||
|
|
||||||
mBackend = ZenModeBackend.getInstance(context);
|
mBackend = ZenModeBackend.getInstance(context);
|
||||||
@@ -62,17 +61,22 @@ public class ZenRulePreference extends TwoTargetPreference {
|
|||||||
final AutomaticZenRule rule = ruleEntry.getValue();
|
final AutomaticZenRule rule = ruleEntry.getValue();
|
||||||
mName = rule.getName();
|
mName = rule.getName();
|
||||||
mId = ruleEntry.getKey();
|
mId = ruleEntry.getKey();
|
||||||
mParent = prefCategory;
|
mParent = parent;
|
||||||
mPm = mContext.getPackageManager();
|
mPm = mContext.getPackageManager();
|
||||||
mServiceListing = new ZenServiceListing(mContext, CONFIG);
|
mServiceListing = new ZenServiceListing(mContext, CONFIG);
|
||||||
mServiceListing.reloadApprovedServices();
|
mServiceListing.reloadApprovedServices();
|
||||||
mPref = this;
|
mPref = this;
|
||||||
|
mMetricsFeatureProvider = metricsProvider;
|
||||||
|
|
||||||
setAttributes(rule);
|
setAttributes(rule);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected int getSecondTargetResId() {
|
protected int getSecondTargetResId() {
|
||||||
|
if (mId != null && ZenModeConfig.DEFAULT_RULE_IDS.contains(mId)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
return R.layout.zen_rule_widget;
|
return R.layout.zen_rule_widget;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,25 +93,21 @@ public class ZenRulePreference extends TwoTargetPreference {
|
|||||||
private final View.OnClickListener mDeleteListener = new View.OnClickListener() {
|
private final View.OnClickListener mDeleteListener = new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
showDeleteRuleDialog(mId, mName, mParent, mPref);
|
showDeleteRuleDialog(mParent, mId, mName.toString());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private void showDeleteRuleDialog(final String ruleId, final CharSequence ruleName,
|
private void showDeleteRuleDialog(final Fragment parent, final String ruleId,
|
||||||
PreferenceCategory parent, Preference pref) {
|
final String ruleName) {
|
||||||
new AlertDialog.Builder(mContext)
|
ZenDeleteRuleDialog.show(parent, ruleName, ruleId,
|
||||||
.setMessage(mContext.getResources().getString(
|
new ZenDeleteRuleDialog.PositiveClickListener() {
|
||||||
R.string.zen_mode_delete_rule_confirmation, ruleName))
|
@Override
|
||||||
.setNegativeButton(R.string.cancel, null)
|
public void onOk(String id) {
|
||||||
.setPositiveButton(R.string.zen_mode_delete_rule_button,
|
mMetricsFeatureProvider.action(mContext,
|
||||||
new DialogInterface.OnClickListener() {
|
MetricsProto.MetricsEvent.ACTION_ZEN_DELETE_RULE_OK);
|
||||||
@Override
|
mBackend.removeZenRule(id);
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
}
|
||||||
mBackend.removeZenRule(ruleId);
|
});
|
||||||
parent.removePreference(pref);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.show();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setAttributes(AutomaticZenRule rule) {
|
protected void setAttributes(AutomaticZenRule rule) {
|
||||||
@@ -141,26 +141,8 @@ public class ZenRulePreference extends TwoTargetPreference {
|
|||||||
|
|
||||||
private String computeRuleSummary(AutomaticZenRule rule, boolean isSystemRule,
|
private String computeRuleSummary(AutomaticZenRule rule, boolean isSystemRule,
|
||||||
CharSequence providerLabel) {
|
CharSequence providerLabel) {
|
||||||
final String mode = computeZenModeCaption(mContext.getResources(),
|
return (rule == null || !rule.isEnabled())
|
||||||
rule.getInterruptionFilter());
|
|
||||||
final String ruleState = (rule == null || !rule.isEnabled())
|
|
||||||
? mContext.getResources().getString(R.string.switch_off_text)
|
? mContext.getResources().getString(R.string.switch_off_text)
|
||||||
: mContext.getResources().getString(
|
: mContext.getResources().getString(R.string.switch_on_text);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -16,16 +16,20 @@
|
|||||||
|
|
||||||
package com.android.settings.notification;
|
package com.android.settings.notification;
|
||||||
|
|
||||||
|
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||||
|
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
|
import android.app.Dialog;
|
||||||
|
import android.app.Fragment;
|
||||||
import android.app.NotificationManager;
|
import android.app.NotificationManager;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.DialogInterface.OnDismissListener;
|
|
||||||
import android.content.pm.ApplicationInfo;
|
import android.content.pm.ApplicationInfo;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.pm.ServiceInfo;
|
import android.content.pm.ServiceInfo;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
|
import android.os.Bundle;
|
||||||
import android.service.notification.ZenModeConfig;
|
import android.service.notification.ZenModeConfig;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
@@ -35,6 +39,7 @@ import android.widget.LinearLayout;
|
|||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
|
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
|
||||||
import com.android.settings.utils.ZenServiceListing;
|
import com.android.settings.utils.ZenServiceListing;
|
||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
@@ -43,24 +48,48 @@ import java.util.Comparator;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
|
|
||||||
public abstract class ZenRuleSelectionDialog {
|
public class ZenRuleSelectionDialog extends InstrumentedDialogFragment {
|
||||||
private static final String TAG = "ZenRuleSelectionDialog";
|
private static final String TAG = "ZenRuleSelectionDialog";
|
||||||
private static final boolean DEBUG = ZenModeSettings.DEBUG;
|
private static final boolean DEBUG = ZenModeSettings.DEBUG;
|
||||||
|
|
||||||
private final Context mContext;
|
private static ZenServiceListing mServiceListing;
|
||||||
private final PackageManager mPm;
|
protected static PositiveClickListener mPositiveClickListener;
|
||||||
private NotificationManager mNm;
|
|
||||||
private final AlertDialog mDialog;
|
|
||||||
private final LinearLayout mRuleContainer;
|
|
||||||
private final ZenServiceListing mServiceListing;
|
|
||||||
|
|
||||||
public ZenRuleSelectionDialog(Context context, ZenServiceListing serviceListing) {
|
private static Context mContext;
|
||||||
|
private static PackageManager mPm;
|
||||||
|
private static NotificationManager mNm;
|
||||||
|
private LinearLayout mRuleContainer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The interface we expect a listener to implement.
|
||||||
|
*/
|
||||||
|
public interface PositiveClickListener {
|
||||||
|
void onSystemRuleSelected(ZenRuleInfo ruleInfo, Fragment parent);
|
||||||
|
void onExternalRuleSelected(ZenRuleInfo ruleInfo, Fragment parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMetricsCategory() {
|
||||||
|
return MetricsEvent.NOTIFICATION_ZEN_MODE_RULE_SELECTION_DIALOG;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void show(Context context, Fragment parent, PositiveClickListener
|
||||||
|
listener, ZenServiceListing serviceListing) {
|
||||||
|
mPositiveClickListener = listener;
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mPm = context.getPackageManager();
|
mPm = mContext.getPackageManager();
|
||||||
mNm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
|
mNm = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||||
mServiceListing = serviceListing;
|
mServiceListing = serviceListing;
|
||||||
final View v =
|
|
||||||
LayoutInflater.from(context).inflate(R.layout.zen_rule_type_selection, null, false);
|
ZenRuleSelectionDialog dialog = new ZenRuleSelectionDialog();
|
||||||
|
dialog.setTargetFragment(parent, 0);
|
||||||
|
dialog.show(parent.getFragmentManager(), TAG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||||
|
final View v = LayoutInflater.from(getContext()).inflate(R.layout.zen_rule_type_selection,
|
||||||
|
null, false);
|
||||||
|
|
||||||
mRuleContainer = (LinearLayout) v.findViewById(R.id.rule_container);
|
mRuleContainer = (LinearLayout) v.findViewById(R.id.rule_container);
|
||||||
if (mServiceListing != null) {
|
if (mServiceListing != null) {
|
||||||
@@ -69,28 +98,21 @@ public abstract class ZenRuleSelectionDialog {
|
|||||||
mServiceListing.addZenCallback(mServiceListingCallback);
|
mServiceListing.addZenCallback(mServiceListingCallback);
|
||||||
mServiceListing.reloadApprovedServices();
|
mServiceListing.reloadApprovedServices();
|
||||||
}
|
}
|
||||||
mDialog = new AlertDialog.Builder(context)
|
return new AlertDialog.Builder(getContext())
|
||||||
.setTitle(R.string.zen_mode_choose_rule_type)
|
.setTitle(R.string.zen_mode_choose_rule_type)
|
||||||
.setView(v)
|
.setView(v)
|
||||||
.setOnDismissListener(new OnDismissListener() {
|
|
||||||
@Override
|
|
||||||
public void onDismiss(DialogInterface dialog) {
|
|
||||||
if (mServiceListing != null) {
|
|
||||||
mServiceListing.removeZenCallback(mServiceListingCallback);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.setNegativeButton(R.string.cancel, null)
|
.setNegativeButton(R.string.cancel, null)
|
||||||
.create();
|
.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void show() {
|
@Override
|
||||||
mDialog.show();
|
public void onDismiss(DialogInterface dialog) {
|
||||||
|
super.onDismiss(dialog);
|
||||||
|
if (mServiceListing != null) {
|
||||||
|
mServiceListing.removeZenCallback(mServiceListingCallback);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract public void onSystemRuleSelected(ZenRuleInfo ruleInfo);
|
|
||||||
abstract public void onExternalRuleSelected(ZenRuleInfo ruleInfo);
|
|
||||||
|
|
||||||
private void bindType(final ZenRuleInfo ri) {
|
private void bindType(final ZenRuleInfo ri) {
|
||||||
try {
|
try {
|
||||||
ApplicationInfo info = mPm.getApplicationInfo(ri.packageName, 0);
|
ApplicationInfo info = mPm.getApplicationInfo(ri.packageName, 0);
|
||||||
@@ -108,11 +130,11 @@ public abstract class ZenRuleSelectionDialog {
|
|||||||
v.setOnClickListener(new View.OnClickListener() {
|
v.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
mDialog.dismiss();
|
dismiss();
|
||||||
if (ri.isSystem) {
|
if (ri.isSystem) {
|
||||||
onSystemRuleSelected(ri);
|
mPositiveClickListener.onSystemRuleSelected(ri, getTargetFragment());
|
||||||
} else {
|
} else {
|
||||||
onExternalRuleSelected(ri);
|
mPositiveClickListener.onExternalRuleSelected(ri, getTargetFragment());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ package com.android.settings;
|
|||||||
|
|
||||||
import static com.android.settings.DeviceInfoSettings.NON_SIM_PREFERENCES_COUNT;
|
import static com.android.settings.DeviceInfoSettings.NON_SIM_PREFERENCES_COUNT;
|
||||||
import static com.android.settings.DeviceInfoSettings.SIM_PREFERENCES_COUNT;
|
import static com.android.settings.DeviceInfoSettings.SIM_PREFERENCES_COUNT;
|
||||||
|
import static com.android.settings.SettingsActivity.EXTRA_FRAGMENT_ARG_KEY;
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.Mockito.doNothing;
|
import static org.mockito.Mockito.doNothing;
|
||||||
@@ -28,6 +29,7 @@ import static org.mockito.Mockito.verify;
|
|||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
|
import android.os.Bundle;
|
||||||
import android.os.SystemProperties;
|
import android.os.SystemProperties;
|
||||||
import android.support.v7.preference.PreferenceScreen;
|
import android.support.v7.preference.PreferenceScreen;
|
||||||
import android.telephony.TelephonyManager;
|
import android.telephony.TelephonyManager;
|
||||||
@@ -118,6 +120,19 @@ public class DeviceInfoSettingsTest {
|
|||||||
assertThat(keys).containsAllIn(niks);
|
assertThat(keys).containsAllIn(niks);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Config(shadows = {SettingsShadowResources.SettingsShadowTheme.class,
|
||||||
|
SettingsShadowSystemProperties.class})
|
||||||
|
public void onCreate_fromSearch_shouldNotOverrideInitialExpandedCount() {
|
||||||
|
final Bundle args = new Bundle();
|
||||||
|
args.putString(EXTRA_FRAGMENT_ARG_KEY, "search_key");
|
||||||
|
mSettings.setArguments(args);
|
||||||
|
|
||||||
|
mSettings.onCreate(null /* icicle */);
|
||||||
|
|
||||||
|
verify(mScreen).setInitialExpandedChildrenCount(Integer.MAX_VALUE);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Config(shadows = {SettingsShadowResources.SettingsShadowTheme.class,
|
@Config(shadows = {SettingsShadowResources.SettingsShadowTheme.class,
|
||||||
SettingsShadowSystemProperties.class})
|
SettingsShadowSystemProperties.class})
|
||||||
|
|||||||
@@ -0,0 +1,191 @@
|
|||||||
|
/*
|
||||||
|
* 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 junit.framework.Assert.assertEquals;
|
||||||
|
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import android.app.AutomaticZenRule;
|
||||||
|
import android.app.Fragment;
|
||||||
|
import android.app.NotificationManager;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.provider.Settings;
|
||||||
|
import android.support.v7.preference.PreferenceCategory;
|
||||||
|
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.Mock;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
|
import org.robolectric.RuntimeEnvironment;
|
||||||
|
import org.robolectric.annotation.Config;
|
||||||
|
import org.robolectric.shadows.ShadowApplication;
|
||||||
|
import org.robolectric.util.ReflectionHelpers;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@RunWith(SettingsRobolectricTestRunner.class)
|
||||||
|
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
|
||||||
|
public class ZenModeAutomaticRulesPreferenceControllerTest {
|
||||||
|
private ZenModeAutomaticRulesPreferenceController mController;
|
||||||
|
private final String GENERIC_RULE_NAME = "test";
|
||||||
|
final String DEFAULT_ID_1 = "DEFAULT_1";
|
||||||
|
final String DEFAULT_ID_2 = "DEFAULT_2";
|
||||||
|
private final List<String> mDefaultIds = Arrays.asList(DEFAULT_ID_1, DEFAULT_ID_2);
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private ZenModeBackend mBackend;
|
||||||
|
@Mock
|
||||||
|
private NotificationManager mNotificationManager;
|
||||||
|
@Mock
|
||||||
|
private PreferenceCategory mockPref;
|
||||||
|
@Mock
|
||||||
|
private NotificationManager.Policy mPolicy;
|
||||||
|
@Mock
|
||||||
|
private PreferenceScreen mPreferenceScreen;
|
||||||
|
|
||||||
|
private Context mContext;
|
||||||
|
|
||||||
|
@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 ZenModeAutomaticRulesPreferenceController(mContext, mock(Fragment.class),
|
||||||
|
mock(Lifecycle.class));
|
||||||
|
|
||||||
|
ReflectionHelpers.setField(mController, "mBackend", mBackend);
|
||||||
|
ReflectionHelpers.setField(mController, "DEFAULT_RULE_IDS", mDefaultIds);
|
||||||
|
|
||||||
|
when(mPreferenceScreen.findPreference(mController.getPreferenceKey())).thenReturn(
|
||||||
|
mockPref);
|
||||||
|
mController.displayPreference(mPreferenceScreen);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void updateState_checkRuleOrderingDescending() {
|
||||||
|
final int NUM_RULES = 4;
|
||||||
|
when(mNotificationManager.getAutomaticZenRules()).thenReturn(
|
||||||
|
mockAutoZenRulesDecreasingCreationTime(NUM_RULES));
|
||||||
|
|
||||||
|
Map.Entry<String, AutomaticZenRule>[] rules = mController.sortedRules();
|
||||||
|
assertEquals(NUM_RULES, rules.length);
|
||||||
|
|
||||||
|
// check ordering, most recent should be at the bottom/end (ie higher creation time)
|
||||||
|
for (int i = 0; i < NUM_RULES; i++) {
|
||||||
|
assertEquals(GENERIC_RULE_NAME + (NUM_RULES - 1 - i), rules[i].getKey());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void updateState_checkRuleOrderingAscending() {
|
||||||
|
final int NUM_RULES = 4;
|
||||||
|
when(mNotificationManager.getAutomaticZenRules()).thenReturn(
|
||||||
|
mockAutoZenRulesAscendingCreationTime(NUM_RULES));
|
||||||
|
|
||||||
|
Map.Entry<String, AutomaticZenRule>[] rules = mController.sortedRules();
|
||||||
|
assertEquals(NUM_RULES, rules.length);
|
||||||
|
|
||||||
|
// check ordering, most recent should be at the bottom/end (ie higher creation time)
|
||||||
|
for (int i = 0; i < NUM_RULES; i++) {
|
||||||
|
assertEquals(GENERIC_RULE_NAME + i, rules[i].getKey());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void updateState_checkRuleOrderingDescending_withDefaultRules() {
|
||||||
|
final int NUM_RULES = 4;
|
||||||
|
|
||||||
|
Map<String, AutomaticZenRule> ruleMap = mockAutoZenRulesDecreasingCreationTime(NUM_RULES);
|
||||||
|
ruleMap.put(DEFAULT_ID_2, new AutomaticZenRule("DEFAULT_1_NAME", null,
|
||||||
|
null, Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, true, 20));
|
||||||
|
ruleMap.put(DEFAULT_ID_1, new AutomaticZenRule("DEFAULT_1_NAME", null,
|
||||||
|
null, Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, true, 10));
|
||||||
|
when(mNotificationManager.getAutomaticZenRules()).thenReturn(ruleMap);
|
||||||
|
|
||||||
|
Map.Entry<String, AutomaticZenRule>[] rules = mController.sortedRules();
|
||||||
|
assertEquals(NUM_RULES + 2, rules.length);
|
||||||
|
|
||||||
|
assertEquals(rules[0].getKey(), DEFAULT_ID_1);
|
||||||
|
assertEquals(rules[1].getKey(), DEFAULT_ID_2);
|
||||||
|
// NON-DEFAULT RULES check ordering, most recent at the bottom/end
|
||||||
|
for (int i = 0; i < NUM_RULES; i++) {
|
||||||
|
assertEquals(GENERIC_RULE_NAME + (NUM_RULES - 1 - i), rules[i + 2].getKey());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void updateState_checkRuleOrderingMix() {
|
||||||
|
final int NUM_RULES = 4;
|
||||||
|
// map with creation times: 0, 2, 4, 6
|
||||||
|
Map<String,AutomaticZenRule> rMap = mockAutoZenRulesAscendingCreationTime(NUM_RULES);
|
||||||
|
|
||||||
|
final String insertedRule1 = "insertedRule1";
|
||||||
|
rMap.put(insertedRule1, new AutomaticZenRule(insertedRule1, null, null,
|
||||||
|
Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, true, 5));
|
||||||
|
|
||||||
|
final String insertedRule2 = "insertedRule2";
|
||||||
|
rMap.put(insertedRule2, new AutomaticZenRule(insertedRule2, null, null,
|
||||||
|
Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, true, 3));
|
||||||
|
|
||||||
|
// rule map with rule creation times, 0, 2, 4, 6, 5, 3
|
||||||
|
// sort should create ordering based on creation times: 0, 2, 3, 4, 5, 6
|
||||||
|
when(mNotificationManager.getAutomaticZenRules()).thenReturn(rMap);
|
||||||
|
|
||||||
|
Map.Entry<String, AutomaticZenRule>[] rules = mController.sortedRules();
|
||||||
|
assertEquals(NUM_RULES + 2, rules.length); // inserted 2 rules
|
||||||
|
|
||||||
|
// check ordering of inserted rules
|
||||||
|
assertEquals(insertedRule1, rules[4].getKey());
|
||||||
|
assertEquals(insertedRule2, rules[2].getKey());
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, AutomaticZenRule> mockAutoZenRulesAscendingCreationTime(int numRules) {
|
||||||
|
Map<String, AutomaticZenRule> ruleMap = new HashMap<>();
|
||||||
|
|
||||||
|
for (int i = 0; i < numRules; i++) {
|
||||||
|
ruleMap.put(GENERIC_RULE_NAME + i, new AutomaticZenRule(GENERIC_RULE_NAME + i, null,
|
||||||
|
null, Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, true, i * 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
return ruleMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, AutomaticZenRule> mockAutoZenRulesDecreasingCreationTime(int numRules) {
|
||||||
|
Map<String, AutomaticZenRule> ruleMap = new HashMap<>();
|
||||||
|
|
||||||
|
for (int i = 0; i < numRules; i++) {
|
||||||
|
ruleMap.put(GENERIC_RULE_NAME + i, new AutomaticZenRule(GENERIC_RULE_NAME + i, null,
|
||||||
|
null, Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, true, numRules - i));
|
||||||
|
}
|
||||||
|
|
||||||
|
return ruleMap;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user