Home | History | Annotate | Download | only in hvac
      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.CarNotConnectedException;
     24 import android.car.hardware.CarPropertyConfig;
     25 import android.car.hardware.CarPropertyValue;
     26 import android.car.hardware.property.CarPropertyManagerBase;
     27 import android.car.hardware.property.CarPropertyManagerBase.CarPropertyEventCallback;
     28 import android.content.Context;
     29 import android.os.Handler;
     30 import android.os.IBinder;
     31 import android.util.ArraySet;
     32 
     33 import java.lang.annotation.Retention;
     34 import java.lang.annotation.RetentionPolicy;
     35 import java.lang.ref.WeakReference;
     36 import java.util.Collection;
     37 import java.util.List;
     38 
     39 /**
     40  * API for controlling HVAC system in cars
     41  * @hide
     42  */
     43 @SystemApi
     44 public final class CarHvacManager implements CarManagerBase {
     45     private final static boolean DBG = false;
     46     private final static String TAG = "CarHvacManager";
     47     private final CarPropertyManagerBase mMgr;
     48     private final ArraySet<CarHvacEventCallback> mCallbacks = new ArraySet<>();
     49     private CarPropertyEventListenerToBase mListenerToBase = null;
     50 
     51     /**
     52      * HVAC property IDs for get/set methods
     53      */
     54     /**
     55      * Global HVAC properties.  There is only a single instance in a car.
     56      * Global properties are in the range of 0-0x3FFF.
     57      */
     58     /**
     59      * Mirror defrosters state, bool type
     60      * true indicates mirror defroster is on
     61      */
     62     public static final int ID_MIRROR_DEFROSTER_ON = 0x0001;
     63     /**
     64      * Steering wheel temp, int type
     65      * Positive values indicate heating.
     66      * Negative values indicate cooling
     67      */
     68     public static final int ID_STEERING_WHEEL_TEMP = 0x0002;
     69     /**
     70      * Outside air temperature, float type
     71      * Value is in degrees of ID_TEMPERATURE_UNITS
     72      */
     73     public static final int ID_OUTSIDE_AIR_TEMP = 0x0003;
     74     /**
     75      * Temperature units being used, int type
     76      *  0x30 = Celsius
     77      *  0x31 = Fahrenheit
     78      */
     79     public static final int ID_TEMPERATURE_UNITS = 0x0004;
     80 
     81 
     82     /**
     83      * The maximum id that can be assigned to global (non-zoned) property.
     84      * @hide
     85      */
     86     public static final int ID_MAX_GLOBAL_PROPERTY_ID = 0x3fff;
     87 
     88     /**
     89      * ID_ZONED_* represents properties available on a per-zone basis.  All zones in a car are
     90      * not required to have the same properties.  Zone specific properties start at 0x4000.
     91      */
     92     /**
     93      * Temperature setpoint, float type
     94      * Temperature set by the user, units are determined by ID_TEMPERTURE_UNITS property.
     95      */
     96     public static final int ID_ZONED_TEMP_SETPOINT = 0x4001;
     97     /**
     98      * Actual temperature, float type
     99      * Actual zone temperature is read only value, in terms of F or C.
    100      */
    101     public static final int ID_ZONED_TEMP_ACTUAL = 0x4002;
    102     /**
    103      * HVAC system powered on / off, bool type
    104      * In many vehicles, if the HVAC system is powered off, the SET and GET command will
    105      * throw an IllegalStateException.  To correct this, need to turn on the HVAC module first
    106      * before manipulating a parameter.
    107      */
    108     public static final int ID_ZONED_HVAC_POWER_ON = 0x4003;
    109     /**
    110      * Fan speed setpoint, int type
    111      * Fan speed is an integer from 0-n, depending on number of fan speeds available.
    112      */
    113     public static final int ID_ZONED_FAN_SPEED_SETPOINT = 0x4004;
    114     /**
    115      * Actual fan speed, int type
    116      * Actual fan speed is a read-only value, expressed in RPM.
    117      */
    118     public static final int ID_ZONED_FAN_SPEED_RPM = 0x4005;
    119     /** Fan position available, int type
    120      *  Fan position is a bitmask of positions available for each zone.
    121      */
    122     public static final int ID_ZONED_FAN_POSITION_AVAILABLE = 0x4006;
    123     /**
    124      * Current fan position setting, int type. The value must be one of the FAN_POSITION_*
    125      * constants declared in {@link CarHvacManager}.
    126      */
    127     public static final int ID_ZONED_FAN_POSITION = 0x4007;
    128     /**
    129      * Seat temperature, int type
    130      * Seat temperature is negative for cooling, positive for heating.  Temperature is a
    131      * setting, i.e. -3 to 3 for 3 levels of cooling and 3 levels of heating.
    132      */
    133     public static final int ID_ZONED_SEAT_TEMP = 0x4008;
    134     /**
    135      * Air ON, bool type
    136      * true indicates AC is ON.
    137      */
    138     public static final int ID_ZONED_AC_ON = 0x4009;
    139     /**
    140      * Automatic Mode ON, bool type
    141      * true indicates HVAC is in automatic mode
    142      */
    143     public static final int ID_ZONED_AUTOMATIC_MODE_ON = 0x400A;
    144     /**
    145      * Air recirculation ON, bool type
    146      * true indicates recirculation is active.
    147      */
    148     public static final int ID_ZONED_AIR_RECIRCULATION_ON = 0x400B;
    149     /**
    150      * Max AC ON, bool type
    151      * true indicates MAX AC is ON
    152      */
    153     public static final int ID_ZONED_MAX_AC_ON = 0x400C;
    154     /** Dual zone ON, bool type
    155      * true indicates dual zone mode is ON
    156      */
    157     public static final int ID_ZONED_DUAL_ZONE_ON = 0x400D;
    158     /**
    159      * Max Defrost ON, bool type
    160      * true indicates max defrost is active.
    161      */
    162     public static final int ID_ZONED_MAX_DEFROST_ON = 0x400E;
    163     /**
    164      * Defroster ON, bool type
    165      * Defroster controls are based on window position.
    166      * True indicates the defroster is ON.
    167      */
    168     public static final int ID_WINDOW_DEFROSTER_ON = 0x5001;
    169 
    170     /** @hide */
    171     @IntDef({
    172             ID_MIRROR_DEFROSTER_ON,
    173             ID_STEERING_WHEEL_TEMP,
    174             ID_OUTSIDE_AIR_TEMP,
    175             ID_TEMPERATURE_UNITS,
    176             ID_ZONED_TEMP_SETPOINT,
    177             ID_ZONED_TEMP_ACTUAL,
    178             ID_ZONED_FAN_SPEED_SETPOINT,
    179             ID_ZONED_FAN_SPEED_RPM,
    180             ID_ZONED_FAN_POSITION_AVAILABLE,
    181             ID_ZONED_FAN_POSITION,
    182             ID_ZONED_SEAT_TEMP,
    183             ID_ZONED_AC_ON,
    184             ID_ZONED_AUTOMATIC_MODE_ON,
    185             ID_ZONED_AIR_RECIRCULATION_ON,
    186             ID_ZONED_MAX_AC_ON,
    187             ID_ZONED_DUAL_ZONE_ON,
    188             ID_ZONED_MAX_DEFROST_ON,
    189             ID_ZONED_HVAC_POWER_ON,
    190             ID_WINDOW_DEFROSTER_ON,
    191     })
    192     @Retention(RetentionPolicy.SOURCE)
    193     public @interface PropertyId {}
    194 
    195     /**
    196      * Represents fan position when air flows through face directed vents.
    197      * This constant must be used with {@link #ID_ZONED_FAN_POSITION} property.
    198      */
    199     public static final int FAN_POSITION_FACE = 1;
    200     /**
    201      * Represents fan position when air flows through floor directed vents.
    202      * This constant must be used with {@link #ID_ZONED_FAN_POSITION} property.
    203      */
    204     public static final int FAN_POSITION_FLOOR = 2;
    205     /**
    206      * Represents fan position when air flows through face and floor directed vents.
    207      * This constant must be used with {@link #ID_ZONED_FAN_POSITION} property.
    208      */
    209     public static final int FAN_POSITION_FACE_AND_FLOOR = 3;
    210     /**
    211      * Represents fan position when air flows through defrost vents.
    212      * This constant must be used with {@link #ID_ZONED_FAN_POSITION} property.
    213      */
    214     public static final int FAN_POSITION_DEFROST = 4;
    215     /**
    216      * Represents fan position when air flows through defrost and floor directed vents.
    217      * This constant must be used with {@link #ID_ZONED_FAN_POSITION} property.
    218      */
    219     public static final int FAN_POSITION_DEFROST_AND_FLOOR = 5;
    220 
    221     /**
    222      * Application registers {@link CarHvacEventCallback} object to receive updates and changes to
    223      * subscribed Car HVAC properties.
    224      */
    225     public interface CarHvacEventCallback {
    226         /**
    227          * Called when a property is updated
    228          * @param value Property that has been updated.
    229          */
    230         void onChangeEvent(CarPropertyValue value);
    231 
    232         /**
    233          * Called when an error is detected with a property
    234          * @param propertyId
    235          * @param zone
    236          */
    237         void onErrorEvent(@PropertyId int propertyId, int zone);
    238     }
    239 
    240     private static class CarPropertyEventListenerToBase implements CarPropertyEventCallback {
    241         private final WeakReference<CarHvacManager> mManager;
    242 
    243         public CarPropertyEventListenerToBase(CarHvacManager manager) {
    244             mManager = new WeakReference<>(manager);
    245         }
    246 
    247         @Override
    248         public void onChangeEvent(CarPropertyValue value) {
    249             CarHvacManager manager = mManager.get();
    250             if (manager != null) {
    251                 manager.handleOnChangeEvent(value);
    252             }
    253         }
    254 
    255         @Override
    256         public void onErrorEvent(int propertyId, int zone) {
    257             CarHvacManager manager = mManager.get();
    258             if (manager != null) {
    259                 manager.handleOnErrorEvent(propertyId, zone);
    260             }
    261         }
    262     }
    263 
    264     private void handleOnChangeEvent(CarPropertyValue value) {
    265         Collection<CarHvacEventCallback> callbacks;
    266         synchronized (this) {
    267             callbacks = new ArraySet<>(mCallbacks);
    268         }
    269         if (!callbacks.isEmpty()) {
    270             for (CarHvacEventCallback l: callbacks) {
    271                 l.onChangeEvent(value);
    272             }
    273         }
    274     }
    275 
    276     private void handleOnErrorEvent(int propertyId, int zone) {
    277         Collection<CarHvacEventCallback> callbacks;
    278         synchronized (this) {
    279             callbacks = new ArraySet<>(mCallbacks);
    280         }
    281         if (!callbacks.isEmpty()) {
    282             for (CarHvacEventCallback l: callbacks) {
    283                 l.onErrorEvent(propertyId, zone);
    284             }
    285         }
    286     }
    287 
    288     /**
    289      * Get an instance of the CarHvacManager.
    290      *
    291      * Should not be obtained directly by clients, use {@link Car#getCarManager(String)} instead.
    292      * @param service
    293      * @param context
    294      * @param handler
    295      * @hide
    296      */
    297     public CarHvacManager(IBinder service, Context context, Handler handler) {
    298         mMgr = new CarPropertyManagerBase(service, handler, DBG, TAG);
    299     }
    300 
    301     /**
    302      * Determine if a property is zoned or not.
    303      * @param propertyId
    304      * @return true if property is a zoned type.
    305      */
    306     public static boolean isZonedProperty(@PropertyId int propertyId) {
    307         return propertyId > ID_MAX_GLOBAL_PROPERTY_ID;
    308     }
    309 
    310     /**
    311      * Implement wrappers for contained CarPropertyManagerBase object
    312      * @param callback
    313      * @throws CarNotConnectedException
    314      */
    315     public synchronized void registerCallback(CarHvacEventCallback callback) throws
    316             CarNotConnectedException {
    317         if (mCallbacks.isEmpty()) {
    318             mListenerToBase = new CarPropertyEventListenerToBase(this);
    319             mMgr.registerCallback(mListenerToBase);
    320         }
    321         mCallbacks.add(callback);
    322     }
    323 
    324     /**
    325      * Stop getting property updates for the given callback. If there are multiple registrations for
    326      * this listener, all listening will be stopped.
    327      * @param callback
    328      */
    329     public synchronized void unregisterCallback(CarHvacEventCallback callback) {
    330         mCallbacks.remove(callback);
    331         if (mCallbacks.isEmpty()) {
    332             mMgr.unregisterCallback();
    333             mListenerToBase = null;
    334         }
    335     }
    336 
    337     /**
    338      * Get list of properties available to Car Hvac Manager
    339      * @return List of CarPropertyConfig objects available via Car Hvac Manager.
    340      * @throws CarNotConnectedException if the connection to the car service has been lost.
    341      */
    342     public List<CarPropertyConfig> getPropertyList() throws CarNotConnectedException {
    343         return mMgr.getPropertyList();
    344     }
    345 
    346     /**
    347      * Get value of boolean property
    348      * @param propertyId
    349      * @param area
    350      * @return value of requested boolean property
    351      * @throws CarNotConnectedException
    352      */
    353     public boolean getBooleanProperty(@PropertyId int propertyId, int area)
    354             throws CarNotConnectedException {
    355         return mMgr.getBooleanProperty(propertyId, area);
    356     }
    357 
    358     /**
    359      * Get value of float property
    360      * @param propertyId
    361      * @param area
    362      * @return value of requested float property
    363      * @throws CarNotConnectedException
    364      */
    365     public float getFloatProperty(@PropertyId int propertyId, int area)
    366             throws CarNotConnectedException {
    367         return mMgr.getFloatProperty(propertyId, area);
    368     }
    369 
    370     /**
    371      * Get value of integer property
    372      * @param propertyId
    373      * @param area
    374      * @return value of requested integer property
    375      * @throws CarNotConnectedException
    376      */
    377     public int getIntProperty(@PropertyId int propertyId, int area)
    378             throws CarNotConnectedException {
    379         return mMgr.getIntProperty(propertyId, area);
    380     }
    381 
    382     /**
    383      * Set the value of a boolean property
    384      * @param propertyId
    385      * @param area
    386      * @param val
    387      * @throws CarNotConnectedException
    388      */
    389     public void setBooleanProperty(@PropertyId int propertyId, int area, boolean val)
    390             throws CarNotConnectedException {
    391         mMgr.setBooleanProperty(propertyId, area, val);
    392     }
    393 
    394     /**
    395      * Set the value of a float property
    396      * @param propertyId
    397      * @param area
    398      * @param val
    399      * @throws CarNotConnectedException
    400      */
    401     public void setFloatProperty(@PropertyId int propertyId, int area, float val)
    402             throws CarNotConnectedException {
    403         mMgr.setFloatProperty(propertyId, area, val);
    404     }
    405 
    406     /**
    407      * Set the value of an integer property
    408      * @param propertyId
    409      * @param area
    410      * @param val
    411      * @throws CarNotConnectedException
    412      */
    413     public void setIntProperty(@PropertyId int propertyId, int area, int val)
    414             throws CarNotConnectedException {
    415         mMgr.setIntProperty(propertyId, area, val);
    416     }
    417 
    418     /** @hide */
    419     @Override
    420     public void onCarDisconnected() {
    421         mMgr.onCarDisconnected();
    422     }
    423 }
    424