diff --git a/res/layout/zen_rule_name.xml b/res/layout/zen_rule_name.xml index 39262ab2438..1112ce22b8b 100755 --- a/res/layout/zen_rule_name.xml +++ b/res/layout/zen_rule_name.xml @@ -43,37 +43,4 @@ android:textColor="@color/zen_rule_name_warning" android:text="@string/zen_mode_rule_name_warning" /> - - - - - - - - - - - - - - diff --git a/res/layout/zen_rule_type.xml b/res/layout/zen_rule_type.xml new file mode 100644 index 00000000000..a6675c9ac12 --- /dev/null +++ b/res/layout/zen_rule_type.xml @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/layout/zen_rule_type_selection.xml b/res/layout/zen_rule_type_selection.xml new file mode 100644 index 00000000000..6d0ad07bdc5 --- /dev/null +++ b/res/layout/zen_rule_type_selection.xml @@ -0,0 +1,33 @@ + + + + + + + + \ No newline at end of file diff --git a/res/values/strings.xml b/res/values/strings.xml index e638de5163f..bab5395d2ad 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -6214,6 +6214,9 @@ Delete rule + + Choose rule type + Delete \u201c%1$s\u201d rule? diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java index 258cb307432..d830c33644d 100644 --- a/src/com/android/settings/SettingsActivity.java +++ b/src/com/android/settings/SettingsActivity.java @@ -106,7 +106,6 @@ import com.android.settings.notification.OtherSoundSettings; import com.android.settings.notification.ZenAccessSettings; import com.android.settings.notification.ZenModeAutomationSettings; import com.android.settings.notification.ZenModeEventRuleSettings; -import com.android.settings.notification.ZenModeExternalRuleSettings; import com.android.settings.notification.ZenModePrioritySettings; import com.android.settings.notification.ZenModeSettings; import com.android.settings.notification.ZenModeScheduleRuleSettings; @@ -348,7 +347,6 @@ public class SettingsActivity extends Activity ZenModeAutomationSettings.class.getName(), ZenModeScheduleRuleSettings.class.getName(), ZenModeEventRuleSettings.class.getName(), - ZenModeExternalRuleSettings.class.getName(), ProcessStatsUi.class.getName(), PowerUsageDetail.class.getName(), ProcessStatsSummary.class.getName(), diff --git a/src/com/android/settings/notification/ZenModeAutomationSettings.java b/src/com/android/settings/notification/ZenModeAutomationSettings.java index 46212c2768f..02fb10fd81f 100644 --- a/src/com/android/settings/notification/ZenModeAutomationSettings.java +++ b/src/com/android/settings/notification/ZenModeAutomationSettings.java @@ -42,7 +42,6 @@ import android.view.View; import com.android.internal.logging.MetricsLogger; import com.android.settings.R; import com.android.settings.notification.ManagedServiceSettings.Config; -import com.android.settings.notification.ZenRuleNameDialog.RuleInfo; import java.lang.ref.WeakReference; import java.util.Arrays; @@ -92,14 +91,30 @@ public class ZenModeAutomationSettings extends ZenModeSettingsBase { } private void showAddRuleDialog() { + new ZenRuleSelectionDialog(mContext, mServiceListing) { + @Override + public void onSystemRuleSelected(ZenRuleInfo ri) { + showNameRuleDialog(ri); + } + + @Override + public void onExternalRuleSelected(ZenRuleInfo ri) { + Intent intent = new Intent().setComponent(ri.configurationActivity); + startActivity(intent); + } + }.show(); + } + + private void showNameRuleDialog(final ZenRuleInfo ri) { new ZenRuleNameDialog(mContext, mServiceListing, null, mRules) { @Override - public void onOk(String ruleName, RuleInfo ri) { + public void onOk(String ruleName) { MetricsLogger.action(mContext, MetricsLogger.ACTION_ZEN_ADD_RULE_OK); - AutomaticZenRule rule = new AutomaticZenRule(ruleName, ri.serviceComponent, ri.defaultConditionId, - NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); + AutomaticZenRule rule = new AutomaticZenRule(ruleName, ri.serviceComponent, + ri.defaultConditionId, NotificationManager.INTERRUPTION_FILTER_PRIORITY, + true); if (setZenRule(rule)) { - showRule(ri.settingsAction, ri.configurationActivity, rule.getName()); + startActivity(getRuleIntent(ri.settingsAction, null, rule.getName())); } } }.show(); @@ -120,12 +135,17 @@ public class ZenModeAutomationSettings extends ZenModeSettingsBase { .show(); } - private void showRule(String settingsAction, ComponentName configurationActivity, + private Intent getRuleIntent(String settingsAction, ComponentName configurationActivity, String ruleName) { - if (DEBUG) Log.d(TAG, "showRule name=" + ruleName); - mContext.startActivity(new Intent(settingsAction) + Intent intent = new Intent() .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) - .putExtra(ZenModeRuleSettingsBase.EXTRA_RULE_NAME, ruleName)); + .putExtra(ConditionProviderService.EXTRA_RULE_NAME, ruleName); + if (configurationActivity != null) { + intent.setComponent(configurationActivity); + } else { + intent.setAction(settingsAction); + } + return intent; } private AutomaticZenRule[] sortedRules() { @@ -201,9 +221,10 @@ public class ZenModeAutomationSettings extends ZenModeSettingsBase { @Override public void onServicesReloaded(List services) { for (ServiceInfo service : services) { - final RuleInfo ri = ZenModeExternalRuleSettings.getRuleInfo(service); + final ZenRuleInfo ri = getRuleInfo(service); if (ri != null && ri.serviceComponent != null - && Objects.equals(ri.settingsAction, ZenModeExternalRuleSettings.ACTION)) { + && Objects.equals(ri.settingsAction, + Settings.ACTION_ZEN_MODE_EXTERNAL_RULE_SETTINGS)) { if (!mServiceListing.isEnabled(ri.serviceComponent)) { Log.i(TAG, "Enabling external condition provider: " + ri.serviceComponent); mServiceListing.setEnabled(ri.serviceComponent, true); @@ -213,6 +234,33 @@ public class ZenModeAutomationSettings extends ZenModeSettingsBase { } }; + public static ZenRuleInfo getRuleInfo(ServiceInfo si) { + if (si == null || si.metaData == null) return null; + final String ruleType = si.metaData.getString(ConditionProviderService.META_DATA_RULE_TYPE); + final String defaultConditionId = + si.metaData.getString(ConditionProviderService.META_DATA_DEFAULT_CONDITION_ID); + if (ruleType != null && !ruleType.trim().isEmpty() && defaultConditionId != null) { + final ZenRuleInfo ri = new ZenRuleInfo(); + ri.settingsAction = Settings.ACTION_ZEN_MODE_EXTERNAL_RULE_SETTINGS; + ri.title = ruleType; + ri.packageName = si.packageName; + ri.configurationActivity = getSettingsActivity(si); + + return ri; + } + return null; + } + + private static ComponentName getSettingsActivity(ServiceInfo si) { + if (si == null || si.metaData == null) return null; + final String configurationActivity = + si.metaData.getString(ConditionProviderService.META_DATA_CONFIGURATION_ACTIVITY); + if (configurationActivity != null) { + return ComponentName.unflattenFromString(configurationActivity); + } + return null; + } + // TODO: Sort by creation date, once that data is available. private static final Comparator RULE_COMPARATOR = new Comparator() { @@ -243,8 +291,7 @@ public class ZenModeAutomationSettings extends ZenModeSettingsBase { final boolean isSystemRule = isSchedule || isEvent; try { - ApplicationInfo info = mPm.getApplicationInfo( - rule.getOwner().getPackageName(), 0); + ApplicationInfo info = mPm.getApplicationInfo(rule.getOwner().getPackageName(), 0); LoadIconTask task = new LoadIconTask(this); task.execute(info); setSummary(computeRuleSummary(rule, isSystemRule, info.loadLabel(mPm))); @@ -254,16 +301,13 @@ public class ZenModeAutomationSettings extends ZenModeSettingsBase { setTitle(rule.getName()); setPersistent(false); - setOnPreferenceClickListener(new OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - final String action = isSchedule ? ZenModeScheduleRuleSettings.ACTION - : isEvent ? ZenModeEventRuleSettings.ACTION - : ZenModeExternalRuleSettings.ACTION; - showRule(action, null, rule.getName()); - return true; - } - }); + + final String action = isSchedule ? ZenModeScheduleRuleSettings.ACTION + : isEvent ? ZenModeEventRuleSettings.ACTION : ""; + ServiceInfo si = mServiceListing.findService(mContext, CONFIG, rule.getOwner()); + ComponentName settingsActivity = getSettingsActivity(si); + setIntent(getRuleIntent(action, settingsActivity, rule.getName())); + setWidgetLayoutResource(R.layout.zen_rule_widget); } diff --git a/src/com/android/settings/notification/ZenModeExternalRuleSettings.java b/src/com/android/settings/notification/ZenModeExternalRuleSettings.java deleted file mode 100644 index c2ade6a31d0..00000000000 --- a/src/com/android/settings/notification/ZenModeExternalRuleSettings.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (C) 2015 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.Activity; -import android.app.AutomaticZenRule; -import android.content.ComponentName; -import android.content.Intent; -import android.content.pm.ServiceInfo; -import android.net.Uri; -import android.preference.Preference; -import android.preference.Preference.OnPreferenceClickListener; -import android.preference.PreferenceScreen; -import android.provider.Settings; -import android.service.notification.ConditionProviderService; -import android.util.Log; - -import com.android.internal.logging.MetricsLogger; -import com.android.settings.R; -import com.android.settings.notification.ZenRuleNameDialog.RuleInfo; - -public class ZenModeExternalRuleSettings extends ZenModeRuleSettingsBase { - private static final String KEY_TYPE = "type"; - private static final String KEY_CONFIGURE = "configure"; - - public static final String ACTION = Settings.ACTION_ZEN_MODE_EXTERNAL_RULE_SETTINGS; - private static final int REQUEST_CODE_CONFIGURE = 1; - - private Preference mType; - private Preference mConfigure; - - @Override - protected boolean setRule(AutomaticZenRule rule) { - return rule != null; - } - - @Override - protected String getZenModeDependency() { - return null; - } - - @Override - protected int getEnabledToastText() { - return 0; - } - - @Override - protected void onCreateInternal() { - addPreferencesFromResource(R.xml.zen_mode_external_rule_settings); - final PreferenceScreen root = getPreferenceScreen(); - final ServiceInfo si = ServiceListing.findService(mContext, - ZenModeAutomationSettings.CONFIG, mRule.getOwner()); - if (DEBUG) Log.d(TAG, "ServiceInfo: " + si); - final RuleInfo ri = getRuleInfo(si); - if (DEBUG) Log.d(TAG, "RuleInfo: " + ri); - mType = root.findPreference(KEY_TYPE); - if (ri == null) { - mType.setSummary(R.string.zen_mode_rule_type_unknown); - } else { - mType.setSummary(ri.caption); - } - - mConfigure = root.findPreference(KEY_CONFIGURE); - if (ri == null || ri.configurationActivity == null) { - mConfigure.setEnabled(false); - } else { - mConfigure.setOnPreferenceClickListener(new OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - Intent intent = new Intent().setComponent(ri.configurationActivity); - intent.putExtra(ConditionProviderService.EXTRA_RULE_NAME, mRule.getName()); - intent.putExtra(ConditionProviderService.EXTRA_CONDITION_ID, - mRule.getConditionId()); - startActivityForResult(intent, REQUEST_CODE_CONFIGURE); - return true; - } - }); - } - } - - @Override - public void onActivityResult(int requestCode, int resultCode, Intent data) { - super.onActivityResult(requestCode, resultCode, data); - if (requestCode == REQUEST_CODE_CONFIGURE) { - if (resultCode == Activity.RESULT_OK && data != null) { - final Uri conditionId = - data.getParcelableExtra(ConditionProviderService.EXTRA_CONDITION_ID); - if (conditionId != null && !conditionId.equals(mRule.getConditionId())) { - updateRule(conditionId); - } - } - } - } - - public static RuleInfo getRuleInfo(ServiceInfo si) { - if (si == null || si.metaData == null) return null; - final String ruleType = si.metaData.getString(ConditionProviderService.META_DATA_RULE_TYPE); - final String defaultConditionId = - si.metaData.getString(ConditionProviderService.META_DATA_DEFAULT_CONDITION_ID); - final String configurationActivity = - si.metaData.getString(ConditionProviderService.META_DATA_CONFIGURATION_ACTIVITY); - if (ruleType != null && !ruleType.trim().isEmpty() && defaultConditionId != null) { - final RuleInfo ri = new RuleInfo(); - ri.serviceComponent = new ComponentName(si.packageName, si.name); - ri.settingsAction = ZenModeExternalRuleSettings.ACTION; - ri.caption = ruleType; - ri.defaultConditionId = Uri.parse(defaultConditionId); - if (configurationActivity != null) { - ri.configurationActivity = ComponentName.unflattenFromString(configurationActivity); - } - return ri; - } - return null; - } - - @Override - protected void updateControlsInternal() { - // everything done up front - } - - @Override - protected int getMetricsCategory() { - return MetricsLogger.NOTIFICATION_ZEN_MODE_EXTERNAL_RULE; - } - -} diff --git a/src/com/android/settings/notification/ZenModeRuleSettingsBase.java b/src/com/android/settings/notification/ZenModeRuleSettingsBase.java index 1f17acec72a..580fee1fda7 100644 --- a/src/com/android/settings/notification/ZenModeRuleSettingsBase.java +++ b/src/com/android/settings/notification/ZenModeRuleSettingsBase.java @@ -29,6 +29,7 @@ import android.preference.Preference; import android.preference.Preference.OnPreferenceChangeListener; import android.preference.Preference.OnPreferenceClickListener; import android.preference.PreferenceScreen; +import android.service.notification.ConditionProviderService; import android.util.Log; import android.view.Menu; import android.view.MenuInflater; @@ -48,7 +49,6 @@ public abstract class ZenModeRuleSettingsBase extends ZenModeSettingsBase protected static final String TAG = ZenModeSettingsBase.TAG; protected static final boolean DEBUG = ZenModeSettingsBase.DEBUG; - public static final String EXTRA_RULE_NAME = "rule_name"; private static final String KEY_RULE_NAME = "rule_name"; private static final String KEY_ZEN_MODE = "zen_mode"; @@ -83,7 +83,7 @@ public abstract class ZenModeRuleSettingsBase extends ZenModeSettingsBase return; } - mName = intent.getStringExtra(EXTRA_RULE_NAME); + mName = intent.getStringExtra(ConditionProviderService.EXTRA_RULE_NAME); if (DEBUG) Log.d(TAG, "mName=" + mName); if (refreshRuleOrFinish()) { return; @@ -213,7 +213,7 @@ public abstract class ZenModeRuleSettingsBase extends ZenModeSettingsBase private void showRuleNameDialog() { new ZenRuleNameDialog(mContext, null, mRule.getName(), mRules) { @Override - public void onOk(String ruleName, RuleInfo type) { + public void onOk(String ruleName) { renameZenRule(mRule.getName(), ruleName); } }.show(); diff --git a/src/com/android/settings/notification/ZenRuleInfo.java b/src/com/android/settings/notification/ZenRuleInfo.java new file mode 100644 index 00000000000..46ed4972c24 --- /dev/null +++ b/src/com/android/settings/notification/ZenRuleInfo.java @@ -0,0 +1,14 @@ +package com.android.settings.notification; + +import android.content.ComponentName; +import android.net.Uri; + +public class ZenRuleInfo { + public String packageName; + public String title; + public String settingsAction; + public ComponentName configurationActivity; + public Uri defaultConditionId; + public ComponentName serviceComponent; + public boolean isSystem; +} diff --git a/src/com/android/settings/notification/ZenRuleNameDialog.java b/src/com/android/settings/notification/ZenRuleNameDialog.java index 95515e8bc0d..f26e7e4b9a0 100644 --- a/src/com/android/settings/notification/ZenRuleNameDialog.java +++ b/src/com/android/settings/notification/ZenRuleNameDialog.java @@ -18,46 +18,34 @@ package com.android.settings.notification; import android.app.AlertDialog; import android.app.AutomaticZenRule; -import android.content.ComponentName; import android.content.Context; import android.content.DialogInterface; -import android.content.DialogInterface.OnDismissListener; -import android.content.pm.ServiceInfo; import android.content.res.ColorStateList; -import android.net.Uri; -import android.service.notification.ZenModeConfig; -import android.service.notification.ZenModeConfig.EventInfo; -import android.service.notification.ZenModeConfig.ScheduleInfo; import android.text.Editable; import android.text.TextUtils; import android.text.TextWatcher; import android.util.ArraySet; -import android.util.Log; import android.util.TypedValue; import android.view.LayoutInflater; import android.view.View; import android.widget.EditText; -import android.widget.RadioButton; -import android.widget.RadioGroup; import com.android.settings.R; import java.util.List; public abstract class ZenRuleNameDialog { - private static final String TAG = ZenModeSettings.TAG; + private static final String TAG = "ZenRuleNameDialog"; private static final boolean DEBUG = ZenModeSettings.DEBUG; private final AlertDialog mDialog; private final EditText mEditText; private final View mWarning; - private final RadioGroup mTypes; private final ColorStateList mWarningTint; private final ColorStateList mOriginalTint; private final String mOriginalRuleName; private final ArraySet mExistingNames; private final ServiceListing mServiceListing; - private final RuleInfo[] mExternalRules = new RuleInfo[3]; private final boolean mIsNew; public ZenRuleNameDialog(Context context, ServiceListing serviceListing, String ruleName, @@ -76,16 +64,7 @@ public abstract class ZenRuleNameDialog { context.getTheme().resolveAttribute(android.R.attr.colorAccent, outValue, true); mOriginalTint = ColorStateList.valueOf(outValue.data); mEditText.setSelectAllOnFocus(true); - mTypes = (RadioGroup) v.findViewById(R.id.rule_types); - if (mServiceListing != null) { - bindType(R.id.rule_type_schedule, defaultNewSchedule()); - bindType(R.id.rule_type_event, defaultNewEvent()); - bindExternalRules(); - mServiceListing.addCallback(mServiceListingCallback); - mServiceListing.reload(); - } else { - mTypes.setVisibility(View.GONE); - } + mDialog = new AlertDialog.Builder(context) .setTitle(mIsNew ? R.string.zen_mode_add_rule : R.string.zen_mode_rule_name) .setView(v) @@ -97,15 +76,7 @@ public abstract class ZenRuleNameDialog { && mOriginalRuleName.equalsIgnoreCase(newName)) { return; // no change to an existing rule, just dismiss } - onOk(newName, selectedRuleInfo()); - } - }) - .setOnDismissListener(new OnDismissListener() { - @Override - public void onDismiss(DialogInterface dialog) { - if (mServiceListing != null) { - mServiceListing.removeCallback(mServiceListingCallback); - } + onOk(newName); } }) .setNegativeButton(R.string.cancel, null) @@ -129,7 +100,7 @@ public abstract class ZenRuleNameDialog { mExistingNames = getAutomaticRuleNames(rules); } - abstract public void onOk(String ruleName, RuleInfo ruleInfo); + abstract public void onOk(String ruleName); public void show() { mDialog.show(); @@ -144,26 +115,6 @@ public abstract class ZenRuleNameDialog { return rt; } - private void bindType(int id, RuleInfo ri) { - final RadioButton rb = (RadioButton) mTypes.findViewById(id); - if (ri == null) { - rb.setVisibility(View.GONE); - return; - } - rb.setVisibility(View.VISIBLE); - if (ri.caption != null) { - rb.setText(ri.caption); - } - rb.setTag(ri); - } - - private RuleInfo selectedRuleInfo() { - final int id = mTypes.getCheckedRadioButtonId(); - if (id == -1) return null; - final RadioButton rb = (RadioButton) mTypes.findViewById(id); - return (RuleInfo) rb.getTag(); - } - private String trimmedText() { return mEditText.getText() == null ? null : mEditText.getText().toString().trim(); } @@ -178,62 +129,4 @@ public abstract class ZenRuleNameDialog { mWarning.setVisibility(showWarning ? View.VISIBLE : View.INVISIBLE); mEditText.setBackgroundTintList(showWarning ? mWarningTint : mOriginalTint); } - - private static RuleInfo defaultNewSchedule() { - final ScheduleInfo schedule = new ScheduleInfo(); - schedule.days = ZenModeConfig.ALL_DAYS; - schedule.startHour = 22; - schedule.endHour = 7; - final RuleInfo rt = new RuleInfo(); - rt.settingsAction = ZenModeScheduleRuleSettings.ACTION; - rt.defaultConditionId = ZenModeConfig.toScheduleConditionId(schedule); - rt.serviceComponent = ZenModeConfig.getScheduleConditionProvider(); - return rt; - } - - private static RuleInfo defaultNewEvent() { - final EventInfo event = new EventInfo(); - event.calendar = null; // any calendar - event.reply = EventInfo.REPLY_ANY_EXCEPT_NO; - final RuleInfo rt = new RuleInfo(); - rt.settingsAction = ZenModeEventRuleSettings.ACTION; - rt.defaultConditionId = ZenModeConfig.toEventConditionId(event); - rt.serviceComponent = ZenModeConfig.getEventConditionProvider(); - return rt; - } - - private void bindExternalRules() { - bindType(R.id.rule_type_3, mExternalRules[0]); - bindType(R.id.rule_type_4, mExternalRules[1]); - bindType(R.id.rule_type_5, mExternalRules[2]); - } - - private final ServiceListing.Callback mServiceListingCallback = new ServiceListing.Callback() { - @Override - public void onServicesReloaded(List services) { - if (DEBUG) Log.d(TAG, "Services reloaded: count=" + services.size()); - mExternalRules[0] = mExternalRules[1] = mExternalRules[2] = null; - int i = 0; - for (ServiceInfo si : services) { - final RuleInfo ri = ZenModeExternalRuleSettings.getRuleInfo(si); - if (ri != null) { - mExternalRules[i] = ri; - i++; - if (i == mExternalRules.length) { - break; - } - } - } - bindExternalRules(); - } - }; - - public static class RuleInfo { - public String caption; - public String settingsAction; - public Uri defaultConditionId; - public ComponentName serviceComponent; - public ComponentName configurationActivity; - } - } \ No newline at end of file diff --git a/src/com/android/settings/notification/ZenRuleSelectionDialog.java b/src/com/android/settings/notification/ZenRuleSelectionDialog.java new file mode 100644 index 00000000000..997180a3a6a --- /dev/null +++ b/src/com/android/settings/notification/ZenRuleSelectionDialog.java @@ -0,0 +1,192 @@ +/* + * Copyright (C) 2015 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 com.android.settings.R; + +import android.app.AlertDialog; +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.service.notification.ZenModeConfig; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; + +import java.lang.ref.WeakReference; +import java.util.ArrayList; +import java.util.List; + +public abstract class ZenRuleSelectionDialog { + private static final String TAG = "ZenRuleSelectionDialog"; + private static final boolean DEBUG = ZenModeSettings.DEBUG; + + private final Context mContext; + private final PackageManager mPm; + private final AlertDialog mDialog; + private final LinearLayout mRuleContainer; + private final ServiceListing mServiceListing; + private final List mExternalRuleTypes = new ArrayList(); + + public ZenRuleSelectionDialog(Context context, ServiceListing serviceListing) { + mContext = context; + mPm = context.getPackageManager(); + mServiceListing = serviceListing; + final View v = + LayoutInflater.from(context).inflate(R.layout.zen_rule_type_selection, null, false); + + mRuleContainer = (LinearLayout) v.findViewById(R.id.rule_container); + if (mServiceListing != null) { + bindType(defaultNewSchedule()); + bindType(defaultNewEvent()); + bindExternalRules(); + mServiceListing.addCallback(mServiceListingCallback); + mServiceListing.reload(); + } + mDialog = new AlertDialog.Builder(context) + .setTitle(R.string.zen_mode_choose_rule_type) + .setView(v) + .setOnDismissListener(new OnDismissListener() { + @Override + public void onDismiss(DialogInterface dialog) { + if (mServiceListing != null) { + mServiceListing.removeCallback(mServiceListingCallback); + } + } + }) + .setNegativeButton(R.string.cancel, null) + .create(); + } + + public void show() { + mDialog.show(); + } + + 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); + final LinearLayout v = (LinearLayout) LayoutInflater.from(mContext).inflate( + R.layout.zen_rule_type, null, false); + + LoadIconTask task = new LoadIconTask((ImageView) v.findViewById(R.id.icon)); + task.execute(info); + ((TextView) v.findViewById(R.id.title)).setText(ri.title); + if (!ri.isSystem) { + TextView subtitle = (TextView) v.findViewById(R.id.subtitle); + subtitle.setText(info.loadLabel(mPm)); + subtitle.setVisibility(View.VISIBLE); + } + v.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + mDialog.dismiss(); + if (ri.isSystem) { + onSystemRuleSelected(ri); + } else { + onExternalRuleSelected(ri); + } + } + }); + mRuleContainer.addView(v); + } catch (PackageManager.NameNotFoundException e) { + // Omit rule. + } + } + + private ZenRuleInfo defaultNewSchedule() { + final ZenModeConfig.ScheduleInfo schedule = new ZenModeConfig.ScheduleInfo(); + schedule.days = ZenModeConfig.ALL_DAYS; + schedule.startHour = 22; + schedule.endHour = 7; + final ZenRuleInfo rt = new ZenRuleInfo(); + rt.settingsAction = ZenModeScheduleRuleSettings.ACTION; + rt.title = mContext.getString(R.string.zen_schedule_rule_type_name); + rt.packageName = ZenModeConfig.getEventConditionProvider().getPackageName(); + rt.defaultConditionId = ZenModeConfig.toScheduleConditionId(schedule); + rt.serviceComponent = ZenModeConfig.getScheduleConditionProvider(); + rt.isSystem = true; + return rt; + } + + private ZenRuleInfo defaultNewEvent() { + final ZenModeConfig.EventInfo event = new ZenModeConfig.EventInfo(); + event.calendar = null; // any calendar + event.reply = ZenModeConfig.EventInfo.REPLY_ANY_EXCEPT_NO; + final ZenRuleInfo rt = new ZenRuleInfo(); + rt.settingsAction = ZenModeEventRuleSettings.ACTION; + rt.title = mContext.getString(R.string.zen_event_rule_type_name); + rt.packageName = ZenModeConfig.getScheduleConditionProvider().getPackageName(); + rt.defaultConditionId = ZenModeConfig.toEventConditionId(event); + rt.serviceComponent = ZenModeConfig.getEventConditionProvider(); + rt.isSystem = true; + return rt; + } + + private void bindExternalRules() { + for (ZenRuleInfo ri : mExternalRuleTypes) { + bindType(ri); + } + } + + private final ServiceListing.Callback mServiceListingCallback = new ServiceListing.Callback() { + @Override + public void onServicesReloaded(List services) { + if (DEBUG) Log.d(TAG, "Services reloaded: count=" + services.size()); + for (ServiceInfo si : services) { + final ZenRuleInfo ri = ZenModeAutomationSettings.getRuleInfo(si); + if (ri != null && ri.configurationActivity != null) { + mExternalRuleTypes.add(ri); + } + } + bindExternalRules(); + } + }; + + private class LoadIconTask extends AsyncTask { + private final WeakReference viewReference; + + public LoadIconTask(ImageView view) { + viewReference = new WeakReference<>(view); + } + + @Override + protected Drawable doInBackground(ApplicationInfo... params) { + return params[0].loadIcon(mPm); + } + + @Override + protected void onPostExecute(Drawable icon) { + if (icon != null) { + final ImageView view = viewReference.get(); + if (view != null) { + view.setImageDrawable(icon); + } + } + } + } +} \ No newline at end of file