blob: 76cd9ceaf7c4254c476cf6bdf3ef91cafeaa73d5 [file] [log] [blame]
Arthur Ishiguro7a23a962017-11-01 10:52:28 -07001/*
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
17package com.android.server.location;
18
Arthur Ishiguro0cf065e2020-01-22 17:05:26 +000019import static android.content.pm.PackageManager.PERMISSION_GRANTED;
20
Arthur Ishiguro4e39aa12017-11-14 14:59:08 -080021import android.Manifest;
22import android.content.Context;
Arthur Ishiguro7a23a962017-11-01 10:52:28 -070023import android.hardware.contexthub.V1_0.ContextHub;
Arthur Ishiguro170611d2017-11-17 10:02:17 -080024import android.hardware.contexthub.V1_0.ContextHubMsg;
25import android.hardware.contexthub.V1_0.HostEndPoint;
Arthur Ishiguro7a23a962017-11-01 10:52:28 -070026import android.hardware.contexthub.V1_0.HubAppInfo;
Arthur Ishiguro4e39aa12017-11-14 14:59:08 -080027import android.hardware.contexthub.V1_0.Result;
Arthur Ishiguro7a23a962017-11-01 10:52:28 -070028import android.hardware.location.ContextHubInfo;
Arthur Ishiguro4e39aa12017-11-14 14:59:08 -080029import android.hardware.location.ContextHubTransaction;
Arthur Ishiguro7a23a962017-11-01 10:52:28 -070030import android.hardware.location.NanoAppBinary;
Arthur Ishiguro170611d2017-11-17 10:02:17 -080031import android.hardware.location.NanoAppMessage;
Arthur Ishiguro7a23a962017-11-01 10:52:28 -070032import android.hardware.location.NanoAppState;
33import android.util.Log;
34
Arthur Ishiguro0cf065e2020-01-22 17:05:26 +000035import java.util.ArrayList;
Arthur Ishiguroab7113d2017-12-15 14:32:51 -080036import java.util.Collection;
37import java.util.HashMap;
Arthur Ishiguro7a23a962017-11-01 10:52:28 -070038import java.util.List;
Arthur Ishiguro7a23a962017-11-01 10:52:28 -070039
40/**
41 * A class encapsulating helper functions used by the ContextHubService class
42 */
43/* package */ class ContextHubServiceUtil {
44 private static final String TAG = "ContextHubServiceUtil";
Arthur Ishiguro4e39aa12017-11-14 14:59:08 -080045 private static final String HARDWARE_PERMISSION = Manifest.permission.LOCATION_HARDWARE;
Arthur Ishiguro0cf065e2020-01-22 17:05:26 +000046 private static final String CONTEXT_HUB_PERMISSION = Manifest.permission.ACCESS_CONTEXT_HUB;
Arthur Ishiguro7a23a962017-11-01 10:52:28 -070047
48 /**
Arthur Ishiguroab7113d2017-12-15 14:32:51 -080049 * Creates a ConcurrentHashMap of the Context Hub ID to the ContextHubInfo object given an
50 * ArrayList of HIDL ContextHub objects.
Arthur Ishiguro7a23a962017-11-01 10:52:28 -070051 *
52 * @param hubList the ContextHub ArrayList
Arthur Ishiguroab7113d2017-12-15 14:32:51 -080053 * @return the HashMap object
Arthur Ishiguro7a23a962017-11-01 10:52:28 -070054 */
55 /* package */
Arthur Ishiguroab7113d2017-12-15 14:32:51 -080056 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));
Arthur Ishiguro7a23a962017-11-01 10:52:28 -070060 }
61
Arthur Ishiguroab7113d2017-12-15 14:32:51 -080062 return contextHubIdToInfoMap;
Arthur Ishiguro7a23a962017-11-01 10:52:28 -070063 }
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 /**
Arthur Ishiguroab7113d2017-12-15 14:32:51 -080097 * 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 /**
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700113 * 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 }
Arthur Ishiguro170611d2017-11-17 10:02:17 -0800161
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 }
Arthur Ishiguro4e39aa12017-11-14 14:59:08 -0800195
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) {
Arthur Ishiguro0cf065e2020-01-22 17:05:26 +0000203 if (context.checkCallingPermission(HARDWARE_PERMISSION) != PERMISSION_GRANTED
204 && context.checkCallingPermission(CONTEXT_HUB_PERMISSION) != PERMISSION_GRANTED) {
205 throw new SecurityException(
206 "LOCATION_HARDWARE or ACCESS_CONTEXT_HUB permission required to use Context Hub");
207 }
Arthur Ishiguro4e39aa12017-11-14 14:59:08 -0800208 }
209
210 /**
211 * Helper function to convert from the HAL Result enum error code to the
212 * ContextHubTransaction.Result type.
213 *
214 * @param halResult the Result enum error code
215 * @return the ContextHubTransaction.Result equivalent
216 */
217 @ContextHubTransaction.Result
218 /* package */
219 static int toTransactionResult(int halResult) {
220 switch (halResult) {
221 case Result.OK:
Arthur Ishiguro6100aa72017-12-20 09:35:00 -0800222 return ContextHubTransaction.RESULT_SUCCESS;
Arthur Ishiguro4e39aa12017-11-14 14:59:08 -0800223 case Result.BAD_PARAMS:
Arthur Ishiguro6100aa72017-12-20 09:35:00 -0800224 return ContextHubTransaction.RESULT_FAILED_BAD_PARAMS;
Arthur Ishiguro4e39aa12017-11-14 14:59:08 -0800225 case Result.NOT_INIT:
Arthur Ishiguro6100aa72017-12-20 09:35:00 -0800226 return ContextHubTransaction.RESULT_FAILED_UNINITIALIZED;
Arthur Ishiguro4e39aa12017-11-14 14:59:08 -0800227 case Result.TRANSACTION_PENDING:
Arthur Ishigurof3691da2018-01-02 09:52:21 -0800228 return ContextHubTransaction.RESULT_FAILED_BUSY;
Arthur Ishiguro4e39aa12017-11-14 14:59:08 -0800229 case Result.TRANSACTION_FAILED:
230 case Result.UNKNOWN_FAILURE:
231 default: /* fall through */
Arthur Ishiguro6100aa72017-12-20 09:35:00 -0800232 return ContextHubTransaction.RESULT_FAILED_UNKNOWN;
Arthur Ishiguro4e39aa12017-11-14 14:59:08 -0800233 }
234 }
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700235}