Home | History | Annotate | Download | only in hardware
      1 /*
      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 
     17 package android.support.car.hardware;
     18 
     19 import android.content.Context;
     20 import android.support.annotation.RestrictTo;
     21 import android.support.car.CarNotConnectedException;
     22 import java.util.Collection;
     23 import java.util.HashSet;
     24 import java.util.LinkedList;
     25 import java.util.Set;
     26 
     27 import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
     28 
     29 /**
     30  *  @hide
     31  */
     32 @RestrictTo(GROUP_ID)
     33 public class CarSensorManagerEmbedded extends CarSensorManager {
     34     private static final String TAG = "CarSensorsProxy";
     35 
     36     private final android.car.hardware.CarSensorManager mManager;
     37     private final CarSensorsProxy mCarSensorsProxy;
     38     private final LinkedList<OnSensorChangedListenerProxy> mListeners = new LinkedList<>();
     39 
     40     public CarSensorManagerEmbedded(Object manager, Context context) {
     41         mManager = (android.car.hardware.CarSensorManager) manager;
     42         mCarSensorsProxy = new CarSensorsProxy(this, context);
     43     }
     44 
     45     @Override
     46     public int[] getSupportedSensors() throws CarNotConnectedException {
     47         try {
     48             Set<Integer> sensorsSet = new HashSet<Integer>();
     49             for (Integer sensor : mManager.getSupportedSensors()) {
     50                 sensorsSet.add(sensor);
     51             }
     52             for (Integer proxySensor : mCarSensorsProxy.getSupportedSensors()) {
     53                 sensorsSet.add(proxySensor);
     54             }
     55             return toIntArray(sensorsSet);
     56         } catch (android.car.CarNotConnectedException e) {
     57             throw new CarNotConnectedException(e);
     58         }
     59     }
     60 
     61     private static int[] toIntArray(Collection<Integer> collection) {
     62         int len = collection.size();
     63         int[] arr = new int[len];
     64         int arrIndex = 0;
     65         for (Integer item : collection) {
     66             arr[arrIndex] = item;
     67             arrIndex++;
     68         }
     69         return arr;
     70     }
     71 
     72     @Override
     73     public boolean isSensorSupported(int sensorType) throws CarNotConnectedException {
     74         try {
     75             return mManager.isSensorSupported(sensorType)
     76                     || mCarSensorsProxy.isSensorSupported(sensorType);
     77         } catch (android.car.CarNotConnectedException e) {
     78             throw new CarNotConnectedException(e);
     79         }
     80     }
     81 
     82     private boolean isSensorProxied(int sensorType) throws CarNotConnectedException {
     83         try {
     84             return !mManager.isSensorSupported(sensorType)
     85                     && mCarSensorsProxy.isSensorSupported(sensorType);
     86         } catch (android.car.CarNotConnectedException e) {
     87             throw new CarNotConnectedException(e);
     88         }
     89     }
     90 
     91     @Override
     92     public boolean addListener(OnSensorChangedListener listener, int sensorType,
     93             int rate) throws CarNotConnectedException, IllegalArgumentException {
     94         if (isSensorProxied(sensorType)) {
     95             return mCarSensorsProxy.registerSensorListener(listener, sensorType, rate);
     96         }
     97         OnSensorChangedListenerProxy proxy = null;
     98         synchronized (this) {
     99             proxy = findListenerLocked(listener);
    100             if (proxy == null) {
    101                 proxy = new OnSensorChangedListenerProxy(listener, sensorType, this);
    102                 mListeners.add(proxy);
    103             } else {
    104                 proxy.sensors.add(sensorType);
    105             }
    106         }
    107         try {
    108             return mManager.registerListener(proxy, sensorType, rate);
    109         } catch (android.car.CarNotConnectedException e) {
    110             throw new CarNotConnectedException(e);
    111         }
    112     }
    113 
    114     @Override
    115     public void removeListener(OnSensorChangedListener listener) {
    116         mCarSensorsProxy.unregisterSensorListener(listener);
    117         OnSensorChangedListenerProxy proxy = null;
    118         synchronized (this) {
    119             proxy = findListenerLocked(listener);
    120             if (proxy == null) {
    121                 return;
    122             }
    123             mListeners.remove(proxy);
    124         }
    125         mManager.unregisterListener(proxy);
    126     }
    127 
    128     @Override
    129     public void removeListener(OnSensorChangedListener listener, int sensorType) {
    130         mCarSensorsProxy.unregisterSensorListener(listener, sensorType);
    131         OnSensorChangedListenerProxy proxy = null;
    132         synchronized (this) {
    133             proxy = findListenerLocked(listener);
    134             if (proxy == null) {
    135                 return;
    136             }
    137             proxy.sensors.remove(sensorType);
    138             if (proxy.sensors.isEmpty()) {
    139                 mListeners.remove(proxy);
    140             }
    141         }
    142         mManager.unregisterListener(proxy, sensorType);
    143     }
    144 
    145     @Override
    146     public CarSensorEvent getLatestSensorEvent(int type) throws CarNotConnectedException {
    147         if (isSensorProxied(type)) {
    148             return mCarSensorsProxy.getLatestSensorEvent(type);
    149         }
    150         try {
    151             return convert(mManager.getLatestSensorEvent(type));
    152         } catch (android.car.CarNotConnectedException e) {
    153             throw new CarNotConnectedException(e);
    154         }
    155     }
    156 
    157     @Override
    158     public CarSensorConfig getSensorConfig(@SensorType int type)
    159         throws CarNotConnectedException {
    160         try {
    161             return convert(mManager.getSensorConfig(type));
    162         } catch (android.car.CarNotConnectedException e) {
    163             throw new CarNotConnectedException(e);
    164         }
    165     }
    166 
    167     @Override
    168     public void onCarDisconnected() {
    169         //nothing to do
    170     }
    171 
    172     private OnSensorChangedListenerProxy findListenerLocked(OnSensorChangedListener listener) {
    173         for (OnSensorChangedListenerProxy proxy : mListeners) {
    174             if (proxy.listener == listener) {
    175                 return proxy;
    176             }
    177         }
    178         return null;
    179     }
    180 
    181     private static CarSensorEvent convert(android.car.hardware.CarSensorEvent event) {
    182         if (event == null) {
    183             return null;
    184         }
    185         return new CarSensorEvent(event.sensorType, event.timestamp, event.floatValues,
    186                 event.intValues, event.longValues);
    187     }
    188 
    189     private static CarSensorConfig convert(android.car.hardware.CarSensorConfig cfg) {
    190         if (cfg == null) {
    191             return null;
    192         }
    193         return new CarSensorConfig(cfg.getType(), cfg.getBundle());
    194     }
    195 
    196     private static class OnSensorChangedListenerProxy
    197             implements android.car.hardware.CarSensorManager.OnSensorChangedListener {
    198 
    199         public final OnSensorChangedListener listener;
    200         public final Set<Integer> sensors = new HashSet<>();
    201         public final CarSensorManager manager;
    202 
    203         OnSensorChangedListenerProxy(OnSensorChangedListener listener, int sensor,
    204                 CarSensorManager manager) {
    205             this.listener = listener;
    206             this.sensors.add(sensor);
    207             this.manager = manager;
    208         }
    209 
    210         @Override
    211         public void onSensorChanged(android.car.hardware.CarSensorEvent event) {
    212             CarSensorEvent newEvent = convert(event);
    213             listener.onSensorChanged(manager, newEvent);
    214         }
    215     }
    216 }
    217