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.car.hardware; 18 19 import android.annotation.SystemApi; 20 import android.car.Car; 21 import android.car.CarManagerBase; 22 import android.car.hardware.property.CarPropertyManager; 23 import android.car.hardware.property.CarPropertyManager.CarPropertyEventCallback; 24 import android.car.hardware.property.ICarProperty; 25 import android.os.IBinder; 26 import android.util.ArraySet; 27 28 import com.android.internal.annotations.GuardedBy; 29 30 import java.lang.ref.WeakReference; 31 import java.util.ArrayList; 32 import java.util.Collection; 33 import java.util.List; 34 35 /** 36 * API to access custom vehicle properties defined by OEMs. 37 * <p> 38 * System permission {@link Car#PERMISSION_VENDOR_EXTENSION} is required to get this manager. 39 * </p> 40 * @hide 41 * @deprecated consider using {@link CarPropertyManager} instead. 42 */ 43 @Deprecated 44 @SystemApi 45 public final class CarVendorExtensionManager extends CarManagerBase { 46 47 private static final boolean DBG = false; 48 private static final String TAG = CarVendorExtensionManager.class.getSimpleName(); 49 private final CarPropertyManager mPropertyManager; 50 51 @GuardedBy("mLock") 52 private final ArraySet<CarVendorExtensionCallback> mCallbacks = new ArraySet<>(); 53 private final Object mLock = new Object(); 54 55 @GuardedBy("mLock") 56 private CarPropertyEventListenerToBase mListenerToBase = null; 57 handleOnChangeEvent(CarPropertyValue value)58 private void handleOnChangeEvent(CarPropertyValue value) { 59 Collection<CarVendorExtensionCallback> callbacks; 60 synchronized (mLock) { 61 callbacks = new ArrayList<>(mCallbacks); 62 } 63 for (CarVendorExtensionCallback l: callbacks) { 64 l.onChangeEvent(value); 65 } 66 } 67 handleOnErrorEvent(int propertyId, int zone)68 private void handleOnErrorEvent(int propertyId, int zone) { 69 Collection<CarVendorExtensionCallback> listeners; 70 synchronized (mLock) { 71 listeners = new ArrayList<>(mCallbacks); 72 } 73 for (CarVendorExtensionCallback l: listeners) { 74 l.onErrorEvent(propertyId, zone); 75 } 76 77 } 78 79 /** 80 * Creates an instance of the {@link CarVendorExtensionManager}. 81 * 82 * <p>Should not be obtained directly by clients, use {@link Car#getCarManager(String)} instead. 83 * @hide 84 */ CarVendorExtensionManager(Car car, IBinder service)85 public CarVendorExtensionManager(Car car, IBinder service) { 86 super(car); 87 ICarProperty mCarPropertyService = ICarProperty.Stub.asInterface(service); 88 mPropertyManager = new CarPropertyManager(car, mCarPropertyService); 89 } 90 91 /** 92 * Contains callback functions that will be called when some event happens with vehicle 93 * property. 94 */ 95 public interface CarVendorExtensionCallback { 96 /** Called when a property is updated */ onChangeEvent(CarPropertyValue value)97 void onChangeEvent(CarPropertyValue value); 98 99 /** Called when an error is detected with a property */ onErrorEvent(int propertyId, int zone)100 void onErrorEvent(int propertyId, int zone); 101 } 102 103 /** 104 * Registers listener. The methods of the listener will be called when new events arrived in 105 * the main thread. 106 */ registerCallback(CarVendorExtensionCallback callback)107 public void registerCallback(CarVendorExtensionCallback callback) { 108 synchronized (mLock) { 109 if (mCallbacks.isEmpty()) { 110 mListenerToBase = new CarPropertyEventListenerToBase(this); 111 } 112 List<CarPropertyConfig> configs = mPropertyManager.getPropertyList(); 113 for (CarPropertyConfig c : configs) { 114 // Register each individual propertyId 115 mPropertyManager.registerCallback(mListenerToBase, c.getPropertyId(), 0); 116 } 117 mCallbacks.add(callback); 118 } 119 } 120 121 /** Unregisters listener that was previously registered. */ unregisterCallback(CarVendorExtensionCallback callback)122 public void unregisterCallback(CarVendorExtensionCallback callback) { 123 synchronized (mLock) { 124 mCallbacks.remove(callback); 125 List<CarPropertyConfig> configs = mPropertyManager.getPropertyList(); 126 for (CarPropertyConfig c : configs) { 127 // Register each individual propertyId 128 mPropertyManager.unregisterCallback(mListenerToBase, c.getPropertyId()); 129 } 130 if (mCallbacks.isEmpty()) { 131 mListenerToBase = null; 132 } 133 } 134 } 135 136 /** Get list of properties represented by CarVendorExtensionManager for this car. */ getProperties()137 public List<CarPropertyConfig> getProperties() { 138 return mPropertyManager.getPropertyList(); 139 } 140 141 /** 142 * Check whether a given property is available or disabled based on the cars current state. 143 * @return true if the property is AVAILABLE, false otherwise 144 */ isPropertyAvailable(int propertyId, int area)145 public boolean isPropertyAvailable(int propertyId, int area) { 146 return mPropertyManager.isPropertyAvailable(propertyId, area); 147 } 148 149 /** 150 * Returns property value. Use this function for global vehicle properties. 151 * 152 * @param propertyClass - data type of the given property, for example property that was 153 * defined as {@code VEHICLE_VALUE_TYPE_INT32} in vehicle HAL could be accessed using 154 * {@code Integer.class}. 155 * @param propId - property id which is matched with the one defined in vehicle HAL 156 */ getGlobalProperty(Class<E> propertyClass, int propId)157 public <E> E getGlobalProperty(Class<E> propertyClass, int propId) { 158 return getProperty(propertyClass, propId, 0 /* area */); 159 } 160 161 /** 162 * Returns property value. Use this function for "zoned" vehicle properties. 163 * 164 * @param propertyClass - data type of the given property, for example property that was 165 * defined as {@code VEHICLE_VALUE_TYPE_INT32} in vehicle HAL could be accessed using 166 * {@code Integer.class}. 167 * @param propId - property id which is matched with the one defined in vehicle HAL 168 * @param area - vehicle area (e.g. {@code VehicleAreaSeat.ROW_1_LEFT} 169 * or {@code VEHICLE_MIRROR_DRIVER_LEFT} 170 */ getProperty(Class<E> propertyClass, int propId, int area)171 public <E> E getProperty(Class<E> propertyClass, int propId, int area) { 172 return mPropertyManager.getProperty(propertyClass, propId, area).getValue(); 173 } 174 175 /** 176 * Call this function to set a value to global vehicle property. 177 * 178 * @param propertyClass - data type of the given property, for example property that was 179 * defined as {@code VEHICLE_VALUE_TYPE_INT32} in vehicle HAL could be accessed using 180 * {@code Integer.class}. 181 * @param propId - property id which is matched with the one defined in vehicle HAL 182 * @param value - new value, this object should match a class provided in {@code propertyClass} 183 * argument. 184 */ setGlobalProperty(Class<E> propertyClass, int propId, E value)185 public <E> void setGlobalProperty(Class<E> propertyClass, int propId, E value) { 186 mPropertyManager.setProperty(propertyClass, propId, 0 /* area */, value); 187 } 188 189 /** 190 * Call this function to set a value to "zoned" vehicle property. 191 * 192 * @param propertyClass - data type of the given property, for example property that was 193 * defined as {@code VEHICLE_VALUE_TYPE_INT32} in vehicle HAL could be accessed using 194 * {@code Integer.class}. 195 * @param propId - property id which is matched with the one defined in vehicle HAL 196 * @param area - vehicle area (e.g. {@code VehicleAreaSeat.ROW_1_LEFT} 197 * or {@code VEHICLE_MIRROR_DRIVER_LEFT} 198 * @param value - new value, this object should match a class provided in {@code propertyClass} 199 * argument. 200 */ setProperty(Class<E> propertyClass, int propId, int area, E value)201 public <E> void setProperty(Class<E> propertyClass, int propId, int area, E value) { 202 mPropertyManager.setProperty(propertyClass, propId, area, value); 203 } 204 205 /** @hide */ 206 @Override onCarDisconnected()207 public void onCarDisconnected() { 208 synchronized (mLock) { 209 mCallbacks.clear(); 210 } 211 mPropertyManager.onCarDisconnected(); 212 } 213 private static class CarPropertyEventListenerToBase implements CarPropertyEventCallback { 214 private final WeakReference<CarVendorExtensionManager> mManager; 215 CarPropertyEventListenerToBase(CarVendorExtensionManager manager)216 CarPropertyEventListenerToBase(CarVendorExtensionManager manager) { 217 mManager = new WeakReference<>(manager); 218 } 219 220 @Override onChangeEvent(CarPropertyValue value)221 public void onChangeEvent(CarPropertyValue value) { 222 CarVendorExtensionManager manager = mManager.get(); 223 if (manager != null) { 224 manager.handleOnChangeEvent(value); 225 } 226 } 227 228 @Override onErrorEvent(int propertyId, int zone)229 public void onErrorEvent(int propertyId, int zone) { 230 CarVendorExtensionManager manager = mManager.get(); 231 if (manager != null) { 232 manager.handleOnErrorEvent(propertyId, zone); 233 } 234 } 235 } 236 } 237