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