Joseph Pirozzo | 317343d | 2016-01-25 10:22:37 -0800 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2016 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 | |
Yao Chen | e33f07e | 2016-07-26 12:02:51 -0700 | [diff] [blame] | 19 | import android.annotation.IntDef; |
Joseph Pirozzo | 317343d | 2016-01-25 10:22:37 -0800 | [diff] [blame] | 20 | import android.app.UiModeManager; |
Steve Paik | 4d25702 | 2018-04-27 13:28:31 -0700 | [diff] [blame] | 21 | import android.car.hardware.CarPropertyValue; |
| 22 | import android.car.hardware.property.CarPropertyEvent; |
| 23 | import android.car.hardware.property.ICarPropertyEventListener; |
Joseph Pirozzo | 317343d | 2016-01-25 10:22:37 -0800 | [diff] [blame] | 24 | import android.content.Context; |
Steve Paik | 4d25702 | 2018-04-27 13:28:31 -0700 | [diff] [blame] | 25 | import android.hardware.automotive.vehicle.V2_0.VehicleProperty; |
| 26 | import android.os.RemoteException; |
Felipe Leme | 176a5fd | 2021-01-20 15:48:33 -0800 | [diff] [blame] | 27 | import android.util.IndentingPrintWriter; |
Eric Jeong | bd5fb56 | 2020-12-21 13:49:40 -0800 | [diff] [blame] | 28 | import android.util.Slog; |
Joseph Pirozzo | 317343d | 2016-01-25 10:22:37 -0800 | [diff] [blame] | 29 | |
Antonio Kantek | b0de6ce | 2019-11-18 19:41:35 -0800 | [diff] [blame] | 30 | import com.android.internal.annotations.GuardedBy; |
| 31 | |
Yao Chen | e33f07e | 2016-07-26 12:02:51 -0700 | [diff] [blame] | 32 | import java.lang.annotation.Retention; |
| 33 | import java.lang.annotation.RetentionPolicy; |
Joseph Pirozzo | 317343d | 2016-01-25 10:22:37 -0800 | [diff] [blame] | 34 | import java.util.List; |
| 35 | |
Antonio Kantek | b0de6ce | 2019-11-18 19:41:35 -0800 | [diff] [blame] | 36 | /** |
| 37 | * Class used to handle events used to set vehicle in night mode. |
| 38 | */ |
Joseph Pirozzo | 317343d | 2016-01-25 10:22:37 -0800 | [diff] [blame] | 39 | public class CarNightService implements CarServiceBase { |
| 40 | |
Keun-young Park | 9ec0547 | 2016-04-26 21:18:18 -0700 | [diff] [blame] | 41 | public static final boolean DBG = false; |
Yao Chen | e33f07e | 2016-07-26 12:02:51 -0700 | [diff] [blame] | 42 | |
| 43 | @IntDef({FORCED_SENSOR_MODE, FORCED_DAY_MODE, FORCED_NIGHT_MODE}) |
| 44 | @Retention(RetentionPolicy.SOURCE) |
| 45 | public @interface DayNightSensorMode {} |
| 46 | |
| 47 | public static final int FORCED_SENSOR_MODE = 0; |
| 48 | public static final int FORCED_DAY_MODE = 1; |
| 49 | public static final int FORCED_NIGHT_MODE = 2; |
| 50 | |
Antonio Kantek | b0de6ce | 2019-11-18 19:41:35 -0800 | [diff] [blame] | 51 | private final Object mLock = new Object(); |
| 52 | @GuardedBy("mLock") |
Joseph Pirozzo | 317343d | 2016-01-25 10:22:37 -0800 | [diff] [blame] | 53 | private int mNightSetting = UiModeManager.MODE_NIGHT_YES; |
Antonio Kantek | b0de6ce | 2019-11-18 19:41:35 -0800 | [diff] [blame] | 54 | @GuardedBy("mLock") |
Yao Chen | e33f07e | 2016-07-26 12:02:51 -0700 | [diff] [blame] | 55 | private int mForcedMode = FORCED_SENSOR_MODE; |
Antonio Kantek | b0de6ce | 2019-11-18 19:41:35 -0800 | [diff] [blame] | 56 | @GuardedBy("mLock") |
Kai | a4481e1 | 2019-10-17 17:45:39 -0700 | [diff] [blame] | 57 | private long mLastSensorEventTime = -1; |
Joseph Pirozzo | 317343d | 2016-01-25 10:22:37 -0800 | [diff] [blame] | 58 | private final Context mContext; |
Antonio Kantek | b0de6ce | 2019-11-18 19:41:35 -0800 | [diff] [blame] | 59 | @GuardedBy("mLock") |
Joseph Pirozzo | 317343d | 2016-01-25 10:22:37 -0800 | [diff] [blame] | 60 | private final UiModeManager mUiModeManager; |
Antonio Kantek | b0de6ce | 2019-11-18 19:41:35 -0800 | [diff] [blame] | 61 | private final CarPropertyService mCarPropertyService; |
Joseph Pirozzo | 317343d | 2016-01-25 10:22:37 -0800 | [diff] [blame] | 62 | |
Steve Paik | 4d25702 | 2018-04-27 13:28:31 -0700 | [diff] [blame] | 63 | private final ICarPropertyEventListener mICarPropertyEventListener = |
| 64 | new ICarPropertyEventListener.Stub() { |
Antonio Kantek | b0de6ce | 2019-11-18 19:41:35 -0800 | [diff] [blame] | 65 | @Override |
| 66 | public void onEvent(List<CarPropertyEvent> events) throws RemoteException { |
| 67 | synchronized (mLock) { |
| 68 | for (CarPropertyEvent event : events) { |
| 69 | onNightModeCarPropertyEventLocked(event); |
| 70 | } |
| 71 | } |
| 72 | } |
| 73 | }; |
Joseph Pirozzo | 317343d | 2016-01-25 10:22:37 -0800 | [diff] [blame] | 74 | |
Steve Paik | 4d25702 | 2018-04-27 13:28:31 -0700 | [diff] [blame] | 75 | /** |
Antonio Kantek | b0de6ce | 2019-11-18 19:41:35 -0800 | [diff] [blame] | 76 | * Acts on {@link CarPropertyEvent} events marked with |
| 77 | * {@link CarPropertyEvent.PROPERTY_EVENT_PROPERTY_CHANGE} and marked with {@link |
| 78 | * VehicleProperty.NIGHT_MODE} by |
| 79 | * setting the vehicle in night mode. |
| 80 | * <p> |
| 81 | * This method does nothing if the event parameter is {@code null}. |
| 82 | * |
| 83 | * @param event the car property event to be handled |
Steve Paik | 4d25702 | 2018-04-27 13:28:31 -0700 | [diff] [blame] | 84 | */ |
Antonio Kantek | b0de6ce | 2019-11-18 19:41:35 -0800 | [diff] [blame] | 85 | @GuardedBy("mLock") |
| 86 | private void onNightModeCarPropertyEventLocked(CarPropertyEvent event) { |
Joseph Pirozzo | 317343d | 2016-01-25 10:22:37 -0800 | [diff] [blame] | 87 | if (event == null) { |
| 88 | return; |
| 89 | } |
Steve Paik | 4d25702 | 2018-04-27 13:28:31 -0700 | [diff] [blame] | 90 | if (event.getEventType() == CarPropertyEvent.PROPERTY_EVENT_PROPERTY_CHANGE) { |
| 91 | // Only handle onChange events |
| 92 | CarPropertyValue value = event.getCarPropertyValue(); |
Kai | a4481e1 | 2019-10-17 17:45:39 -0700 | [diff] [blame] | 93 | if (value.getPropertyId() == VehicleProperty.NIGHT_MODE |
| 94 | && value.getTimestamp() > mLastSensorEventTime) { |
| 95 | mLastSensorEventTime = value.getTimestamp(); |
Steve Paik | 4d25702 | 2018-04-27 13:28:31 -0700 | [diff] [blame] | 96 | boolean nightMode = (Boolean) value.getValue(); |
Eric Jeong | bd5fb56 | 2020-12-21 13:49:40 -0800 | [diff] [blame] | 97 | Slog.i(CarLog.TAG_SENSOR, "Set dayNight Mode as " |
Kai | a4481e1 | 2019-10-17 17:45:39 -0700 | [diff] [blame] | 98 | + nightMode + " at timestamp: " + mLastSensorEventTime); |
Antonio Kantek | b0de6ce | 2019-11-18 19:41:35 -0800 | [diff] [blame] | 99 | setNightModeLocked(nightMode); |
Joseph Pirozzo | 317343d | 2016-01-25 10:22:37 -0800 | [diff] [blame] | 100 | } |
| 101 | } |
| 102 | } |
| 103 | |
Antonio Kantek | b0de6ce | 2019-11-18 19:41:35 -0800 | [diff] [blame] | 104 | @GuardedBy("mLock") |
| 105 | private void setNightModeLocked(boolean nightMode) { |
Kai | 46f42a7 | 2018-06-22 14:41:57 -0700 | [diff] [blame] | 106 | if (nightMode) { |
| 107 | mNightSetting = UiModeManager.MODE_NIGHT_YES; |
Eric Jeong | bd5fb56 | 2020-12-21 13:49:40 -0800 | [diff] [blame] | 108 | if (DBG) Slog.d(CarLog.TAG_SENSOR, "CAR dayNight handleSensorEvent NIGHT"); |
Kai | 46f42a7 | 2018-06-22 14:41:57 -0700 | [diff] [blame] | 109 | } else { |
| 110 | mNightSetting = UiModeManager.MODE_NIGHT_NO; |
Eric Jeong | bd5fb56 | 2020-12-21 13:49:40 -0800 | [diff] [blame] | 111 | if (DBG) Slog.d(CarLog.TAG_SENSOR, "CAR dayNight handleSensorEvent DAY"); |
Kai | 46f42a7 | 2018-06-22 14:41:57 -0700 | [diff] [blame] | 112 | } |
| 113 | if (mUiModeManager != null && (mForcedMode == FORCED_SENSOR_MODE)) { |
| 114 | mUiModeManager.setNightMode(mNightSetting); |
Eric Jeong | bd5fb56 | 2020-12-21 13:49:40 -0800 | [diff] [blame] | 115 | if (DBG) Slog.d(CarLog.TAG_SENSOR, "CAR dayNight handleSensorEvent APPLIED"); |
Kai | 46f42a7 | 2018-06-22 14:41:57 -0700 | [diff] [blame] | 116 | } else { |
Eric Jeong | bd5fb56 | 2020-12-21 13:49:40 -0800 | [diff] [blame] | 117 | if (DBG) Slog.d(CarLog.TAG_SENSOR, "CAR dayNight handleSensorEvent IGNORED"); |
Kai | 46f42a7 | 2018-06-22 14:41:57 -0700 | [diff] [blame] | 118 | } |
| 119 | } |
| 120 | |
Antonio Kantek | b0de6ce | 2019-11-18 19:41:35 -0800 | [diff] [blame] | 121 | /** |
| 122 | * Sets {@link UiModeManager} to night mode according to the {@link DayNightSensorMode} passed |
| 123 | * as parameter. |
| 124 | * |
| 125 | * @param mode the sensor mode used to set vehicle in night mode |
| 126 | * @return the current night mode, or {@code -1} on error |
| 127 | */ |
| 128 | public int forceDayNightMode(@DayNightSensorMode int mode) { |
| 129 | synchronized (mLock) { |
| 130 | if (mUiModeManager == null) { |
Yao Chen | e33f07e | 2016-07-26 12:02:51 -0700 | [diff] [blame] | 131 | return -1; |
Antonio Kantek | b0de6ce | 2019-11-18 19:41:35 -0800 | [diff] [blame] | 132 | } |
| 133 | int resultMode; |
| 134 | switch (mode) { |
| 135 | case FORCED_SENSOR_MODE: |
| 136 | resultMode = mNightSetting; |
| 137 | mForcedMode = FORCED_SENSOR_MODE; |
| 138 | break; |
| 139 | case FORCED_DAY_MODE: |
| 140 | resultMode = UiModeManager.MODE_NIGHT_NO; |
| 141 | mForcedMode = FORCED_DAY_MODE; |
| 142 | break; |
| 143 | case FORCED_NIGHT_MODE: |
| 144 | resultMode = UiModeManager.MODE_NIGHT_YES; |
| 145 | mForcedMode = FORCED_NIGHT_MODE; |
| 146 | break; |
| 147 | default: |
Eric Jeong | bd5fb56 | 2020-12-21 13:49:40 -0800 | [diff] [blame] | 148 | Slog.e(CarLog.TAG_SENSOR, "Unknown forced day/night mode " + mode); |
Antonio Kantek | b0de6ce | 2019-11-18 19:41:35 -0800 | [diff] [blame] | 149 | return -1; |
| 150 | } |
| 151 | mUiModeManager.setNightMode(resultMode); |
| 152 | return mUiModeManager.getNightMode(); |
Yao Chen | e33f07e | 2016-07-26 12:02:51 -0700 | [diff] [blame] | 153 | } |
Yao Chen | e33f07e | 2016-07-26 12:02:51 -0700 | [diff] [blame] | 154 | } |
| 155 | |
Steve Paik | 4d25702 | 2018-04-27 13:28:31 -0700 | [diff] [blame] | 156 | CarNightService(Context context, CarPropertyService propertyService) { |
Joseph Pirozzo | 317343d | 2016-01-25 10:22:37 -0800 | [diff] [blame] | 157 | mContext = context; |
Steve Paik | 4d25702 | 2018-04-27 13:28:31 -0700 | [diff] [blame] | 158 | mCarPropertyService = propertyService; |
Joseph Pirozzo | 317343d | 2016-01-25 10:22:37 -0800 | [diff] [blame] | 159 | mUiModeManager = (UiModeManager) mContext.getSystemService(Context.UI_MODE_SERVICE); |
| 160 | if (mUiModeManager == null) { |
Eric Jeong | bd5fb56 | 2020-12-21 13:49:40 -0800 | [diff] [blame] | 161 | Slog.w(CarLog.TAG_SENSOR, "Failed to get UI_MODE_SERVICE"); |
Joseph Pirozzo | 317343d | 2016-01-25 10:22:37 -0800 | [diff] [blame] | 162 | } |
| 163 | } |
| 164 | |
| 165 | @Override |
Antonio Kantek | b0de6ce | 2019-11-18 19:41:35 -0800 | [diff] [blame] | 166 | public void init() { |
Joseph Pirozzo | 317343d | 2016-01-25 10:22:37 -0800 | [diff] [blame] | 167 | if (DBG) { |
Eric Jeong | bd5fb56 | 2020-12-21 13:49:40 -0800 | [diff] [blame] | 168 | Slog.d(CarLog.TAG_SENSOR, "CAR dayNight init."); |
Joseph Pirozzo | 317343d | 2016-01-25 10:22:37 -0800 | [diff] [blame] | 169 | } |
Antonio Kantek | b0de6ce | 2019-11-18 19:41:35 -0800 | [diff] [blame] | 170 | synchronized (mLock) { |
| 171 | mCarPropertyService.registerListener(VehicleProperty.NIGHT_MODE, 0, |
| 172 | mICarPropertyEventListener); |
Kai Wang | 301dd47 | 2021-05-18 06:09:44 +0000 | [diff] [blame] | 173 | CarPropertyValue propertyValue = mCarPropertyService.getPropertySafe( |
Antonio Kantek | b0de6ce | 2019-11-18 19:41:35 -0800 | [diff] [blame] | 174 | VehicleProperty.NIGHT_MODE, 0); |
| 175 | if (propertyValue != null && propertyValue.getTimestamp() != 0) { |
| 176 | mLastSensorEventTime = propertyValue.getTimestamp(); |
| 177 | setNightModeLocked((Boolean) propertyValue.getValue()); |
| 178 | } else { |
Eric Jeong | bd5fb56 | 2020-12-21 13:49:40 -0800 | [diff] [blame] | 179 | Slog.w(CarLog.TAG_SENSOR, "Failed to get value of NIGHT_MODE"); |
Antonio Kantek | b0de6ce | 2019-11-18 19:41:35 -0800 | [diff] [blame] | 180 | setNightModeLocked(true); |
| 181 | } |
Kai | 46f42a7 | 2018-06-22 14:41:57 -0700 | [diff] [blame] | 182 | } |
Joseph Pirozzo | 317343d | 2016-01-25 10:22:37 -0800 | [diff] [blame] | 183 | } |
| 184 | |
| 185 | @Override |
Antonio Kantek | b0de6ce | 2019-11-18 19:41:35 -0800 | [diff] [blame] | 186 | public void release() { |
Joseph Pirozzo | 317343d | 2016-01-25 10:22:37 -0800 | [diff] [blame] | 187 | } |
| 188 | |
| 189 | @Override |
Felipe Leme | 176a5fd | 2021-01-20 15:48:33 -0800 | [diff] [blame] | 190 | public void dump(IndentingPrintWriter writer) { |
Antonio Kantek | b0de6ce | 2019-11-18 19:41:35 -0800 | [diff] [blame] | 191 | synchronized (mLock) { |
| 192 | writer.println("*DAY NIGHT POLICY*"); |
| 193 | writer.println( |
| 194 | "Mode:" + ((mNightSetting == UiModeManager.MODE_NIGHT_YES) ? "night" : "day")); |
| 195 | writer.println("Forced Mode? " + (mForcedMode == FORCED_SENSOR_MODE |
| 196 | ? "false, timestamp of dayNight sensor is: " + mLastSensorEventTime |
| 197 | : (mForcedMode == FORCED_DAY_MODE ? "day" : "night"))); |
| 198 | } |
Joseph Pirozzo | 317343d | 2016-01-25 10:22:37 -0800 | [diff] [blame] | 199 | } |
| 200 | } |
Antonio Kantek | b0de6ce | 2019-11-18 19:41:35 -0800 | [diff] [blame] | 201 | |