1 /*
2  * Copyright (C) 2015 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.zen;
18 
19 import static android.app.NotificationManager.EXTRA_AUTOMATIC_RULE_ID;
20 
21 import android.app.AutomaticZenRule;
22 import android.app.Flags;
23 import android.app.NotificationManager;
24 import android.app.settings.SettingsEnums;
25 import android.content.Context;
26 import android.content.Intent;
27 import android.os.Bundle;
28 import android.service.notification.ConditionProviderService;
29 import android.service.notification.SystemZenRules;
30 import android.service.notification.ZenModeConfig;
31 import android.util.Log;
32 import android.view.View;
33 import android.widget.Toast;
34 
35 import androidx.annotation.NonNull;
36 import androidx.annotation.Nullable;
37 import androidx.preference.Preference;
38 import androidx.preference.PreferenceScreen;
39 
40 import com.android.settings.R;
41 import com.android.settings.Utils;
42 import com.android.settings.core.SubSettingLauncher;
43 
44 public abstract class ZenModeRuleSettingsBase extends ZenModeSettingsBase {
45 
46     protected static final String TAG = ZenModeSettingsBase.TAG;
47     protected static final boolean DEBUG = ZenModeSettingsBase.DEBUG;
48 
49     private final String CUSTOM_BEHAVIOR_KEY = "zen_custom_setting";
50 
51     protected boolean mDisableListeners;
52     protected AutomaticZenRule mRule;
53     protected String mId;
54     private boolean mRuleRemoved;
55 
56     protected ZenAutomaticRuleHeaderPreferenceController mHeader;
57     protected ZenRuleButtonsPreferenceController mActionButtons;
58     protected ZenAutomaticRuleSwitchPreferenceController mSwitch;
59     protected Preference mCustomBehaviorPreference;
60 
onCreateInternal()61     abstract protected void onCreateInternal();
setRule(AutomaticZenRule rule)62     abstract protected boolean setRule(AutomaticZenRule rule);
updateControlsInternal()63     abstract protected void updateControlsInternal();
64 
65     @Override
onAttach(Context context)66     public void onAttach(Context context) {
67         super.onAttach(context);
68 
69         final Intent intent = getActivity().getIntent();
70         if (DEBUG) Log.d(TAG, "onCreate getIntent()=" + intent);
71         if (intent == null) {
72             Log.w(TAG, "No intent");
73             toastAndFinish();
74             return;
75         }
76 
77         mId = intent.getStringExtra(ConditionProviderService.EXTRA_RULE_ID);
78         if (mId == null) {
79             mId = intent.getStringExtra(EXTRA_AUTOMATIC_RULE_ID);
80             if (mId == null) {
81                 Log.w(TAG, "rule id is null");
82                 toastAndFinish();
83                 return;
84             }
85         }
86 
87         if (DEBUG) Log.d(TAG, "mId=" + mId);
88         refreshRuleOrFinish();
89     }
90 
91     @Override
onCreate(Bundle icicle)92     public void onCreate(Bundle icicle) {
93         super.onCreate(icicle);
94 
95         if (isFinishingOrDestroyed()) {
96             return;
97         }
98 
99         mCustomBehaviorPreference = getPreferenceScreen().findPreference(CUSTOM_BEHAVIOR_KEY);
100         mCustomBehaviorPreference.setOnPreferenceClickListener(
101                 new Preference.OnPreferenceClickListener() {
102                     @Override
103                     public boolean onPreferenceClick(Preference preference) {
104                         Bundle bundle = new Bundle();
105                         bundle.putString(ZenCustomRuleSettings.RULE_ID, mId);
106 
107                         // When modes_api flag is on, we skip the radio button screen distinguishing
108                         // between "default" and "custom" and take users directly to the custom
109                         // settings screen.
110                         String destination = ZenCustomRuleSettings.class.getName();
111                         int sourceMetricsCategory = 0;
112                         if (Flags.modesApi()) {
113                             // From ZenRuleCustomPolicyPreferenceController#launchCustomSettings
114                             destination = ZenCustomRuleConfigSettings.class.getName();
115                             sourceMetricsCategory = SettingsEnums.ZEN_CUSTOM_RULE_SOUND_SETTINGS;
116                         }
117                         new SubSettingLauncher(mContext)
118                                 .setDestination(destination)
119                                 .setArguments(bundle)
120                                 .setSourceMetricsCategory(sourceMetricsCategory)
121                                 .launch();
122                         return true;
123                     }
124                 });
125         onCreateInternal();
126     }
127 
128     @Override
onResume()129     public void onResume() {
130         super.onResume();
131         if (isUiRestricted()) {
132             return;
133         }
134         if (!refreshRuleOrFinish()) {
135             updateControls();
136         }
137     }
138 
139     @Override
onViewCreated(@onNull View view, @Nullable Bundle savedInstanceState)140     public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
141         super.onViewCreated(view, savedInstanceState);
142         Utils.setActionBarShadowAnimation(getActivity(), getSettingsLifecycle(), getListView());
143     }
144 
145     @Override
getHelpResource()146     public int getHelpResource() {
147         return R.string.help_uri_interruptions;
148     }
149 
150     /**
151      * Update state of header preference managed by PreferenceController.
152      */
updateHeader()153     protected void updateHeader() {
154         final PreferenceScreen screen = getPreferenceScreen();
155 
156         mSwitch.displayPreference(screen);
157         updatePreference(mSwitch);
158 
159         mHeader.displayPreference(screen);
160         updatePreference(mHeader);
161 
162         mActionButtons.displayPreference(screen);
163         updatePreference(mActionButtons);
164     }
165 
updateScheduleRule(ZenModeConfig.ScheduleInfo schedule)166     protected void updateScheduleRule(ZenModeConfig.ScheduleInfo schedule) {
167         mRule.setConditionId(ZenModeConfig.toScheduleConditionId(schedule));
168         if (Flags.modesApi() && Flags.modesUi()) {
169             mRule.setTriggerDescription(
170                     SystemZenRules.getTriggerDescriptionForScheduleTime(mContext, schedule));
171         }
172         mBackend.updateZenRule(mId, mRule);
173     }
174 
updateEventRule(ZenModeConfig.EventInfo event)175     protected void updateEventRule(ZenModeConfig.EventInfo event) {
176         mRule.setConditionId(ZenModeConfig.toEventConditionId(event));
177         if (Flags.modesApi() && Flags.modesUi()) {
178             mRule.setTriggerDescription(
179                     SystemZenRules.getTriggerDescriptionForScheduleEvent(mContext, event));
180         }
181         mBackend.updateZenRule(mId, mRule);
182     }
183 
184     @Override
onZenModeConfigChanged()185     protected void onZenModeConfigChanged() {
186         super.onZenModeConfigChanged();
187         if (!refreshRuleOrFinish()) {
188             updateControls();
189         }
190     }
191 
refreshRuleOrFinish()192     private boolean refreshRuleOrFinish() {
193         if (mRuleRemoved && getActivity() != null) {
194             getActivity().finish();
195             return true;
196         }
197         mRule = getZenRule();
198         if (DEBUG) Log.d(TAG, "mRule=" + mRule);
199         mHeader.setRule(mRule);
200         mSwitch.setIdAndRule(mId, mRule);
201         mActionButtons.setIdAndRule(mId, mRule);
202         if (!setRule(mRule)) {
203             toastAndFinish();
204             return true;
205         }
206         return false;
207     }
208 
toastAndFinish()209     private void toastAndFinish() {
210         Toast.makeText(mContext, R.string.zen_mode_rule_not_found_text, Toast.LENGTH_SHORT)
211                 .show();
212 
213         getActivity().finish();
214     }
215 
getZenRule()216     private AutomaticZenRule getZenRule() {
217         return NotificationManager.from(mContext).getAutomaticZenRule(mId);
218     }
219 
updateControls()220     private void updateControls() {
221         mDisableListeners = true;
222         updateControlsInternal();
223         updateHeader();
224         if (mRule.getZenPolicy() == null) {
225             mCustomBehaviorPreference.setSummary(R.string.zen_mode_custom_behavior_summary_default);
226         } else {
227             mCustomBehaviorPreference.setSummary(R.string.zen_mode_custom_behavior_summary);
228         }
229         mDisableListeners = false;
230     }
231 
onRuleRemoved()232     void onRuleRemoved() {
233         mRuleRemoved = true;
234     }
235 }
236