11d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi/* 21d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi * Copyright (C) 2016 The Android Open Source Project 31d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi * 41d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi * Licensed under the Apache License, Version 2.0 (the "License"); 51d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi * you may not use this file except in compliance with the License. 61d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi * You may obtain a copy of the License at 71d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi * 81d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi * http://www.apache.org/licenses/LICENSE-2.0 91d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi * 101d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi * Unless required by applicable law or agreed to in writing, software 111d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi * distributed under the License is distributed on an "AS IS" BASIS, 121d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi * See the License for the specific language governing permissions and 141d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi * limitations under the License. 151d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi */ 161d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi 17420e45e9cb004ea6c6e11f69adcdbf3dac5fc800Ashutosh Joshipackage com.android.server.location; 181d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi 198bad3fec0f54959958352c0bef90b813cd0d823adestradaaimport android.Manifest; 201d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshiimport android.content.Context; 216239cc6fe1d18ce4365c56346a09c7963dfa8f10Ashutosh Joshiimport android.content.pm.PackageManager; 22420e45e9cb004ea6c6e11f69adcdbf3dac5fc800Ashutosh Joshiimport android.hardware.location.ContextHubInfo; 23420e45e9cb004ea6c6e11f69adcdbf3dac5fc800Ashutosh Joshiimport android.hardware.location.ContextHubManager; 24420e45e9cb004ea6c6e11f69adcdbf3dac5fc800Ashutosh Joshiimport android.hardware.location.ContextHubMessage; 25420e45e9cb004ea6c6e11f69adcdbf3dac5fc800Ashutosh Joshiimport android.hardware.location.IContextHubService; 26420e45e9cb004ea6c6e11f69adcdbf3dac5fc800Ashutosh Joshiimport android.hardware.location.IContextHubCallback; 27420e45e9cb004ea6c6e11f69adcdbf3dac5fc800Ashutosh Joshiimport android.hardware.location.NanoAppFilter; 28420e45e9cb004ea6c6e11f69adcdbf3dac5fc800Ashutosh Joshiimport android.hardware.location.NanoApp; 29420e45e9cb004ea6c6e11f69adcdbf3dac5fc800Ashutosh Joshiimport android.hardware.location.NanoAppInstanceInfo; 3078cebca7204f85ebb7c583bab2fc9891367cd403destradaaimport android.os.RemoteCallbackList; 311d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshiimport android.os.RemoteException; 321d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshiimport android.util.Log; 331d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi 34fe9a53bc45fd0124a876dc0a49680aaf86641d3eJeff Sharkeyimport com.android.internal.util.DumpUtils; 35fe9a53bc45fd0124a876dc0a49680aaf86641d3eJeff Sharkey 366239cc6fe1d18ce4365c56346a09c7963dfa8f10Ashutosh Joshiimport java.io.FileDescriptor; 376239cc6fe1d18ce4365c56346a09c7963dfa8f10Ashutosh Joshiimport java.io.PrintWriter; 3819753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshiimport java.nio.ByteBuffer; 3919753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshiimport java.nio.ByteOrder; 401d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshiimport java.util.ArrayList; 41c3d8a529c69b754fbd77231d8fd480db94763143Brian Duddieimport java.util.concurrent.ConcurrentHashMap; 4219753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshiimport java.util.HashMap; 431d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi 441d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi/** 451d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi * @hide 461d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi */ 479ff7d2235427b211344fa58b608424805a21aa24Peng Xupublic class ContextHubService extends IContextHubService.Stub { 481d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi private static final String TAG = "ContextHubService"; 498bad3fec0f54959958352c0bef90b813cd0d823adestradaa private static final String HARDWARE_PERMISSION = Manifest.permission.LOCATION_HARDWARE; 508bad3fec0f54959958352c0bef90b813cd0d823adestradaa private static final String ENFORCE_HW_PERMISSION_MESSAGE = "Permission '" 516239cc6fe1d18ce4365c56346a09c7963dfa8f10Ashutosh Joshi + HARDWARE_PERMISSION + "' not granted to access ContextHub Hardware"; 521d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi 53b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi public static final int ANY_HUB = -1; 54cafdee9a72652354c5bde0b13c86dac3d88ac2aeAshutosh Joshi public static final int MSG_LOAD_NANO_APP = 3; 55cafdee9a72652354c5bde0b13c86dac3d88ac2aeAshutosh Joshi public static final int MSG_UNLOAD_NANO_APP = 4; 56b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi 57b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi private static final String PRE_LOADED_GENERIC_UNKNOWN = "Preloaded app, unknown"; 58b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi private static final String PRE_LOADED_APP_NAME = PRE_LOADED_GENERIC_UNKNOWN; 59b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi private static final String PRE_LOADED_APP_PUBLISHER = PRE_LOADED_GENERIC_UNKNOWN; 60b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi private static final int PRE_LOADED_APP_MEM_REQ = 0; 61b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi 62b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi private static final int MSG_HEADER_SIZE = 4; 6354787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi private static final int HEADER_FIELD_MSG_TYPE = 0; 6454787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi private static final int HEADER_FIELD_MSG_VERSION = 1; 6554787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi private static final int HEADER_FIELD_HUB_HANDLE = 2; 6654787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi private static final int HEADER_FIELD_APP_INSTANCE = 3; 6754787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi 6854787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi private static final int HEADER_FIELD_LOAD_APP_ID_LO = MSG_HEADER_SIZE; 6954787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi private static final int HEADER_FIELD_LOAD_APP_ID_HI = MSG_HEADER_SIZE + 1; 7054787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi private static final int MSG_LOAD_APP_HEADER_SIZE = MSG_HEADER_SIZE + 2; 71b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi 72b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi private static final int OS_APP_INSTANCE = -1; 739ff7d2235427b211344fa58b608424805a21aa24Peng Xu 749ff7d2235427b211344fa58b608424805a21aa24Peng Xu private final Context mContext; 75c3d8a529c69b754fbd77231d8fd480db94763143Brian Duddie private final ConcurrentHashMap<Integer, NanoAppInstanceInfo> mNanoAppHash = 76c3d8a529c69b754fbd77231d8fd480db94763143Brian Duddie new ConcurrentHashMap<>(); 7778cebca7204f85ebb7c583bab2fc9891367cd403destradaa private final ContextHubInfo[] mContextHubInfo; 7878cebca7204f85ebb7c583bab2fc9891367cd403destradaa private final RemoteCallbackList<IContextHubCallback> mCallbacksList = 7978cebca7204f85ebb7c583bab2fc9891367cd403destradaa new RemoteCallbackList<>(); 809ff7d2235427b211344fa58b608424805a21aa24Peng Xu 81b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi private native int nativeSendMessage(int[] header, byte[] data); 82b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi private native ContextHubInfo[] nativeInitialize(); 83b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi 849ff7d2235427b211344fa58b608424805a21aa24Peng Xu public ContextHubService(Context context) { 859ff7d2235427b211344fa58b608424805a21aa24Peng Xu mContext = context; 869ff7d2235427b211344fa58b608424805a21aa24Peng Xu mContextHubInfo = nativeInitialize(); 871d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi 889ff7d2235427b211344fa58b608424805a21aa24Peng Xu for (int i = 0; i < mContextHubInfo.length; i++) { 89b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi Log.d(TAG, "ContextHub[" + i + "] id: " + mContextHubInfo[i].getId() 909ff7d2235427b211344fa58b608424805a21aa24Peng Xu + ", name: " + mContextHubInfo[i].getName()); 919ff7d2235427b211344fa58b608424805a21aa24Peng Xu } 929ff7d2235427b211344fa58b608424805a21aa24Peng Xu } 931d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi 949ff7d2235427b211344fa58b608424805a21aa24Peng Xu @Override 95b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi public int registerCallback(IContextHubCallback callback) throws RemoteException { 968bad3fec0f54959958352c0bef90b813cd0d823adestradaa checkPermissions(); 9778cebca7204f85ebb7c583bab2fc9891367cd403destradaa mCallbacksList.register(callback); 981d94181f44217979f2242281ebb9da50592e770eAshutosh Joshi Log.d(TAG, "Added callback, total callbacks " + 991d94181f44217979f2242281ebb9da50592e770eAshutosh Joshi mCallbacksList.getRegisteredCallbackCount()); 1009ff7d2235427b211344fa58b608424805a21aa24Peng Xu return 0; 1011d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi } 1021d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi 1031d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi @Override 1049ff7d2235427b211344fa58b608424805a21aa24Peng Xu public int[] getContextHubHandles() throws RemoteException { 1058bad3fec0f54959958352c0bef90b813cd0d823adestradaa checkPermissions(); 1066239cc6fe1d18ce4365c56346a09c7963dfa8f10Ashutosh Joshi int[] returnArray = new int[mContextHubInfo.length]; 1071d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi 1081d94181f44217979f2242281ebb9da50592e770eAshutosh Joshi Log.d(TAG, "System supports " + returnArray.length + " hubs"); 1099ff7d2235427b211344fa58b608424805a21aa24Peng Xu for (int i = 0; i < returnArray.length; ++i) { 1106239cc6fe1d18ce4365c56346a09c7963dfa8f10Ashutosh Joshi returnArray[i] = i; 1119ff7d2235427b211344fa58b608424805a21aa24Peng Xu Log.d(TAG, String.format("Hub %s is mapped to %d", 1129ff7d2235427b211344fa58b608424805a21aa24Peng Xu mContextHubInfo[i].getName(), returnArray[i])); 1131d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi } 1141d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi 1159ff7d2235427b211344fa58b608424805a21aa24Peng Xu return returnArray; 1169ff7d2235427b211344fa58b608424805a21aa24Peng Xu } 1171d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi 1189ff7d2235427b211344fa58b608424805a21aa24Peng Xu @Override 1199ff7d2235427b211344fa58b608424805a21aa24Peng Xu public ContextHubInfo getContextHubInfo(int contextHubHandle) throws RemoteException { 1208bad3fec0f54959958352c0bef90b813cd0d823adestradaa checkPermissions(); 1219ff7d2235427b211344fa58b608424805a21aa24Peng Xu if (!(contextHubHandle >= 0 && contextHubHandle < mContextHubInfo.length)) { 1221d94181f44217979f2242281ebb9da50592e770eAshutosh Joshi Log.e(TAG, "Invalid context hub handle " + contextHubHandle); 1239ff7d2235427b211344fa58b608424805a21aa24Peng Xu return null; // null means fail 1241d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi } 1251d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi 1269ff7d2235427b211344fa58b608424805a21aa24Peng Xu return mContextHubInfo[contextHubHandle]; 1279ff7d2235427b211344fa58b608424805a21aa24Peng Xu } 1281d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi 1299ff7d2235427b211344fa58b608424805a21aa24Peng Xu @Override 1309ff7d2235427b211344fa58b608424805a21aa24Peng Xu public int loadNanoApp(int contextHubHandle, NanoApp app) throws RemoteException { 1318bad3fec0f54959958352c0bef90b813cd0d823adestradaa checkPermissions(); 1321d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi 1339ff7d2235427b211344fa58b608424805a21aa24Peng Xu if (!(contextHubHandle >= 0 && contextHubHandle < mContextHubInfo.length)) { 1346239cc6fe1d18ce4365c56346a09c7963dfa8f10Ashutosh Joshi Log.e(TAG, "Invalid contextHubhandle " + contextHubHandle); 1356239cc6fe1d18ce4365c56346a09c7963dfa8f10Ashutosh Joshi return -1; 1369ff7d2235427b211344fa58b608424805a21aa24Peng Xu } 13749ca529a850e60482ddcc8c0762105b4aa10f35fJeff Sharkey if (app == null) { 1381d94181f44217979f2242281ebb9da50592e770eAshutosh Joshi Log.e(TAG, "Invalid null app"); 13949ca529a850e60482ddcc8c0762105b4aa10f35fJeff Sharkey return -1; 14049ca529a850e60482ddcc8c0762105b4aa10f35fJeff Sharkey } 1411d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi 14254787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi int[] msgHeader = new int[MSG_LOAD_APP_HEADER_SIZE]; 14354787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi msgHeader[HEADER_FIELD_HUB_HANDLE] = contextHubHandle; 14454787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi msgHeader[HEADER_FIELD_APP_INSTANCE] = OS_APP_INSTANCE; 14554787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi msgHeader[HEADER_FIELD_MSG_VERSION] = 0; 14654787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi msgHeader[HEADER_FIELD_MSG_TYPE] = MSG_LOAD_NANO_APP; 14754787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi 14854787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi long appId = app.getAppId(); 14954787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi 15054787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi msgHeader[HEADER_FIELD_LOAD_APP_ID_LO] = (int)(appId & 0xFFFFFFFF); 15154787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi msgHeader[HEADER_FIELD_LOAD_APP_ID_HI] = (int)((appId >> 32) & 0xFFFFFFFF); 152b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi 153118644056f3c442f0aa9451aaeac8e8b35dde3f8Ashutosh Joshi int errVal = nativeSendMessage(msgHeader, app.getAppBinary()); 154118644056f3c442f0aa9451aaeac8e8b35dde3f8Ashutosh Joshi if (errVal != 0) { 155118644056f3c442f0aa9451aaeac8e8b35dde3f8Ashutosh Joshi Log.e(TAG, "Send Message returns error" + contextHubHandle); 156b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi return -1; 157b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi } 158118644056f3c442f0aa9451aaeac8e8b35dde3f8Ashutosh Joshi 159b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi // Do not add an entry to mNanoAppInstance Hash yet. The HAL may reject the app 160b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi return 0; 1619ff7d2235427b211344fa58b608424805a21aa24Peng Xu } 1621d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi 1638bad3fec0f54959958352c0bef90b813cd0d823adestradaa @Override 1648bad3fec0f54959958352c0bef90b813cd0d823adestradaa public int unloadNanoApp(int nanoAppInstanceHandle) throws RemoteException { 1658bad3fec0f54959958352c0bef90b813cd0d823adestradaa checkPermissions(); 1669ff7d2235427b211344fa58b608424805a21aa24Peng Xu NanoAppInstanceInfo info = mNanoAppHash.get(nanoAppInstanceHandle); 1679ff7d2235427b211344fa58b608424805a21aa24Peng Xu if (info == null) { 1681d94181f44217979f2242281ebb9da50592e770eAshutosh Joshi Log.e(TAG, "Cannot find app with handle " + nanoAppInstanceHandle); 1698bad3fec0f54959958352c0bef90b813cd0d823adestradaa return -1; //means failed 1701d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi } 1711d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi 1729ff7d2235427b211344fa58b608424805a21aa24Peng Xu // Call Native interface here 173b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi int[] msgHeader = new int[MSG_HEADER_SIZE]; 17454787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi msgHeader[HEADER_FIELD_HUB_HANDLE] = ANY_HUB; 17554787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi msgHeader[HEADER_FIELD_APP_INSTANCE] = nanoAppInstanceHandle; 17654787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi msgHeader[HEADER_FIELD_MSG_VERSION] = 0; 17754787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi msgHeader[HEADER_FIELD_MSG_TYPE] = MSG_UNLOAD_NANO_APP; 178b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi 17954787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi byte msg[] = new byte[0]; 18054787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi 18154787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi if (nativeSendMessage(msgHeader, msg) != 0) { 1821d94181f44217979f2242281ebb9da50592e770eAshutosh Joshi Log.e(TAG, "native send message fails"); 183b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi return -1; 184b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi } 1851d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi 186b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi // Do not add an entry to mNanoAppInstance Hash yet. The HAL may reject the app 187b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi return 0; 1888bad3fec0f54959958352c0bef90b813cd0d823adestradaa } 1891d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi 1909ff7d2235427b211344fa58b608424805a21aa24Peng Xu @Override 1918bad3fec0f54959958352c0bef90b813cd0d823adestradaa public NanoAppInstanceInfo getNanoAppInstanceInfo(int nanoAppInstanceHandle) 1926239cc6fe1d18ce4365c56346a09c7963dfa8f10Ashutosh Joshi throws RemoteException { 1938bad3fec0f54959958352c0bef90b813cd0d823adestradaa checkPermissions(); 1949ff7d2235427b211344fa58b608424805a21aa24Peng Xu // This assumes that all the nanoAppInfo is current. This is reasonable 1959ff7d2235427b211344fa58b608424805a21aa24Peng Xu // for the use cases for tightly controlled nanoApps. 1969ff7d2235427b211344fa58b608424805a21aa24Peng Xu if (mNanoAppHash.containsKey(nanoAppInstanceHandle)) { 1979ff7d2235427b211344fa58b608424805a21aa24Peng Xu return mNanoAppHash.get(nanoAppInstanceHandle); 1989ff7d2235427b211344fa58b608424805a21aa24Peng Xu } else { 1991d94181f44217979f2242281ebb9da50592e770eAshutosh Joshi Log.e(TAG, "Could not find nanoApp with handle " + nanoAppInstanceHandle); 2009ff7d2235427b211344fa58b608424805a21aa24Peng Xu return null; 2019ff7d2235427b211344fa58b608424805a21aa24Peng Xu } 2029ff7d2235427b211344fa58b608424805a21aa24Peng Xu } 2031d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi 2049ff7d2235427b211344fa58b608424805a21aa24Peng Xu @Override 2059ff7d2235427b211344fa58b608424805a21aa24Peng Xu public int[] findNanoAppOnHub(int hubHandle, NanoAppFilter filter) throws RemoteException { 2068bad3fec0f54959958352c0bef90b813cd0d823adestradaa checkPermissions(); 2079ff7d2235427b211344fa58b608424805a21aa24Peng Xu ArrayList<Integer> foundInstances = new ArrayList<Integer>(); 2089ff7d2235427b211344fa58b608424805a21aa24Peng Xu 2096239cc6fe1d18ce4365c56346a09c7963dfa8f10Ashutosh Joshi for (Integer nanoAppInstance: mNanoAppHash.keySet()) { 2109ff7d2235427b211344fa58b608424805a21aa24Peng Xu NanoAppInstanceInfo info = mNanoAppHash.get(nanoAppInstance); 2111d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi 2126239cc6fe1d18ce4365c56346a09c7963dfa8f10Ashutosh Joshi if (filter.testMatch(info)) { 2139ff7d2235427b211344fa58b608424805a21aa24Peng Xu foundInstances.add(nanoAppInstance); 2141d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi } 2159ff7d2235427b211344fa58b608424805a21aa24Peng Xu } 2161d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi 2179ff7d2235427b211344fa58b608424805a21aa24Peng Xu int[] retArray = new int[foundInstances.size()]; 2189ff7d2235427b211344fa58b608424805a21aa24Peng Xu for (int i = 0; i < foundInstances.size(); i++) { 2199ff7d2235427b211344fa58b608424805a21aa24Peng Xu retArray[i] = foundInstances.get(i).intValue(); 2201d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi } 2211d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi 2221d94181f44217979f2242281ebb9da50592e770eAshutosh Joshi Log.w(TAG, "Found " + retArray.length + " apps on hub handle " + hubHandle); 2239ff7d2235427b211344fa58b608424805a21aa24Peng Xu return retArray; 2249ff7d2235427b211344fa58b608424805a21aa24Peng Xu } 2251d1ac5409597ef668e52c6f27293eaf9af575e33Ashutosh Joshi 2269ff7d2235427b211344fa58b608424805a21aa24Peng Xu @Override 2278bad3fec0f54959958352c0bef90b813cd0d823adestradaa public int sendMessage(int hubHandle, int nanoAppHandle, ContextHubMessage msg) 2286239cc6fe1d18ce4365c56346a09c7963dfa8f10Ashutosh Joshi throws RemoteException { 2298bad3fec0f54959958352c0bef90b813cd0d823adestradaa checkPermissions(); 230b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi 23149ca529a850e60482ddcc8c0762105b4aa10f35fJeff Sharkey if (msg == null || msg.getData() == null) { 23249ca529a850e60482ddcc8c0762105b4aa10f35fJeff Sharkey Log.w(TAG, "null ptr"); 23349ca529a850e60482ddcc8c0762105b4aa10f35fJeff Sharkey return -1; 23449ca529a850e60482ddcc8c0762105b4aa10f35fJeff Sharkey } 23549ca529a850e60482ddcc8c0762105b4aa10f35fJeff Sharkey 236b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi int[] msgHeader = new int[MSG_HEADER_SIZE]; 23754787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi msgHeader[HEADER_FIELD_HUB_HANDLE] = hubHandle; 23854787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi msgHeader[HEADER_FIELD_APP_INSTANCE] = nanoAppHandle; 23954787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi msgHeader[HEADER_FIELD_MSG_VERSION] = msg.getVersion(); 24054787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi msgHeader[HEADER_FIELD_MSG_TYPE] = msg.getMsgType(); 2419ff7d2235427b211344fa58b608424805a21aa24Peng Xu 2429ff7d2235427b211344fa58b608424805a21aa24Peng Xu return nativeSendMessage(msgHeader, msg.getData()); 2439ff7d2235427b211344fa58b608424805a21aa24Peng Xu } 2448bad3fec0f54959958352c0bef90b813cd0d823adestradaa 2456239cc6fe1d18ce4365c56346a09c7963dfa8f10Ashutosh Joshi @Override 2466239cc6fe1d18ce4365c56346a09c7963dfa8f10Ashutosh Joshi protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 247fe9a53bc45fd0124a876dc0a49680aaf86641d3eJeff Sharkey if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return; 2486239cc6fe1d18ce4365c56346a09c7963dfa8f10Ashutosh Joshi 2496239cc6fe1d18ce4365c56346a09c7963dfa8f10Ashutosh Joshi pw.println("Dumping ContextHub Service"); 2506239cc6fe1d18ce4365c56346a09c7963dfa8f10Ashutosh Joshi 2516239cc6fe1d18ce4365c56346a09c7963dfa8f10Ashutosh Joshi pw.println(""); 2526239cc6fe1d18ce4365c56346a09c7963dfa8f10Ashutosh Joshi // dump ContextHubInfo 2536239cc6fe1d18ce4365c56346a09c7963dfa8f10Ashutosh Joshi pw.println("=================== CONTEXT HUBS ===================="); 2546239cc6fe1d18ce4365c56346a09c7963dfa8f10Ashutosh Joshi for (int i = 0; i < mContextHubInfo.length; i++) { 2556239cc6fe1d18ce4365c56346a09c7963dfa8f10Ashutosh Joshi pw.println("Handle " + i + " : " + mContextHubInfo[i].toString()); 2566239cc6fe1d18ce4365c56346a09c7963dfa8f10Ashutosh Joshi } 2576239cc6fe1d18ce4365c56346a09c7963dfa8f10Ashutosh Joshi pw.println(""); 2586239cc6fe1d18ce4365c56346a09c7963dfa8f10Ashutosh Joshi pw.println("=================== NANOAPPS ===================="); 2596239cc6fe1d18ce4365c56346a09c7963dfa8f10Ashutosh Joshi // Dump nanoAppHash 2606239cc6fe1d18ce4365c56346a09c7963dfa8f10Ashutosh Joshi for (Integer nanoAppInstance: mNanoAppHash.keySet()) { 2616239cc6fe1d18ce4365c56346a09c7963dfa8f10Ashutosh Joshi pw.println(nanoAppInstance + " : " + mNanoAppHash.get(nanoAppInstance).toString()); 2626239cc6fe1d18ce4365c56346a09c7963dfa8f10Ashutosh Joshi } 2636239cc6fe1d18ce4365c56346a09c7963dfa8f10Ashutosh Joshi 2646239cc6fe1d18ce4365c56346a09c7963dfa8f10Ashutosh Joshi // dump eventLog 2656239cc6fe1d18ce4365c56346a09c7963dfa8f10Ashutosh Joshi } 2666239cc6fe1d18ce4365c56346a09c7963dfa8f10Ashutosh Joshi 2678bad3fec0f54959958352c0bef90b813cd0d823adestradaa private void checkPermissions() { 2688bad3fec0f54959958352c0bef90b813cd0d823adestradaa mContext.enforceCallingPermission(HARDWARE_PERMISSION, ENFORCE_HW_PERMISSION_MESSAGE); 2698bad3fec0f54959958352c0bef90b813cd0d823adestradaa } 2702c697fb4a8b8f8c0a2acf1fb15027f363f74c2dcAshutosh Joshi 271b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi private int onMessageReceipt(int[] header, byte[] data) { 272b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi if (header == null || data == null || header.length < MSG_HEADER_SIZE) { 273b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi return -1; 274b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi } 2751d94181f44217979f2242281ebb9da50592e770eAshutosh Joshi 27678cebca7204f85ebb7c583bab2fc9891367cd403destradaa int callbacksCount = mCallbacksList.beginBroadcast(); 2771d94181f44217979f2242281ebb9da50592e770eAshutosh Joshi int msgType = header[HEADER_FIELD_MSG_TYPE]; 2781d94181f44217979f2242281ebb9da50592e770eAshutosh Joshi int msgVersion = header[HEADER_FIELD_MSG_VERSION]; 2791d94181f44217979f2242281ebb9da50592e770eAshutosh Joshi int hubHandle = header[HEADER_FIELD_HUB_HANDLE]; 2801d94181f44217979f2242281ebb9da50592e770eAshutosh Joshi int appInstance = header[HEADER_FIELD_APP_INSTANCE]; 2811d94181f44217979f2242281ebb9da50592e770eAshutosh Joshi 2821d94181f44217979f2242281ebb9da50592e770eAshutosh Joshi Log.d(TAG, "Sending message " + msgType + " version " + msgVersion + " from hubHandle " + 2831d94181f44217979f2242281ebb9da50592e770eAshutosh Joshi hubHandle + ", appInstance " + appInstance + ", callBackCount " + callbacksCount); 2841d94181f44217979f2242281ebb9da50592e770eAshutosh Joshi 28578cebca7204f85ebb7c583bab2fc9891367cd403destradaa if (callbacksCount < 1) { 28678cebca7204f85ebb7c583bab2fc9891367cd403destradaa Log.v(TAG, "No message callbacks registered."); 28778cebca7204f85ebb7c583bab2fc9891367cd403destradaa return 0; 28878cebca7204f85ebb7c583bab2fc9891367cd403destradaa } 28954787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi 2901d94181f44217979f2242281ebb9da50592e770eAshutosh Joshi ContextHubMessage msg = new ContextHubMessage(msgType, msgVersion, data); 29178cebca7204f85ebb7c583bab2fc9891367cd403destradaa for (int i = 0; i < callbacksCount; ++i) { 29278cebca7204f85ebb7c583bab2fc9891367cd403destradaa IContextHubCallback callback = mCallbacksList.getBroadcastItem(i); 29378cebca7204f85ebb7c583bab2fc9891367cd403destradaa try { 2941d94181f44217979f2242281ebb9da50592e770eAshutosh Joshi callback.onMessageReceipt(hubHandle, appInstance, msg); 29578cebca7204f85ebb7c583bab2fc9891367cd403destradaa } catch (RemoteException e) { 29678cebca7204f85ebb7c583bab2fc9891367cd403destradaa Log.i(TAG, "Exception (" + e + ") calling remote callback (" + callback + ")."); 29778cebca7204f85ebb7c583bab2fc9891367cd403destradaa continue; 298b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi } 299b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi } 30078cebca7204f85ebb7c583bab2fc9891367cd403destradaa mCallbacksList.finishBroadcast(); 301b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi return 0; 302b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi } 303b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi 304b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi private int addAppInstance(int hubHandle, int appInstanceHandle, long appId, int appVersion) { 305b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi // App Id encodes vendor & version 306b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi NanoAppInstanceInfo appInfo = new NanoAppInstanceInfo(); 307b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi 308b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi appInfo.setAppId(appId); 309b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi appInfo.setAppVersion(appVersion); 310b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi appInfo.setName(PRE_LOADED_APP_NAME); 311b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi appInfo.setContexthubId(hubHandle); 312b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi appInfo.setHandle(appInstanceHandle); 313b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi appInfo.setPublisher(PRE_LOADED_APP_PUBLISHER); 314b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi appInfo.setNeededExecMemBytes(PRE_LOADED_APP_MEM_REQ); 315b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi appInfo.setNeededReadMemBytes(PRE_LOADED_APP_MEM_REQ); 316b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi appInfo.setNeededWriteMemBytes(PRE_LOADED_APP_MEM_REQ); 317b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi 318fe6d4f518a34aa620eda9fe36365c2f750e6c67fGreg Kaiser String action; 319fe6d4f518a34aa620eda9fe36365c2f750e6c67fGreg Kaiser if (mNanoAppHash.containsKey(appInstanceHandle)) { 320fe6d4f518a34aa620eda9fe36365c2f750e6c67fGreg Kaiser action = "Updated"; 321fe6d4f518a34aa620eda9fe36365c2f750e6c67fGreg Kaiser } else { 322fe6d4f518a34aa620eda9fe36365c2f750e6c67fGreg Kaiser action = "Added"; 323fe6d4f518a34aa620eda9fe36365c2f750e6c67fGreg Kaiser } 324fe6d4f518a34aa620eda9fe36365c2f750e6c67fGreg Kaiser 325b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi mNanoAppHash.put(appInstanceHandle, appInfo); 326fe6d4f518a34aa620eda9fe36365c2f750e6c67fGreg Kaiser Log.d(TAG, action + " app instance " + appInstanceHandle + " with id " 327fe6d4f518a34aa620eda9fe36365c2f750e6c67fGreg Kaiser + appId + " version " + appVersion); 328b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi 329b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi return 0; 330b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi } 331c3d8a529c69b754fbd77231d8fd480db94763143Brian Duddie 33254787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi private int deleteAppInstance(int appInstanceHandle) { 33354787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi if (mNanoAppHash.remove(appInstanceHandle) == null) { 33454787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi return -1; 33554787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi } 33654787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi 33754787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi return 0; 33854787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi } 339b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi} 340