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