ConditionProviders.java revision e86de4c0670550a29edae77ebb9f5c8ba5631231
11dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/**
21dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Copyright (c) 2014, The Android Open Source Project
31dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *
41dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
51dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * you may not use this file except in compliance with the License.
61dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * You may obtain a copy of the License at
71dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *
81dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *     http://www.apache.org/licenses/LICENSE-2.0
91dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *
101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * See the License for the specific language governing permissions and
141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * limitations under the License.
151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */
161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectpackage com.android.server.notification;
181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectimport android.content.Context;
201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectimport android.net.Uri;
211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectimport android.os.Handler;
221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectimport android.os.IBinder;
231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectimport android.os.IInterface;
241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectimport android.os.RemoteException;
251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectimport android.provider.Settings;
261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectimport android.provider.Settings.Global;
271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectimport android.service.notification.Condition;
281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectimport android.service.notification.ConditionProviderService;
291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectimport android.service.notification.IConditionListener;
3023d3e6b21b4b6debff87da8c6558495e564cc38eMattias Falkimport android.service.notification.IConditionProvider;
311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectimport android.util.ArrayMap;
321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectimport android.util.Slog;
331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectimport com.android.internal.R;
351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
363e0c5102e6d57e5b7296f95e1b318fda6114b48eMattias Falkimport libcore.util.Objects;
373e0c5102e6d57e5b7296f95e1b318fda6114b48eMattias Falk
383a4910c6161d57e40ba01cc9693f1a4514892b03Mattias Falkimport java.io.PrintWriter;
3923d3e6b21b4b6debff87da8c6558495e564cc38eMattias Falkimport java.util.Arrays;
4023d3e6b21b4b6debff87da8c6558495e564cc38eMattias Falk
4123d3e6b21b4b6debff87da8c6558495e564cc38eMattias Falkpublic class ConditionProviders extends ManagedServices {
4223d3e6b21b4b6debff87da8c6558495e564cc38eMattias Falk
4323d3e6b21b4b6debff87da8c6558495e564cc38eMattias Falk    private final ZenModeHelper mZenModeHelper;
4423d3e6b21b4b6debff87da8c6558495e564cc38eMattias Falk    private final ArrayMap<IBinder, IConditionListener> mListeners
45208898ee776117f42815c2fcb15903b2781bf0aaDavid 'Digit' Turner            = new ArrayMap<IBinder, IConditionListener>();
463e0c5102e6d57e5b7296f95e1b318fda6114b48eMattias Falk    private final ArrayMap<Uri, ManagedServiceInfo> mConditions
471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project            = new ArrayMap<Uri, ManagedServiceInfo>();
481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
493e0c5102e6d57e5b7296f95e1b318fda6114b48eMattias Falk    private Uri mCurrentConditionId;
503e0c5102e6d57e5b7296f95e1b318fda6114b48eMattias Falk
513e0c5102e6d57e5b7296f95e1b318fda6114b48eMattias Falk    public ConditionProviders(Context context, Handler handler,
523e0c5102e6d57e5b7296f95e1b318fda6114b48eMattias Falk            UserProfiles userProfiles, ZenModeHelper zenModeHelper) {
531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        super(context, handler, new Object(), userProfiles);
541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        mZenModeHelper = zenModeHelper;
551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        mZenModeHelper.addCallback(new ZenModeHelperCallback());
561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    }
571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    @Override
591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    protected Config getConfig() {
601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        Config c = new Config();
611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        c.caption = "condition provider";
623e0c5102e6d57e5b7296f95e1b318fda6114b48eMattias Falk        c.serviceInterface = ConditionProviderService.SERVICE_INTERFACE;
633e0c5102e6d57e5b7296f95e1b318fda6114b48eMattias Falk        c.secureSettingName = Settings.Secure.ENABLED_CONDITION_PROVIDERS;
641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        c.bindPermission = android.Manifest.permission.BIND_CONDITION_PROVIDER_SERVICE;
651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        c.settingsAction = Settings.ACTION_CONDITION_PROVIDER_SETTINGS;
661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        c.clientLabel = R.string.condition_provider_service_binding_label;
671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        return c;
681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    }
691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    @Override
711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    public void dump(PrintWriter pw) {
721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        super.dump(pw);
731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        synchronized(mMutex) {
741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project            pw.print("    mCurrentConditionId="); pw.println(mCurrentConditionId);
751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project            pw.print("    mListeners("); pw.print(mListeners.size()); pw.println("):");
761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project            for (int i = 0; i < mListeners.size(); i++) {
771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                pw.print("      "); pw.println(mListeners.keyAt(i));
781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project            }
791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project            pw.print("    mConditions("); pw.print(mConditions.size()); pw.println("):");
801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project            for (int i = 0; i < mConditions.size(); i++) {
811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                pw.print("      "); pw.print(mConditions.keyAt(i));
821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                final ManagedServiceInfo info = mConditions.valueAt(i);
831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                pw.print(" -> "); pw.print(info.component);
841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                if (!mServices.contains(info)) {
851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                    pw.print(" (orphan)");
861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                }
871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                pw.println();
881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project            }
891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        }
901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    }
911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    @Override
931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    protected IInterface asInterface(IBinder binder) {
941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        return IConditionProvider.Stub.asInterface(binder);
951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    }
961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    @Override
981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    protected void onServiceAdded(IInterface service) {
991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        Slog.d(TAG, "onServiceAdded " + service);
1001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        final IConditionProvider provider = (IConditionProvider) service;
1011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        try {
1021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project            provider.onConnected();
1031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        } catch (RemoteException e) {
1041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project            // we tried
1051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        }
1061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    }
1071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    @Override
1091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    protected void onServiceRemovedLocked(ManagedServiceInfo removed) {
1101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        if (removed == null) return;
1111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        if (mCurrentConditionId != null) {
1121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project            if (removed.equals(mConditions.get(mCurrentConditionId))) {
1131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                mCurrentConditionId = null;
1141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                mZenModeHelper.setZenMode(Global.ZEN_MODE_OFF);
1151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project            }
1161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        }
1171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        for (int i = mConditions.size() - 1; i >= 0; i--) {
1183a4910c6161d57e40ba01cc9693f1a4514892b03Mattias Falk            if (removed.equals(mConditions.valueAt(i))) {
1191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                mConditions.removeAt(i);
1201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project            }
1211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        }
1221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    }
1231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    public ManagedServiceInfo checkServiceToken(IConditionProvider provider) {
1251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        synchronized(mMutex) {
1261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project            return checkServiceTokenLocked(provider);
1271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        }
1281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    }
1291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    public void requestZenModeConditions(IConditionListener callback, boolean requested) {
1311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        synchronized(mMutex) {
1321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project            if (DEBUG) Slog.d(TAG, "requestZenModeConditions callback=" + callback
1331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                    + " requested=" + requested);
1341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project            if (callback == null) return;
1351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project            if (requested) {
1361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                mListeners.put(callback.asBinder(), callback);
1373a4910c6161d57e40ba01cc9693f1a4514892b03Mattias Falk                requestConditionsLocked(Condition.FLAG_RELEVANT_NOW);
1383a4910c6161d57e40ba01cc9693f1a4514892b03Mattias Falk            } else {
1393a4910c6161d57e40ba01cc9693f1a4514892b03Mattias Falk                mListeners.remove(callback.asBinder());
1403a4910c6161d57e40ba01cc9693f1a4514892b03Mattias Falk                if (mListeners.isEmpty()) {
14152764f5546362d0ffab99afaffe8e8c7f21f8ef2Robert Greenwalt                    requestConditionsLocked(0);
14252764f5546362d0ffab99afaffe8e8c7f21f8ef2Robert Greenwalt                }
14352764f5546362d0ffab99afaffe8e8c7f21f8ef2Robert Greenwalt            }
14452764f5546362d0ffab99afaffe8e8c7f21f8ef2Robert Greenwalt        }
14552764f5546362d0ffab99afaffe8e8c7f21f8ef2Robert Greenwalt    }
14652764f5546362d0ffab99afaffe8e8c7f21f8ef2Robert Greenwalt
14752764f5546362d0ffab99afaffe8e8c7f21f8ef2Robert Greenwalt    public void notifyConditions(String pkg, ManagedServiceInfo info, Condition[] conditions) {
14852764f5546362d0ffab99afaffe8e8c7f21f8ef2Robert Greenwalt        synchronized(mMutex) {
14952764f5546362d0ffab99afaffe8e8c7f21f8ef2Robert Greenwalt            if (DEBUG) Slog.d(TAG, "notifyConditions pkg=" + pkg + " info=" + info + " conditions="
15052764f5546362d0ffab99afaffe8e8c7f21f8ef2Robert Greenwalt                    + (conditions == null ? null : Arrays.asList(conditions)));
15152764f5546362d0ffab99afaffe8e8c7f21f8ef2Robert Greenwalt            if (conditions == null || conditions.length == 0) return;
1521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project            final int N = conditions.length;
15352764f5546362d0ffab99afaffe8e8c7f21f8ef2Robert Greenwalt            boolean valid = true;
1543a4910c6161d57e40ba01cc9693f1a4514892b03Mattias Falk            for (int i = 0; i < N; i++) {
1553a4910c6161d57e40ba01cc9693f1a4514892b03Mattias Falk                final Uri id = conditions[i].id;
1563a4910c6161d57e40ba01cc9693f1a4514892b03Mattias Falk                if (!Condition.isValidId(id, pkg)) {
1571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                    Slog.w(TAG, "Ignoring conditions from " + pkg + " for invalid id: " + id);
1581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                    valid = false;
1591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                }
1601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project            }
1611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project            if (!valid) return;
1621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project            for (int i = 0; i < N; i++) {
1641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                mConditions.put(conditions[i].id, info);
1651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project            }
1661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project            for (IConditionListener listener : mListeners.values()) {
1671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                try {
1681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                    listener.onConditionsReceived(conditions);
1691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                } catch (RemoteException e) {
1701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                    Slog.w(TAG, "Error sending conditions to listener " + listener, e);
1713e0c5102e6d57e5b7296f95e1b318fda6114b48eMattias Falk                }
1721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project            }
1731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project            if (mCurrentConditionId != null) {
1741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                for (int i = 0; i < N; i++) {
1751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                    final Condition c = conditions[i];
1761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                    if (!c.id.equals(mCurrentConditionId)) continue;
1771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                    if (c.state == Condition.STATE_TRUE || c.state == Condition.STATE_ERROR) {
1781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                        triggerExitLocked(c.state == Condition.STATE_ERROR);
1791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                        return;
1801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                    }
1811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                }
1821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project            }
1831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        }
1841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    }
1851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    private void triggerExitLocked(boolean error) {
1871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        if (error) {
1881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project            Slog.w(TAG, "Zen mode exit condition failed");
1891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        } else if (DEBUG) {
1901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project            Slog.d(TAG, "Zen mode exit condition triggered");
1911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        }
1921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        mZenModeHelper.setZenMode(Settings.Global.ZEN_MODE_OFF);
1931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        unsubscribeLocked(mCurrentConditionId);
1941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        mCurrentConditionId = null;
1951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    }
1961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    public void setZenModeCondition(Uri conditionId) {
1981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        synchronized(mMutex) {
1991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project            if (DEBUG) Slog.d(TAG, "setZenModeCondition " + conditionId);
2001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project            if (Objects.equal(mCurrentConditionId, conditionId)) return;
2011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project            if (mCurrentConditionId != null) {
2031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                unsubscribeLocked(mCurrentConditionId);
2041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project            }
2051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project            if (conditionId != null) {
2061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                final ManagedServiceInfo info = mConditions.get(conditionId);
2071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                final IConditionProvider provider = provider(info);
2081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                if (provider == null) return;
2091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                try {
2101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                    provider.onSubscribe(conditionId);
2111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                } catch (RemoteException e) {
2121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                    Slog.w(TAG, "Error subscribing to " + conditionId
2131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                            + " from " + info.component, e);
2141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                }
2151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project            }
2161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project            mCurrentConditionId = conditionId;
2171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        }
2181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    }
2191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    private void unsubscribeLocked(Uri conditionId) {
2211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        final ManagedServiceInfo info = mConditions.get(mCurrentConditionId);
2221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        final IConditionProvider provider = provider(info);
2231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        if (provider == null) return;
2241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        try {
2251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project            provider.onUnsubscribe(conditionId);
2261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        } catch (RemoteException e) {
2271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project            Slog.w(TAG, "Error unsubscribing to " + conditionId + " from " + info.component, e);
2281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        }
2291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    }
2301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    private static IConditionProvider provider(ManagedServiceInfo info) {
2321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        return info == null ? null : (IConditionProvider) info.service;
2331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    }
2341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    private void requestConditionsLocked(int flags) {
2361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        for (ManagedServiceInfo info : mServices) {
2371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project            final IConditionProvider provider = provider(info);
2381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project            if (provider == null) continue;
2391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project            try {
2401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                provider.onRequestConditions(flags);
2411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project            } catch (RemoteException e) {
2421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                Slog.w(TAG, "Error requesting conditions from " + info.component, e);
2431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project            }
2441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        }
2451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    }
2461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    private class ZenModeHelperCallback extends ZenModeHelper.Callback {
2481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        @Override
2491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        void onZenModeChanged() {
2501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project            final int mode = mZenModeHelper.getZenMode();
2511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project            if (mode == Global.ZEN_MODE_OFF) {
2521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                synchronized (mMutex) {
2531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                    if (mCurrentConditionId != null) {
2541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                        if (DEBUG) Slog.d(TAG, "Zen mode off, forcing unsubscribe from "
2551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                                + mCurrentConditionId);
2561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                        unsubscribeLocked(mCurrentConditionId);
2571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                        mCurrentConditionId = null;
2581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                    }
2591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                }
2601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project            }
2611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        }
2621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    }
2631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
2641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project