ZenRuleNameDialog.java revision 33bf636e7237bd5dc4c1ace0d0bc63004fa54bc8
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
17package com.android.settings.notification;
18
19import android.app.AlertDialog;
20import android.content.ComponentName;
21import android.content.Context;
22import android.content.DialogInterface;
23import android.content.DialogInterface.OnDismissListener;
24import android.content.pm.ServiceInfo;
25import android.net.Uri;
26import android.service.notification.ZenModeConfig;
27import android.service.notification.ZenModeConfig.EventInfo;
28import android.service.notification.ZenModeConfig.ScheduleInfo;
29import android.text.Editable;
30import android.text.TextUtils;
31import android.text.TextWatcher;
32import android.util.ArraySet;
33import android.util.Log;
34import android.view.LayoutInflater;
35import android.view.View;
36import android.widget.EditText;
37import android.widget.RadioButton;
38import android.widget.RadioGroup;
39
40import com.android.settings.R;
41
42import java.util.List;
43
44public abstract class ZenRuleNameDialog {
45    private static final String TAG = ZenModeSettings.TAG;
46    private static final boolean DEBUG = ZenModeSettings.DEBUG;
47
48    private final AlertDialog mDialog;
49    private final EditText mEditText;
50    private final RadioGroup mTypes;
51    private final ArraySet<String> mExistingNames;
52    private final ServiceListing mServiceListing;
53    private final RuleInfo[] mExternalRules = new RuleInfo[3];
54    private final boolean mIsNew;
55
56    public ZenRuleNameDialog(Context context, ServiceListing serviceListing, String ruleName,
57            ArraySet<String> existingNames) {
58        mServiceListing = serviceListing;
59        mIsNew = ruleName == null;
60        final View v = LayoutInflater.from(context).inflate(R.layout.zen_rule_name, null, false);
61        mEditText = (EditText) v.findViewById(R.id.rule_name);
62        if (!mIsNew) {
63            mEditText.setText(ruleName);
64        }
65        mEditText.setSelectAllOnFocus(true);
66        mTypes = (RadioGroup) v.findViewById(R.id.rule_types);
67        if (mServiceListing != null) {
68            bindType(R.id.rule_type_schedule, defaultNewSchedule());
69            bindType(R.id.rule_type_event, defaultNewEvent());
70            bindExternalRules();
71            mServiceListing.addCallback(mServiceListingCallback);
72            mServiceListing.reload();
73        } else {
74            mTypes.setVisibility(View.GONE);
75        }
76        mDialog = new AlertDialog.Builder(context)
77                .setTitle(mIsNew ? R.string.zen_mode_add_rule : R.string.zen_mode_rule_name)
78                .setView(v)
79                .setPositiveButton(R.string.okay, new DialogInterface.OnClickListener() {
80                    @Override
81                    public void onClick(DialogInterface dialog, int which) {
82                        onOk(trimmedText(), selectedRuleInfo());
83                    }
84                })
85                .setOnDismissListener(new OnDismissListener() {
86                    @Override
87                    public void onDismiss(DialogInterface dialog) {
88                        if (mServiceListing != null) {
89                            mServiceListing.removeCallback(mServiceListingCallback);
90                        }
91                    }
92                })
93                .setNegativeButton(R.string.cancel, null)
94                .create();
95        mEditText.addTextChangedListener(new TextWatcher() {
96            @Override
97            public void onTextChanged(CharSequence s, int start, int before, int count) {
98                // noop
99            }
100
101            @Override
102            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
103                // noop
104            }
105
106            @Override
107            public void afterTextChanged(Editable s) {
108                updatePositiveButton();
109            }
110        });
111        mExistingNames = new ArraySet<String>(existingNames.size());
112        for (String existingName : existingNames) {
113            mExistingNames.add(existingName.toLowerCase());
114        }
115    }
116
117    abstract public void onOk(String ruleName, RuleInfo ruleInfo);
118
119    public void show() {
120        mDialog.show();
121        updatePositiveButton();
122    }
123
124    private void bindType(int id, RuleInfo ri) {
125        final RadioButton rb = (RadioButton) mTypes.findViewById(id);
126        if (ri == null) {
127            rb.setVisibility(View.GONE);
128            return;
129        }
130        rb.setVisibility(View.VISIBLE);
131        if (ri.caption != null) {
132            rb.setText(ri.caption);
133        }
134        rb.setTag(ri);
135    }
136
137    private RuleInfo selectedRuleInfo() {
138        final int id = mTypes.getCheckedRadioButtonId();
139        if (id == -1) return null;
140        final RadioButton rb = (RadioButton) mTypes.findViewById(id);
141        return (RuleInfo) rb.getTag();
142    }
143
144    private String trimmedText() {
145        return mEditText.getText() == null ? null : mEditText.getText().toString().trim();
146    }
147
148    private void updatePositiveButton() {
149        final String name = trimmedText();
150        final boolean validName = !TextUtils.isEmpty(name)
151                && !mExistingNames.contains(name.toLowerCase());
152        mDialog.getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(validName);
153    }
154
155    private static RuleInfo defaultNewSchedule() {
156        final ScheduleInfo schedule = new ScheduleInfo();
157        schedule.days = ZenModeConfig.ALL_DAYS;
158        schedule.startHour = 22;
159        schedule.endHour = 7;
160        final RuleInfo rt = new RuleInfo();
161        rt.settingsAction = ZenModeScheduleRuleSettings.ACTION;
162        rt.defaultConditionId = ZenModeConfig.toScheduleConditionId(schedule);
163        return rt;
164    }
165
166    private static RuleInfo defaultNewEvent() {
167        final EventInfo event = new EventInfo();
168        event.calendar = EventInfo.ANY_CALENDAR;
169        event.reply = EventInfo.REPLY_ANY_EXCEPT_NO;
170        final RuleInfo rt = new RuleInfo();
171        rt.settingsAction = ZenModeEventRuleSettings.ACTION;
172        rt.defaultConditionId = ZenModeConfig.toEventConditionId(event);
173        return rt;
174    }
175
176    private void bindExternalRules() {
177        bindType(R.id.rule_type_3, mExternalRules[0]);
178        bindType(R.id.rule_type_4, mExternalRules[1]);
179        bindType(R.id.rule_type_5, mExternalRules[2]);
180    }
181
182    private final ServiceListing.Callback mServiceListingCallback = new ServiceListing.Callback() {
183        @Override
184        public void onServicesReloaded(List<ServiceInfo> services) {
185            if (DEBUG) Log.d(TAG, "Services reloaded: count=" + services.size());
186            mExternalRules[0] = mExternalRules[1] = mExternalRules[2] = null;
187            int i = 0;
188            for (ServiceInfo si : services) {
189                final RuleInfo ri = ZenModeExternalRuleSettings.getRuleInfo(si);
190                if (ri != null) {
191                    mExternalRules[i] = ri;
192                    i++;
193                    if (i == mExternalRules.length) {
194                        break;
195                    }
196                }
197            }
198            bindExternalRules();
199        }
200    };
201
202    public static class RuleInfo {
203        public String caption;
204        public String settingsAction;
205        public Uri defaultConditionId;
206        public ComponentName serviceComponent;
207        public ComponentName configurationActivity;
208    }
209
210}