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