• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 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.hvac;
18 
19 import android.annotation.IntDef;
20 import android.annotation.SystemApi;
21 import android.car.Car;
22 import android.car.CarManagerBase;
23 import android.car.annotation.AddedInOrBefore;
24 import android.car.hardware.CarPropertyConfig;
25 import android.car.hardware.CarPropertyValue;
26 import android.car.hardware.property.CarPropertyManager;
27 import android.car.hardware.property.CarPropertyManager.CarPropertyEventCallback;
28 import android.car.hardware.property.ICarProperty;
29 import android.os.IBinder;
30 import android.util.ArraySet;
31 import android.util.Log;
32 
33 import com.android.internal.annotations.GuardedBy;
34 
35 import java.lang.annotation.Retention;
36 import java.lang.annotation.RetentionPolicy;
37 import java.lang.ref.WeakReference;
38 import java.util.Arrays;
39 import java.util.Collection;
40 import java.util.List;
41 
42 /**
43  * @deprecated Use {@link CarPropertyManager} instead.
44  *
45  * API for controlling HVAC system in cars
46  * @hide
47  */
48 @Deprecated
49 @SystemApi
50 public final class CarHvacManager extends CarManagerBase {
51     private static final String TAG = "CarHvacManager";
52     private final CarPropertyManager mCarPropertyMgr;
53     @GuardedBy("mLock")
54     private CarPropertyEventListenerToBase mListenerToBase = null;
55 
56     private final Object mLock = new Object();
57 
58     @GuardedBy("mLock")
59     private final ArraySet<CarHvacEventCallback> mCallbacks = new ArraySet<>();
60 
61     /**
62      * HVAC property IDs for get/set methods
63      */
64     /**
65      * Mirror defrosters state, int type
66      * Positive values indicate mirror defroster is on
67      */
68     @AddedInOrBefore(majorVersion = 33)
69     public static final int ID_MIRROR_DEFROSTER_ON = 0x1440050c;
70     /**
71      * Steering wheel temp, int type
72      * Positive values indicate heating.
73      * Negative values indicate cooling
74      */
75     @AddedInOrBefore(majorVersion = 33)
76     public static final int ID_STEERING_WHEEL_HEAT = 0x1140050d;
77     /**
78      * Outside air temperature, float type
79      * Value is in degrees Celsius
80      */
81     @AddedInOrBefore(majorVersion = 33)
82     public static final int ID_OUTSIDE_AIR_TEMP = 0x11600703;
83     /**
84      * Temperature units being used, int type
85      *  0x30 = Celsius
86      *  0x31 = Fahrenheit
87      */
88     @AddedInOrBefore(majorVersion = 33)
89     public static final int ID_TEMPERATURE_DISPLAY_UNITS = 0x1140050e;
90 
91     /**
92      * Temperature setpoint, float type
93      * Temperature set by the user, units are in degrees Celsius.
94      */
95     @AddedInOrBefore(majorVersion = 33)
96     public static final int ID_ZONED_TEMP_SETPOINT = 0x15600503;
97     /**
98      * Actual temperature, float type
99      * Actual zone temperature is read only value, in terms of F or C.
100      */
101     @AddedInOrBefore(majorVersion = 33)
102     public static final int ID_ZONED_TEMP_ACTUAL = 0x15600502;
103     /**
104      * HVAC system powered on / off, bool type
105      * In many vehicles, if the HVAC system is powered off, the SET and GET command will
106      * throw an IllegalStateException.  To correct this, need to turn on the HVAC module first
107      * before manipulating a parameter.
108      */
109     @AddedInOrBefore(majorVersion = 33)
110     public static final int ID_ZONED_HVAC_POWER_ON = 0x15200510;
111     /**
112      * Fan speed setpoint, int type
113      * Fan speed is an integer from 0-n, depending on number of fan speeds available.
114      */
115     @AddedInOrBefore(majorVersion = 33)
116     public static final int ID_ZONED_FAN_SPEED_SETPOINT = 0x15400500;
117     /**
118      * Actual fan speed, int type
119      * Actual fan speed is a read-only value, expressed in RPM.
120      */
121     @AddedInOrBefore(majorVersion = 33)
122     public static final int ID_ZONED_FAN_SPEED_RPM = 0x1540050f;
123     /**
124      *  Fan direction available, int vector type
125      *  Fan direction is a bitmask of directions available for each zone.
126      */
127     @AddedInOrBefore(majorVersion = 33)
128     public static final int ID_ZONED_FAN_DIRECTION_AVAILABLE = 0x15410511;
129     /**
130      * Current fan direction setting, int type. The value must be one of the FAN_DIRECTION_AVAILABLE
131      * values declared above.
132      */
133     @AddedInOrBefore(majorVersion = 33)
134     public static final int ID_ZONED_FAN_DIRECTION = 0x15400501;
135     /**
136      * Seat temperature, int type
137      * Seat temperature is negative for cooling, positive for heating.  Temperature is a
138      * setting, i.e. -3 to 3 for 3 levels of cooling and 3 levels of heating.
139      */
140     @AddedInOrBefore(majorVersion = 33)
141     public static final int ID_ZONED_SEAT_TEMP = 0x1540050b;
142     /**
143      * Air ON, bool type
144      * true indicates AC is ON.
145      */
146     @AddedInOrBefore(majorVersion = 33)
147     public static final int ID_ZONED_AC_ON = 0x15200505;
148     /**
149      * Automatic Mode ON, bool type
150      * true indicates HVAC is in automatic mode
151      */
152     @AddedInOrBefore(majorVersion = 33)
153     public static final int ID_ZONED_AUTOMATIC_MODE_ON = 0x1520050A;
154     /**
155      * Air recirculation ON, bool type
156      * true indicates recirculation is active.
157      */
158     @AddedInOrBefore(majorVersion = 33)
159     public static final int ID_ZONED_AIR_RECIRCULATION_ON = 0x15200508;
160     /**
161      * Max AC ON, bool type
162      * true indicates MAX AC is ON
163      */
164     @AddedInOrBefore(majorVersion = 33)
165     public static final int ID_ZONED_MAX_AC_ON = 0x15200506;
166     /** Dual zone ON, bool type
167      * true indicates dual zone mode is ON
168      */
169     @AddedInOrBefore(majorVersion = 33)
170     public static final int ID_ZONED_DUAL_ZONE_ON = 0x15200509;
171     /**
172      * Max Defrost ON, bool type
173      * true indicates max defrost is active.
174      */
175     @AddedInOrBefore(majorVersion = 33)
176     public static final int ID_ZONED_MAX_DEFROST_ON = 0x15200507;
177     /**
178      * Automatic recirculation mode ON
179      * true indicates recirculation is in automatic mode
180      */
181     @AddedInOrBefore(majorVersion = 33)
182     public static final int ID_ZONED_HVAC_AUTO_RECIRC_ON = 0x15200512;
183     /**
184      * Defroster ON, bool type
185      * Defroster controls are based on window position.
186      * True indicates the defroster is ON.
187      */
188     @AddedInOrBefore(majorVersion = 33)
189     public static final int ID_WINDOW_DEFROSTER_ON = 0x13200504;
190 
191     /** @hide */
192     @IntDef({
193             ID_MIRROR_DEFROSTER_ON,
194             ID_STEERING_WHEEL_HEAT,
195             ID_OUTSIDE_AIR_TEMP,
196             ID_TEMPERATURE_DISPLAY_UNITS,
197             ID_ZONED_TEMP_SETPOINT,
198             ID_ZONED_TEMP_ACTUAL,
199             ID_ZONED_FAN_SPEED_SETPOINT,
200             ID_ZONED_FAN_SPEED_RPM,
201             ID_ZONED_FAN_DIRECTION_AVAILABLE,
202             ID_ZONED_FAN_DIRECTION,
203             ID_ZONED_SEAT_TEMP,
204             ID_ZONED_AC_ON,
205             ID_ZONED_AUTOMATIC_MODE_ON,
206             ID_ZONED_AIR_RECIRCULATION_ON,
207             ID_ZONED_MAX_AC_ON,
208             ID_ZONED_DUAL_ZONE_ON,
209             ID_ZONED_MAX_DEFROST_ON,
210             ID_ZONED_HVAC_POWER_ON,
211             ID_ZONED_HVAC_AUTO_RECIRC_ON,
212             ID_WINDOW_DEFROSTER_ON
213     })
214     @Retention(RetentionPolicy.SOURCE)
215     public @interface PropertyId {}
216     private final ArraySet<Integer> mHvacPropertyIds = new ArraySet<>(Arrays.asList(new Integer [] {
217             ID_MIRROR_DEFROSTER_ON,
218             ID_STEERING_WHEEL_HEAT,
219             ID_OUTSIDE_AIR_TEMP,
220             ID_TEMPERATURE_DISPLAY_UNITS,
221             ID_ZONED_TEMP_SETPOINT,
222             ID_ZONED_TEMP_ACTUAL,
223             ID_ZONED_FAN_SPEED_SETPOINT,
224             ID_ZONED_FAN_SPEED_RPM,
225             ID_ZONED_FAN_DIRECTION_AVAILABLE,
226             ID_ZONED_FAN_DIRECTION,
227             ID_ZONED_SEAT_TEMP,
228             ID_ZONED_AC_ON,
229             ID_ZONED_AUTOMATIC_MODE_ON,
230             ID_ZONED_AIR_RECIRCULATION_ON,
231             ID_ZONED_MAX_AC_ON,
232             ID_ZONED_DUAL_ZONE_ON,
233             ID_ZONED_MAX_DEFROST_ON,
234             ID_ZONED_HVAC_POWER_ON,
235             ID_ZONED_HVAC_AUTO_RECIRC_ON,
236             ID_WINDOW_DEFROSTER_ON
237     }));
238 
239 
240     /**
241      * Use {@link android.car.hardware.CarHvacFanDirection#FACE} instead.
242      * Represents fan direction when air flows through face directed vents.
243      * This constant must be used with {@link #ID_ZONED_FAN_DIRECTION} property.
244      */
245     @AddedInOrBefore(majorVersion = 33)
246     public static final int FAN_DIRECTION_FACE = 0x1;
247     /**
248      * Use {@link android.car.hardware.CarHvacFanDirection#FLOOR} instead.
249      * Represents fan direction when air flows through floor directed vents.
250      * This constant must be used with {@link #ID_ZONED_FAN_DIRECTION} property.
251      */
252     @AddedInOrBefore(majorVersion = 33)
253     public static final int FAN_DIRECTION_FLOOR = 0x2;
254     /**
255      * Use {@link android.car.hardware.CarHvacFanDirection#DEFROST} instead.
256      * Represents fan direction when air flows through defrost vents.
257      * This constant must be used with {@link #ID_ZONED_FAN_DIRECTION} property.
258      */
259     @AddedInOrBefore(majorVersion = 33)
260     public static final int FAN_DIRECTION_DEFROST = 0x4;
261 
262     /**
263      * Application registers {@link CarHvacEventCallback} object to receive updates and changes to
264      * subscribed Car HVAC properties.
265      */
266     public interface CarHvacEventCallback {
267         /**
268          * Called when a property is updated
269          * @param value Property that has been updated.
270          */
271         @AddedInOrBefore(majorVersion = 33)
onChangeEvent(CarPropertyValue value)272         void onChangeEvent(CarPropertyValue value);
273 
274         /**
275          * Called when an error is detected with a property
276          * @param propertyId
277          * @param zone
278          */
279         @AddedInOrBefore(majorVersion = 33)
onErrorEvent(@ropertyId int propertyId, int zone)280         void onErrorEvent(@PropertyId int propertyId, int zone);
281     }
282 
283     private static class CarPropertyEventListenerToBase implements CarPropertyEventCallback {
284         private final WeakReference<CarHvacManager> mManager;
285 
CarPropertyEventListenerToBase(CarHvacManager manager)286         CarPropertyEventListenerToBase(CarHvacManager manager) {
287             mManager = new WeakReference<>(manager);
288         }
289 
290         @Override
onChangeEvent(CarPropertyValue value)291         public void onChangeEvent(CarPropertyValue value) {
292             CarHvacManager manager = mManager.get();
293             if (manager != null) {
294                 manager.handleOnChangeEvent(value);
295             }
296         }
297 
298         @Override
onErrorEvent(int propertyId, int zone)299         public void onErrorEvent(int propertyId, int zone) {
300             CarHvacManager manager = mManager.get();
301             if (manager != null) {
302                 manager.handleOnErrorEvent(propertyId, zone);
303             }
304         }
305     }
306 
handleOnChangeEvent(CarPropertyValue value)307     private void handleOnChangeEvent(CarPropertyValue value) {
308         Collection<CarHvacEventCallback> callbacks;
309         synchronized (mLock) {
310             callbacks = new ArraySet<>(mCallbacks);
311         }
312         if (!callbacks.isEmpty()) {
313             for (CarHvacEventCallback l: callbacks) {
314                 l.onChangeEvent(value);
315             }
316         }
317     }
318 
handleOnErrorEvent(int propertyId, int zone)319     private void handleOnErrorEvent(int propertyId, int zone) {
320         Collection<CarHvacEventCallback> callbacks;
321         synchronized (mLock) {
322             callbacks = new ArraySet<>(mCallbacks);
323         }
324         if (!callbacks.isEmpty()) {
325             for (CarHvacEventCallback l: callbacks) {
326                 l.onErrorEvent(propertyId, zone);
327             }
328         }
329     }
330 
331     /**
332      * Get an instance of the CarHvacManager.
333      *
334      * Should not be obtained directly by clients, use {@link Car#getCarManager(String)} instead.
335      * @param service
336      *
337      * @hide
338      */
CarHvacManager(Car car, IBinder service)339     public CarHvacManager(Car car, IBinder service) {
340         super(car);
341         ICarProperty mCarPropertyService = ICarProperty.Stub.asInterface(service);
342         mCarPropertyMgr = new CarPropertyManager(car, mCarPropertyService);
343     }
344 
345     /**
346      * Implement wrappers for contained CarPropertyManager object
347      * @param callback
348      */
349     @AddedInOrBefore(majorVersion = 33)
registerCallback(CarHvacEventCallback callback)350     public void registerCallback(CarHvacEventCallback callback) {
351         synchronized (mLock) {
352             if (mCallbacks.isEmpty()) {
353                 mListenerToBase = new CarPropertyEventListenerToBase(this);
354             }
355             List<CarPropertyConfig> configs = getPropertyList();
356             for (CarPropertyConfig c : configs) {
357                 // Register each individual propertyId
358                 mCarPropertyMgr.registerCallback(mListenerToBase, c.getPropertyId(), 0);
359             }
360             mCallbacks.add(callback);
361         }
362     }
363 
364     /**
365      * Stop getting property updates for the given callback. If there are multiple registrations for
366      * this listener, all listening will be stopped.
367      * @param callback
368      */
369     @AddedInOrBefore(majorVersion = 33)
unregisterCallback(CarHvacEventCallback callback)370     public void unregisterCallback(CarHvacEventCallback callback) {
371         synchronized (mLock) {
372             mCallbacks.remove(callback);
373             try {
374                 List<CarPropertyConfig> configs = getPropertyList();
375                 for (CarPropertyConfig c : configs) {
376                     // Register each individual propertyId
377                     mCarPropertyMgr.unregisterCallback(mListenerToBase, c.getPropertyId());
378 
379                 }
380             } catch (RuntimeException e) {
381                 Log.e(TAG, "getPropertyList exception ", e);
382             }
383             if (mCallbacks.isEmpty()) {
384                 mCarPropertyMgr.unregisterCallback(mListenerToBase);
385                 mListenerToBase = null;
386             }
387         }
388     }
389 
390     /**
391      * Get list of properties represented by Car Hvac Manager for this car.
392      * @return List of CarPropertyConfig objects available via Car Hvac Manager.
393      */
394     @AddedInOrBefore(majorVersion = 33)
getPropertyList()395     public List<CarPropertyConfig> getPropertyList() {
396         return mCarPropertyMgr.getPropertyList(mHvacPropertyIds);
397     }
398 
399     /**
400      * Check whether a given property is available or disabled based on the cars current state.
401      * @return true if the property is AVAILABLE, false otherwise
402      */
403     @AddedInOrBefore(majorVersion = 33)
isPropertyAvailable(@ropertyId int propertyId, int area)404     public boolean isPropertyAvailable(@PropertyId int propertyId, int area) {
405         return mCarPropertyMgr.isPropertyAvailable(propertyId, area);
406     }
407 
408     /**
409      * Get value of boolean property
410      * @param propertyId
411      * @param area
412      * @return value of requested boolean property
413      */
414     @AddedInOrBefore(majorVersion = 33)
getBooleanProperty(@ropertyId int propertyId, int area)415     public boolean getBooleanProperty(@PropertyId int propertyId, int area) {
416         return mCarPropertyMgr.getBooleanProperty(propertyId, area);
417     }
418 
419     /**
420      * Get value of float property
421      * @param propertyId
422      * @param area
423      * @return value of requested float property
424      */
425     @AddedInOrBefore(majorVersion = 33)
getFloatProperty(@ropertyId int propertyId, int area)426     public float getFloatProperty(@PropertyId int propertyId, int area) {
427         return mCarPropertyMgr.getFloatProperty(propertyId, area);
428     }
429 
430     /**
431      * Get value of integer property
432      * @param propertyId
433      * @param area
434      * @return value of requested integer property
435      */
436     @AddedInOrBefore(majorVersion = 33)
getIntProperty(@ropertyId int propertyId, int area)437     public int getIntProperty(@PropertyId int propertyId, int area) {
438         return mCarPropertyMgr.getIntProperty(propertyId, area);
439     }
440 
441     /**
442      * Set the value of a boolean property
443      * @param propertyId
444      * @param area
445      * @param val
446      */
447     @AddedInOrBefore(majorVersion = 33)
setBooleanProperty(@ropertyId int propertyId, int area, boolean val)448     public void setBooleanProperty(@PropertyId int propertyId, int area, boolean val) {
449         if (mHvacPropertyIds.contains(propertyId)) {
450             mCarPropertyMgr.setBooleanProperty(propertyId, area, val);
451         }
452     }
453 
454     /**
455      * Set the value of a float property
456      * @param propertyId
457      * @param area
458      * @param val
459      */
460     @AddedInOrBefore(majorVersion = 33)
setFloatProperty(@ropertyId int propertyId, int area, float val)461     public void setFloatProperty(@PropertyId int propertyId, int area, float val) {
462         if (mHvacPropertyIds.contains(propertyId)) {
463             mCarPropertyMgr.setFloatProperty(propertyId, area, val);
464         }
465     }
466 
467     /**
468      * Set the value of an integer property
469      * @param propertyId
470      * @param area
471      * @param val
472      */
473     @AddedInOrBefore(majorVersion = 33)
setIntProperty(@ropertyId int propertyId, int area, int val)474     public void setIntProperty(@PropertyId int propertyId, int area, int val) {
475         if (mHvacPropertyIds.contains(propertyId)) {
476             mCarPropertyMgr.setIntProperty(propertyId, area, val);
477         }
478     }
479 
480     /** @hide */
481     @AddedInOrBefore(majorVersion = 33)
onCarDisconnected()482     public void onCarDisconnected() {
483         synchronized (mLock) {
484             mCallbacks.clear();
485         }
486         mCarPropertyMgr.onCarDisconnected();
487     }
488 }
489