ConditionProviderService.java revision 7340fc8665ae3f9f1978f42aa0e5e1da85036158
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
60    abstract public Condition[] queryConditions(int relevance);
61    abstract public Condition[] getConditions(Uri[] conditionIds);
62    abstract public boolean subscribe(Uri conditionId);
63    abstract public boolean unsubscribe(Uri conditionId);
64
65    private final INotificationManager getNotificationInterface() {
66        if (mNoMan == null) {
67            mNoMan = INotificationManager.Stub.asInterface(
68                    ServiceManager.getService(Context.NOTIFICATION_SERVICE));
69        }
70        return mNoMan;
71    }
72
73    public final void notifyCondition(Condition condition) {
74        if (!isBound()) return;
75        try {
76            getNotificationInterface().notifyCondition(mProvider, condition);
77        } catch (android.os.RemoteException ex) {
78            Log.v(TAG, "Unable to contact notification manager", ex);
79        }
80    }
81
82    @Override
83    public IBinder onBind(Intent intent) {
84        if (mProvider == null) {
85            mProvider = new Provider();
86        }
87        return mProvider;
88    }
89
90    private boolean isBound() {
91        if (mProvider == null) {
92            Log.w(TAG, "Condition provider service not yet bound.");
93            return false;
94        }
95        return true;
96    }
97
98    private final class Provider extends IConditionProvider.Stub {
99        private final ConditionProviderService mService = ConditionProviderService.this;
100
101        @Override
102        public Condition[] queryConditions(int relevance) {
103            try {
104                return mService.queryConditions(relevance);
105            } catch (Throwable t) {
106                Log.w(TAG, "Error running queryConditions", t);
107                return null;
108            }
109        }
110
111        @Override
112        public Condition[] getConditions(Uri[] conditionIds) {
113            try {
114                return mService.getConditions(conditionIds);
115            } catch (Throwable t) {
116                Log.w(TAG, "Error running getConditions", t);
117                return null;
118            }
119        }
120
121        @Override
122        public boolean subscribe(Uri conditionId) {
123            try {
124                return mService.subscribe(conditionId);
125            } catch (Throwable t) {
126                Log.w(TAG, "Error running subscribe", t);
127                return false;
128            }
129        }
130
131        @Override
132        public boolean unsubscribe(Uri conditionId) {
133            try {
134                return mService.unsubscribe(conditionId);
135            } catch (Throwable t) {
136                Log.w(TAG, "Error running unsubscribe", t);
137                return false;
138            }
139        }
140    }
141}
142