From 39581cc16d3c44acc8f0881d8e63afe53acaa1c1 Mon Sep 17 00:00:00 2001 From: John Spurlock Date: Fri, 10 Apr 2015 11:59:01 -0400 Subject: [PATCH] Zen: Support external condition providers. - Manage provider subscriptions for external condition providers within ZenModeConditions. - Move "is automatic rule active" check into common location. - Add constant for external rule setting configuration page. - Consolidate log tags. - Reset rule snoozing on boot. Bug: 20064962 Change-Id: Ida207dbf363f61e1727974e611f43f27c23accfb --- core/java/android/provider/Settings.java | 9 +++ .../service/notification/ZenModeConfig.java | 11 ++- .../internal/logging/MetricsLogger.java | 3 +- .../notification/ConditionProviders.java | 14 ++++ .../CountdownConditionProvider.java | 2 +- .../ScheduleConditionProvider.java | 2 +- .../notification/ZenModeConditions.java | 78 +++++++++++++++---- .../server/notification/ZenModeHelper.java | 5 +- 8 files changed, 97 insertions(+), 27 deletions(-) diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 3087e1dc3bb2b..9edf6ad42b202 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -888,6 +888,15 @@ public final class Settings { public static final String ACTION_ZEN_MODE_SCHEDULE_RULE_SETTINGS = "android.settings.ZEN_MODE_SCHEDULE_RULE_SETTINGS"; + /** + * Activity Action: Show Zen Mode external rule configuration settings. + * + * @hide + */ + @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) + public static final String ACTION_ZEN_MODE_EXTERNAL_RULE_SETTINGS + = "android.settings.ZEN_MODE_EXTERNAL_RULE_SETTINGS"; + /** * Activity Action: Show the regulatory information screen for the device. *

diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java index 56eb51066db29..1ed47791aa5f3 100644 --- a/core/java/android/service/notification/ZenModeConfig.java +++ b/core/java/android/service/notification/ZenModeConfig.java @@ -654,8 +654,7 @@ public class ZenModeConfig implements Parcelable { } String summary = ""; for (ZenRule automaticRule : config.automaticRules.values()) { - if (automaticRule.enabled && !automaticRule.snoozing - && automaticRule.isTrueOrUnknown()) { + if (automaticRule.isAutomaticActive()) { if (summary.isEmpty()) { summary = automaticRule.name; } else { @@ -745,9 +744,13 @@ public class ZenModeConfig implements Parcelable { component); } + public boolean isAutomaticActive() { + return enabled && !snoozing && component != null && isTrueOrUnknown(); + } + public boolean isTrueOrUnknown() { - return condition == null || condition.state == Condition.STATE_TRUE - || condition.state == Condition.STATE_UNKNOWN; + return condition != null && (condition.state == Condition.STATE_TRUE + || condition.state == Condition.STATE_UNKNOWN); } public static final Parcelable.Creator CREATOR diff --git a/core/java/com/android/internal/logging/MetricsLogger.java b/core/java/com/android/internal/logging/MetricsLogger.java index 6be6389ae314f..24b5d0da36500 100644 --- a/core/java/com/android/internal/logging/MetricsLogger.java +++ b/core/java/com/android/internal/logging/MetricsLogger.java @@ -26,9 +26,10 @@ import android.os.Build; */ public class MetricsLogger implements MetricsConstants { // These constants are temporary, they should migrate to MetricsConstants. - // next value is 145; + // next value is 146; public static final int NOTIFICATION_ZEN_MODE_SCHEDULE_RULE = 144; + public static final int NOTIFICATION_ZEN_MODE_EXTERNAL_RULE = 145; public static void visible(Context context, int category) throws IllegalArgumentException { if (Build.IS_DEBUGGABLE && category == VIEW_UNKNOWN) { diff --git a/services/core/java/com/android/server/notification/ConditionProviders.java b/services/core/java/com/android/server/notification/ConditionProviders.java index fc2eceda17feb..b36fcd2cc09c6 100644 --- a/services/core/java/com/android/server/notification/ConditionProviders.java +++ b/services/core/java/com/android/server/notification/ConditionProviders.java @@ -142,6 +142,9 @@ public class ConditionProviders extends ManagedServices { } catch (RemoteException e) { // we tried } + if (mCallback != null) { + mCallback.onServiceAdded(info.component); + } } @Override @@ -246,6 +249,16 @@ public class ConditionProviders extends ManagedServices { } } + public IConditionProvider findConditionProvider(ComponentName component) { + if (component == null) return null; + for (ManagedServiceInfo service : mServices) { + if (component.equals(service.component)) { + return provider(service); + } + } + return null; + } + public void ensureRecordExists(ComponentName component, Uri conditionId, IConditionProvider provider) { // constructed by convention, make sure the record exists... @@ -378,6 +391,7 @@ public class ConditionProviders extends ManagedServices { public interface Callback { void onBootComplete(); + void onServiceAdded(ComponentName component); void onConditionChanged(Uri id, Condition condition); void onUserSwitched(); } diff --git a/services/core/java/com/android/server/notification/CountdownConditionProvider.java b/services/core/java/com/android/server/notification/CountdownConditionProvider.java index d223353f95821..6a04688cf5ad1 100644 --- a/services/core/java/com/android/server/notification/CountdownConditionProvider.java +++ b/services/core/java/com/android/server/notification/CountdownConditionProvider.java @@ -38,7 +38,7 @@ import java.util.Date; /** Built-in zen condition provider for simple time-based conditions */ public class CountdownConditionProvider extends SystemConditionProviderService { - private static final String TAG = "CountdownConditions"; + private static final String TAG = "ConditionProviders"; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); public static final ComponentName COMPONENT = diff --git a/services/core/java/com/android/server/notification/ScheduleConditionProvider.java b/services/core/java/com/android/server/notification/ScheduleConditionProvider.java index c997e45530d14..383d56c62fc5b 100644 --- a/services/core/java/com/android/server/notification/ScheduleConditionProvider.java +++ b/services/core/java/com/android/server/notification/ScheduleConditionProvider.java @@ -43,7 +43,7 @@ import java.util.TimeZone; * Built-in zen condition provider for daily scheduled time-based conditions. */ public class ScheduleConditionProvider extends SystemConditionProviderService { - private static final String TAG = "ScheduleConditions"; + private static final String TAG = "ConditionProviders"; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); public static final ComponentName COMPONENT = diff --git a/services/core/java/com/android/server/notification/ZenModeConditions.java b/services/core/java/com/android/server/notification/ZenModeConditions.java index 67a2a5439efbe..766d6c55e71ec 100644 --- a/services/core/java/com/android/server/notification/ZenModeConditions.java +++ b/services/core/java/com/android/server/notification/ZenModeConditions.java @@ -20,6 +20,7 @@ import android.content.ComponentName; import android.net.Uri; import android.service.notification.Condition; import android.service.notification.IConditionListener; +import android.service.notification.IConditionProvider; import android.service.notification.ZenModeConfig; import android.service.notification.ZenModeConfig.ZenRule; import android.util.ArrayMap; @@ -39,6 +40,7 @@ public class ZenModeConditions implements ConditionProviders.Callback { private CountdownConditionProvider mCountdown; private ScheduleConditionProvider mSchedule; + private boolean mFirstEvaluation = true; public ZenModeConditions(ZenModeHelper helper, ConditionProviders conditionProviders) { mHelper = helper; @@ -64,7 +66,8 @@ public class ZenModeConditions implements ConditionProviders.Callback { public void evaluateConfig(ZenModeConfig config) { if (config == null) return; - if (config.manualRule != null && !config.manualRule.isTrueOrUnknown()) { + if (config.manualRule != null && config.manualRule.condition != null + && !config.manualRule.isTrueOrUnknown()) { if (DEBUG) Log.d(TAG, "evaluateConfig: clearing manual rule"); config.manualRule = null; } @@ -72,6 +75,7 @@ public class ZenModeConditions implements ConditionProviders.Callback { evaluateRule(config.manualRule, current); for (ZenRule automaticRule : config.automaticRules.values()) { evaluateRule(automaticRule, current); + updateSnoozing(automaticRule); } final int N = mSubscriptions.size(); for (int i = N - 1; i >= 0; i--) { @@ -82,21 +86,7 @@ public class ZenModeConditions implements ConditionProviders.Callback { mSubscriptions.removeAt(i); } } - } - - private void evaluateRule(ZenRule rule, ArraySet current) { - if (rule == null || rule.conditionId == null) return; - final Uri id = rule.conditionId; - for (SystemConditionProviderService sp : mConditionProviders.getSystemProviders()) { - if (sp.isValidConditionid(id)) { - mConditionProviders.ensureRecordExists(sp.getComponent(), id, sp.asInterface()); - rule.component = sp.getComponent(); - } - } - current.add(id); - if (mConditionProviders.subscribeIfNecessary(rule.component, rule.conditionId)) { - mSubscriptions.put(rule.conditionId, rule.component); - } + mFirstEvaluation = false; } @Override @@ -109,6 +99,14 @@ public class ZenModeConditions implements ConditionProviders.Callback { // noop } + @Override + public void onServiceAdded(ComponentName component) { + if (DEBUG) Log.d(TAG, "onServiceAdded " + component); + if (isAutomaticActive(component)) { + mHelper.setConfig(mHelper.getConfig(), "zmc.onServiceAdded"); + } + } + @Override public void onConditionChanged(Uri id, Condition condition) { if (DEBUG) Log.d(TAG, "onConditionChanged " + id + " " + condition); @@ -125,8 +123,53 @@ public class ZenModeConditions implements ConditionProviders.Callback { } } + private void evaluateRule(ZenRule rule, ArraySet current) { + if (rule == null || rule.conditionId == null) return; + final Uri id = rule.conditionId; + boolean isSystemCondition = false; + for (SystemConditionProviderService sp : mConditionProviders.getSystemProviders()) { + if (sp.isValidConditionid(id)) { + mConditionProviders.ensureRecordExists(sp.getComponent(), id, sp.asInterface()); + rule.component = sp.getComponent(); + isSystemCondition = true; + } + } + if (!isSystemCondition) { + final IConditionProvider cp = mConditionProviders.findConditionProvider(rule.component); + if (DEBUG) Log.d(TAG, "Ensure external rule exists: " + (cp != null) + " for " + id); + if (cp != null) { + mConditionProviders.ensureRecordExists(rule.component, id, cp); + } + } + if (rule.component == null) { + Log.w(TAG, "No component found for automatic rule: " + rule.conditionId); + rule.enabled = false; + return; + } + if (current != null) { + current.add(id); + } + if (mConditionProviders.subscribeIfNecessary(rule.component, rule.conditionId)) { + mSubscriptions.put(rule.conditionId, rule.component); + } else { + if (DEBUG) Log.d(TAG, "zmc failed to subscribe"); + } + } + + private boolean isAutomaticActive(ComponentName component) { + if (component == null) return false; + final ZenModeConfig config = mHelper.getConfig(); + if (config == null) return false; + for (ZenRule rule : config.automaticRules.values()) { + if (component.equals(rule.component) && rule.isAutomaticActive()) { + return true; + } + } + return false; + } + private boolean updateSnoozing(ZenRule rule) { - if (rule != null && rule.snoozing && !rule.isTrueOrUnknown()) { + if (rule != null && rule.snoozing && (mFirstEvaluation || !rule.isTrueOrUnknown())) { rule.snoozing = false; if (DEBUG) Log.d(TAG, "Snoozing reset for " + rule.conditionId); return true; @@ -141,4 +184,5 @@ public class ZenModeConditions implements ConditionProviders.Callback { rule.condition = condition; return true; } + } diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java index e5925fede62b0..683d1fdcbafd3 100644 --- a/services/core/java/com/android/server/notification/ZenModeHelper.java +++ b/services/core/java/com/android/server/notification/ZenModeHelper.java @@ -175,7 +175,7 @@ public class ZenModeHelper { if (zenMode == Global.ZEN_MODE_OFF) { newConfig.manualRule = null; for (ZenRule automaticRule : newConfig.automaticRules.values()) { - if (automaticRule.isTrueOrUnknown()) { + if (automaticRule.isAutomaticActive()) { automaticRule.snoozing = true; } } @@ -286,8 +286,7 @@ public class ZenModeHelper { if (mConfig.manualRule != null) return mConfig.manualRule.zenMode; int zen = Global.ZEN_MODE_OFF; for (ZenRule automaticRule : mConfig.automaticRules.values()) { - if (automaticRule.enabled && !automaticRule.snoozing - && automaticRule.isTrueOrUnknown()) { + if (automaticRule.isAutomaticActive()) { if (zenSeverity(automaticRule.zenMode) > zenSeverity(zen)) { zen = automaticRule.zenMode; }