Updates to automatic rule pages in Settings
- Re-added metrics for zen behavior preference controllers - Dialogs in zen mode settings are rotate-friendly - Automatic rules are refreshed on update state - User-created (and default) automatic rules are always priority only and user cannot change this - Automatic rules redesigned to have headers Test: make ROBOTEST_FILTER=ZenModeAutomaticRulesPreferenceControllerTest RunSettingsRoboTests -j40 Bug: 63077372 Fixes: 68324465 Fixes: 69057696 Change-Id: I163acef2715dd4e60bfc08207f0e22352c4c0e28
This commit is contained in:
@@ -6741,6 +6741,9 @@
|
||||
<!-- 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>
|
||||
|
||||
<!-- 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] -->
|
||||
<string name="zen_mode_automation_suggestion_title">Set Do Not Disturb rules</string>
|
||||
|
||||
|
@@ -15,8 +15,18 @@
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:key="zen_mode_event_rule_settings" >
|
||||
<PreferenceScreen
|
||||
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 -->
|
||||
<Preference
|
||||
@@ -36,10 +46,4 @@
|
||||
android:title="@string/zen_mode_event_rule_reply"
|
||||
android:summary="%s" />
|
||||
|
||||
<!-- Zen mode -->
|
||||
<DropDownPreference
|
||||
android:key="zen_mode"
|
||||
android:title="@string/zen_mode_settings_title"
|
||||
android:summary="%s" />
|
||||
|
||||
</PreferenceScreen>
|
||||
|
@@ -15,8 +15,18 @@
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:key="zen_mode_schedule_rule_settings" >
|
||||
<PreferenceScreen
|
||||
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 -->
|
||||
<Preference
|
||||
@@ -39,11 +49,4 @@
|
||||
android:summary="@string/zen_mode_schedule_alarm_summary"
|
||||
android:order="99" />
|
||||
|
||||
<!-- Zen mode -->
|
||||
<DropDownPreference
|
||||
android:key="zen_mode"
|
||||
android:title="@string/zen_mode_settings_title"
|
||||
android:order="100"
|
||||
android:summary="%s" />
|
||||
|
||||
</PreferenceScreen>
|
||||
|
@@ -29,8 +29,9 @@ import android.service.notification.ConditionProviderService;
|
||||
import android.service.notification.ZenModeConfig;
|
||||
import android.support.v7.preference.Preference;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
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.Comparator;
|
||||
@@ -38,19 +39,19 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
abstract public class AbstractZenModeAutomaticRulePreferenceController extends
|
||||
AbstractPreferenceController implements PreferenceControllerMixin {
|
||||
AbstractZenModePreferenceController implements PreferenceControllerMixin {
|
||||
|
||||
private static final String TAG = "ZenModeAutomaticRule";
|
||||
protected ZenModeBackend mBackend;
|
||||
protected Fragment mParent;
|
||||
protected Set<Map.Entry<String, AutomaticZenRule>> mRules;
|
||||
protected PackageManager mPm;
|
||||
|
||||
public AbstractZenModeAutomaticRulePreferenceController(Context context, Fragment parent) {
|
||||
super(context);
|
||||
public AbstractZenModeAutomaticRulePreferenceController(Context context, String key, Fragment
|
||||
parent, Lifecycle lifecycle) {
|
||||
super(context, key, lifecycle);
|
||||
mBackend = ZenModeBackend.getInstance(context);
|
||||
mParent = parent;
|
||||
mPm = mContext.getPackageManager();
|
||||
mParent = parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -65,19 +66,9 @@ abstract public class AbstractZenModeAutomaticRulePreferenceController extends
|
||||
return ruleMap.entrySet();
|
||||
}
|
||||
|
||||
protected void showNameRuleDialog(final ZenRuleInfo ri) {
|
||||
new ZenRuleNameDialog(mContext, null, ri.defaultConditionId) {
|
||||
@Override
|
||||
public void onOk(String ruleName) {
|
||||
AutomaticZenRule rule = new AutomaticZenRule(ruleName, ri.serviceComponent,
|
||||
ri.defaultConditionId, NotificationManager.INTERRUPTION_FILTER_PRIORITY,
|
||||
true);
|
||||
String savedRuleId = mBackend.addZenRule(rule);
|
||||
if (savedRuleId != null) {
|
||||
mParent.startActivity(getRuleIntent(ri.settingsAction, null, savedRuleId));
|
||||
}
|
||||
}
|
||||
}.show();
|
||||
protected void showNameRuleDialog(final ZenRuleInfo ri, Fragment parent) {
|
||||
ZenRuleNameDialog.show(parent, null, ri.defaultConditionId, new
|
||||
RuleNameChangeListener(ri));
|
||||
}
|
||||
|
||||
protected Map.Entry<String, AutomaticZenRule>[] sortedRules() {
|
||||
@@ -157,4 +148,26 @@ abstract public class AbstractZenModeAutomaticRulePreferenceController extends
|
||||
}
|
||||
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.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.lifecycle.Lifecycle;
|
||||
import com.android.settingslib.core.lifecycle.LifecycleObserver;
|
||||
@@ -51,6 +53,7 @@ abstract public class AbstractZenModePreferenceController extends
|
||||
private final String KEY;
|
||||
final private NotificationManager mNotificationManager;
|
||||
protected static ZenModeConfigWrapper mZenModeConfigWrapper;
|
||||
protected MetricsFeatureProvider mMetricsFeatureProvider;
|
||||
|
||||
public AbstractZenModePreferenceController(Context context, String key,
|
||||
Lifecycle lifecycle) {
|
||||
@@ -62,6 +65,9 @@ abstract public class AbstractZenModePreferenceController extends
|
||||
KEY = key;
|
||||
mNotificationManager = (NotificationManager) context.getSystemService(
|
||||
Context.NOTIFICATION_SERVICE);
|
||||
|
||||
final FeatureFactory featureFactory = FeatureFactory.getFactory(mContext);
|
||||
mMetricsFeatureProvider = featureFactory.getMetricsFeatureProvider();
|
||||
}
|
||||
|
||||
@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.support.v7.preference.Preference;
|
||||
import android.support.v7.preference.PreferenceScreen;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
|
||||
import com.android.settings.utils.ZenServiceListing;
|
||||
|
||||
@@ -28,19 +29,18 @@ public class ZenModeAddAutomaticRulePreferenceController extends
|
||||
AbstractZenModeAutomaticRulePreferenceController implements
|
||||
Preference.OnPreferenceClickListener {
|
||||
|
||||
private final String KEY_ADD_RULE;
|
||||
protected static final String KEY = "zen_mode_add_automatic_rule";
|
||||
private final ZenServiceListing mZenServiceListing;
|
||||
|
||||
public ZenModeAddAutomaticRulePreferenceController(Context context, String key,
|
||||
Fragment parent, ZenServiceListing serviceListing) {
|
||||
super(context, parent);
|
||||
KEY_ADD_RULE = key;
|
||||
public ZenModeAddAutomaticRulePreferenceController(Context context, Fragment parent,
|
||||
ZenServiceListing serviceListing, Lifecycle lifecycle) {
|
||||
super(context, KEY, parent, lifecycle);
|
||||
mZenServiceListing = serviceListing;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreferenceKey() {
|
||||
return KEY_ADD_RULE;
|
||||
return KEY;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -51,25 +51,30 @@ public class ZenModeAddAutomaticRulePreferenceController extends
|
||||
@Override
|
||||
public void displayPreference(PreferenceScreen screen) {
|
||||
super.displayPreference(screen);
|
||||
Preference pref = screen.findPreference(KEY_ADD_RULE);
|
||||
Preference pref = screen.findPreference(KEY);
|
||||
pref.setPersistent(false);
|
||||
pref.setOnPreferenceClickListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceClick(Preference preference) {
|
||||
new ZenRuleSelectionDialog(mContext, mZenServiceListing) {
|
||||
@Override
|
||||
public void onSystemRuleSelected(ZenRuleInfo ri) {
|
||||
showNameRuleDialog(ri);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onExternalRuleSelected(ZenRuleInfo ri) {
|
||||
Intent intent = new Intent().setComponent(ri.configurationActivity);
|
||||
mParent.startActivity(intent);
|
||||
}
|
||||
}.show();
|
||||
ZenRuleSelectionDialog.show(mContext, mParent, new RuleSelectionListener(),
|
||||
mZenServiceListing);
|
||||
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.util.Log;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
|
||||
public class ZenModeAlarmsPreferenceController extends
|
||||
@@ -73,6 +74,9 @@ public class ZenModeAlarmsPreferenceController extends
|
||||
if (ZenModeSettingsBase.DEBUG) {
|
||||
Log.d(TAG, "onPrefChange allowAlarms=" + allowAlarms);
|
||||
}
|
||||
|
||||
mMetricsFeatureProvider.action(mContext, MetricsProto.MetricsEvent.ACTION_ZEN_ALLOW_ALARMS,
|
||||
allowAlarms);
|
||||
mBackend.saveSoundPolicy(Policy.PRIORITY_CATEGORY_ALARMS, allowAlarms);
|
||||
return true;
|
||||
}
|
||||
|
@@ -19,28 +19,31 @@ package com.android.settings.notification;
|
||||
import android.app.AutomaticZenRule;
|
||||
import android.app.Fragment;
|
||||
import android.content.Context;
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.support.v7.preference.PreferenceCategory;
|
||||
import android.support.v7.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class ZenModeAutomaticRulesPreferenceController extends
|
||||
AbstractZenModeAutomaticRulePreferenceController {
|
||||
|
||||
private final String KEY_AUTOMATIC_RULES;
|
||||
private PreferenceCategory mPreferenceCategory;
|
||||
Map.Entry<String, AutomaticZenRule>[] mSortedRules;
|
||||
protected static final String KEY = "zen_mode_automatic_rules";
|
||||
|
||||
public ZenModeAutomaticRulesPreferenceController(Context context, String key,
|
||||
Fragment parent) {
|
||||
super(context, parent);
|
||||
KEY_AUTOMATIC_RULES = key;
|
||||
mSortedRules = sortedRules();
|
||||
@VisibleForTesting
|
||||
protected PreferenceCategory mPreferenceCategory;
|
||||
|
||||
public ZenModeAutomaticRulesPreferenceController(Context context, Fragment parent, Lifecycle
|
||||
lifecycle) {
|
||||
super(context, KEY, parent, lifecycle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreferenceKey() {
|
||||
return KEY_AUTOMATIC_RULES;
|
||||
return KEY;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -59,40 +62,14 @@ public class ZenModeAutomaticRulesPreferenceController extends
|
||||
public void updateState(Preference preference) {
|
||||
super.updateState(preference);
|
||||
|
||||
// no need to update AutomaticRule if a rule was deleted
|
||||
// (on rule deletion, the preference removes itself from its parent)
|
||||
int oldRuleLength = mSortedRules.length;
|
||||
mSortedRules = sortedRules();
|
||||
if (!wasRuleDeleted(oldRuleLength)) {
|
||||
updateAutomaticRules();
|
||||
mPreferenceCategory.removeAll();
|
||||
Map.Entry<String, AutomaticZenRule>[] sortedRules = sortedRules();
|
||||
for (Map.Entry<String, AutomaticZenRule> sortedRule : sortedRules) {
|
||||
ZenRulePreference pref = new ZenRulePreference(mPreferenceCategory.getContext(),
|
||||
sortedRule, mParent, mMetricsFeatureProvider);
|
||||
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.ZenServiceListing;
|
||||
import com.android.settingslib.core.AbstractPreferenceController;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ZenModeAutomationSettings extends ZenModeSettingsBase {
|
||||
private static final String KEY_ADD_RULE = "zen_mode_add_automatic_rule";
|
||||
private static final String KEY_AUTOMATIC_RULES = "zen_mode_automatic_rules";
|
||||
protected static final ManagedServiceSettings.Config CONFIG = getConditionProviderConfig();
|
||||
protected final ManagedServiceSettings.Config CONFIG = getConditionProviderConfig();
|
||||
|
||||
@Override
|
||||
protected List<AbstractPreferenceController> getPreferenceControllers(Context context) {
|
||||
ZenServiceListing serviceListing = new ZenServiceListing(getContext(), CONFIG);
|
||||
serviceListing.reloadApprovedServices();
|
||||
return buildPreferenceControllers(context, this, serviceListing);
|
||||
return buildPreferenceControllers(context, this, serviceListing, getLifecycle());
|
||||
}
|
||||
|
||||
private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
|
||||
Fragment parent, ZenServiceListing serviceListing) {
|
||||
Fragment parent, ZenServiceListing serviceListing, Lifecycle lifecycle) {
|
||||
List<AbstractPreferenceController> controllers = new ArrayList<>();
|
||||
controllers.add(new ZenModeAddAutomaticRulePreferenceController(context, KEY_ADD_RULE,
|
||||
parent, serviceListing));
|
||||
controllers.add(new ZenModeAutomaticRulesPreferenceController(context,
|
||||
KEY_AUTOMATIC_RULES, parent));
|
||||
controllers.add(new ZenModeAddAutomaticRulePreferenceController(context, parent,
|
||||
serviceListing, lifecycle));
|
||||
controllers.add(new ZenModeAutomaticRulesPreferenceController(context, parent, lifecycle));
|
||||
|
||||
return controllers;
|
||||
}
|
||||
@@ -94,15 +92,15 @@ public class ZenModeAutomationSettings extends ZenModeSettingsBase {
|
||||
@Override
|
||||
public List<String> getNonIndexableKeys(Context context) {
|
||||
final List<String> keys = super.getNonIndexableKeys(context);
|
||||
keys.add(KEY_ADD_RULE);
|
||||
keys.add(KEY_AUTOMATIC_RULES);
|
||||
keys.add(ZenModeAddAutomaticRulePreferenceController.KEY);
|
||||
keys.add(ZenModeAutomaticRulesPreferenceController.KEY);
|
||||
return keys;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AbstractPreferenceController> getPreferenceControllers(
|
||||
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.widget.Button;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.applications.LayoutPreference;
|
||||
import com.android.settings.core.PreferenceControllerMixin;
|
||||
@@ -57,15 +58,21 @@ public class ZenModeButtonPreferenceController extends AbstractZenModePreference
|
||||
if (null == mZenButtonOn) {
|
||||
mZenButtonOn = (Button) ((LayoutPreference) preference)
|
||||
.findViewById(R.id.zen_mode_settings_turn_on_button);
|
||||
mZenButtonOn.setOnClickListener(v ->
|
||||
mBackend.setZenMode(Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS));
|
||||
mZenButtonOn.setOnClickListener(v -> {
|
||||
mMetricsFeatureProvider.action(mContext,
|
||||
MetricsProto.MetricsEvent.ACTION_ZEN_TOGGLE_DND_BUTTON, true);
|
||||
mBackend.setZenMode(Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS);
|
||||
});
|
||||
}
|
||||
|
||||
if (null == mZenButtonOff) {
|
||||
mZenButtonOff = (Button) ((LayoutPreference) preference)
|
||||
.findViewById(R.id.zen_mode_settings_turn_off_button);
|
||||
mZenButtonOff.setOnClickListener(v ->
|
||||
mBackend.setZenMode(Settings.Global.ZEN_MODE_OFF));
|
||||
mZenButtonOff.setOnClickListener(v -> {
|
||||
mMetricsFeatureProvider.action(mContext,
|
||||
MetricsProto.MetricsEvent.ACTION_ZEN_TOGGLE_DND_BUTTON, false);
|
||||
mBackend.setZenMode(Settings.Global.ZEN_MODE_OFF);
|
||||
});
|
||||
}
|
||||
|
||||
updateButtons();
|
||||
|
@@ -60,16 +60,6 @@ public class ZenModeEventRuleSettings extends ZenModeRuleSettingsBase {
|
||||
return mEvent != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getZenModeDependency() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getEnabledToastText() {
|
||||
return R.string.zen_event_rule_enabled_toast;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
@@ -89,7 +79,14 @@ public class ZenModeEventRuleSettings extends ZenModeRuleSettingsBase {
|
||||
|
||||
@Override
|
||||
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() {
|
||||
|
@@ -24,6 +24,7 @@ import android.support.v7.preference.Preference;
|
||||
import android.util.Log;
|
||||
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
|
||||
public class ZenModeEventsPreferenceController extends AbstractZenModePreferenceController
|
||||
@@ -71,6 +72,8 @@ public class ZenModeEventsPreferenceController extends AbstractZenModePreference
|
||||
if (ZenModeSettingsBase.DEBUG) {
|
||||
Log.d(TAG, "onPrefChange allowEvents=" + allowEvents);
|
||||
}
|
||||
mMetricsFeatureProvider.action(mContext, MetricsProto.MetricsEvent.ACTION_ZEN_ALLOW_EVENTS,
|
||||
allowEvents);
|
||||
mBackend.saveSoundPolicy(Policy.PRIORITY_CATEGORY_EVENTS, allowEvents);
|
||||
return true;
|
||||
}
|
||||
|
@@ -23,6 +23,7 @@ import android.support.v14.preference.SwitchPreference;
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
|
||||
public class ZenModeRemindersPreferenceController extends AbstractZenModePreferenceController
|
||||
@@ -67,7 +68,11 @@ public class ZenModeRemindersPreferenceController extends AbstractZenModePrefere
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object 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,
|
||||
allowReminders);
|
||||
return true;
|
||||
|
@@ -23,6 +23,7 @@ import android.support.v14.preference.SwitchPreference;
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
|
||||
public class ZenModeRepeatCallersPreferenceController extends AbstractZenModePreferenceController
|
||||
@@ -77,8 +78,11 @@ public class ZenModeRepeatCallersPreferenceController extends AbstractZenModePre
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
final boolean allowRepeatCallers = (Boolean) newValue;
|
||||
if (ZenModeSettingsBase.DEBUG) Log.d(TAG, "onPrefChange allowRepeatCallers="
|
||||
+ allowRepeatCallers);
|
||||
if (ZenModeSettingsBase.DEBUG) {
|
||||
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);
|
||||
return true;
|
||||
}
|
||||
|
@@ -16,62 +16,43 @@
|
||||
|
||||
package com.android.settings.notification;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.AutomaticZenRule;
|
||||
import android.app.Fragment;
|
||||
import android.app.NotificationManager;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.DialogInterface.OnClickListener;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.service.notification.ConditionProviderService;
|
||||
import android.support.v7.preference.DropDownPreference;
|
||||
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.PreferenceScreen;
|
||||
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 com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SettingsActivity;
|
||||
import com.android.settings.widget.SwitchBar;
|
||||
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 boolean DEBUG = ZenModeSettingsBase.DEBUG;
|
||||
|
||||
private static final String KEY_RULE_NAME = "rule_name";
|
||||
private static final String KEY_ZEN_MODE = "zen_mode";
|
||||
|
||||
protected Context mContext;
|
||||
protected boolean mDisableListeners;
|
||||
protected AutomaticZenRule mRule;
|
||||
protected String mId;
|
||||
|
||||
private boolean mDeleting;
|
||||
private Preference mRuleName;
|
||||
private SwitchBar mSwitchBar;
|
||||
private DropDownPreference mZenMode;
|
||||
private Toast mEnabledToast;
|
||||
protected ZenAutomaticRuleHeaderPreferenceController mHeader;
|
||||
protected ZenAutomaticRuleSwitchPreferenceController mSwitch;
|
||||
|
||||
abstract protected void onCreateInternal();
|
||||
abstract protected boolean setRule(AutomaticZenRule rule);
|
||||
abstract protected String getZenModeDependency();
|
||||
abstract protected void updateControlsInternal();
|
||||
abstract protected int getEnabledToastText();
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle icicle) {
|
||||
@@ -99,8 +80,6 @@ public abstract class ZenModeRuleSettingsBase extends ZenModeSettingsBase
|
||||
|
||||
super.onCreate(icicle);
|
||||
|
||||
setHasOptionsMenu(true);
|
||||
|
||||
onCreateInternal();
|
||||
|
||||
final PreferenceScreen root = getPreferenceScreen();
|
||||
@@ -112,37 +91,6 @@ public abstract class ZenModeRuleSettingsBase extends ZenModeSettingsBase
|
||||
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
|
||||
@@ -155,43 +103,39 @@ public abstract class ZenModeRuleSettingsBase extends ZenModeSettingsBase
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
|
||||
final SettingsActivity activity = (SettingsActivity) getActivity();
|
||||
mSwitchBar = activity.getSwitchBar();
|
||||
mSwitchBar.addOnSwitchChangeListener(this);
|
||||
mSwitchBar.show();
|
||||
public int getHelpResource() {
|
||||
return R.string.help_uri_interruptions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
mSwitchBar.removeOnSwitchChangeListener(this);
|
||||
mSwitchBar.hide();
|
||||
/**
|
||||
* Update state of header preference managed by PreferenceController.
|
||||
*/
|
||||
protected void updateHeader() {
|
||||
final PreferenceScreen screen = getPreferenceScreen();
|
||||
|
||||
mSwitch.onResume(mRule,mId);
|
||||
mSwitch.displayPreference(screen);
|
||||
updatePreference(mSwitch);
|
||||
|
||||
mHeader.onResume(mRule);
|
||||
mHeader.displayPreference(screen);
|
||||
updatePreference(mHeader);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSwitchChanged(Switch switchView, boolean isChecked) {
|
||||
if (DEBUG) Log.d(TAG, "onSwitchChanged " + isChecked);
|
||||
if (mDisableListeners) 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();
|
||||
}
|
||||
private void updatePreference(AbstractPreferenceController controller) {
|
||||
final PreferenceScreen screen = getPreferenceScreen();
|
||||
if (!controller.isAvailable()) {
|
||||
return;
|
||||
}
|
||||
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) {
|
||||
@@ -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() {
|
||||
mRule = getZenRule();
|
||||
if (DEBUG) Log.d(TAG, "mRule=" + mRule);
|
||||
@@ -244,42 +161,22 @@ public abstract class ZenModeRuleSettingsBase extends ZenModeSettingsBase
|
||||
return false;
|
||||
}
|
||||
|
||||
private void showDeleteRuleDialog() {
|
||||
final AlertDialog dialog = new AlertDialog.Builder(mContext)
|
||||
.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 showRuleNameDialog() {
|
||||
ZenRuleNameDialog.show(this, mRule.getName(), null, new RuleNameChangeListener());
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
getActivity().finish();
|
||||
}
|
||||
|
||||
private void updateRuleName() {
|
||||
Activity activity = getActivity();
|
||||
if (activity != null) {
|
||||
activity.setTitle(mRule.getName());
|
||||
if (mRule != null) {
|
||||
mRuleName.setSummary(mRule.getName());
|
||||
} else {
|
||||
if (DEBUG) Log.d(TAG, "updateRuleName - activity title and mRuleName "
|
||||
+ "not updated; getActivity() returned null");
|
||||
if (DEBUG) Log.d(TAG, "updateRuleName - mRuleName "
|
||||
+ "not updated; mRuleName returned null");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -291,10 +188,19 @@ public abstract class ZenModeRuleSettingsBase extends ZenModeSettingsBase
|
||||
mDisableListeners = true;
|
||||
updateRuleName();
|
||||
updateControlsInternal();
|
||||
mZenMode.setValue(Integer.toString(mRule.getInterruptionFilter()));
|
||||
if (mSwitchBar != null) {
|
||||
mSwitchBar.setChecked(mRule.isEnabled());
|
||||
}
|
||||
updateHeader();
|
||||
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 java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
import java.util.List;
|
||||
@@ -76,21 +77,6 @@ public class ZenModeScheduleRuleSettings extends ZenModeRuleSettingsBase {
|
||||
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
|
||||
protected void onCreateInternal() {
|
||||
final PreferenceScreen root = getPreferenceScreen();
|
||||
@@ -208,6 +194,20 @@ public class ZenModeScheduleRuleSettings extends ZenModeRuleSettingsBase {
|
||||
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
|
||||
public int getMetricsCategory() {
|
||||
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.util.Log;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
|
||||
public class ZenModeScreenOffPreferenceController extends
|
||||
@@ -56,8 +57,11 @@ public class ZenModeScreenOffPreferenceController extends
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
final boolean bypass = (Boolean) newValue;
|
||||
if (ZenModeSettingsBase.DEBUG) Log.d(TAG, "onPrefChange allowWhenScreenOff="
|
||||
+ !bypass);
|
||||
if (ZenModeSettingsBase.DEBUG) {
|
||||
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);
|
||||
return true;
|
||||
}
|
||||
|
@@ -22,6 +22,7 @@ import android.support.v14.preference.SwitchPreference;
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
|
||||
public class ZenModeScreenOnPreferenceController extends
|
||||
@@ -57,8 +58,9 @@ public class ZenModeScreenOnPreferenceController extends
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
final boolean bypass = (Boolean) newValue;
|
||||
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);
|
||||
return true;
|
||||
}
|
||||
|
@@ -17,73 +17,103 @@
|
||||
package com.android.settings.notification;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.app.Fragment;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.service.notification.ZenModeConfig;
|
||||
import android.text.TextUtils;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.EditText;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
|
||||
|
||||
public abstract class ZenRuleNameDialog {
|
||||
private static final String TAG = "ZenRuleNameDialog";
|
||||
private static final boolean DEBUG = ZenModeSettings.DEBUG;
|
||||
public class ZenRuleNameDialog extends InstrumentedDialogFragment {
|
||||
protected static final String TAG = "ZenRuleNameDialog";
|
||||
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;
|
||||
private final EditText mEditText;
|
||||
private final CharSequence mOriginalRuleName;
|
||||
private final boolean mIsNew;
|
||||
@Override
|
||||
public int getMetricsCategory() {
|
||||
return MetricsProto.MetricsEvent.NOTIFICATION_ZEN_MODE_RULE_NAME_DIALOG;
|
||||
}
|
||||
|
||||
public ZenRuleNameDialog(Context context, CharSequence ruleName, Uri conditionId) {
|
||||
mIsNew = ruleName == null;
|
||||
mOriginalRuleName = ruleName;
|
||||
/**
|
||||
* The interface we expect a listener to implement.
|
||||
*/
|
||||
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,
|
||||
false);
|
||||
mEditText = (EditText) v.findViewById(R.id.zen_mode_rule_name);
|
||||
if (!mIsNew) {
|
||||
mEditText.setText(ruleName);
|
||||
EditText editText = (EditText) v.findViewById(R.id.zen_mode_rule_name);
|
||||
if (!isNew) {
|
||||
// set text to current rule name
|
||||
editText.setText(ruleName);
|
||||
// move cursor to end of text
|
||||
editText.setSelection(editText.getText().length());
|
||||
}
|
||||
mEditText.setSelectAllOnFocus(true);
|
||||
mDialog = new AlertDialog.Builder(context)
|
||||
.setTitle(getTitleResource(conditionId))
|
||||
editText.setSelectAllOnFocus(true);
|
||||
return new AlertDialog.Builder(context)
|
||||
.setTitle(getTitleResource(conditionId, isNew))
|
||||
.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() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
final String newName = trimmedText();
|
||||
if (TextUtils.isEmpty(newName)) {
|
||||
return;
|
||||
}
|
||||
if (!mIsNew && mOriginalRuleName != null
|
||||
&& mOriginalRuleName.equals(newName)) {
|
||||
return; // no change to an existing rule, just dismiss
|
||||
}
|
||||
onOk(newName);
|
||||
}
|
||||
})
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
final String newName = trimmedText(editText);
|
||||
if (TextUtils.isEmpty(newName)) {
|
||||
return;
|
||||
}
|
||||
if (!isNew && originalRuleName != null
|
||||
&& originalRuleName.equals(newName)) {
|
||||
return; // no change to an existing rule, just dismiss
|
||||
}
|
||||
mPositiveClickListener.onOk(newName, getTargetFragment());
|
||||
}
|
||||
})
|
||||
.setNegativeButton(R.string.cancel, null)
|
||||
.create();
|
||||
}
|
||||
|
||||
abstract public void onOk(String ruleName);
|
||||
|
||||
public void show() {
|
||||
mDialog.show();
|
||||
private String trimmedText(EditText editText) {
|
||||
return editText.getText() == null ? null : editText.getText().toString().trim();
|
||||
}
|
||||
|
||||
private String trimmedText() {
|
||||
return mEditText.getText() == null ? null : mEditText.getText().toString().trim();
|
||||
}
|
||||
|
||||
private int getTitleResource(Uri conditionId) {
|
||||
private int getTitleResource(Uri conditionId, boolean isNew) {
|
||||
final boolean isEvent = ZenModeConfig.isValidEventConditionId(conditionId);
|
||||
final boolean isTime = ZenModeConfig.isValidScheduleConditionId(conditionId);
|
||||
int titleResource = R.string.zen_mode_rule_name;
|
||||
if (mIsNew) {
|
||||
if (isNew) {
|
||||
if (isEvent) {
|
||||
titleResource = R.string.zen_mode_add_event_rule;
|
||||
} else if (isTime) {
|
||||
|
@@ -16,23 +16,21 @@
|
||||
|
||||
package com.android.settings.notification;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.AutomaticZenRule;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.Fragment;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ServiceInfo;
|
||||
import android.content.res.Resources;
|
||||
import android.service.notification.ZenModeConfig;
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.support.v7.preference.PreferenceCategory;
|
||||
import android.support.v7.preference.PreferenceViewHolder;
|
||||
import android.view.View;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.instrumentation.MetricsFeatureProvider;
|
||||
import com.android.settings.utils.ManagedServiceSettings;
|
||||
import com.android.settings.utils.ZenServiceListing;
|
||||
import com.android.settingslib.TwoTargetPreference;
|
||||
@@ -45,16 +43,17 @@ public class ZenRulePreference extends TwoTargetPreference {
|
||||
final CharSequence mName;
|
||||
final String mId;
|
||||
boolean appExists;
|
||||
final PreferenceCategory mParent;
|
||||
final Fragment mParent;
|
||||
final Preference mPref;
|
||||
final Context mContext;
|
||||
final ZenModeBackend mBackend;
|
||||
final ZenServiceListing mServiceListing;
|
||||
final PackageManager mPm;
|
||||
final MetricsFeatureProvider mMetricsFeatureProvider;
|
||||
|
||||
public ZenRulePreference(Context context,
|
||||
final Map.Entry<String, AutomaticZenRule> ruleEntry,
|
||||
PreferenceCategory prefCategory) {
|
||||
Fragment parent, MetricsFeatureProvider metricsProvider) {
|
||||
super(context);
|
||||
|
||||
mBackend = ZenModeBackend.getInstance(context);
|
||||
@@ -62,11 +61,12 @@ public class ZenRulePreference extends TwoTargetPreference {
|
||||
final AutomaticZenRule rule = ruleEntry.getValue();
|
||||
mName = rule.getName();
|
||||
mId = ruleEntry.getKey();
|
||||
mParent = prefCategory;
|
||||
mParent = parent;
|
||||
mPm = mContext.getPackageManager();
|
||||
mServiceListing = new ZenServiceListing(mContext, CONFIG);
|
||||
mServiceListing.reloadApprovedServices();
|
||||
mPref = this;
|
||||
mMetricsFeatureProvider = metricsProvider;
|
||||
|
||||
setAttributes(rule);
|
||||
}
|
||||
@@ -89,25 +89,21 @@ public class ZenRulePreference extends TwoTargetPreference {
|
||||
private final View.OnClickListener mDeleteListener = new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
showDeleteRuleDialog(mId, mName, mParent, mPref);
|
||||
showDeleteRuleDialog(mParent, mId, mName.toString());
|
||||
}
|
||||
};
|
||||
|
||||
private void showDeleteRuleDialog(final String ruleId, final CharSequence ruleName,
|
||||
PreferenceCategory parent, Preference pref) {
|
||||
new AlertDialog.Builder(mContext)
|
||||
.setMessage(mContext.getResources().getString(
|
||||
R.string.zen_mode_delete_rule_confirmation, ruleName))
|
||||
.setNegativeButton(R.string.cancel, null)
|
||||
.setPositiveButton(R.string.zen_mode_delete_rule_button,
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
mBackend.removeZenRule(ruleId);
|
||||
parent.removePreference(pref);
|
||||
}
|
||||
})
|
||||
.show();
|
||||
private void showDeleteRuleDialog(final Fragment parent, final String ruleId,
|
||||
final String ruleName) {
|
||||
ZenDeleteRuleDialog.show(parent, ruleName, ruleId,
|
||||
new ZenDeleteRuleDialog.PositiveClickListener() {
|
||||
@Override
|
||||
public void onOk(String id) {
|
||||
mMetricsFeatureProvider.action(mContext,
|
||||
MetricsProto.MetricsEvent.ACTION_ZEN_DELETE_RULE_OK);
|
||||
mBackend.removeZenRule(id);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected void setAttributes(AutomaticZenRule rule) {
|
||||
@@ -141,26 +137,8 @@ public class ZenRulePreference extends TwoTargetPreference {
|
||||
|
||||
private String computeRuleSummary(AutomaticZenRule rule, boolean isSystemRule,
|
||||
CharSequence providerLabel) {
|
||||
final String mode = computeZenModeCaption(mContext.getResources(),
|
||||
rule.getInterruptionFilter());
|
||||
final String ruleState = (rule == null || !rule.isEnabled())
|
||||
return (rule == null || !rule.isEnabled())
|
||||
? mContext.getResources().getString(R.string.switch_off_text)
|
||||
: mContext.getResources().getString(
|
||||
R.string.zen_mode_rule_summary_enabled_combination, mode);
|
||||
|
||||
return ruleState;
|
||||
}
|
||||
|
||||
private static String computeZenModeCaption(Resources res, int zenMode) {
|
||||
switch (zenMode) {
|
||||
case NotificationManager.INTERRUPTION_FILTER_ALARMS:
|
||||
return res.getString(R.string.zen_mode_option_alarms);
|
||||
case NotificationManager.INTERRUPTION_FILTER_PRIORITY:
|
||||
return res.getString(R.string.zen_mode_option_important_interruptions);
|
||||
case NotificationManager.INTERRUPTION_FILTER_NONE:
|
||||
return res.getString(R.string.zen_mode_option_no_interruptions);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
: mContext.getResources().getString(R.string.switch_on_text);
|
||||
}
|
||||
}
|
@@ -16,16 +16,20 @@
|
||||
|
||||
package com.android.settings.notification;
|
||||
|
||||
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.app.Fragment;
|
||||
import android.app.NotificationManager;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.DialogInterface.OnDismissListener;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ServiceInfo;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.service.notification.ZenModeConfig;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
@@ -35,6 +39,7 @@ import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
|
||||
import com.android.settings.utils.ZenServiceListing;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
@@ -43,24 +48,48 @@ import java.util.Comparator;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
public abstract class ZenRuleSelectionDialog {
|
||||
public class ZenRuleSelectionDialog extends InstrumentedDialogFragment {
|
||||
private static final String TAG = "ZenRuleSelectionDialog";
|
||||
private static final boolean DEBUG = ZenModeSettings.DEBUG;
|
||||
|
||||
private final Context mContext;
|
||||
private final PackageManager mPm;
|
||||
private NotificationManager mNm;
|
||||
private final AlertDialog mDialog;
|
||||
private final LinearLayout mRuleContainer;
|
||||
private final ZenServiceListing mServiceListing;
|
||||
private static ZenServiceListing mServiceListing;
|
||||
protected static PositiveClickListener mPositiveClickListener;
|
||||
|
||||
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;
|
||||
mPm = context.getPackageManager();
|
||||
mNm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
mPm = mContext.getPackageManager();
|
||||
mNm = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
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);
|
||||
if (mServiceListing != null) {
|
||||
@@ -69,28 +98,21 @@ public abstract class ZenRuleSelectionDialog {
|
||||
mServiceListing.addZenCallback(mServiceListingCallback);
|
||||
mServiceListing.reloadApprovedServices();
|
||||
}
|
||||
mDialog = new AlertDialog.Builder(context)
|
||||
return new AlertDialog.Builder(getContext())
|
||||
.setTitle(R.string.zen_mode_choose_rule_type)
|
||||
.setView(v)
|
||||
.setOnDismissListener(new OnDismissListener() {
|
||||
@Override
|
||||
public void onDismiss(DialogInterface dialog) {
|
||||
if (mServiceListing != null) {
|
||||
mServiceListing.removeZenCallback(mServiceListingCallback);
|
||||
}
|
||||
}
|
||||
})
|
||||
.setNegativeButton(R.string.cancel, null)
|
||||
.create();
|
||||
}
|
||||
|
||||
public void show() {
|
||||
mDialog.show();
|
||||
@Override
|
||||
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) {
|
||||
try {
|
||||
ApplicationInfo info = mPm.getApplicationInfo(ri.packageName, 0);
|
||||
@@ -108,11 +130,11 @@ public abstract class ZenRuleSelectionDialog {
|
||||
v.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
mDialog.dismiss();
|
||||
dismiss();
|
||||
if (ri.isSystem) {
|
||||
onSystemRuleSelected(ri);
|
||||
mPositiveClickListener.onSystemRuleSelected(ri, getTargetFragment());
|
||||
} else {
|
||||
onExternalRuleSelected(ri);
|
||||
mPositiveClickListener.onExternalRuleSelected(ri, getTargetFragment());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.notification;
|
||||
|
||||
import static junit.framework.Assert.assertEquals;
|
||||
import static junit.framework.Assert.assertTrue;
|
||||
|
||||
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.ContentResolver;
|
||||
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.HashMap;
|
||||
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";
|
||||
|
||||
@Mock
|
||||
private ZenModeBackend mBackend;
|
||||
@Mock
|
||||
private NotificationManager mNotificationManager;
|
||||
@Mock
|
||||
private PreferenceCategory mockPref;
|
||||
@Mock
|
||||
private NotificationManager.Policy mPolicy;
|
||||
@Mock
|
||||
private PreferenceScreen mPreferenceScreen;
|
||||
|
||||
private Context mContext;
|
||||
private ContentResolver mContentResolver;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
ShadowApplication shadowApplication = ShadowApplication.getInstance();
|
||||
shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNotificationManager);
|
||||
|
||||
mContext = shadowApplication.getApplicationContext();
|
||||
mContentResolver = RuntimeEnvironment.application.getContentResolver();
|
||||
when(mNotificationManager.getNotificationPolicy()).thenReturn(mPolicy);
|
||||
mController = new ZenModeAutomaticRulesPreferenceController(mContext, mock(Fragment.class),
|
||||
mock(Lifecycle.class));
|
||||
ReflectionHelpers.setField(mController, "mBackend", mBackend);
|
||||
|
||||
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(rules[i].getKey(), GENERIC_RULE_NAME + (NUM_RULES - 1 - i));
|
||||
}
|
||||
}
|
||||
|
||||
@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(rules[i].getKey(), GENERIC_RULE_NAME + i);
|
||||
}
|
||||
}
|
||||
|
||||
@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(rules[4].getKey(), insertedRule1);
|
||||
assertEquals(rules[2].getKey(), insertedRule2);
|
||||
}
|
||||
|
||||
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