blob: 4ddf7673b58cac1429353013c6aeaa89ba5c79a6 [file] [log] [blame]
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -08001/*
2 * Copyright (C) 2016 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 */
16package android.hardware.location;
17
18import android.annotation.SystemApi;
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -080019import android.content.Context;
Peng Xu9ff7d222016-02-11 13:02:05 -080020import android.os.Handler;
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -080021import android.os.IBinder;
Peng Xu9ff7d222016-02-11 13:02:05 -080022import android.os.Looper;
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -080023import android.os.RemoteException;
Peng Xu9ff7d222016-02-11 13:02:05 -080024import android.os.ServiceManager;
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -080025import android.util.Log;
26
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -080027/**
destradaa8bad3fe2016-03-15 12:33:40 -070028 * A class that exposes the Context hubs on a device to applications.
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -080029 *
destradaa8bad3fe2016-03-15 12:33:40 -070030 * Please note that this class is not expected to be used by unbundled applications. Also, calling
31 * applications are expected to have LOCATION_HARDWARE permissions to use this class.
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -080032 *
33 * @hide
34 */
35@SystemApi
36public final class ContextHubManager {
37
38 private static final String TAG = "ContextHubManager";
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -080039
Peng Xu9ff7d222016-02-11 13:02:05 -080040 private final Looper mMainLooper;
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -080041 private IContextHubService mContextHubService;
Greg Kaiser6ba60e62016-03-18 10:08:39 -070042 private Callback mCallback;
Peng Xu9ff7d222016-02-11 13:02:05 -080043 private Handler mCallbackHandler;
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -080044
45 /**
destradaa8bad3fe2016-03-15 12:33:40 -070046 * A special context hub identifier meaning any possible hub on the system.
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -080047 */
48 public static final int ANY_HUB = -1;
49 /**
50 * A constant denoting a message to load a a Nano App
51 */
52 public static final int MSG_LOAD_NANO_APP = 1;
53 /**
54 * A constant denoting a message to unload a a Nano App
55 */
56 public static final int MSG_UNLOAD_NANO_APP = 2;
57 /**
58 * A constant denoting a message to send a message
59 */
60 public static final int MSG_DATA_SEND = 3;
61
Peng Xu9ff7d222016-02-11 13:02:05 -080062 /**
destradaa8bad3fe2016-03-15 12:33:40 -070063 * An interface to receive asynchronous communication from the context hub.
Peng Xu9ff7d222016-02-11 13:02:05 -080064 */
Greg Kaiser6ba60e62016-03-18 10:08:39 -070065 public abstract static class Callback {
66 protected Callback() {}
destradaa8bad3fe2016-03-15 12:33:40 -070067
Peng Xu9ff7d222016-02-11 13:02:05 -080068 /**
destradaa8bad3fe2016-03-15 12:33:40 -070069 * Callback function called on message receipt from context hub.
Peng Xu9ff7d222016-02-11 13:02:05 -080070 *
destradaa8bad3fe2016-03-15 12:33:40 -070071 * @param hubHandle Handle (system-wide unique identifier) of the hub of the message.
72 * @param nanoAppHandle Handle (unique identifier) for the app that sent the message.
73 * @param message The context hub message.
Peng Xu9ff7d222016-02-11 13:02:05 -080074 *
75 * @see ContextHubMessage
76 */
destradaa8bad3fe2016-03-15 12:33:40 -070077 public abstract void onMessageReceipt(
78 int hubHandle,
79 int nanoAppHandle,
80 ContextHubMessage message);
Peng Xu9ff7d222016-02-11 13:02:05 -080081 }
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -080082
83 /**
84 * Get a handle to all the context hubs in the system
85 * @return array of context hub handles
86 */
Peng Xu9ff7d222016-02-11 13:02:05 -080087 public int[] getContextHubHandles() {
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -080088 int[] retVal = null;
Peng Xu9ff7d222016-02-11 13:02:05 -080089 try {
90 retVal = getBinder().getContextHubHandles();
91 } catch (RemoteException e) {
destradaa8bad3fe2016-03-15 12:33:40 -070092 Log.e(TAG, "Could not fetch context hub handles : " + e);
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -080093 }
94 return retVal;
95 }
96
97 /**
98 * Get more information about a specific hub.
99 *
destradaa8bad3fe2016-03-15 12:33:40 -0700100 * @param hubHandle Handle (system-wide unique identifier) of a context hub.
101 * @return ContextHubInfo Information about the requested context hub.
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -0800102 *
103 * @see ContextHubInfo
104 */
destradaa8bad3fe2016-03-15 12:33:40 -0700105 public ContextHubInfo getContextHubInfo(int hubHandle) {
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -0800106 ContextHubInfo retVal = null;
Peng Xu9ff7d222016-02-11 13:02:05 -0800107 try {
destradaa8bad3fe2016-03-15 12:33:40 -0700108 retVal = getBinder().getContextHubInfo(hubHandle);
Peng Xu9ff7d222016-02-11 13:02:05 -0800109 } catch (RemoteException e) {
destradaa8bad3fe2016-03-15 12:33:40 -0700110 Log.e(TAG, "Could not fetch context hub info :" + e);
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -0800111 }
112
Peng Xu9ff7d222016-02-11 13:02:05 -0800113 return retVal;
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -0800114 }
115
116 /**
destradaa8bad3fe2016-03-15 12:33:40 -0700117 * Load a nano app on a specified context hub.
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -0800118 *
119 * @param hubHandle handle of context hub to load the app on.
120 * @param app the nanoApp to load on the hub
121 *
122 * @return int nanoAppInstance of the loaded nanoApp on success,
123 * -1 otherwise
124 *
125 * @see NanoApp
126 */
127 public int loadNanoApp(int hubHandle, NanoApp app) {
128 int retVal = -1;
Peng Xu9ff7d222016-02-11 13:02:05 -0800129 if (app == null) {
130 return retVal;
131 }
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -0800132
Peng Xu9ff7d222016-02-11 13:02:05 -0800133 try {
134 retVal = getBinder().loadNanoApp(hubHandle, app);
135 } catch (RemoteException e) {
destradaa8bad3fe2016-03-15 12:33:40 -0700136 Log.e(TAG, "Could not fetch load nanoApp :" + e);
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -0800137 }
138
139 return retVal;
140 }
141
142 /**
143 * Unload a specified nanoApp
144 *
destradaa8bad3fe2016-03-15 12:33:40 -0700145 * @param nanoAppHandle handle of the nanoApp to load
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -0800146 *
destradaa8bad3fe2016-03-15 12:33:40 -0700147 * @return int 0 on success, -1 otherwise
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -0800148 */
destradaa8bad3fe2016-03-15 12:33:40 -0700149 public int unloadNanoApp(int nanoAppHandle) {
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -0800150 int retVal = -1;
151
Peng Xu9ff7d222016-02-11 13:02:05 -0800152 try {
destradaa8bad3fe2016-03-15 12:33:40 -0700153 retVal = getBinder().unloadNanoApp(nanoAppHandle);
Peng Xu9ff7d222016-02-11 13:02:05 -0800154 } catch (RemoteException e) {
destradaa8bad3fe2016-03-15 12:33:40 -0700155 Log.e(TAG, "Could not fetch unload nanoApp :" + e);
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -0800156 }
157
158 return retVal;
159 }
160
161 /**
162 * get information about the nano app instance
163 *
destradaa8bad3fe2016-03-15 12:33:40 -0700164 * @param nanoAppHandle handle of the nanoAppInstance
165 * @return NanoAppInstanceInfo Information about the nano app instance.
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -0800166 *
167 * @see NanoAppInstanceInfo
168 */
destradaa8bad3fe2016-03-15 12:33:40 -0700169 public NanoAppInstanceInfo getNanoAppInstanceInfo(int nanoAppHandle) {
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -0800170 NanoAppInstanceInfo retVal = null;
171
Peng Xu9ff7d222016-02-11 13:02:05 -0800172 try {
destradaa8bad3fe2016-03-15 12:33:40 -0700173 retVal = getBinder().getNanoAppInstanceInfo(nanoAppHandle);
Peng Xu9ff7d222016-02-11 13:02:05 -0800174 } catch (RemoteException e) {
destradaa8bad3fe2016-03-15 12:33:40 -0700175 Log.e(TAG, "Could not fetch nanoApp info :" + e);
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -0800176 }
177
178 return retVal;
179 }
180
181 /**
182 * Find a specified nano app on the system
183 *
184 * @param hubHandle handle of hub to search for nano app
185 * @param filter filter specifying the search criteria for app
186 *
187 * @see NanoAppFilter
188 *
destradaa8bad3fe2016-03-15 12:33:40 -0700189 * @return int[] Array of handles to any found nano apps
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -0800190 */
destradaa8bad3fe2016-03-15 12:33:40 -0700191 public int[] findNanoAppOnHub(int hubHandle, NanoAppFilter filter) {
192 int[] retVal = null;
Peng Xu9ff7d222016-02-11 13:02:05 -0800193 try {
destradaa8bad3fe2016-03-15 12:33:40 -0700194 retVal = getBinder().findNanoAppOnHub(hubHandle, filter);
Peng Xu9ff7d222016-02-11 13:02:05 -0800195 } catch (RemoteException e) {
destradaa8bad3fe2016-03-15 12:33:40 -0700196 Log.e(TAG, "Could not query nanoApp instance :" + e);
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -0800197 }
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -0800198 return retVal;
199 }
200
201 /**
destradaa8bad3fe2016-03-15 12:33:40 -0700202 * Send a message to a specific nano app instance on a context hub.
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -0800203 *
204 * @param hubHandle handle of the hub to send the message to
205 * @param nanoAppHandle handle of the nano app to send to
destradaa8bad3fe2016-03-15 12:33:40 -0700206 * @param message Message to be sent
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -0800207 *
208 * @see ContextHubMessage
209 *
210 * @return int 0 on success, -1 otherwise
211 */
Peng Xu9ff7d222016-02-11 13:02:05 -0800212 public int sendMessage(int hubHandle, int nanoAppHandle, ContextHubMessage message) {
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -0800213 int retVal = -1;
214
Peng Xu9ff7d222016-02-11 13:02:05 -0800215 try {
216 retVal = getBinder().sendMessage(hubHandle, nanoAppHandle, message);
217 } catch (RemoteException e) {
218 Log.e(TAG, "Could not fetch send message :" + e.toString());
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -0800219 }
220
221 return retVal;
222 }
223
Peng Xu9ff7d222016-02-11 13:02:05 -0800224 /**
225 * Set a callback to receive messages from the context hub
226 *
Peng Xu9ff7d222016-02-11 13:02:05 -0800227 * @param callback Callback object
228 *
Greg Kaiser6ba60e62016-03-18 10:08:39 -0700229 * @see Callback
Peng Xu9ff7d222016-02-11 13:02:05 -0800230 *
231 * @return int 0 on success, -1 otherwise
232 */
Greg Kaiser6ba60e62016-03-18 10:08:39 -0700233 public int registerCallback(Callback callback) {
234 return registerCallback(callback, null);
Peng Xu9ff7d222016-02-11 13:02:05 -0800235 }
236
237 /**
238 * Set a callback to receive messages from the context hub
239 *
Peng Xu9ff7d222016-02-11 13:02:05 -0800240 * @param callback Callback object
destradaa8bad3fe2016-03-15 12:33:40 -0700241 * @param handler Handler object
Peng Xu9ff7d222016-02-11 13:02:05 -0800242 *
Greg Kaiser6ba60e62016-03-18 10:08:39 -0700243 * @see Callback
Peng Xu9ff7d222016-02-11 13:02:05 -0800244 *
245 * @return int 0 on success, -1 otherwise
246 */
Greg Kaiser6ba60e62016-03-18 10:08:39 -0700247 public int registerCallback(Callback callback, Handler handler) {
Peng Xu9ff7d222016-02-11 13:02:05 -0800248 synchronized(this) {
249 if (mCallback != null) {
250 Log.e(TAG, "Max number of callbacks reached!");
251 return -1;
252 }
253 mCallback = callback;
254 mCallbackHandler = handler;
255 }
256 return 0;
257 }
258
259 /**
destradaa8bad3fe2016-03-15 12:33:40 -0700260 * Unregister a callback for receive messages from the context hub.
Peng Xu9ff7d222016-02-11 13:02:05 -0800261 *
Greg Kaiser6ba60e62016-03-18 10:08:39 -0700262 * @see Callback
Peng Xu9ff7d222016-02-11 13:02:05 -0800263 *
264 * @param callback method to deregister
265 *
266 * @return int 0 on success, -1 otherwise
267 */
Greg Kaiser6ba60e62016-03-18 10:08:39 -0700268 public int unregisterCallback(Callback callback) {
Peng Xu9ff7d222016-02-11 13:02:05 -0800269 synchronized(this) {
270 if (callback != mCallback) {
271 Log.e(TAG, "Cannot recognize callback!");
272 return -1;
273 }
274
275 mCallback = null;
276 mCallbackHandler = null;
277 }
278 return 0;
279 }
280
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -0800281 private IContextHubCallback.Stub mClientCallback = new IContextHubCallback.Stub() {
282 @Override
Peng Xu9ff7d222016-02-11 13:02:05 -0800283 public void onMessageReceipt(final int hubId, final int nanoAppId,
destradaa8bad3fe2016-03-15 12:33:40 -0700284 final ContextHubMessage message) {
Peng Xu9ff7d222016-02-11 13:02:05 -0800285 if (mCallback != null) {
286 synchronized(this) {
Greg Kaiser6ba60e62016-03-18 10:08:39 -0700287 final Callback callback = mCallback;
Peng Xu9ff7d222016-02-11 13:02:05 -0800288 Handler handler = mCallbackHandler == null ?
289 new Handler(mMainLooper) : mCallbackHandler;
290 handler.post(new Runnable() {
291 @Override
292 public void run() {
293 callback.onMessageReceipt(hubId, nanoAppId, message);
294 }
295 });
296 }
297 } else {
298 Log.d(TAG, "Context hub manager client callback is NULL");
299 }
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -0800300 }
301 };
302
Peng Xu9ff7d222016-02-11 13:02:05 -0800303 /** @hide */
304 public ContextHubManager(Context context, Looper mainLooper) {
Peng Xu9ff7d222016-02-11 13:02:05 -0800305 mMainLooper = mainLooper;
306
307 IBinder b = ServiceManager.getService(ContextHubService.CONTEXTHUB_SERVICE);
308 if (b != null) {
309 mContextHubService = IContextHubService.Stub.asInterface(b);
310
311 try {
312 getBinder().registerCallback(mClientCallback);
313 } catch (RemoteException e) {
destradaa8bad3fe2016-03-15 12:33:40 -0700314 Log.e(TAG, "Could not register callback:" + e);
Peng Xu9ff7d222016-02-11 13:02:05 -0800315 }
316
317 } else {
318 Log.d(TAG, "failed to getService");
319 }
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -0800320 }
321
Peng Xu9ff7d222016-02-11 13:02:05 -0800322 private IContextHubService getBinder() throws RemoteException {
323 if (mContextHubService == null) {
324 throw new RemoteException("Service not connected.");
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -0800325 }
Peng Xu9ff7d222016-02-11 13:02:05 -0800326 return mContextHubService;
327 }
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -0800328}