blob: 274babe6a93048a60ca7ba4fca60fc33ec4429a4 [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 */
16
17package android.hardware.location;
18
destradaa8bad3fe2016-03-15 12:33:40 -070019import android.Manifest;
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -080020import android.content.Context;
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -080021import android.os.RemoteException;
22import android.util.Log;
23
24import java.util.ArrayList;
25import java.util.HashMap;
26
27/**
28 * @hide
29 */
Peng Xu9ff7d222016-02-11 13:02:05 -080030public class ContextHubService extends IContextHubService.Stub {
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -080031
32 private static final String TAG = "ContextHubService";
destradaa8bad3fe2016-03-15 12:33:40 -070033 private static final String HARDWARE_PERMISSION = Manifest.permission.LOCATION_HARDWARE;
34 private static final String ENFORCE_HW_PERMISSION_MESSAGE = "Permission '"
35 + HARDWARE_PERMISSION + "' not granted to access ContextHub Hardware";
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -080036
Peng Xu9ff7d222016-02-11 13:02:05 -080037 public static final String CONTEXTHUB_SERVICE = "contexthub_service";
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -080038
Peng Xu9ff7d222016-02-11 13:02:05 -080039 private final Context mContext;
40
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -080041 private HashMap<Integer, NanoAppInstanceInfo> mNanoAppHash;
Peng Xu9ff7d222016-02-11 13:02:05 -080042 private ContextHubInfo[] mContextHubInfo;
43 private IContextHubCallback mCallback;
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -080044
Peng Xu9ff7d222016-02-11 13:02:05 -080045 public ContextHubService(Context context) {
46 mContext = context;
47 mContextHubInfo = nativeInitialize();
48
49 for (int i = 0; i < mContextHubInfo.length; i++) {
50 Log.v(TAG, "ContextHub[" + i + "] id: " + mContextHubInfo[i].getId()
51 + ", name: " + mContextHubInfo[i].getName());
52 }
53 }
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -080054
55 private native int nativeSendMessage(int[] header, byte[] data);
56 private native ContextHubInfo[] nativeInitialize();
57
Peng Xu9ff7d222016-02-11 13:02:05 -080058 @Override
59 public int registerCallback(IContextHubCallback callback) throws RemoteException{
destradaa8bad3fe2016-03-15 12:33:40 -070060 checkPermissions();
Peng Xu9ff7d222016-02-11 13:02:05 -080061 mCallback = callback;
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -080062 return 0;
63 }
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -080064
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -080065
Peng Xu9ff7d222016-02-11 13:02:05 -080066 private int onMessageReceipt(int[] header, byte[] data) {
67 if (mCallback != null) {
68 // TODO : Defend against unexpected header sizes
69 // Add abstraction for magic numbers
70 // onMessageRecipt should pass the right arguments
71 ContextHubMessage msg = new ContextHubMessage(header[0], header[1], data);
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -080072
Peng Xu9ff7d222016-02-11 13:02:05 -080073 try {
74 mCallback.onMessageReceipt(0, 0, msg);
75 } catch (Exception e) {
76 Log.e(TAG, "Exception " + e + " when calling remote callback");
77 return -1;
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -080078 }
Peng Xu9ff7d222016-02-11 13:02:05 -080079 } else {
80 Log.d(TAG, "Message Callback is NULL");
81 }
82
83 return 0;
84 }
85
86 @Override
87 public int[] getContextHubHandles() throws RemoteException {
destradaa8bad3fe2016-03-15 12:33:40 -070088 checkPermissions();
Peng Xu9ff7d222016-02-11 13:02:05 -080089 int [] returnArray = new int[mContextHubInfo.length];
90
91 for (int i = 0; i < returnArray.length; ++i) {
92 returnArray[i] = i + 1; //valid handles from 1...n
93 Log.d(TAG, String.format("Hub %s is mapped to %d",
94 mContextHubInfo[i].getName(), returnArray[i]));
95 }
96
97 return returnArray;
98 }
99
100 @Override
101 public ContextHubInfo getContextHubInfo(int contextHubHandle) throws RemoteException {
destradaa8bad3fe2016-03-15 12:33:40 -0700102 checkPermissions();
Peng Xu9ff7d222016-02-11 13:02:05 -0800103 contextHubHandle -= 1;
104 if (!(contextHubHandle >= 0 && contextHubHandle < mContextHubInfo.length)) {
105 return null; // null means fail
106 }
107
108 return mContextHubInfo[contextHubHandle];
109 }
110
111 @Override
112 public int loadNanoApp(int contextHubHandle, NanoApp app) throws RemoteException {
destradaa8bad3fe2016-03-15 12:33:40 -0700113 checkPermissions();
Peng Xu9ff7d222016-02-11 13:02:05 -0800114 contextHubHandle -= 1;
115
116 if (!(contextHubHandle >= 0 && contextHubHandle < mContextHubInfo.length)) {
117 return -1; // negative handle are invalid, means failed
118 }
119
120 // Call Native interface here
121 int[] msgHeader = new int[8];
122 msgHeader[0] = contextHubHandle;
123 msgHeader[1] = app.getAppId();
124 msgHeader[2] = app.getAppVersion();
125 msgHeader[3] = ContextHubManager.MSG_LOAD_NANO_APP;
126 msgHeader[4] = 0; // Loading hints
127
128 return nativeSendMessage(msgHeader, app.getAppBinary());
129 }
130
destradaa8bad3fe2016-03-15 12:33:40 -0700131 @Override
132 public int unloadNanoApp(int nanoAppInstanceHandle) throws RemoteException {
133 checkPermissions();
Peng Xu9ff7d222016-02-11 13:02:05 -0800134 NanoAppInstanceInfo info = mNanoAppHash.get(nanoAppInstanceHandle);
135 if (info == null) {
destradaa8bad3fe2016-03-15 12:33:40 -0700136 return -1; //means failed
Peng Xu9ff7d222016-02-11 13:02:05 -0800137 }
138
139 // Call Native interface here
140 int[] msgHeader = new int[8];
141 msgHeader[0] = info.getContexthubId();
142 msgHeader[1] = ContextHubManager.MSG_UNLOAD_NANO_APP;
143 msgHeader[2] = info.getHandle();
144
145 return nativeSendMessage(msgHeader, null);
destradaa8bad3fe2016-03-15 12:33:40 -0700146 }
Peng Xu9ff7d222016-02-11 13:02:05 -0800147
148 @Override
destradaa8bad3fe2016-03-15 12:33:40 -0700149 public NanoAppInstanceInfo getNanoAppInstanceInfo(int nanoAppInstanceHandle)
150 throws RemoteException {
151 checkPermissions();
Peng Xu9ff7d222016-02-11 13:02:05 -0800152 // This assumes that all the nanoAppInfo is current. This is reasonable
153 // for the use cases for tightly controlled nanoApps.
154 if (mNanoAppHash.containsKey(nanoAppInstanceHandle)) {
155 return mNanoAppHash.get(nanoAppInstanceHandle);
156 } else {
157 return null;
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -0800158 }
159 }
160
161 @Override
Peng Xu9ff7d222016-02-11 13:02:05 -0800162 public int[] findNanoAppOnHub(int hubHandle, NanoAppFilter filter) throws RemoteException {
destradaa8bad3fe2016-03-15 12:33:40 -0700163 checkPermissions();
Peng Xu9ff7d222016-02-11 13:02:05 -0800164 ArrayList<Integer> foundInstances = new ArrayList<Integer>();
165
166 for(Integer nanoAppInstance : mNanoAppHash.keySet()) {
167 NanoAppInstanceInfo info = mNanoAppHash.get(nanoAppInstance);
168
169 if(filter.testMatch(info)){
170 foundInstances.add(nanoAppInstance);
171 }
172 }
173
174 int[] retArray = new int[foundInstances.size()];
175 for (int i = 0; i < foundInstances.size(); i++) {
176 retArray[i] = foundInstances.get(i).intValue();
177 }
178
179 return retArray;
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -0800180 }
181
182 @Override
destradaa8bad3fe2016-03-15 12:33:40 -0700183 public int sendMessage(int hubHandle, int nanoAppHandle, ContextHubMessage msg)
184 throws RemoteException {
185 checkPermissions();
Peng Xu9ff7d222016-02-11 13:02:05 -0800186 int[] msgHeader = new int[8];
187 msgHeader[0] = ContextHubManager.MSG_DATA_SEND;
188 msgHeader[1] = hubHandle;
189 msgHeader[2] = nanoAppHandle;
190 msgHeader[3] = msg.getMsgType();
191 msgHeader[4] = msg.getVersion();
192
193 return nativeSendMessage(msgHeader, msg.getData());
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -0800194 }
destradaa8bad3fe2016-03-15 12:33:40 -0700195
196 private void checkPermissions() {
197 mContext.enforceCallingPermission(HARDWARE_PERMISSION, ENFORCE_HW_PERMISSION_MESSAGE);
198 }
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -0800199}
Peng Xu9ff7d222016-02-11 13:02:05 -0800200