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
17package android.support.car.hardware;
18
19import android.Manifest;
20import android.os.Looper;
21import android.support.annotation.RequiresPermission;
22import android.support.car.Car;
23import android.support.car.CarManagerBase;
24import android.support.car.CarNotConnectedException;
25
26/**
27 *  API for monitoring car sensor data.
28 */
29public abstract class CarSensorManager implements CarManagerBase {
30    /**
31     * SENSOR_TYPE_* represents type of sensor supported from the connected car. This sensor
32     * represents the direction of the car as an angle in degree measured clockwise with 0 degree
33     * pointing to north. Sensor data in {@link CarSensorEvent} is a float (floatValues[0]).
34     */
35    public static final int SENSOR_TYPE_COMPASS = 1;
36    /**
37     * This sensor represents vehicle speed in m/s. Sensor data in {@link CarSensorEvent} is a float
38     * which will be >= 0. This requires {@link Car#PERMISSION_SPEED} permission.
39     */
40    public static final int SENSOR_TYPE_CAR_SPEED = 2;
41    /**
42     * Represents engine RPM of the car. Sensor data in {@link CarSensorEvent} is a float.
43     */
44    public static final int SENSOR_TYPE_RPM = 3;
45    /**
46     * Total travel distance of the car in Kilometer. Sensor data is a float. This requires {@link
47     * Car#PERMISSION_MILEAGE} permission.
48     */
49    public static final int SENSOR_TYPE_ODOMETER = 4;
50    /**
51     * Indicates fuel level of the car. In {@link CarSensorEvent}, floatValues[{@link
52     * CarSensorEvent#INDEX_FUEL_LEVEL_IN_PERCENTILE}] represents fuel level in percentile (0 to
53     * 100) while floatValues[{@link CarSensorEvent#INDEX_FUEL_LEVEL_IN_DISTANCE}] represents
54     * estimated range in Kilometer with the remaining fuel. Note that the gas mileage used for the
55     * estimation may not represent the current driving condition. This requires {@link
56     * Car#PERMISSION_FUEL} permission.
57     */
58    public static final int SENSOR_TYPE_FUEL_LEVEL = 5;
59    /**
60     * Represents the current status of parking brake. Sensor data in {@link CarSensorEvent} is an
61     * intValues[0]. Value of 1 represents parking brake applied while 0 means the other way around.
62     * For this sensor, rate in {@link #registerListener(CarSensorEventListener, int, int)} will be
63     * ignored and all changes will be notified.
64     */
65    public static final int SENSOR_TYPE_PARKING_BRAKE = 6;
66    /**
67     * This represents the current position of transmission gear. Sensor data in {@link
68     * CarSensorEvent} is an intValues[0]. For the meaning of the value, check {@link
69     * CarSensorEvent#GEAR_NEUTRAL} and other GEAR_*.
70     */
71    public static final int SENSOR_TYPE_GEAR = 7;
72
73    /**@hide*/
74    public static final int SENSOR_TYPE_RESERVED8 = 8;
75
76    /**
77     * Day/night sensor. Sensor data is intValues[0].
78     */
79    public static final int SENSOR_TYPE_NIGHT = 9;
80    /**
81     * Sensor type for location. Sensor data passed in floatValues.
82     */
83    public static final int SENSOR_TYPE_LOCATION = 10;
84    /**
85     * Represents the current driving status of car. Different user interaction should be used
86     * depending on the current driving status. Driving status is intValues[0].
87     */
88    public static final int SENSOR_TYPE_DRIVING_STATUS = 11;
89    /**
90     * Environment like temperature and pressure.
91     */
92    public static final int SENSOR_TYPE_ENVIRONMENT = 12;
93    /** @hide */
94    public static final int SENSOR_TYPE_RESERVED13 = 13;
95    /** @hide */
96    public static final int SENSOR_TYPE_ACCELEROMETER = 14;
97    /** @hide */
98    public static final int SENSOR_TYPE_RESERVED15 = 15;
99    /** @hide */
100    public static final int SENSOR_TYPE_RESERVED16 = 16;
101    /** @hide */
102    public static final int SENSOR_TYPE_GPS_SATELLITE = 17;
103    /** @hide */
104    public static final int SENSOR_TYPE_GYROSCOPE = 18;
105    /** @hide */
106    public static final int SENSOR_TYPE_RESERVED19 = 19;
107    /** @hide */
108    public static final int SENSOR_TYPE_RESERVED20 = 20;
109    /** @hide */
110    public static final int SENSOR_TYPE_RESERVED21 = 21;
111
112    /**
113     * Sensor type bigger than this is invalid. Always update this after adding a new sensor.
114     */
115    private static final int SENSOR_TYPE_MAX = SENSOR_TYPE_RESERVED21;
116
117    /**
118     * Sensors defined in this range [{@link #SENSOR_TYPE_VENDOR_EXTENSION_START},
119     * {@link #SENSOR_TYPE_VENDOR_EXTENSION_END}] is for each car vendor's to use.
120     * This should be only used for system app to access sensors not defined as standard types.
121     * So the sensor supproted in this range can vary depending on car models / manufacturers.
122     * 3rd party apps should not use sensors in this range as they are not compatible across
123     * different cars. Additionally 3rd party apps trying to access sensor in this range will get
124     * security exception as their access is restricted to system apps.
125     *
126     * @hide
127     */
128    public static final int SENSOR_TYPE_VENDOR_EXTENSION_START = 0x60000000;
129    public static final int SENSOR_TYPE_VENDOR_EXTENSION_END   = 0x6fffffff;
130
131    /** Read sensor in default normal rate set for each sensors. This is default rate. */
132    public static final int SENSOR_RATE_NORMAL  = 3;
133    public static final int SENSOR_RATE_UI = 2;
134    public static final int SENSOR_RATE_FAST = 1;
135    /** Read sensor at the maximum rate. Actual rate will be different depending on the sensor. */
136    public static final int SENSOR_RATE_FASTEST = 0;
137
138    /**
139     * Listener for car sensor data change.
140     * Callbacks are called in the Looper context.
141     */
142    public interface CarSensorEventListener {
143        /**
144         * Called when there is a new sensor data from car.
145         * @param event Incoming sensor event for the given sensor type.
146         */
147        void onSensorChanged(final CarSensorEvent event);
148    }
149
150    /**
151     * Give the list of CarSensors available in the connected car.
152     * @return array of all sensor types supported.
153     * @throws CarNotConnectedException
154     */
155    public abstract int[] getSupportedSensors() throws CarNotConnectedException;
156
157    /**
158     * Tells if given sensor is supported or not.
159     * @param sensorType
160     * @return true if the sensor is supported.
161     * @throws CarNotConnectedException
162     */
163    public abstract boolean isSensorSupported(int sensorType) throws CarNotConnectedException;
164
165    /**
166     * Check if given sensorList is including the sensorType.
167     * @param sensorList
168     * @param sensorType
169     * @return
170     */
171    public static boolean isSensorSupported(int[] sensorList, int sensorType) {
172        for (int sensorSupported: sensorList) {
173            if (sensorType == sensorSupported) {
174                return true;
175            }
176        }
177        return false;
178    }
179
180    /**
181     * Register {@link CarSensorEventListener} to get repeated sensor updates. Multiple listeners
182     * can be registered for a single sensor or the same listener can be used for different sensors.
183     * If the same listener is registered again for the same sensor, it will be either ignored or
184     * updated depending on the rate.
185     * <p>
186     * Requires {@link android.Manifest.permission#ACCESS_FINE_LOCATION} for
187     * {@link #SENSOR_TYPE_LOCATION}, {@link Car#PERMISSION_SPEED} for
188     * {@link #SENSOR_TYPE_CAR_SPEED}, {@link Car#PERMISSION_MILEAGE} for
189     * {@link #SENSOR_TYPE_ODOMETER}, or {@link Car#PERMISSION_FUEL} for
190     * {@link #SENSOR_TYPE_FUEL_LEVEL}.
191     *
192     * @param listener
193     * @param sensorType sensor type to subscribe.
194     * @param rate how fast the sensor events are delivered. It should be one of
195     *        {@link #SENSOR_RATE_FASTEST} or {@link #SENSOR_RATE_NORMAL}. Rate may not be respected
196     *        especially when the same sensor is registered with different listener with different
197     *        rates.
198     * @return if the sensor was successfully enabled.
199     * @throws CarNotConnectedException
200     * @throws IllegalArgumentException for wrong argument like wrong rate
201     * @throws SecurityException if missing the appropriate permission
202     */
203    @RequiresPermission(anyOf={Manifest.permission.ACCESS_FINE_LOCATION, Car.PERMISSION_SPEED,
204            Car.PERMISSION_MILEAGE, Car.PERMISSION_FUEL}, conditional=true)
205    public abstract boolean registerListener(CarSensorEventListener listener, int sensorType,
206            int rate) throws CarNotConnectedException, IllegalArgumentException;
207
208    /**
209     * Stop getting sensor update for the given listener. If there are multiple registrations for
210     * this listener, all listening will be stopped.
211     * @param listener
212     */
213    public abstract  void unregisterListener(CarSensorEventListener listener)
214            throws CarNotConnectedException;
215
216    /**
217     * Stop getting sensor update for the given listener and sensor. If the same listener is used
218     * for other sensors, those subscriptions will not be affected.
219     * @param listener
220     * @param sensorType
221     */
222    public abstract  void unregisterListener(CarSensorEventListener listener, int sensorType)
223            throws CarNotConnectedException;
224
225    /**
226     * Get the most recent CarSensorEvent for the given type.
227     * @param type A sensor to request
228     * @return null if there was no sensor update since connected to the car.
229     * @throws CarNotConnectedException
230     */
231    public abstract CarSensorEvent getLatestSensorEvent(int type) throws CarNotConnectedException;
232}
233