Methods Summary |
---|
protected android.os.IInterface | asInterface(android.os.IBinder binder)
return IConditionProvider.Stub.asInterface(binder);
|
public ManagedServiceInfo | checkServiceToken(android.service.notification.IConditionProvider provider)
synchronized(mMutex) {
return checkServiceTokenLocked(provider);
}
|
public void | dump(java.io.PrintWriter pw, com.android.server.notification.NotificationManagerService.DumpFilter filter)
super.dump(pw, filter);
synchronized(mMutex) {
if (filter == null) {
pw.print(" mListeners("); pw.print(mListeners.size()); pw.println("):");
for (int i = 0; i < mListeners.size(); i++) {
pw.print(" "); pw.println(mListeners.keyAt(i));
}
}
pw.print(" mRecords("); pw.print(mRecords.size()); pw.println("):");
for (int i = 0; i < mRecords.size(); i++) {
final ConditionRecord r = mRecords.get(i);
if (filter != null && !filter.matches(r.component)) continue;
pw.print(" "); pw.println(r);
final String countdownDesc = CountdownConditionProvider.tryParseDescription(r.id);
if (countdownDesc != null) {
pw.print(" ("); pw.print(countdownDesc); pw.println(")");
}
}
}
pw.print(" mSystemConditionProviders: "); pw.println(mSystemConditionProviders);
if (mCountdown != null) {
mCountdown.dump(pw, filter);
}
if (mDowntime != null) {
mDowntime.dump(pw, filter);
}
if (mNextAlarm != null) {
mNextAlarm.dump(pw, filter);
}
if (mNextAlarmTracker != null) {
mNextAlarmTracker.dump(pw, filter);
}
|
private void | ensureRecordExists(android.service.notification.Condition condition, android.service.notification.IConditionProvider provider, android.content.ComponentName component)
// constructed by convention, make sure the record exists...
final ConditionRecord r = getRecordLocked(condition.id, component);
if (r.info == null) {
// ... and is associated with the in-process service
r.info = checkServiceTokenLocked(provider);
}
|
public android.service.notification.Condition[] | getAutomaticZenModeConditions()
synchronized(mMutex) {
final int N = mRecords.size();
ArrayList<Condition> rt = null;
for (int i = 0; i < N; i++) {
final ConditionRecord r = mRecords.get(i);
if (r.isAutomatic && r.condition != null) {
if (rt == null) rt = new ArrayList<Condition>();
rt.add(r.condition);
}
}
return rt == null ? NO_CONDITIONS : rt.toArray(new Condition[rt.size()]);
}
|
protected Config | getConfig()
Config c = new Config();
c.caption = "condition provider";
c.serviceInterface = ConditionProviderService.SERVICE_INTERFACE;
c.secureSettingName = Settings.Secure.ENABLED_CONDITION_PROVIDERS;
c.bindPermission = android.Manifest.permission.BIND_CONDITION_PROVIDER_SERVICE;
c.settingsAction = Settings.ACTION_CONDITION_PROVIDER_SETTINGS;
c.clientLabel = R.string.condition_provider_service_binding_label;
return c;
|
private com.android.server.notification.ConditionProviders$ConditionRecord | getRecordLocked(android.net.Uri id, android.content.ComponentName component)
final int N = mRecords.size();
for (int i = 0; i < N; i++) {
final ConditionRecord r = mRecords.get(i);
if (r.id.equals(id) && r.component.equals(component)) {
return r;
}
}
final ConditionRecord r = new ConditionRecord(id, component);
mRecords.add(r);
return r;
|
public boolean | isSystemConditionProviderEnabled(java.lang.String path)
return mSystemConditionProviders.contains(path);
|
private void | loadZenConfig()
final ZenModeConfig config = mZenModeHelper.getConfig();
if (config == null) {
if (DEBUG) Slog.d(TAG, "loadZenConfig: no config");
return;
}
synchronized (mMutex) {
final boolean changingExit = !Objects.equals(mExitCondition, config.exitCondition);
mExitCondition = config.exitCondition;
mExitConditionComponent = config.exitConditionComponent;
if (changingExit) {
ZenLog.traceExitCondition(mExitCondition, mExitConditionComponent, "config");
}
if (mDowntime != null) {
mDowntime.setConfig(config);
}
if (config.conditionComponents == null || config.conditionIds == null
|| config.conditionComponents.length != config.conditionIds.length) {
if (DEBUG) Slog.d(TAG, "loadZenConfig: no conditions");
setAutomaticZenModeConditions(null, false /*save*/);
return;
}
final ArraySet<Uri> newIds = new ArraySet<Uri>();
final int N = config.conditionComponents.length;
for (int i = 0; i < N; i++) {
final ComponentName component = config.conditionComponents[i];
final Uri id = config.conditionIds[i];
if (component != null && id != null) {
getRecordLocked(id, component); // ensure record exists
newIds.add(id);
}
}
if (DEBUG) Slog.d(TAG, "loadZenConfig: N=" + N);
setAutomaticZenModeConditions(newIds.toArray(new Uri[newIds.size()]), false /*save*/);
}
|
public void | notifyConditions(java.lang.String pkg, ManagedServiceInfo info, android.service.notification.Condition[] conditions)
synchronized(mMutex) {
if (DEBUG) Slog.d(TAG, "notifyConditions pkg=" + pkg + " info=" + info + " conditions="
+ (conditions == null ? null : Arrays.asList(conditions)));
conditions = validateConditions(pkg, conditions);
if (conditions == null || conditions.length == 0) return;
final int N = conditions.length;
for (IConditionListener listener : mListeners.values()) {
try {
listener.onConditionsReceived(conditions);
} catch (RemoteException e) {
Slog.w(TAG, "Error sending conditions to listener " + listener, e);
}
}
for (int i = 0; i < N; i++) {
final Condition c = conditions[i];
final ConditionRecord r = getRecordLocked(c.id, info.component);
final Condition oldCondition = r.condition;
final boolean conditionUpdate = oldCondition != null && !oldCondition.equals(c);
r.info = info;
r.condition = c;
// if manual, exit zen if false (or failed), update if true (and changed)
if (r.isManual) {
if (c.state == Condition.STATE_FALSE || c.state == Condition.STATE_ERROR) {
final boolean failed = c.state == Condition.STATE_ERROR;
if (failed) {
Slog.w(TAG, "Exit zen: manual condition failed: " + c);
} else if (DEBUG) {
Slog.d(TAG, "Exit zen: manual condition false: " + c);
}
onManualConditionClearing();
mZenModeHelper.setZenMode(Settings.Global.ZEN_MODE_OFF,
"manualConditionExit");
unsubscribeLocked(r);
r.isManual = false;
} else if (c.state == Condition.STATE_TRUE && conditionUpdate) {
if (DEBUG) Slog.d(TAG, "Current condition updated, still true. old="
+ oldCondition + " new=" + c);
setZenModeCondition(c, "conditionUpdate");
}
}
// if automatic, exit zen if false (or failed), enter zen if true
if (r.isAutomatic) {
if (c.state == Condition.STATE_FALSE || c.state == Condition.STATE_ERROR) {
final boolean failed = c.state == Condition.STATE_ERROR;
if (failed) {
Slog.w(TAG, "Exit zen: automatic condition failed: " + c);
} else if (DEBUG) {
Slog.d(TAG, "Exit zen: automatic condition false: " + c);
}
mZenModeHelper.setZenMode(Settings.Global.ZEN_MODE_OFF,
"automaticConditionExit");
} else if (c.state == Condition.STATE_TRUE) {
Slog.d(TAG, "Enter zen: automatic condition true: " + c);
mZenModeHelper.setZenMode(Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS,
"automaticConditionEnter");
}
}
}
}
|
public void | onBootPhaseAppsCanStart()
super.onBootPhaseAppsCanStart();
if (mNextAlarmTracker != null) {
mNextAlarmTracker.init();
}
if (mCountdown != null) {
mCountdown.attachBase(mContext);
registerService(mCountdown.asInterface(), CountdownConditionProvider.COMPONENT,
UserHandle.USER_OWNER);
}
if (mDowntime != null) {
mDowntime.attachBase(mContext);
registerService(mDowntime.asInterface(), DowntimeConditionProvider.COMPONENT,
UserHandle.USER_OWNER);
}
if (mNextAlarm != null) {
mNextAlarm.attachBase(mContext);
registerService(mNextAlarm.asInterface(), NextAlarmConditionProvider.COMPONENT,
UserHandle.USER_OWNER);
}
|
private void | onManualConditionClearing()
if (mDowntime != null) {
mDowntime.onManualConditionClearing();
}
|
protected void | onServiceAdded(ManagedServiceInfo info)
final IConditionProvider provider = provider(info);
try {
provider.onConnected();
} catch (RemoteException e) {
// we tried
}
synchronized (mMutex) {
if (info.component.equals(mExitConditionComponent)) {
// ensure record exists, we'll wire it up and subscribe below
final ConditionRecord manualRecord =
getRecordLocked(mExitCondition.id, mExitConditionComponent);
manualRecord.isManual = true;
}
final int N = mRecords.size();
for(int i = 0; i < N; i++) {
final ConditionRecord r = mRecords.get(i);
if (!r.component.equals(info.component)) continue;
r.info = info;
// if automatic or manual, auto-subscribe
if (r.isAutomatic || r.isManual) {
subscribeLocked(r);
}
}
}
|
protected void | onServiceRemovedLocked(ManagedServiceInfo removed)
if (removed == null) return;
for (int i = mRecords.size() - 1; i >= 0; i--) {
final ConditionRecord r = mRecords.get(i);
if (!r.component.equals(removed.component)) continue;
if (r.isManual) {
// removing the current manual condition, exit zen
onManualConditionClearing();
mZenModeHelper.setZenMode(Global.ZEN_MODE_OFF, "manualServiceRemoved");
}
if (r.isAutomatic) {
// removing an automatic condition, exit zen
mZenModeHelper.setZenMode(Global.ZEN_MODE_OFF, "automaticServiceRemoved");
}
mRecords.remove(i);
}
|
public void | onUserSwitched()
super.onUserSwitched();
if (mNextAlarmTracker != null) {
mNextAlarmTracker.onUserSwitched();
}
|
private static android.service.notification.IConditionProvider | provider(com.android.server.notification.ConditionProviders$ConditionRecord r)
return r == null ? null : provider(r.info);
|
private static android.service.notification.IConditionProvider | provider(ManagedServiceInfo info)
return info == null ? null : (IConditionProvider) info.service;
|
private void | requestConditionsLocked(int flags)
for (ManagedServiceInfo info : mServices) {
final IConditionProvider provider = provider(info);
if (provider == null) continue;
// clear all stored conditions from this provider that we no longer care about
for (int i = mRecords.size() - 1; i >= 0; i--) {
final ConditionRecord r = mRecords.get(i);
if (r.info != info) continue;
if (r.isManual || r.isAutomatic) continue;
mRecords.remove(i);
}
try {
provider.onRequestConditions(flags);
} catch (RemoteException e) {
Slog.w(TAG, "Error requesting conditions from " + info.component, e);
}
}
|
public void | requestZenModeConditions(android.service.notification.IConditionListener callback, int relevance)
synchronized(mMutex) {
if (DEBUG) Slog.d(TAG, "requestZenModeConditions callback=" + callback
+ " relevance=" + Condition.relevanceToString(relevance));
if (callback == null) return;
relevance = relevance & (Condition.FLAG_RELEVANT_NOW | Condition.FLAG_RELEVANT_ALWAYS);
if (relevance != 0) {
mListeners.put(callback.asBinder(), callback);
requestConditionsLocked(relevance);
} else {
mListeners.remove(callback.asBinder());
if (mListeners.isEmpty()) {
requestConditionsLocked(0);
}
}
}
|
private static android.util.ArraySet | safeSet(T items)
final ArraySet<T> rt = new ArraySet<T>();
if (items == null || items.length == 0) return rt;
final int N = items.length;
for (int i = 0; i < N; i++) {
final T item = items[i];
if (item != null) {
rt.add(item);
}
}
return rt;
|
private void | saveZenConfigLocked()
ZenModeConfig config = mZenModeHelper.getConfig();
if (config == null) return;
config = config.copy();
final ArrayList<ConditionRecord> automatic = new ArrayList<ConditionRecord>();
final int automaticN = mRecords.size();
for (int i = 0; i < automaticN; i++) {
final ConditionRecord r = mRecords.get(i);
if (r.isAutomatic) {
automatic.add(r);
}
}
if (automatic.isEmpty()) {
config.conditionComponents = null;
config.conditionIds = null;
} else {
final int N = automatic.size();
config.conditionComponents = new ComponentName[N];
config.conditionIds = new Uri[N];
for (int i = 0; i < N; i++) {
final ConditionRecord r = automatic.get(i);
config.conditionComponents[i] = r.component;
config.conditionIds[i] = r.id;
}
}
config.exitCondition = mExitCondition;
config.exitConditionComponent = mExitConditionComponent;
if (DEBUG) Slog.d(TAG, "Setting zen config to: " + config);
mZenModeHelper.setConfig(config);
|
public void | setAutomaticZenModeConditions(android.net.Uri[] conditionIds)
setAutomaticZenModeConditions(conditionIds, true /*save*/);
|
private void | setAutomaticZenModeConditions(android.net.Uri[] conditionIds, boolean save)
if (DEBUG) Slog.d(TAG, "setAutomaticZenModeConditions "
+ (conditionIds == null ? null : Arrays.asList(conditionIds)));
synchronized(mMutex) {
final ArraySet<Uri> newIds = safeSet(conditionIds);
final int N = mRecords.size();
boolean changed = false;
for (int i = 0; i < N; i++) {
final ConditionRecord r = mRecords.get(i);
final boolean automatic = newIds.contains(r.id);
if (!r.isAutomatic && automatic) {
// subscribe to new automatic
subscribeLocked(r);
r.isAutomatic = true;
changed = true;
} else if (r.isAutomatic && !automatic) {
// unsubscribe from old automatic
unsubscribeLocked(r);
r.isAutomatic = false;
changed = true;
}
}
if (save && changed) {
saveZenConfigLocked();
}
}
|
public void | setZenModeCondition(android.service.notification.Condition condition, java.lang.String reason)
if (DEBUG) Slog.d(TAG, "setZenModeCondition " + condition + " reason=" + reason);
synchronized(mMutex) {
ComponentName conditionComponent = null;
if (condition != null) {
if (mCountdown != null && ZenModeConfig.isValidCountdownConditionId(condition.id)) {
ensureRecordExists(condition, mCountdown.asInterface(),
CountdownConditionProvider.COMPONENT);
}
if (mDowntime != null && ZenModeConfig.isValidDowntimeConditionId(condition.id)) {
ensureRecordExists(condition, mDowntime.asInterface(),
DowntimeConditionProvider.COMPONENT);
}
}
final int N = mRecords.size();
for (int i = 0; i < N; i++) {
final ConditionRecord r = mRecords.get(i);
final boolean idEqual = condition != null && r.id.equals(condition.id);
if (r.isManual && !idEqual) {
// was previous manual condition, unsubscribe
unsubscribeLocked(r);
r.isManual = false;
} else if (idEqual && !r.isManual) {
// is new manual condition, subscribe
subscribeLocked(r);
r.isManual = true;
}
if (idEqual) {
conditionComponent = r.component;
}
}
if (!Objects.equals(mExitCondition, condition)) {
mExitCondition = condition;
mExitConditionComponent = conditionComponent;
ZenLog.traceExitCondition(mExitCondition, mExitConditionComponent, reason);
saveZenConfigLocked();
}
}
|
private void | subscribeLocked(com.android.server.notification.ConditionProviders$ConditionRecord r)
if (DEBUG) Slog.d(TAG, "subscribeLocked " + r);
final IConditionProvider provider = provider(r);
RemoteException re = null;
if (provider != null) {
try {
Slog.d(TAG, "Subscribing to " + r.id + " with " + provider);
provider.onSubscribe(r.id);
} catch (RemoteException e) {
Slog.w(TAG, "Error subscribing to " + r, e);
re = e;
}
}
ZenLog.traceSubscribe(r != null ? r.id : null, provider, re);
|
private void | unsubscribeLocked(com.android.server.notification.ConditionProviders$ConditionRecord r)
if (DEBUG) Slog.d(TAG, "unsubscribeLocked " + r);
final IConditionProvider provider = provider(r);
RemoteException re = null;
if (provider != null) {
try {
provider.onUnsubscribe(r.id);
} catch (RemoteException e) {
Slog.w(TAG, "Error unsubscribing to " + r, e);
re = e;
}
}
ZenLog.traceUnsubscribe(r != null ? r.id : null, provider, re);
|
private android.service.notification.Condition[] | validateConditions(java.lang.String pkg, android.service.notification.Condition[] conditions)
if (conditions == null || conditions.length == 0) return null;
final int N = conditions.length;
final ArrayMap<Uri, Condition> valid = new ArrayMap<Uri, Condition>(N);
for (int i = 0; i < N; i++) {
final Uri id = conditions[i].id;
if (!Condition.isValidId(id, pkg)) {
Slog.w(TAG, "Ignoring condition from " + pkg + " for invalid id: " + id);
continue;
}
if (valid.containsKey(id)) {
Slog.w(TAG, "Ignoring condition from " + pkg + " for duplicate id: " + id);
continue;
}
valid.put(id, conditions[i]);
}
if (valid.size() == 0) return null;
if (valid.size() == N) return conditions;
final Condition[] rt = new Condition[valid.size()];
for (int i = 0; i < rt.length; i++) {
rt[i] = valid.valueAt(i);
}
return rt;
|