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.CarNotConnectedException; 23 import android.car.hardware.property.CarPropertyManagerBase; 24 import android.car.hardware.property.CarPropertyManagerBase.CarPropertyEventCallback; 25 import android.os.Handler; 26 import android.os.IBinder; 27 import android.os.Looper; 28 import android.util.ArraySet; 29 30 import com.android.internal.annotations.GuardedBy; 31 32 import java.util.List; 33 34 /** 35 * API to access custom vehicle properties defined by OEMs. 36 * <p> 37 * System permission {@link Car#PERMISSION_VENDOR_EXTENSION} is required to get this manager. 38 * </p> 39 * @hide 40 */ 41 @SystemApi 42 public final class CarVendorExtensionManager implements CarManagerBase { 43 44 private final static boolean DBG = false; 45 private final static String TAG = CarVendorExtensionManager.class.getSimpleName(); 46 private final CarPropertyManagerBase mPropertyManager; 47 48 @GuardedBy("mLock") 49 private ArraySet<CarVendorExtensionCallback> mCallbacks; 50 private final Object mLock = new Object(); 51 52 /** 53 * Creates an instance of the {@link CarVendorExtensionManager}. 54 * 55 * <p>Should not be obtained directly by clients, use {@link Car#getCarManager(String)} instead. 56 * @hide 57 */ CarVendorExtensionManager(IBinder service, Handler handler)58 public CarVendorExtensionManager(IBinder service, Handler handler) { 59 mPropertyManager = new CarPropertyManagerBase(service, handler, DBG, TAG); 60 } 61 62 /** 63 * Contains callback functions that will be called when some event happens with vehicle 64 * property. 65 */ 66 public interface CarVendorExtensionCallback { 67 /** Called when a property is updated */ onChangeEvent(CarPropertyValue value)68 void onChangeEvent(CarPropertyValue value); 69 70 /** Called when an error is detected with a property */ onErrorEvent(int propertyId, int zone)71 void onErrorEvent(int propertyId, int zone); 72 } 73 74 /** 75 * Registers listener. The methods of the listener will be called when new events arrived in 76 * the main thread. 77 */ registerCallback(CarVendorExtensionCallback callback)78 public void registerCallback(CarVendorExtensionCallback callback) 79 throws CarNotConnectedException { 80 synchronized (mLock) { 81 if (mCallbacks == null) { 82 mPropertyManager.registerCallback(new CarPropertyEventCallback() { 83 @Override 84 public void onChangeEvent(CarPropertyValue value) { 85 for (CarVendorExtensionCallback listener: getCallbacks()) { 86 listener.onChangeEvent(value); 87 } 88 } 89 90 @Override 91 public void onErrorEvent(int propertyId, int zone) { 92 for (CarVendorExtensionCallback listener: getCallbacks()) { 93 listener.onErrorEvent(propertyId, zone); 94 } 95 } 96 }); 97 mCallbacks = new ArraySet<>(1 /* We expect at least one element */); 98 } 99 mCallbacks.add(callback); 100 } 101 } 102 103 /** Unregisters listener that was previously registered. */ unregisterCallback(CarVendorExtensionCallback callback)104 public void unregisterCallback(CarVendorExtensionCallback callback) { 105 synchronized (mLock) { 106 mCallbacks.remove(callback); 107 if (mCallbacks.isEmpty()) { 108 mPropertyManager.unregisterCallback(); 109 mCallbacks = null; 110 } 111 } 112 } 113 114 /** Returns copy of listeners. Thread safe. */ getCallbacks()115 private CarVendorExtensionCallback[] getCallbacks() { 116 synchronized (mLock) { 117 return mCallbacks.toArray(new CarVendorExtensionCallback[mCallbacks.size()]); 118 } 119 } 120 getProperties()121 public List<CarPropertyConfig> getProperties() throws CarNotConnectedException { 122 return mPropertyManager.getPropertyList(); 123 } 124 125 /** 126 * Returns property value. Use this function for global vehicle properties. 127 * 128 * @param propertyClass - data type of the given property, for example property that was 129 * defined as {@code VEHICLE_VALUE_TYPE_INT32} in vehicle HAL could be accessed using 130 * {@code Integer.class}. 131 * @param propId - property id which is matched with the one defined in vehicle HAL 132 * 133 * @throws CarNotConnectedException if the connection to the car service has been lost. 134 */ getGlobalProperty(Class<E> propertyClass, int propId)135 public <E> E getGlobalProperty(Class<E> propertyClass, int propId) 136 throws CarNotConnectedException { 137 return getProperty(propertyClass, propId, 0 /* area */); 138 } 139 140 /** 141 * Returns property value. Use this function for "zoned" vehicle properties. 142 * 143 * @param propertyClass - data type of the given property, for example property that was 144 * defined as {@code VEHICLE_VALUE_TYPE_INT32} in vehicle HAL could be accessed using 145 * {@code Integer.class}. 146 * @param propId - property id which is matched with the one defined in vehicle HAL 147 * @param area - vehicle area (e.g. {@code VehicleAreaZone.ROW_1_LEFT} 148 * or {@code VEHICLE_MIRROR_DRIVER_LEFT} 149 * 150 * @throws CarNotConnectedException if the connection to the car service has been lost. 151 */ getProperty(Class<E> propertyClass, int propId, int area)152 public <E> E getProperty(Class<E> propertyClass, int propId, int area) 153 throws CarNotConnectedException { 154 return mPropertyManager.getProperty(propertyClass, propId, area).getValue(); 155 } 156 157 /** 158 * Call this function to set a value to global vehicle property. 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 * @param value - new value, this object should match a class provided in {@code propertyClass} 165 * argument. 166 * 167 * @throws CarNotConnectedException if the connection to the car service has been lost. 168 */ setGlobalProperty(Class<E> propertyClass, int propId, E value)169 public <E> void setGlobalProperty(Class<E> propertyClass, int propId, E value) 170 throws CarNotConnectedException { 171 mPropertyManager.setProperty(propertyClass, propId, 0 /* area */, value); 172 } 173 174 /** 175 * Call this function to set a value to "zoned" vehicle property. 176 * 177 * @param propertyClass - data type of the given property, for example property that was 178 * defined as {@code VEHICLE_VALUE_TYPE_INT32} in vehicle HAL could be accessed using 179 * {@code Integer.class}. 180 * @param propId - property id which is matched with the one defined in vehicle HAL 181 * @param area - vehicle area (e.g. {@code VehicleAreaZone.ROW_1_LEFT} 182 * or {@code VEHICLE_MIRROR_DRIVER_LEFT} 183 * @param value - new value, this object should match a class provided in {@code propertyClass} 184 * argument. 185 * 186 * @throws CarNotConnectedException if the connection to the car service has been lost. 187 */ setProperty(Class<E> propertyClass, int propId, int area, E value)188 public <E> void setProperty(Class<E> propertyClass, int propId, int area, E value) 189 throws CarNotConnectedException { 190 mPropertyManager.setProperty(propertyClass, propId, area, value); 191 } 192 193 /** @hide */ 194 @Override onCarDisconnected()195 public void onCarDisconnected() { 196 mPropertyManager.onCarDisconnected(); 197 } 198 } 199