Home | History | Annotate | Download | only in location
      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