blob: a53e91c622fb3aa0aff86367510b882b19f4e9e1 [file] [log] [blame]
Dan Gittik8dbd7e92018-12-03 15:35:53 +00001/*
2 * Copyright (C) 2019 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 com.android.server.display.whitebalance;
18
19import android.annotation.NonNull;
20import android.content.Context;
21import android.database.ContentObserver;
22import android.net.Uri;
23import android.os.Handler;
24import android.os.Looper;
25import android.os.Message;
26import android.os.UserHandle;
27import android.provider.Settings.Secure;
28import android.util.Slog;
29
30import com.android.internal.util.Preconditions;
31import com.android.server.LocalServices;
32import com.android.server.display.ColorDisplayService;
33import com.android.server.display.ColorDisplayService.ColorDisplayServiceInternal;
34import com.android.server.display.whitebalance.DisplayWhiteBalanceController.Callbacks;
35
36import java.io.PrintWriter;
37
38/**
39 * The DisplayWhiteBalanceSettings holds the state of all the settings related to
40 * display white-balance, and can be used to decide whether to enable the
41 * DisplayWhiteBalanceController.
42 */
43public class DisplayWhiteBalanceSettings implements
44 ColorDisplayService.DisplayWhiteBalanceListener {
45
46 protected static final String TAG = "DisplayWhiteBalanceSettings";
47 protected boolean mLoggingEnabled;
48
49 private static final String SETTING_URI = Secure.DISPLAY_WHITE_BALANCE_ENABLED;
50 private static final int SETTING_DEFAULT = 0;
51 private static final int SETTING_ENABLED = 1;
52
53 private static final int MSG_SET_ACTIVE = 1;
54
55 private final Context mContext;
56 private final Handler mHandler;
57 private final SettingsObserver mSettingsObserver;
58
59 // To decouple the DisplayPowerController from the DisplayWhiteBalanceSettings, the DPC
60 // implements Callbacks and passes itself to the DWBS so it can call back into it without
61 // knowing about it.
62 private Callbacks mCallbacks;
63
64 private int mSetting;
65 private boolean mActive;
66
67 /**
68 * @param context
69 * The context in which display white-balance is used.
70 * @param handler
71 * The handler used to determine which thread to run on.
72 *
73 * @throws NullPointerException
74 * - context is null;
75 * - handler is null.
76 */
77 public DisplayWhiteBalanceSettings(@NonNull Context context, @NonNull Handler handler) {
78 validateArguments(context, handler);
79 mLoggingEnabled = false;
80 mContext = context;
81 mHandler = new DisplayWhiteBalanceSettingsHandler(handler.getLooper());
82 mSettingsObserver = new SettingsObserver(mHandler);
83 mSetting = getSetting();
84 mActive = false;
85 mCallbacks = null;
86
87 mContext.getContentResolver().registerContentObserver(
88 Secure.getUriFor(SETTING_URI), false /* notifyForDescendants */, mSettingsObserver,
89 UserHandle.USER_ALL);
90
91 ColorDisplayServiceInternal cds =
92 LocalServices.getService(ColorDisplayServiceInternal.class);
93 cds.setDisplayWhiteBalanceListener(this);
94 }
95
96 /**
97 * Set an object to call back to when the display white balance state should be updated.
98 *
99 * @param callbacks
100 * The object to call back to.
101 *
102 * @return Whether the method suceeded or not.
103 */
104 public boolean setCallbacks(Callbacks callbacks) {
105 if (mCallbacks == callbacks) {
106 return false;
107 }
108 mCallbacks = callbacks;
109 return true;
110 }
111
112 /**
113 * Enable/disable logging.
114 *
115 * @param loggingEnabled
116 * Whether logging should be on/off.
117 *
118 * @return Whether the method succeeded or not.
119 */
120 public boolean setLoggingEnabled(boolean loggingEnabled) {
121 if (mLoggingEnabled == loggingEnabled) {
122 return false;
123 }
124 mLoggingEnabled = loggingEnabled;
125 return true;
126 }
127
128 /**
129 * Returns whether display white-balance is enabled.
130 *
131 * @return Whether display white-balance is enabled.
132 */
133 public boolean isEnabled() {
134 return (mSetting == SETTING_ENABLED) && mActive;
135 }
136
137 /**
138 * Re-evaluate state after switching to a new user.
139 */
140 public void onSwitchUser() {
141 handleSettingChange();
142 }
143
144 /**
145 * Dump the state.
146 *
147 * @param writer
148 * The writer used to dump the state.
149 */
150 public void dump(PrintWriter writer) {
151 writer.println("DisplayWhiteBalanceSettings");
152 writer.println(" mLoggingEnabled=" + mLoggingEnabled);
153 writer.println(" mContext=" + mContext);
154 writer.println(" mHandler=" + mHandler);
155 writer.println(" mSettingsObserver=" + mSettingsObserver);
156 writer.println(" mSetting=" + mSetting);
157 writer.println(" mActive=" + mActive);
158 writer.println(" mCallbacks=" + mCallbacks);
159 }
160
161 @Override
162 public void onDisplayWhiteBalanceStatusChanged(boolean active) {
163 Message msg = mHandler.obtainMessage(MSG_SET_ACTIVE, active ? 1 : 0, 0);
164 msg.sendToTarget();
165 }
166
167 private void validateArguments(Context context, Handler handler) {
168 Preconditions.checkNotNull(context, "context must not be null");
169 Preconditions.checkNotNull(handler, "handler must not be null");
170 }
171
172 private int getSetting() {
173 return Secure.getIntForUser(mContext.getContentResolver(), SETTING_URI, SETTING_DEFAULT,
174 UserHandle.USER_CURRENT);
175 }
176
177 private void handleSettingChange() {
178 final int setting = getSetting();
179 if (mSetting == setting) {
180 return;
181 }
182 if (mLoggingEnabled) {
183 Slog.d(TAG, "Setting: " + setting);
184 }
185 mSetting = setting;
186 if (mCallbacks != null) {
187 mCallbacks.updateWhiteBalance();
188 }
189 }
190
191 private void setActive(boolean active) {
192 if (mActive == active) {
193 return;
194 }
195 if (mLoggingEnabled) {
196 Slog.d(TAG, "Active: " + active);
197 }
198 mActive = active;
199 if (mCallbacks != null) {
200 mCallbacks.updateWhiteBalance();
201 }
202 }
203
204 private final class SettingsObserver extends ContentObserver {
205 SettingsObserver(Handler handler) {
206 super(handler);
207 }
208
209 @Override
210 public void onChange(boolean selfChange, Uri uri) {
211 handleSettingChange();
212 }
213 }
214
215 private final class DisplayWhiteBalanceSettingsHandler extends Handler {
216 DisplayWhiteBalanceSettingsHandler(Looper looper) {
217 super(looper, null, true /* async */);
218 }
219
220 @Override
221 public void handleMessage(Message msg) {
222 switch (msg.what) {
223 case MSG_SET_ACTIVE:
224 setActive(msg.arg1 != 0);
225 break;
226 }
227 }
228 }
229
230}