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