• 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 com.android.car;
18 
19 import android.car.Car;
20 import android.car.hardware.CarSensorEvent;
21 import android.car.hardware.CarSensorManager;
22 import android.car.hardware.ICarSensorEventListener;
23 import android.content.Context;
24 import android.os.SystemClock;
25 import android.util.Log;
26 
27 import com.android.car.hal.SensorHalServiceBase.SensorListener;
28 
29 import java.io.PrintWriter;
30 import java.util.List;
31 
32 
33 /**
34  * Logical sensor implementing driving state policy. This policy sets only two states:
35  * no restriction vs fully restrictive. To enter no restriction state, speed should be zero
36  * while either parking brake is applied or transmission gear is in P.
37  */
38 public class DrivingStatePolicy extends CarSensorService.LogicalSensorHalBase {
39 
40     private final Context mContext;
41     private CarSensorService mSensorService;
42     private int mDringState = CarSensorEvent.DRIVE_STATUS_FULLY_RESTRICTED;
43     private SensorListener mSensorListener;
44     private boolean mIsReady = false;
45     private boolean mStarted = false;
46 
47     private static final int[] SUPPORTED_SENSORS = { CarSensorManager.SENSOR_TYPE_DRIVING_STATUS };
48 
49     private final ICarSensorEventListener mICarSensorEventListener =
50             new ICarSensorEventListener.Stub() {
51         @Override
52         public void onSensorChanged(List<CarSensorEvent> events) {
53             for (CarSensorEvent event: events) {
54                 handleSensorEvent(event);
55             }
56         }
57     };
58 
DrivingStatePolicy(Context context)59     public DrivingStatePolicy(Context context) {
60         mContext = context;
61     }
62 
63     @Override
init()64     public void init() {
65         mIsReady = true;
66     }
67 
68     @Override
onSensorServiceReady()69     public synchronized void onSensorServiceReady() {
70         mSensorService =
71                 (CarSensorService) ICarImpl.getInstance(mContext).getCarService(Car.SENSOR_SERVICE);
72         int sensorList[] = mSensorService.getSupportedSensors();
73         boolean hasSpeed = subscribeIfSupportedLocked(sensorList,
74                 CarSensorManager.SENSOR_TYPE_CAR_SPEED, CarSensorManager.SENSOR_RATE_FASTEST);
75         if (!hasSpeed) {
76             Log.w(CarLog.TAG_SENSOR,
77                     "No speed sensor from car. Driving state will be always fully restrictive");
78         }
79         boolean hasParkingBrake = subscribeIfSupportedLocked(sensorList,
80                 CarSensorManager.SENSOR_TYPE_PARKING_BRAKE, CarSensorManager.SENSOR_RATE_FASTEST);
81         boolean hasGear = subscribeIfSupportedLocked(sensorList, CarSensorManager.SENSOR_TYPE_GEAR,
82                 CarSensorManager.SENSOR_RATE_FASTEST);
83         if (!hasParkingBrake && !hasGear) {
84             Log.w(CarLog.TAG_SENSOR,
85                     "No brake info from car. Driving state will be always fully restrictive");
86         }
87     }
88 
89     @Override
release()90     public void release() {
91         // TODO Auto-generated method stub
92     }
93 
getDefaultValue(int sensorType)94     public static CarSensorEvent getDefaultValue(int sensorType) {
95         if (sensorType != CarSensorManager.SENSOR_TYPE_DRIVING_STATUS) {
96             Log.w(CarLog.TAG_SENSOR, "getDefaultValue to DrivingStatePolicy with sensorType:" +
97                     sensorType);
98             return null;
99         }
100         return createEvent(CarSensorEvent.DRIVE_STATUS_FULLY_RESTRICTED);
101     }
102 
103     @Override
registerSensorListener(SensorListener listener)104     public synchronized void registerSensorListener(SensorListener listener) {
105         mSensorListener = listener;
106         if (mIsReady) {
107             mSensorListener.onSensorHalReady(this);
108         }
109     }
110 
111     @Override
isReady()112     public synchronized boolean isReady() {
113         return mIsReady;
114     }
115 
116     @Override
getSupportedSensors()117     public int[] getSupportedSensors() {
118         return SUPPORTED_SENSORS;
119     }
120 
121     @Override
requestSensorStart(int sensorType, int rate)122     public synchronized boolean requestSensorStart(int sensorType, int rate) {
123         mStarted = true;
124         dispatchCarSensorEvent(mSensorListener, createEvent(mDringState));
125         return true;
126     }
127 
128     @Override
requestSensorStop(int sensorType)129     public synchronized void requestSensorStop(int sensorType) {
130         mStarted = false;
131     }
132 
133     @Override
dump(PrintWriter writer)134     public void dump(PrintWriter writer) {
135         // TODO Auto-generated method stub
136     }
137 
subscribeIfSupportedLocked(int sensorList[], int sensorType, int rate)138     private boolean subscribeIfSupportedLocked(int sensorList[], int sensorType, int rate) {
139         if (!CarSensorManager.isSensorSupported(sensorList, sensorType)) {
140             Log.i(CarLog.TAG_SENSOR, "Sensor not supported:" + sensorType);
141             return false;
142         }
143         return mSensorService.registerOrUpdateSensorListener(sensorType, rate,
144                 mICarSensorEventListener);
145     }
146 
handleSensorEvent(CarSensorEvent event)147     private synchronized void handleSensorEvent(CarSensorEvent event) {
148         switch (event.sensorType) {
149             case CarSensorManager.SENSOR_TYPE_PARKING_BRAKE:
150             case CarSensorManager.SENSOR_TYPE_GEAR:
151             case CarSensorManager.SENSOR_TYPE_CAR_SPEED:
152                 int drivingState = recalcDrivingStateLocked();
153                 if (drivingState != mDringState && mSensorListener != null) {
154                     mDringState = drivingState;
155                     dispatchCarSensorEvent(mSensorListener, createEvent(mDringState));
156                 }
157                 break;
158             default:
159                 break;
160         }
161     }
162 
recalcDrivingStateLocked()163     private int recalcDrivingStateLocked() {
164         int drivingState = CarSensorEvent.DRIVE_STATUS_FULLY_RESTRICTED;
165         CarSensorEvent lastParkingBrake = mSensorService.getLatestSensorEvent(
166                 CarSensorManager.SENSOR_TYPE_PARKING_BRAKE);
167         CarSensorEvent lastGear = mSensorService.getLatestSensorEvent(
168                 CarSensorManager.SENSOR_TYPE_GEAR);
169         CarSensorEvent lastSpeed = mSensorService.getLatestSensorEvent(
170                 CarSensorManager.SENSOR_TYPE_CAR_SPEED);
171         if (lastSpeed != null && lastSpeed.floatValues[0] == 0f) { // stopped
172             if (lastParkingBrake == null && isParkingBrakeApplied(lastParkingBrake)) {
173                 if (lastGear != null && isGearInParkingOrNeutral(lastGear)) {
174                     drivingState = CarSensorEvent.DRIVE_STATUS_UNRESTRICTED;
175                 }
176             } else { // parking break not applied or not available
177                 if (lastGear != null && isGearInParking(lastGear)) { // gear in P
178                     drivingState = CarSensorEvent.DRIVE_STATUS_UNRESTRICTED;
179                 }
180             }
181         } // else moving, full restriction
182         return drivingState;
183     }
184 
isSpeedZero(CarSensorEvent event)185     private boolean isSpeedZero(CarSensorEvent event) {
186         return event.floatValues[0] == 0f;
187     }
188 
isParkingBrakeApplied(CarSensorEvent event)189     private boolean isParkingBrakeApplied(CarSensorEvent event) {
190         return event.intValues[0] == 1;
191     }
192 
isGearInParkingOrNeutral(CarSensorEvent event)193     private boolean isGearInParkingOrNeutral(CarSensorEvent event) {
194         int gear = event.intValues[0];
195         return (gear == CarSensorEvent.GEAR_NEUTRAL) ||
196                 (gear == CarSensorEvent.GEAR_PARK);
197     }
198 
isGearInParking(CarSensorEvent event)199     private boolean isGearInParking(CarSensorEvent event) {
200         int gear = event.intValues[0];
201         return gear == CarSensorEvent.GEAR_PARK;
202     }
203 
createEvent(int drivingState)204     private static CarSensorEvent createEvent(int drivingState) {
205         CarSensorEvent event = new CarSensorEvent(CarSensorManager.SENSOR_TYPE_DRIVING_STATUS,
206                 SystemClock.elapsedRealtimeNanos(), 0, 1);
207         event.intValues[0] = drivingState;
208         return event;
209     }
210 }
211