1 /* 2 * Copyright 2017 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 17 package com.android.server.location; 18 19 import android.Manifest; 20 import android.content.Context; 21 import android.hardware.contexthub.V1_0.ContextHub; 22 import android.hardware.contexthub.V1_0.ContextHubMsg; 23 import android.hardware.contexthub.V1_0.HostEndPoint; 24 import android.hardware.contexthub.V1_0.HubAppInfo; 25 import android.hardware.contexthub.V1_0.Result; 26 import android.hardware.location.ContextHubInfo; 27 import android.hardware.location.ContextHubTransaction; 28 import android.hardware.location.NanoAppBinary; 29 import android.hardware.location.NanoAppMessage; 30 import android.hardware.location.NanoAppState; 31 import android.util.Log; 32 33 import java.util.Collection; 34 import java.util.HashMap; 35 import java.util.Iterator; 36 import java.util.List; 37 import java.util.ArrayList; 38 39 /** 40 * A class encapsulating helper functions used by the ContextHubService class 41 */ 42 /* package */ class ContextHubServiceUtil { 43 private static final String TAG = "ContextHubServiceUtil"; 44 private static final String HARDWARE_PERMISSION = Manifest.permission.LOCATION_HARDWARE; 45 private static final String ENFORCE_HW_PERMISSION_MESSAGE = "Permission '" 46 + HARDWARE_PERMISSION + "' not granted to access ContextHub Hardware"; 47 48 /** 49 * Creates a ConcurrentHashMap of the Context Hub ID to the ContextHubInfo object given an 50 * ArrayList of HIDL ContextHub objects. 51 * 52 * @param hubList the ContextHub ArrayList 53 * @return the HashMap object 54 */ 55 /* package */ 56 static HashMap<Integer, ContextHubInfo> createContextHubInfoMap(List<ContextHub> hubList) { 57 HashMap<Integer, ContextHubInfo> contextHubIdToInfoMap = new HashMap<>(); 58 for (ContextHub contextHub : hubList) { 59 contextHubIdToInfoMap.put(contextHub.hubId, new ContextHubInfo(contextHub)); 60 } 61 62 return contextHubIdToInfoMap; 63 } 64 65 /** 66 * Copies a primitive byte array to a ArrayList<Byte>. 67 * 68 * @param inputArray the primitive byte array 69 * @param outputArray the ArrayList<Byte> array to append 70 */ 71 /* package */ 72 static void copyToByteArrayList(byte[] inputArray, ArrayList<Byte> outputArray) { 73 outputArray.clear(); 74 outputArray.ensureCapacity(inputArray.length); 75 for (byte element : inputArray) { 76 outputArray.add(element); 77 } 78 } 79 80 /** 81 * Creates a byte array given a ArrayList<Byte> and copies its contents. 82 * 83 * @param array the ArrayList<Byte> object 84 * @return the byte array 85 */ 86 /* package */ 87 static byte[] createPrimitiveByteArray(ArrayList<Byte> array) { 88 byte[] primitiveArray = new byte[array.size()]; 89 for (int i = 0; i < array.size(); i++) { 90 primitiveArray[i] = array.get(i); 91 } 92 93 return primitiveArray; 94 } 95 96 /** 97 * Creates a primitive integer array given a Collection<Integer>. 98 * @param collection the collection to iterate 99 * @return the primitive integer array 100 */ 101 static int[] createPrimitiveIntArray(Collection<Integer> collection) { 102 int[] primitiveArray = new int[collection.size()]; 103 104 int i = 0; 105 for (int contextHubId : collection) { 106 primitiveArray[i++] = contextHubId; 107 } 108 109 return primitiveArray; 110 } 111 112 /** 113 * Generates the Context Hub HAL's NanoAppBinary object from the client-facing 114 * android.hardware.location.NanoAppBinary object. 115 * 116 * @param nanoAppBinary the client-facing NanoAppBinary object 117 * @return the Context Hub HAL's NanoAppBinary object 118 */ 119 /* package */ 120 static android.hardware.contexthub.V1_0.NanoAppBinary createHidlNanoAppBinary( 121 NanoAppBinary nanoAppBinary) { 122 android.hardware.contexthub.V1_0.NanoAppBinary hidlNanoAppBinary = 123 new android.hardware.contexthub.V1_0.NanoAppBinary(); 124 125 hidlNanoAppBinary.appId = nanoAppBinary.getNanoAppId(); 126 hidlNanoAppBinary.appVersion = nanoAppBinary.getNanoAppVersion(); 127 hidlNanoAppBinary.flags = nanoAppBinary.getFlags(); 128 hidlNanoAppBinary.targetChreApiMajorVersion = nanoAppBinary.getTargetChreApiMajorVersion(); 129 hidlNanoAppBinary.targetChreApiMinorVersion = nanoAppBinary.getTargetChreApiMinorVersion(); 130 131 // Log exceptions while processing the binary, but continue to pass down the binary 132 // since the error checking is deferred to the Context Hub. 133 try { 134 copyToByteArrayList(nanoAppBinary.getBinaryNoHeader(), hidlNanoAppBinary.customBinary); 135 } catch (IndexOutOfBoundsException e) { 136 Log.w(TAG, e.getMessage()); 137 } catch (NullPointerException e) { 138 Log.w(TAG, "NanoApp binary was null"); 139 } 140 141 return hidlNanoAppBinary; 142 } 143 144 /** 145 * Generates a client-facing NanoAppState array from a HAL HubAppInfo array. 146 * 147 * @param nanoAppInfoList the array of HubAppInfo objects 148 * @return the corresponding array of NanoAppState objects 149 */ 150 /* package */ 151 static List<NanoAppState> createNanoAppStateList( 152 List<HubAppInfo> nanoAppInfoList) { 153 ArrayList<NanoAppState> nanoAppStateList = new ArrayList<>(); 154 for (HubAppInfo appInfo : nanoAppInfoList) { 155 nanoAppStateList.add( 156 new NanoAppState(appInfo.appId, appInfo.version, appInfo.enabled)); 157 } 158 159 return nanoAppStateList; 160 } 161 162 /** 163 * Creates a HIDL ContextHubMsg object to send to a nanoapp. 164 * 165 * @param hostEndPoint the ID of the client sending the message 166 * @param message the client-facing NanoAppMessage object describing the message 167 * @return the HIDL ContextHubMsg object 168 */ 169 /* package */ 170 static ContextHubMsg createHidlContextHubMessage(short hostEndPoint, NanoAppMessage message) { 171 ContextHubMsg hidlMessage = new ContextHubMsg(); 172 173 hidlMessage.appName = message.getNanoAppId(); 174 hidlMessage.hostEndPoint = hostEndPoint; 175 hidlMessage.msgType = message.getMessageType(); 176 copyToByteArrayList(message.getMessageBody(), hidlMessage.msg); 177 178 return hidlMessage; 179 } 180 181 /** 182 * Creates a client-facing NanoAppMessage object to send to a client. 183 * 184 * @param message the HIDL ContextHubMsg object from a nanoapp 185 * @return the NanoAppMessage object 186 */ 187 /* package */ 188 static NanoAppMessage createNanoAppMessage(ContextHubMsg message) { 189 byte[] messageArray = createPrimitiveByteArray(message.msg); 190 191 return NanoAppMessage.createMessageFromNanoApp( 192 message.appName, message.msgType, messageArray, 193 message.hostEndPoint == HostEndPoint.BROADCAST); 194 } 195 196 /** 197 * Checks for location hardware permissions. 198 * 199 * @param context the context of the service 200 */ 201 /* package */ 202 static void checkPermissions(Context context) { 203 context.enforceCallingPermission(HARDWARE_PERMISSION, ENFORCE_HW_PERMISSION_MESSAGE); 204 } 205 206 /** 207 * Helper function to convert from the HAL Result enum error code to the 208 * ContextHubTransaction.Result type. 209 * 210 * @param halResult the Result enum error code 211 * @return the ContextHubTransaction.Result equivalent 212 */ 213 @ContextHubTransaction.Result 214 /* package */ 215 static int toTransactionResult(int halResult) { 216 switch (halResult) { 217 case Result.OK: 218 return ContextHubTransaction.RESULT_SUCCESS; 219 case Result.BAD_PARAMS: 220 return ContextHubTransaction.RESULT_FAILED_BAD_PARAMS; 221 case Result.NOT_INIT: 222 return ContextHubTransaction.RESULT_FAILED_UNINITIALIZED; 223 case Result.TRANSACTION_PENDING: 224 return ContextHubTransaction.RESULT_FAILED_BUSY; 225 case Result.TRANSACTION_FAILED: 226 case Result.UNKNOWN_FAILURE: 227 default: /* fall through */ 228 return ContextHubTransaction.RESULT_FAILED_UNKNOWN; 229 } 230 } 231 } 232