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