• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.settings.notification;
18 
19 import android.app.AutomaticZenRule;
20 import android.app.Fragment;
21 import android.app.NotificationManager;
22 import android.content.ComponentName;
23 import android.content.Context;
24 import android.content.Intent;
25 import android.content.pm.PackageManager;
26 import android.content.pm.ServiceInfo;
27 import android.provider.Settings;
28 import android.service.notification.ConditionProviderService;
29 import android.service.notification.ZenModeConfig;
30 import android.support.v7.preference.Preference;
31 
32 import com.android.internal.logging.nano.MetricsProto;
33 import com.android.settings.core.PreferenceControllerMixin;
34 import com.android.settingslib.core.lifecycle.Lifecycle;
35 
36 import java.util.Arrays;
37 import java.util.Comparator;
38 import java.util.List;
39 import java.util.Map;
40 import java.util.Set;
41 
42 abstract public class AbstractZenModeAutomaticRulePreferenceController extends
43         AbstractZenModePreferenceController implements PreferenceControllerMixin {
44 
45     protected ZenModeBackend mBackend;
46     protected Fragment mParent;
47     protected Set<Map.Entry<String, AutomaticZenRule>> mRules;
48     protected PackageManager mPm;
49     private static List<String> mDefaultRuleIds;
50 
AbstractZenModeAutomaticRulePreferenceController(Context context, String key, Fragment parent, Lifecycle lifecycle)51     public AbstractZenModeAutomaticRulePreferenceController(Context context, String key, Fragment
52             parent, Lifecycle lifecycle) {
53         super(context, key, lifecycle);
54         mBackend = ZenModeBackend.getInstance(context);
55         mPm = mContext.getPackageManager();
56         mParent = parent;
57     }
58 
59     @Override
updateState(Preference preference)60     public void updateState(Preference preference) {
61         super.updateState(preference);
62         mRules = getZenModeRules();
63     }
64 
getDefaultRuleIds()65     private static List<String> getDefaultRuleIds() {
66         if (mDefaultRuleIds == null) {
67             mDefaultRuleIds = ZenModeConfig.DEFAULT_RULE_IDS;
68         }
69         return mDefaultRuleIds;
70     }
71 
getZenModeRules()72     private Set<Map.Entry<String, AutomaticZenRule>> getZenModeRules() {
73         Map<String, AutomaticZenRule> ruleMap =
74                 NotificationManager.from(mContext).getAutomaticZenRules();
75         return ruleMap.entrySet();
76     }
77 
showNameRuleDialog(final ZenRuleInfo ri, Fragment parent)78     protected void showNameRuleDialog(final ZenRuleInfo ri, Fragment parent) {
79         ZenRuleNameDialog.show(parent, null, ri.defaultConditionId, new
80                 RuleNameChangeListener(ri));
81     }
82 
sortedRules()83     protected Map.Entry<String, AutomaticZenRule>[] sortedRules() {
84         if (mRules == null) {
85             mRules = getZenModeRules();
86         }
87         final Map.Entry<String, AutomaticZenRule>[] rt =
88                 mRules.toArray(new Map.Entry[mRules.size()]);
89         Arrays.sort(rt, RULE_COMPARATOR);
90         return rt;
91     }
92 
getRuleIntent(String settingsAction, ComponentName configurationActivity, String ruleId)93     protected static Intent getRuleIntent(String settingsAction,
94             ComponentName configurationActivity, String ruleId) {
95         final Intent intent = new Intent()
96                 .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
97                 .putExtra(ConditionProviderService.EXTRA_RULE_ID, ruleId);
98         if (configurationActivity != null) {
99             intent.setComponent(configurationActivity);
100         } else {
101             intent.setAction(settingsAction);
102         }
103         return intent;
104     }
105 
106     private static final Comparator<Map.Entry<String, AutomaticZenRule>> RULE_COMPARATOR =
107             new Comparator<Map.Entry<String, AutomaticZenRule>>() {
108                 @Override
109                 public int compare(Map.Entry<String, AutomaticZenRule> lhs,
110                         Map.Entry<String, AutomaticZenRule> rhs) {
111                     // if it's a default rule, should be at the top of automatic rules
112                     boolean lhsIsDefaultRule = getDefaultRuleIds().contains(lhs.getKey());
113                     boolean rhsIsDefaultRule = getDefaultRuleIds().contains(rhs.getKey());
114                     if (lhsIsDefaultRule != rhsIsDefaultRule) {
115                         return lhsIsDefaultRule ? -1 : 1;
116                     }
117 
118                     int byDate = Long.compare(lhs.getValue().getCreationTime(),
119                             rhs.getValue().getCreationTime());
120                     if (byDate != 0) {
121                         return byDate;
122                     } else {
123                         return key(lhs.getValue()).compareTo(key(rhs.getValue()));
124                     }
125                 }
126 
127                 private String key(AutomaticZenRule rule) {
128                     final int type = ZenModeConfig.isValidScheduleConditionId(rule.getConditionId())
129                             ? 1 : ZenModeConfig.isValidEventConditionId(rule.getConditionId())
130                             ? 2 : 3;
131                     return type + rule.getName().toString();
132                 }
133             };
134 
getRuleInfo(PackageManager pm, ServiceInfo si)135     public static ZenRuleInfo getRuleInfo(PackageManager pm, ServiceInfo si) {
136         if (si == null || si.metaData == null) {
137             return null;
138         }
139         final String ruleType = si.metaData.getString(ConditionProviderService.META_DATA_RULE_TYPE);
140         final ComponentName configurationActivity = getSettingsActivity(si);
141         if (ruleType != null && !ruleType.trim().isEmpty() && configurationActivity != null) {
142             final ZenRuleInfo ri = new ZenRuleInfo();
143             ri.serviceComponent = new ComponentName(si.packageName, si.name);
144             ri.settingsAction = Settings.ACTION_ZEN_MODE_EXTERNAL_RULE_SETTINGS;
145             ri.title = ruleType;
146             ri.packageName = si.packageName;
147             ri.configurationActivity = getSettingsActivity(si);
148             ri.packageLabel = si.applicationInfo.loadLabel(pm);
149             ri.ruleInstanceLimit =
150                     si.metaData.getInt(ConditionProviderService.META_DATA_RULE_INSTANCE_LIMIT, -1);
151             return ri;
152         }
153         return null;
154     }
155 
getSettingsActivity(ServiceInfo si)156     protected static ComponentName getSettingsActivity(ServiceInfo si) {
157         if (si == null || si.metaData == null) {
158             return null;
159         }
160         final String configurationActivity =
161                 si.metaData.getString(ConditionProviderService.META_DATA_CONFIGURATION_ACTIVITY);
162         if (configurationActivity != null) {
163             return ComponentName.unflattenFromString(configurationActivity);
164         }
165         return null;
166     }
167 
168     public class RuleNameChangeListener implements ZenRuleNameDialog.PositiveClickListener {
169         ZenRuleInfo mRuleInfo;
170 
RuleNameChangeListener(ZenRuleInfo ruleInfo)171         public RuleNameChangeListener(ZenRuleInfo ruleInfo) {
172             mRuleInfo = ruleInfo;
173         }
174 
175         @Override
onOk(String ruleName, Fragment parent)176         public void onOk(String ruleName, Fragment parent) {
177             mMetricsFeatureProvider.action(mContext,
178                     MetricsProto.MetricsEvent.ACTION_ZEN_MODE_RULE_NAME_CHANGE_OK);
179             AutomaticZenRule rule = new AutomaticZenRule(ruleName, mRuleInfo.serviceComponent,
180                     mRuleInfo.defaultConditionId,
181                     NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
182             String savedRuleId = mBackend.addZenRule(rule);
183             if (savedRuleId != null) {
184                 parent.startActivity(getRuleIntent(mRuleInfo.settingsAction, null,
185                         savedRuleId));
186             }
187         }
188     }
189 }
190