Ashutosh Joshi | 1d1ac54 | 2016-01-18 17:19:27 -0800 | [diff] [blame] | 1 | /* |
| 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 | */ |
| 16 | package android.hardware.location; |
| 17 | |
| 18 | import android.annotation.SystemApi; |
Ashutosh Joshi | 1d1ac54 | 2016-01-18 17:19:27 -0800 | [diff] [blame] | 19 | import android.content.Context; |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 20 | import android.os.Handler; |
Ashutosh Joshi | 1d1ac54 | 2016-01-18 17:19:27 -0800 | [diff] [blame] | 21 | import android.os.IBinder; |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 22 | import android.os.Looper; |
Ashutosh Joshi | 1d1ac54 | 2016-01-18 17:19:27 -0800 | [diff] [blame] | 23 | import android.os.RemoteException; |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 24 | import android.os.ServiceManager; |
Ashutosh Joshi | 1d1ac54 | 2016-01-18 17:19:27 -0800 | [diff] [blame] | 25 | import android.util.Log; |
| 26 | |
Ashutosh Joshi | 1d1ac54 | 2016-01-18 17:19:27 -0800 | [diff] [blame] | 27 | /** |
destradaa | 8bad3fe | 2016-03-15 12:33:40 -0700 | [diff] [blame] | 28 | * A class that exposes the Context hubs on a device to applications. |
Ashutosh Joshi | 1d1ac54 | 2016-01-18 17:19:27 -0800 | [diff] [blame] | 29 | * |
destradaa | 8bad3fe | 2016-03-15 12:33:40 -0700 | [diff] [blame] | 30 | * 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 Joshi | 1d1ac54 | 2016-01-18 17:19:27 -0800 | [diff] [blame] | 32 | * |
| 33 | * @hide |
| 34 | */ |
| 35 | @SystemApi |
| 36 | public final class ContextHubManager { |
| 37 | |
| 38 | private static final String TAG = "ContextHubManager"; |
Ashutosh Joshi | 1d1ac54 | 2016-01-18 17:19:27 -0800 | [diff] [blame] | 39 | |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 40 | private final Looper mMainLooper; |
Ashutosh Joshi | 1d1ac54 | 2016-01-18 17:19:27 -0800 | [diff] [blame] | 41 | private IContextHubService mContextHubService; |
Greg Kaiser | 6ba60e6 | 2016-03-18 10:08:39 -0700 | [diff] [blame] | 42 | private Callback mCallback; |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 43 | private Handler mCallbackHandler; |
Ashutosh Joshi | 1d1ac54 | 2016-01-18 17:19:27 -0800 | [diff] [blame] | 44 | |
| 45 | /** |
destradaa | 78cebca | 2016-04-14 18:40:14 -0700 | [diff] [blame] | 46 | * @deprecated Use {@code mCallback} instead. |
| 47 | */ |
| 48 | @Deprecated |
| 49 | private ICallback mLocalCallback; |
| 50 | |
| 51 | /** |
destradaa | 8bad3fe | 2016-03-15 12:33:40 -0700 | [diff] [blame] | 52 | * An interface to receive asynchronous communication from the context hub. |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 53 | */ |
Greg Kaiser | 6ba60e6 | 2016-03-18 10:08:39 -0700 | [diff] [blame] | 54 | public abstract static class Callback { |
| 55 | protected Callback() {} |
destradaa | 8bad3fe | 2016-03-15 12:33:40 -0700 | [diff] [blame] | 56 | |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 57 | /** |
destradaa | 8bad3fe | 2016-03-15 12:33:40 -0700 | [diff] [blame] | 58 | * Callback function called on message receipt from context hub. |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 59 | * |
destradaa | 8bad3fe | 2016-03-15 12:33:40 -0700 | [diff] [blame] | 60 | * @param hubHandle Handle (system-wide unique identifier) of the hub of the message. |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 61 | * @param nanoAppHandle Handle (unique identifier) for app instance that sent the message. |
destradaa | 8bad3fe | 2016-03-15 12:33:40 -0700 | [diff] [blame] | 62 | * @param message The context hub message. |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 63 | * |
| 64 | * @see ContextHubMessage |
| 65 | */ |
destradaa | 8bad3fe | 2016-03-15 12:33:40 -0700 | [diff] [blame] | 66 | public abstract void onMessageReceipt( |
| 67 | int hubHandle, |
| 68 | int nanoAppHandle, |
| 69 | ContextHubMessage message); |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 70 | } |
Ashutosh Joshi | 1d1ac54 | 2016-01-18 17:19:27 -0800 | [diff] [blame] | 71 | |
| 72 | /** |
destradaa | 78cebca | 2016-04-14 18:40:14 -0700 | [diff] [blame] | 73 | * @deprecated Use {@link Callback} instead. |
| 74 | * @hide |
| 75 | */ |
| 76 | @Deprecated |
| 77 | public interface ICallback { |
| 78 | /** |
| 79 | * Callback function called on message receipt from context hub. |
| 80 | * |
| 81 | * @param hubHandle Handle (system-wide unique identifier) of the hub of the message. |
| 82 | * @param nanoAppHandle Handle (unique identifier) for app instance that sent the message. |
| 83 | * @param message The context hub message. |
| 84 | * |
| 85 | * @see ContextHubMessage |
| 86 | */ |
| 87 | void onMessageReceipt(int hubHandle, int nanoAppHandle, ContextHubMessage message); |
| 88 | } |
| 89 | |
| 90 | /** |
Ashutosh Joshi | 1d1ac54 | 2016-01-18 17:19:27 -0800 | [diff] [blame] | 91 | * Get a handle to all the context hubs in the system |
| 92 | * @return array of context hub handles |
| 93 | */ |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 94 | public int[] getContextHubHandles() { |
Ashutosh Joshi | 1d1ac54 | 2016-01-18 17:19:27 -0800 | [diff] [blame] | 95 | int[] retVal = null; |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 96 | try { |
| 97 | retVal = getBinder().getContextHubHandles(); |
| 98 | } catch (RemoteException e) { |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 99 | Log.w(TAG, "Could not fetch context hub handles : " + e); |
Ashutosh Joshi | 1d1ac54 | 2016-01-18 17:19:27 -0800 | [diff] [blame] | 100 | } |
| 101 | return retVal; |
| 102 | } |
| 103 | |
| 104 | /** |
| 105 | * Get more information about a specific hub. |
| 106 | * |
destradaa | 8bad3fe | 2016-03-15 12:33:40 -0700 | [diff] [blame] | 107 | * @param hubHandle Handle (system-wide unique identifier) of a context hub. |
| 108 | * @return ContextHubInfo Information about the requested context hub. |
Ashutosh Joshi | 1d1ac54 | 2016-01-18 17:19:27 -0800 | [diff] [blame] | 109 | * |
| 110 | * @see ContextHubInfo |
| 111 | */ |
destradaa | 8bad3fe | 2016-03-15 12:33:40 -0700 | [diff] [blame] | 112 | public ContextHubInfo getContextHubInfo(int hubHandle) { |
Ashutosh Joshi | 1d1ac54 | 2016-01-18 17:19:27 -0800 | [diff] [blame] | 113 | ContextHubInfo retVal = null; |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 114 | try { |
destradaa | 8bad3fe | 2016-03-15 12:33:40 -0700 | [diff] [blame] | 115 | retVal = getBinder().getContextHubInfo(hubHandle); |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 116 | } catch (RemoteException e) { |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 117 | Log.w(TAG, "Could not fetch context hub info :" + e); |
Ashutosh Joshi | 1d1ac54 | 2016-01-18 17:19:27 -0800 | [diff] [blame] | 118 | } |
| 119 | |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 120 | return retVal; |
Ashutosh Joshi | 1d1ac54 | 2016-01-18 17:19:27 -0800 | [diff] [blame] | 121 | } |
| 122 | |
| 123 | /** |
destradaa | 8bad3fe | 2016-03-15 12:33:40 -0700 | [diff] [blame] | 124 | * Load a nano app on a specified context hub. |
Ashutosh Joshi | 1d1ac54 | 2016-01-18 17:19:27 -0800 | [diff] [blame] | 125 | * |
Greg Kaiser | fac5be2 | 2016-08-17 15:33:10 -0700 | [diff] [blame] | 126 | * Note that loading is asynchronous. When we return from this method, |
| 127 | * the nano app (probably) hasn't loaded yet. Assuming a return of 0 |
| 128 | * from this method, then the final success/failure for the load, along |
| 129 | * with the "handle" for the nanoapp, is all delivered in a byte |
| 130 | * string via a call to Callback.onMessageReceipt. |
| 131 | * |
| 132 | * TODO(b/30784270): Provide a better success/failure and "handle" delivery. |
| 133 | * |
Ashutosh Joshi | 1d1ac54 | 2016-01-18 17:19:27 -0800 | [diff] [blame] | 134 | * @param hubHandle handle of context hub to load the app on. |
| 135 | * @param app the nanoApp to load on the hub |
| 136 | * |
Greg Kaiser | fac5be2 | 2016-08-17 15:33:10 -0700 | [diff] [blame] | 137 | * @return 0 if the command for loading was sent to the context hub; |
Ashutosh Joshi | 1d1ac54 | 2016-01-18 17:19:27 -0800 | [diff] [blame] | 138 | * -1 otherwise |
| 139 | * |
| 140 | * @see NanoApp |
| 141 | */ |
| 142 | public int loadNanoApp(int hubHandle, NanoApp app) { |
| 143 | int retVal = -1; |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 144 | |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 145 | if (app == null) { |
| 146 | return retVal; |
| 147 | } |
Ashutosh Joshi | 1d1ac54 | 2016-01-18 17:19:27 -0800 | [diff] [blame] | 148 | |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 149 | try { |
| 150 | retVal = getBinder().loadNanoApp(hubHandle, app); |
| 151 | } catch (RemoteException e) { |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 152 | Log.w(TAG, "Could not load nanoApp :" + e); |
Ashutosh Joshi | 1d1ac54 | 2016-01-18 17:19:27 -0800 | [diff] [blame] | 153 | } |
| 154 | |
| 155 | return retVal; |
| 156 | } |
| 157 | |
| 158 | /** |
| 159 | * Unload a specified nanoApp |
| 160 | * |
Greg Kaiser | fac5be2 | 2016-08-17 15:33:10 -0700 | [diff] [blame] | 161 | * Note that unloading is asynchronous. When we return from this method, |
| 162 | * the nano app (probably) hasn't unloaded yet. Assuming a return of 0 |
| 163 | * from this method, then the final success/failure for the unload is |
| 164 | * delivered in a byte string via a call to Callback.onMessageReceipt. |
Ashutosh Joshi | 1d1ac54 | 2016-01-18 17:19:27 -0800 | [diff] [blame] | 165 | * |
Greg Kaiser | fac5be2 | 2016-08-17 15:33:10 -0700 | [diff] [blame] | 166 | * TODO(b/30784270): Provide a better success/failure delivery. |
| 167 | * |
| 168 | * @param nanoAppHandle handle of the nanoApp to unload |
| 169 | * |
| 170 | * @return 0 if the command for unloading was sent to the context hub; |
| 171 | * -1 otherwise |
Ashutosh Joshi | 1d1ac54 | 2016-01-18 17:19:27 -0800 | [diff] [blame] | 172 | */ |
destradaa | 8bad3fe | 2016-03-15 12:33:40 -0700 | [diff] [blame] | 173 | public int unloadNanoApp(int nanoAppHandle) { |
Ashutosh Joshi | 1d1ac54 | 2016-01-18 17:19:27 -0800 | [diff] [blame] | 174 | int retVal = -1; |
| 175 | |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 176 | try { |
destradaa | 8bad3fe | 2016-03-15 12:33:40 -0700 | [diff] [blame] | 177 | retVal = getBinder().unloadNanoApp(nanoAppHandle); |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 178 | } catch (RemoteException e) { |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 179 | Log.w(TAG, "Could not fetch unload nanoApp :" + e); |
Ashutosh Joshi | 1d1ac54 | 2016-01-18 17:19:27 -0800 | [diff] [blame] | 180 | } |
| 181 | |
| 182 | return retVal; |
| 183 | } |
| 184 | |
| 185 | /** |
| 186 | * get information about the nano app instance |
| 187 | * |
Greg Kaiser | 3be73d3 | 2016-08-18 10:13:52 -0700 | [diff] [blame] | 188 | * NOTE: The returned NanoAppInstanceInfo does _not_ contain correct |
| 189 | * information for several fields, specifically: |
| 190 | * - getName() |
| 191 | * - getPublisher() |
| 192 | * - getNeededExecMemBytes() |
| 193 | * - getNeededReadMemBytes() |
| 194 | * - getNeededWriteMemBytes() |
| 195 | * |
| 196 | * For example, say you call loadNanoApp() with a NanoApp that has |
| 197 | * getName() returning "My Name". Later, if you call getNanoAppInstanceInfo |
| 198 | * for that nanoapp, the returned NanoAppInstanceInfo's getName() |
| 199 | * method will claim "Preloaded app, unknown", even though you would |
| 200 | * have expected "My Name". For now, as the user, you'll need to |
| 201 | * separately track the above fields if they are of interest to you. |
| 202 | * |
| 203 | * TODO(b/30943489): Have the returned NanoAppInstanceInfo contain the |
| 204 | * correct information. |
| 205 | * |
destradaa | 8bad3fe | 2016-03-15 12:33:40 -0700 | [diff] [blame] | 206 | * @param nanoAppHandle handle of the nanoAppInstance |
| 207 | * @return NanoAppInstanceInfo Information about the nano app instance. |
Ashutosh Joshi | 1d1ac54 | 2016-01-18 17:19:27 -0800 | [diff] [blame] | 208 | * |
| 209 | * @see NanoAppInstanceInfo |
| 210 | */ |
destradaa | 8bad3fe | 2016-03-15 12:33:40 -0700 | [diff] [blame] | 211 | public NanoAppInstanceInfo getNanoAppInstanceInfo(int nanoAppHandle) { |
Ashutosh Joshi | 1d1ac54 | 2016-01-18 17:19:27 -0800 | [diff] [blame] | 212 | NanoAppInstanceInfo retVal = null; |
| 213 | |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 214 | try { |
destradaa | 8bad3fe | 2016-03-15 12:33:40 -0700 | [diff] [blame] | 215 | retVal = getBinder().getNanoAppInstanceInfo(nanoAppHandle); |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 216 | } catch (RemoteException e) { |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 217 | Log.w(TAG, "Could not fetch nanoApp info :" + e); |
Ashutosh Joshi | 1d1ac54 | 2016-01-18 17:19:27 -0800 | [diff] [blame] | 218 | } |
| 219 | |
| 220 | return retVal; |
| 221 | } |
| 222 | |
| 223 | /** |
| 224 | * Find a specified nano app on the system |
| 225 | * |
| 226 | * @param hubHandle handle of hub to search for nano app |
| 227 | * @param filter filter specifying the search criteria for app |
| 228 | * |
| 229 | * @see NanoAppFilter |
| 230 | * |
destradaa | 8bad3fe | 2016-03-15 12:33:40 -0700 | [diff] [blame] | 231 | * @return int[] Array of handles to any found nano apps |
Ashutosh Joshi | 1d1ac54 | 2016-01-18 17:19:27 -0800 | [diff] [blame] | 232 | */ |
destradaa | 8bad3fe | 2016-03-15 12:33:40 -0700 | [diff] [blame] | 233 | public int[] findNanoAppOnHub(int hubHandle, NanoAppFilter filter) { |
| 234 | int[] retVal = null; |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 235 | try { |
destradaa | 8bad3fe | 2016-03-15 12:33:40 -0700 | [diff] [blame] | 236 | retVal = getBinder().findNanoAppOnHub(hubHandle, filter); |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 237 | } catch (RemoteException e) { |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 238 | Log.w(TAG, "Could not query nanoApp instance :" + e); |
Ashutosh Joshi | 1d1ac54 | 2016-01-18 17:19:27 -0800 | [diff] [blame] | 239 | } |
Ashutosh Joshi | 1d1ac54 | 2016-01-18 17:19:27 -0800 | [diff] [blame] | 240 | return retVal; |
| 241 | } |
| 242 | |
| 243 | /** |
destradaa | 8bad3fe | 2016-03-15 12:33:40 -0700 | [diff] [blame] | 244 | * Send a message to a specific nano app instance on a context hub. |
Ashutosh Joshi | 1d1ac54 | 2016-01-18 17:19:27 -0800 | [diff] [blame] | 245 | * |
Greg Kaiser | fac5be2 | 2016-08-17 15:33:10 -0700 | [diff] [blame] | 246 | * Note that the return value of this method only speaks of success |
| 247 | * up to the point of sending this to the Context Hub. It is not |
| 248 | * an assurance that the Context Hub successfully sent this message |
| 249 | * on to the nanoapp. If assurance is desired, a protocol should be |
| 250 | * established between your code and the nanoapp, with the nanoapp |
| 251 | * sending a confirmation message (which will be reported via |
| 252 | * Callback.onMessageReceipt). |
| 253 | * |
Ashutosh Joshi | 1d1ac54 | 2016-01-18 17:19:27 -0800 | [diff] [blame] | 254 | * @param hubHandle handle of the hub to send the message to |
| 255 | * @param nanoAppHandle handle of the nano app to send to |
destradaa | 8bad3fe | 2016-03-15 12:33:40 -0700 | [diff] [blame] | 256 | * @param message Message to be sent |
Ashutosh Joshi | 1d1ac54 | 2016-01-18 17:19:27 -0800 | [diff] [blame] | 257 | * |
| 258 | * @see ContextHubMessage |
| 259 | * |
| 260 | * @return int 0 on success, -1 otherwise |
| 261 | */ |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 262 | public int sendMessage(int hubHandle, int nanoAppHandle, ContextHubMessage message) { |
Ashutosh Joshi | 1d1ac54 | 2016-01-18 17:19:27 -0800 | [diff] [blame] | 263 | int retVal = -1; |
| 264 | |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 265 | if (message == null || message.getData() == null) { |
| 266 | Log.w(TAG, "null ptr"); |
| 267 | return retVal; |
| 268 | } |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 269 | try { |
| 270 | retVal = getBinder().sendMessage(hubHandle, nanoAppHandle, message); |
| 271 | } catch (RemoteException e) { |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 272 | Log.w(TAG, "Could not send message :" + e.toString()); |
Ashutosh Joshi | 1d1ac54 | 2016-01-18 17:19:27 -0800 | [diff] [blame] | 273 | } |
| 274 | |
| 275 | return retVal; |
| 276 | } |
| 277 | |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 278 | /** |
| 279 | * Set a callback to receive messages from the context hub |
| 280 | * |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 281 | * @param callback Callback object |
| 282 | * |
Greg Kaiser | 6ba60e6 | 2016-03-18 10:08:39 -0700 | [diff] [blame] | 283 | * @see Callback |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 284 | * |
| 285 | * @return int 0 on success, -1 otherwise |
| 286 | */ |
Greg Kaiser | 6ba60e6 | 2016-03-18 10:08:39 -0700 | [diff] [blame] | 287 | public int registerCallback(Callback callback) { |
| 288 | return registerCallback(callback, null); |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 289 | } |
| 290 | |
| 291 | /** |
destradaa | 78cebca | 2016-04-14 18:40:14 -0700 | [diff] [blame] | 292 | * @deprecated Use {@link #registerCallback(Callback)} instead. |
| 293 | * @hide |
| 294 | */ |
| 295 | @Deprecated |
| 296 | public int registerCallback(ICallback callback) { |
| 297 | if (mLocalCallback != null) { |
| 298 | Log.w(TAG, "Max number of local callbacks reached!"); |
| 299 | return -1; |
| 300 | } |
| 301 | mLocalCallback = callback; |
| 302 | return 0; |
| 303 | } |
| 304 | |
| 305 | /** |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 306 | * Set a callback to receive messages from the context hub |
| 307 | * |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 308 | * @param callback Callback object |
destradaa | 8bad3fe | 2016-03-15 12:33:40 -0700 | [diff] [blame] | 309 | * @param handler Handler object |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 310 | * |
Greg Kaiser | 6ba60e6 | 2016-03-18 10:08:39 -0700 | [diff] [blame] | 311 | * @see Callback |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 312 | * |
| 313 | * @return int 0 on success, -1 otherwise |
| 314 | */ |
Greg Kaiser | 6ba60e6 | 2016-03-18 10:08:39 -0700 | [diff] [blame] | 315 | public int registerCallback(Callback callback, Handler handler) { |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 316 | synchronized(this) { |
| 317 | if (mCallback != null) { |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 318 | Log.w(TAG, "Max number of callbacks reached!"); |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 319 | return -1; |
| 320 | } |
| 321 | mCallback = callback; |
| 322 | mCallbackHandler = handler; |
| 323 | } |
| 324 | return 0; |
| 325 | } |
| 326 | |
| 327 | /** |
destradaa | 8bad3fe | 2016-03-15 12:33:40 -0700 | [diff] [blame] | 328 | * Unregister a callback for receive messages from the context hub. |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 329 | * |
Greg Kaiser | 6ba60e6 | 2016-03-18 10:08:39 -0700 | [diff] [blame] | 330 | * @see Callback |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 331 | * |
| 332 | * @param callback method to deregister |
| 333 | * |
| 334 | * @return int 0 on success, -1 otherwise |
| 335 | */ |
Greg Kaiser | 6ba60e6 | 2016-03-18 10:08:39 -0700 | [diff] [blame] | 336 | public int unregisterCallback(Callback callback) { |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 337 | synchronized(this) { |
| 338 | if (callback != mCallback) { |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 339 | Log.w(TAG, "Cannot recognize callback!"); |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 340 | return -1; |
| 341 | } |
| 342 | |
| 343 | mCallback = null; |
| 344 | mCallbackHandler = null; |
| 345 | } |
| 346 | return 0; |
| 347 | } |
| 348 | |
destradaa | 78cebca | 2016-04-14 18:40:14 -0700 | [diff] [blame] | 349 | /** |
| 350 | * @deprecated Use {@link #unregisterCallback(Callback)} instead. |
| 351 | * @hide |
| 352 | */ |
| 353 | public synchronized int unregisterCallback(ICallback callback) { |
| 354 | if (callback != mLocalCallback) { |
| 355 | Log.w(TAG, "Cannot recognize local callback!"); |
| 356 | return -1; |
| 357 | } |
| 358 | mLocalCallback = null; |
| 359 | return 0; |
| 360 | } |
| 361 | |
Ashutosh Joshi | 1d1ac54 | 2016-01-18 17:19:27 -0800 | [diff] [blame] | 362 | private IContextHubCallback.Stub mClientCallback = new IContextHubCallback.Stub() { |
| 363 | @Override |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 364 | public void onMessageReceipt(final int hubId, final int nanoAppId, |
destradaa | 8bad3fe | 2016-03-15 12:33:40 -0700 | [diff] [blame] | 365 | final ContextHubMessage message) { |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 366 | if (mCallback != null) { |
| 367 | synchronized(this) { |
Greg Kaiser | 6ba60e6 | 2016-03-18 10:08:39 -0700 | [diff] [blame] | 368 | final Callback callback = mCallback; |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 369 | Handler handler = mCallbackHandler == null ? |
| 370 | new Handler(mMainLooper) : mCallbackHandler; |
| 371 | handler.post(new Runnable() { |
| 372 | @Override |
| 373 | public void run() { |
| 374 | callback.onMessageReceipt(hubId, nanoAppId, message); |
| 375 | } |
| 376 | }); |
| 377 | } |
destradaa | 78cebca | 2016-04-14 18:40:14 -0700 | [diff] [blame] | 378 | } else if (mLocalCallback != null) { |
| 379 | // we always ensure that mCallback takes precedence, because mLocalCallback is only |
| 380 | // for internal compatibility |
| 381 | synchronized (this) { |
| 382 | mLocalCallback.onMessageReceipt(hubId, nanoAppId, message); |
| 383 | } |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 384 | } else { |
| 385 | Log.d(TAG, "Context hub manager client callback is NULL"); |
| 386 | } |
Ashutosh Joshi | 1d1ac54 | 2016-01-18 17:19:27 -0800 | [diff] [blame] | 387 | } |
| 388 | }; |
| 389 | |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 390 | /** @hide */ |
| 391 | public ContextHubManager(Context context, Looper mainLooper) { |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 392 | mMainLooper = mainLooper; |
| 393 | |
| 394 | IBinder b = ServiceManager.getService(ContextHubService.CONTEXTHUB_SERVICE); |
| 395 | if (b != null) { |
| 396 | mContextHubService = IContextHubService.Stub.asInterface(b); |
| 397 | |
| 398 | try { |
| 399 | getBinder().registerCallback(mClientCallback); |
| 400 | } catch (RemoteException e) { |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 401 | Log.w(TAG, "Could not register callback:" + e); |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 402 | } |
| 403 | |
| 404 | } else { |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 405 | Log.w(TAG, "failed to getService"); |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 406 | } |
Ashutosh Joshi | 1d1ac54 | 2016-01-18 17:19:27 -0800 | [diff] [blame] | 407 | } |
| 408 | |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 409 | private IContextHubService getBinder() throws RemoteException { |
| 410 | if (mContextHubService == null) { |
| 411 | throw new RemoteException("Service not connected."); |
Ashutosh Joshi | 1d1ac54 | 2016-01-18 17:19:27 -0800 | [diff] [blame] | 412 | } |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 413 | return mContextHubService; |
| 414 | } |
Ashutosh Joshi | 1d1ac54 | 2016-01-18 17:19:27 -0800 | [diff] [blame] | 415 | } |