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 19 import android.annotation.IntDef; 20 import android.app.UiModeManager; 21 import android.car.hardware.CarPropertyValue; 22 import android.car.hardware.property.CarPropertyEvent; 23 import android.car.hardware.property.ICarPropertyEventListener; 24 import android.content.Context; 25 import android.hardware.automotive.vehicle.V2_0.VehicleProperty; 26 import android.os.RemoteException; 27 import android.util.Log; 28 29 import java.io.PrintWriter; 30 import java.lang.annotation.Retention; 31 import java.lang.annotation.RetentionPolicy; 32 import java.util.List; 33 34 public class CarNightService implements CarServiceBase { 35 36 public static final boolean DBG = false; 37 38 @IntDef({FORCED_SENSOR_MODE, FORCED_DAY_MODE, FORCED_NIGHT_MODE}) 39 @Retention(RetentionPolicy.SOURCE) 40 public @interface DayNightSensorMode {} 41 42 public static final int FORCED_SENSOR_MODE = 0; 43 public static final int FORCED_DAY_MODE = 1; 44 public static final int FORCED_NIGHT_MODE = 2; 45 46 private int mNightSetting = UiModeManager.MODE_NIGHT_YES; 47 private int mForcedMode = FORCED_SENSOR_MODE; 48 private final Context mContext; 49 private final UiModeManager mUiModeManager; 50 private CarPropertyService mCarPropertyService; 51 52 private final ICarPropertyEventListener mICarPropertyEventListener = 53 new ICarPropertyEventListener.Stub() { 54 @Override 55 public void onEvent(List<CarPropertyEvent> events) throws RemoteException { 56 for (CarPropertyEvent event : events) { 57 handlePropertyEvent(event); 58 } 59 } 60 }; 61 62 /** 63 * Handle CarPropertyEvents 64 * @param event 65 */ handlePropertyEvent(CarPropertyEvent event)66 public synchronized void handlePropertyEvent(CarPropertyEvent event) { 67 if (event == null) { 68 return; 69 } 70 if (event.getEventType() == CarPropertyEvent.PROPERTY_EVENT_PROPERTY_CHANGE) { 71 // Only handle onChange events 72 CarPropertyValue value = event.getCarPropertyValue(); 73 if (value.getPropertyId() == VehicleProperty.NIGHT_MODE) { 74 boolean nightMode = (Boolean) value.getValue(); 75 setNightMode(nightMode); 76 } 77 } 78 } 79 setNightMode(boolean nightMode)80 private synchronized void setNightMode(boolean nightMode) { 81 if (nightMode) { 82 mNightSetting = UiModeManager.MODE_NIGHT_YES; 83 if (DBG) Log.d(CarLog.TAG_SENSOR, "CAR dayNight handleSensorEvent NIGHT"); 84 } else { 85 mNightSetting = UiModeManager.MODE_NIGHT_NO; 86 if (DBG) Log.d(CarLog.TAG_SENSOR, "CAR dayNight handleSensorEvent DAY"); 87 } 88 if (mUiModeManager != null && (mForcedMode == FORCED_SENSOR_MODE)) { 89 mUiModeManager.setNightMode(mNightSetting); 90 if (DBG) Log.d(CarLog.TAG_SENSOR, "CAR dayNight handleSensorEvent APPLIED"); 91 } else { 92 if (DBG) Log.d(CarLog.TAG_SENSOR, "CAR dayNight handleSensorEvent IGNORED"); 93 } 94 } 95 forceDayNightMode(@ayNightSensorMode int mode)96 public synchronized int forceDayNightMode(@DayNightSensorMode int mode) { 97 if (mUiModeManager == null) { 98 return -1; 99 } 100 int resultMode; 101 switch (mode) { 102 case FORCED_SENSOR_MODE: 103 resultMode = mNightSetting; 104 mForcedMode = FORCED_SENSOR_MODE; 105 break; 106 case FORCED_DAY_MODE: 107 resultMode = UiModeManager.MODE_NIGHT_NO; 108 mForcedMode = FORCED_DAY_MODE; 109 break; 110 case FORCED_NIGHT_MODE: 111 resultMode = UiModeManager.MODE_NIGHT_YES; 112 mForcedMode = FORCED_NIGHT_MODE; 113 break; 114 default: 115 Log.e(CarLog.TAG_SENSOR, "Unknown forced day/night mode " + mode); 116 return -1; 117 } 118 mUiModeManager.setNightMode(resultMode); 119 return mUiModeManager.getNightMode(); 120 } 121 CarNightService(Context context, CarPropertyService propertyService)122 CarNightService(Context context, CarPropertyService propertyService) { 123 mContext = context; 124 mCarPropertyService = propertyService; 125 mUiModeManager = (UiModeManager) mContext.getSystemService(Context.UI_MODE_SERVICE); 126 if (mUiModeManager == null) { 127 Log.w(CarLog.TAG_SENSOR, "Failed to get UI_MODE_SERVICE"); 128 } 129 } 130 131 @Override init()132 public synchronized void init() { 133 if (DBG) { 134 Log.d(CarLog.TAG_SENSOR,"CAR dayNight init."); 135 } 136 mCarPropertyService.registerListener(VehicleProperty.NIGHT_MODE, 0, 137 mICarPropertyEventListener); 138 CarPropertyValue propertyValue = mCarPropertyService.getProperty( 139 VehicleProperty.NIGHT_MODE, 0); 140 if (propertyValue != null && propertyValue.getTimestamp() != 0) { 141 setNightMode((Boolean) propertyValue.getValue()); 142 } else { 143 Log.w(CarLog.TAG_SENSOR, "Failed to get value of NIGHT_MODE"); 144 // Initial in Night Mode 145 setNightMode(true); 146 } 147 } 148 149 @Override release()150 public synchronized void release() { 151 } 152 153 @Override dump(PrintWriter writer)154 public synchronized void dump(PrintWriter writer) { 155 writer.println("*DAY NIGHT POLICY*"); 156 writer.println("Mode:" + 157 ((mNightSetting == UiModeManager.MODE_NIGHT_YES) ? "night" : "day")); 158 writer.println("Forced Mode? " + (mForcedMode == FORCED_SENSOR_MODE ? "false" 159 : (mForcedMode == FORCED_DAY_MODE ? "day" : "night"))); 160 } 161 } 162