blob: 658d90bae21e7c9e7c946de92605eb6dc688c4ad [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
19import android.app.Service;
20import android.content.Context;
21import android.content.Intent;
22import android.os.IBinder;
23import android.os.RemoteException;
24import android.util.Log;
25
26import java.util.ArrayList;
27import java.util.HashMap;
28
29/**
30 * @hide
31 */
Peng Xu9ff7d222016-02-11 13:02:05 -080032public class ContextHubService extends IContextHubService.Stub {
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -080033
34 private static final String TAG = "ContextHubService";
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -080035
Peng Xu9ff7d222016-02-11 13:02:05 -080036 public static final String CONTEXTHUB_SERVICE = "contexthub_service";
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -080037
Peng Xu9ff7d222016-02-11 13:02:05 -080038 private final Context mContext;
39
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -080040 private HashMap<Integer, NanoAppInstanceInfo> mNanoAppHash;
Peng Xu9ff7d222016-02-11 13:02:05 -080041 private ContextHubInfo[] mContextHubInfo;
42 private IContextHubCallback mCallback;
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -080043
Peng Xu9ff7d222016-02-11 13:02:05 -080044 public ContextHubService(Context context) {
45 mContext = context;
46 mContextHubInfo = nativeInitialize();
47
48 for (int i = 0; i < mContextHubInfo.length; i++) {
49 Log.v(TAG, "ContextHub[" + i + "] id: " + mContextHubInfo[i].getId()
50 + ", name: " + mContextHubInfo[i].getName());
51 }
52 }
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -080053
54 private native int nativeSendMessage(int[] header, byte[] data);
55 private native ContextHubInfo[] nativeInitialize();
56
Peng Xu9ff7d222016-02-11 13:02:05 -080057 @Override
58 public int registerCallback(IContextHubCallback callback) throws RemoteException{
59 mCallback = callback;
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -080060 return 0;
61 }
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -080062
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -080063
Peng Xu9ff7d222016-02-11 13:02:05 -080064 private int onMessageReceipt(int[] header, byte[] data) {
65 if (mCallback != null) {
66 // TODO : Defend against unexpected header sizes
67 // Add abstraction for magic numbers
68 // onMessageRecipt should pass the right arguments
69 ContextHubMessage msg = new ContextHubMessage(header[0], header[1], data);
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -080070
Peng Xu9ff7d222016-02-11 13:02:05 -080071 try {
72 mCallback.onMessageReceipt(0, 0, msg);
73 } catch (Exception e) {
74 Log.e(TAG, "Exception " + e + " when calling remote callback");
75 return -1;
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -080076 }
Peng Xu9ff7d222016-02-11 13:02:05 -080077 } else {
78 Log.d(TAG, "Message Callback is NULL");
79 }
80
81 return 0;
82 }
83
84 @Override
85 public int[] getContextHubHandles() throws RemoteException {
86 int [] returnArray = new int[mContextHubInfo.length];
87
88 for (int i = 0; i < returnArray.length; ++i) {
89 returnArray[i] = i + 1; //valid handles from 1...n
90 Log.d(TAG, String.format("Hub %s is mapped to %d",
91 mContextHubInfo[i].getName(), returnArray[i]));
92 }
93
94 return returnArray;
95 }
96
97 @Override
98 public ContextHubInfo getContextHubInfo(int contextHubHandle) throws RemoteException {
99 contextHubHandle -= 1;
100 if (!(contextHubHandle >= 0 && contextHubHandle < mContextHubInfo.length)) {
101 return null; // null means fail
102 }
103
104 return mContextHubInfo[contextHubHandle];
105 }
106
107 @Override
108 public int loadNanoApp(int contextHubHandle, NanoApp app) throws RemoteException {
109 contextHubHandle -= 1;
110
111 if (!(contextHubHandle >= 0 && contextHubHandle < mContextHubInfo.length)) {
112 return -1; // negative handle are invalid, means failed
113 }
114
115 // Call Native interface here
116 int[] msgHeader = new int[8];
117 msgHeader[0] = contextHubHandle;
118 msgHeader[1] = app.getAppId();
119 msgHeader[2] = app.getAppVersion();
120 msgHeader[3] = ContextHubManager.MSG_LOAD_NANO_APP;
121 msgHeader[4] = 0; // Loading hints
122
123 return nativeSendMessage(msgHeader, app.getAppBinary());
124 }
125
126 @Override
127 public int unloadNanoApp(int nanoAppInstanceHandle) throws RemoteException {
128 NanoAppInstanceInfo info = mNanoAppHash.get(nanoAppInstanceHandle);
129 if (info == null) {
130 return -1; //means failed
131 }
132
133 // Call Native interface here
134 int[] msgHeader = new int[8];
135 msgHeader[0] = info.getContexthubId();
136 msgHeader[1] = ContextHubManager.MSG_UNLOAD_NANO_APP;
137 msgHeader[2] = info.getHandle();
138
139 return nativeSendMessage(msgHeader, null);
140 }
141
142 @Override
143 public NanoAppInstanceInfo getNanoAppInstanceInfo(int nanoAppInstanceHandle) throws RemoteException {
144 // This assumes that all the nanoAppInfo is current. This is reasonable
145 // for the use cases for tightly controlled nanoApps.
146 if (mNanoAppHash.containsKey(nanoAppInstanceHandle)) {
147 return mNanoAppHash.get(nanoAppInstanceHandle);
148 } else {
149 return null;
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -0800150 }
151 }
152
153 @Override
Peng Xu9ff7d222016-02-11 13:02:05 -0800154 public int[] findNanoAppOnHub(int hubHandle, NanoAppFilter filter) throws RemoteException {
155 ArrayList<Integer> foundInstances = new ArrayList<Integer>();
156
157 for(Integer nanoAppInstance : mNanoAppHash.keySet()) {
158 NanoAppInstanceInfo info = mNanoAppHash.get(nanoAppInstance);
159
160 if(filter.testMatch(info)){
161 foundInstances.add(nanoAppInstance);
162 }
163 }
164
165 int[] retArray = new int[foundInstances.size()];
166 for (int i = 0; i < foundInstances.size(); i++) {
167 retArray[i] = foundInstances.get(i).intValue();
168 }
169
170 return retArray;
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -0800171 }
172
173 @Override
Peng Xu9ff7d222016-02-11 13:02:05 -0800174 public int sendMessage(int hubHandle, int nanoAppHandle, ContextHubMessage msg) throws RemoteException {
175 int[] msgHeader = new int[8];
176 msgHeader[0] = ContextHubManager.MSG_DATA_SEND;
177 msgHeader[1] = hubHandle;
178 msgHeader[2] = nanoAppHandle;
179 msgHeader[3] = msg.getMsgType();
180 msgHeader[4] = msg.getVersion();
181
182 return nativeSendMessage(msgHeader, msg.getData());
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -0800183 }
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -0800184}
Peng Xu9ff7d222016-02-11 13:02:05 -0800185