Update zen rule type selection and view.

Separate rule type selection from naming, launch 3P UI for non-system rules.

Bug: 22977552
Change-Id: Ifbd82da2192c4aaf5f239a188a016d9e1af542d6
This commit is contained in:
Julia Reynolds
2015-09-29 08:15:43 -04:00
parent a3b0c07a57
commit f7748e4ae1
11 changed files with 378 additions and 312 deletions

View File

@@ -43,37 +43,4 @@
android:textColor="@color/zen_rule_name_warning"
android:text="@string/zen_mode_rule_name_warning" />
<RadioGroup
android:id="@+id/rule_types"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="22dp"
android:layout_marginRight="22dp"
android:orientation="vertical"
android:checkedButton="@+id/rule_type_schedule" >
<RadioButton android:id="@+id/rule_type_schedule"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/zen_schedule_rule_type_name" />
<RadioButton android:id="@+id/rule_type_event"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/zen_event_rule_type_name" />
<RadioButton android:id="@+id/rule_type_3"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<RadioButton android:id="@+id/rule_type_4"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<RadioButton android:id="@+id/rule_type_5"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</RadioGroup>
</LinearLayout>

View File

@@ -0,0 +1,62 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeight"
android:gravity="center_vertical"
android:paddingEnd="?android:attr/scrollbarSize"
android:background="?android:attr/selectableItemBackground" >
<ImageView
android:id="@+id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
/>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="15dip"
android:layout_marginEnd="6dip"
android:layout_marginTop="6dip"
android:layout_marginBottom="6dip"
android:layout_weight="1">
<TextView android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:textSize="16sp"
android:ellipsize="marquee"
android:textAppearance="@android:style/TextAppearance.Material.Body1"
android:fadingEdge="horizontal" />
<TextView android:id="@+id/subtitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/title"
android:layout_alignStart="@id/title"
android:textSize="14sp"
android:textColor="?android:attr/textColorSecondary"
android:textAppearance="@android:style/TextAppearance.Material.Subhead"
android:maxLines="2"
android:visibility="gone" />
</RelativeLayout>
</LinearLayout>

View File

@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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.
-->
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scrollbarStyle="outsideOverlay"
android:fastScrollEnabled="true"
android:paddingStart="24dp"
android:paddingEnd="24dp"
android:paddingTop="20dp"
android:paddingBottom="24dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="@+id/rule_container" />
</ScrollView>

View File

@@ -6214,6 +6214,9 @@
<!-- [CHAR LIMIT=40] Zen mode settings: Delete rule menu option name -->
<string name="zen_mode_delete_rule">Delete rule</string>
<!-- [CHAR LIMIT=60] Zen mode settings: Choose rule type dialog title -->
<string name="zen_mode_choose_rule_type">Choose rule type</string>
<!-- [CHAR LIMIT=40] Zen mode settings: Delete rule dialog confirmation message -->
<string name="zen_mode_delete_rule_confirmation">Delete \u201c<xliff:g id="rule" example="Weekends">%1$s</xliff:g>\u201d rule?</string>

View File

@@ -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(),

View File

@@ -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<ServiceInfo> 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<AutomaticZenRule> RULE_COMPARATOR =
new Comparator<AutomaticZenRule>() {
@@ -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);
}

View File

@@ -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;
}
}

View File

@@ -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();

View File

@@ -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;
}

View File

@@ -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<String> 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<ServiceInfo> 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;
}
}

View File

@@ -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<ZenRuleInfo> mExternalRuleTypes = new ArrayList<ZenRuleInfo>();
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<ServiceInfo> 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<ApplicationInfo, Void, Drawable> {
private final WeakReference<ImageView> 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);
}
}
}
}
}