ConditionProviderService.java revision 1c923a386ee4d8c31cc289f8628b8fc46bf08e86
1/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.service.notification;
18
19import android.annotation.SdkConstant;
20import android.app.INotificationManager;
21import android.app.Service;
22import android.content.Context;
23import android.content.Intent;
24import android.net.Uri;
25import android.os.IBinder;
26import android.os.ServiceManager;
27import android.util.Log;
28
29/**
30 * A service that provides conditions about boolean state.
31 * <p>To extend this class, you must declare the service in your manifest file with
32 * the {@link android.Manifest.permission#BIND_CONDITION_PROVIDER_SERVICE} permission
33 * and include an intent filter with the {@link #SERVICE_INTERFACE} action. For example:</p>
34 * <pre>
35 * &lt;service android:name=".MyConditionProvider"
36 *          android:label="&#64;string/service_name"
37 *          android:permission="android.permission.BIND_CONDITION_PROVIDER_SERVICE">
38 *     &lt;intent-filter>
39 *         &lt;action android:name="android.service.notification.ConditionProviderService" />
40 *     &lt;/intent-filter>
41 * &lt;/service></pre>
42 *
43 * @hide
44 */
45public abstract class ConditionProviderService extends Service {
46    private final String TAG = ConditionProviderService.class.getSimpleName()
47            + "[" + getClass().getSimpleName() + "]";
48
49    private Provider mProvider;
50    private INotificationManager mNoMan;
51
52    /**
53     * The {@link Intent} that must be declared as handled by the service.
54     */
55    @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
56    public static final String SERVICE_INTERFACE
57            = "android.service.notification.ConditionProviderService";
58
59    abstract public void onConnected();
60    abstract public void onRequestConditions(int relevance);
61    abstract public void onSubscribe(Uri conditionId);
62    abstract public void onUnsubscribe(Uri conditionId);
63
64    private final INotificationManager getNotificationInterface() {
65        if (mNoMan == null) {
66            mNoMan = INotificationManager.Stub.asInterface(
67                    ServiceManager.getService(Context.NOTIFICATION_SERVICE));
68        }
69        return mNoMan;
70    }
71
72    public final void notifyCondition(Condition condition) {
73        if (condition == null) return;
74        notifyConditions(new Condition[]{ condition });
75    }
76
77    public final void notifyConditions(Condition... conditions) {
78        if (!isBound() || conditions == null) return;
79        try {
80            getNotificationInterface().notifyConditions(getPackageName(), mProvider, conditions);
81        } catch (android.os.RemoteException ex) {
82            Log.v(TAG, "Unable to contact notification manager", ex);
83        }
84    }
85
86    @Override
87    public IBinder onBind(Intent intent) {
88        if (mProvider == null) {
89            mProvider = new Provider();
90        }
91        return mProvider;
92    }
93
94    private boolean isBound() {
95        if (mProvider == null) {
96            Log.w(TAG, "Condition provider service not yet bound.");
97            return false;
98        }
99        return true;
100    }
101
102    private final class Provider extends IConditionProvider.Stub {
103        private final ConditionProviderService mService = ConditionProviderService.this;
104
105        @Override
106        public void onConnected() {
107            try {
108                mService.onConnected();
109            } catch (Throwable t) {
110                Log.w(TAG, "Error running onConnected", t);
111            }
112        }
113
114        @Override
115        public void onRequestConditions(int relevance) {
116            try {
117                mService.onRequestConditions(relevance);
118            } catch (Throwable t) {
119                Log.w(TAG, "Error running onRequestConditions", t);
120            }
121        }
122
123        @Override
124        public void onSubscribe(Uri conditionId) {
125            try {
126                mService.onSubscribe(conditionId);
127            } catch (Throwable t) {
128                Log.w(TAG, "Error running onSubscribe", t);
129            }
130        }
131
132        @Override
133        public void onUnsubscribe(Uri conditionId) {
134            try {
135                mService.onUnsubscribe(conditionId);
136            } catch (Throwable t) {
137                Log.w(TAG, "Error running onUnsubscribe", t);
138            }
139        }
140    }
141}
142