blob: dae2927cc6e92fc0116f46da7f739add93825ae5 [file] [log] [blame]
Jeff Brownfa25bf52012-07-23 19:26:30 -07001/*
2 * Copyright (C) 2012 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;
18
Andrii Kulianfc8f82b2017-01-26 13:17:27 -080019import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR;
20import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY;
21import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC;
22import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE;
23import static android.hardware.display.DisplayManager
Andrii Kulian7211d2e2017-01-27 15:58:05 -080024 .VIRTUAL_DISPLAY_FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD;
Andrii Kulianfc8f82b2017-01-26 13:17:27 -080025
Santos Cordonee8931e2017-04-05 10:31:15 -070026import com.android.internal.annotations.VisibleForTesting;
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -060027import com.android.internal.util.DumpUtils;
Jeff Brownbd6e1502012-08-28 03:27:37 -070028import com.android.internal.util.IndentingPrintWriter;
29
Jeff Brownfa25bf52012-07-23 19:26:30 -070030import android.Manifest;
Santos Cordonee8931e2017-04-05 10:31:15 -070031import android.annotation.NonNull;
Kenny Guy05ce8092018-01-17 13:44:20 +000032import android.annotation.Nullable;
Michael Wrighteef0e132017-11-21 17:57:52 +000033import android.annotation.UserIdInt;
Kenny Guy29aa30e2017-11-30 13:43:46 +000034import android.app.AppOpsManager;
Jeff Brownfa25bf52012-07-23 19:26:30 -070035import android.content.Context;
36import android.content.pm.PackageManager;
Kenny Guy22bd0442017-10-26 00:15:54 +010037import android.content.pm.ParceledListSlice;
Michael Wrighteedcbf12017-08-16 23:14:54 +010038import android.content.res.Resources;
39import android.graphics.Point;
Jeff Brownad9ef192014-04-08 17:26:30 -070040import android.hardware.SensorManager;
Peeyush Agarwalcc155dd2018-01-10 11:51:33 +000041import android.hardware.display.AmbientBrightnessDayStats;
Kenny Guy22bd0442017-10-26 00:15:54 +010042import android.hardware.display.BrightnessChangeEvent;
Michael Wrighteef0e132017-11-21 17:57:52 +000043import android.hardware.display.BrightnessConfiguration;
Jeff Brownbd6e1502012-08-28 03:27:37 -070044import android.hardware.display.DisplayManagerGlobal;
Jeff Brown4ccb8232014-01-16 22:16:42 -080045import android.hardware.display.DisplayManagerInternal;
46import android.hardware.display.DisplayViewport;
47import android.hardware.display.DisplayManagerInternal.DisplayTransactionListener;
Jeff Brownfa25bf52012-07-23 19:26:30 -070048import android.hardware.display.IDisplayManager;
Jeff Brownbd6e1502012-08-28 03:27:37 -070049import android.hardware.display.IDisplayManagerCallback;
Michael Wright75ee9fc2014-09-01 19:55:22 -070050import android.hardware.display.IVirtualDisplayCallback;
Jeff Browne08ae382012-09-07 20:36:36 -070051import android.hardware.display.WifiDisplayStatus;
Jeff Brown4ccb8232014-01-16 22:16:42 -080052import android.hardware.input.InputManagerInternal;
Michael Wrightc39d47a2014-07-08 18:07:36 -070053import android.media.projection.IMediaProjection;
54import android.media.projection.IMediaProjectionManager;
Jeff Brownfa25bf52012-07-23 19:26:30 -070055import android.os.Binder;
Jeff Brownbd6e1502012-08-28 03:27:37 -070056import android.os.Handler;
Jeff Brown64a55af2012-08-26 02:47:39 -070057import android.os.IBinder;
Jeff Brown4ccb8232014-01-16 22:16:42 -080058import android.os.IBinder.DeathRecipient;
Jeff Brownbd6e1502012-08-28 03:27:37 -070059import android.os.Looper;
60import android.os.Message;
Jeff Brown5d6443b2015-04-10 20:15:01 -070061import android.os.PowerManager;
Craig Mautner4504de52013-12-20 09:06:56 -080062import android.os.Process;
Jeff Brownbd6e1502012-08-28 03:27:37 -070063import android.os.RemoteException;
Michael Wrightc39d47a2014-07-08 18:07:36 -070064import android.os.ServiceManager;
Jeff Brownbd6e1502012-08-28 03:27:37 -070065import android.os.SystemClock;
Jeff Brownfa25bf52012-07-23 19:26:30 -070066import android.os.SystemProperties;
Jeff Brown5d6443b2015-04-10 20:15:01 -070067import android.os.Trace;
Kenny Guy22bd0442017-10-26 00:15:54 +010068import android.os.UserHandle;
Michael Wrighteef0e132017-11-21 17:57:52 +000069import android.os.UserManager;
Jeff Browna506a6e2013-06-04 00:02:38 -070070import android.text.TextUtils;
Andrii Kulianfb1bf692017-01-17 11:17:34 -080071import android.util.IntArray;
Jeff Brownbd6e1502012-08-28 03:27:37 -070072import android.util.Slog;
73import android.util.SparseArray;
Jeff Brownfa25bf52012-07-23 19:26:30 -070074import android.view.Display;
75import android.view.DisplayInfo;
Jeff Browna506a6e2013-06-04 00:02:38 -070076import android.view.Surface;
77
Michael Wrighteef0e132017-11-21 17:57:52 +000078import com.android.internal.util.Preconditions;
Jorim Jaggied7993b2017-03-28 18:50:01 +010079import com.android.server.AnimationThread;
Jeff Brown4ccb8232014-01-16 22:16:42 -080080import com.android.server.DisplayThread;
81import com.android.server.LocalServices;
82import com.android.server.SystemService;
Dianne Hackborn8d044e82013-04-30 17:24:15 -070083import com.android.server.UiThread;
Adrian Roose99bc052017-11-20 17:55:31 +010084import com.android.server.wm.WindowManagerInternal;
Jorim Jaggi21c39a72017-10-20 15:47:51 +020085import com.android.server.wm.SurfaceAnimationThread;
Jeff Brownfa25bf52012-07-23 19:26:30 -070086
87import java.io.FileDescriptor;
88import java.io.PrintWriter;
89import java.util.ArrayList;
Jeff Browna506a6e2013-06-04 00:02:38 -070090import java.util.Arrays;
Jeff Browne75926d2014-09-18 15:24:49 -070091import java.util.List;
Jeff Brown7f3994e2012-12-04 14:04:28 -080092import java.util.concurrent.CopyOnWriteArrayList;
Jeff Brownfa25bf52012-07-23 19:26:30 -070093
94/**
Jeff Brownbd6e1502012-08-28 03:27:37 -070095 * Manages attached displays.
Jeff Brownfa25bf52012-07-23 19:26:30 -070096 * <p>
Jeff Brownbd6e1502012-08-28 03:27:37 -070097 * The {@link DisplayManagerService} manages the global lifecycle of displays,
98 * decides how to configure logical displays based on the physical display devices currently
99 * attached, sends notifications to the system and to applications when the state
100 * changes, and so on.
101 * </p><p>
102 * The display manager service relies on a collection of {@link DisplayAdapter} components,
103 * for discovering and configuring physical display devices attached to the system.
104 * There are separate display adapters for each manner that devices are attached:
105 * one display adapter for built-in local displays, one for simulated non-functional
106 * displays when the system is headless, one for simulated overlay displays used for
107 * development, one for wifi displays, etc.
108 * </p><p>
109 * Display adapters are only weakly coupled to the display manager service.
110 * Display adapters communicate changes in display device state to the display manager
Craig Mautner722285e2012-09-07 13:55:58 -0700111 * service asynchronously via a {@link DisplayAdapter.Listener} registered
Jeff Brownbd6e1502012-08-28 03:27:37 -0700112 * by the display manager service. This separation of concerns is important for
113 * two main reasons. First, it neatly encapsulates the responsibilities of these
114 * two classes: display adapters handle individual display devices whereas
115 * the display manager service handles the global state. Second, it eliminates
116 * the potential for deadlocks resulting from asynchronous display device discovery.
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700117 * </p>
118 *
119 * <h3>Synchronization</h3>
120 * <p>
121 * Because the display manager may be accessed by multiple threads, the synchronization
122 * story gets a little complicated. In particular, the window manager may call into
123 * the display manager while holding a surface transaction with the expectation that
124 * it can apply changes immediately. Unfortunately, that means we can't just do
125 * everything asynchronously (*grump*).
Jeff Brownbd6e1502012-08-28 03:27:37 -0700126 * </p><p>
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700127 * To make this work, all of the objects that belong to the display manager must
128 * use the same lock. We call this lock the synchronization root and it has a unique
129 * type {@link DisplayManagerService.SyncRoot}. Methods that require this lock are
130 * named with the "Locked" suffix.
131 * </p><p>
132 * Where things get tricky is that the display manager is not allowed to make
133 * any potentially reentrant calls, especially into the window manager. We generally
134 * avoid this by making all potentially reentrant out-calls asynchronous.
Jeff Brownfa25bf52012-07-23 19:26:30 -0700135 * </p>
136 */
Jeff Brown4ccb8232014-01-16 22:16:42 -0800137public final class DisplayManagerService extends SystemService {
Jeff Brownfa25bf52012-07-23 19:26:30 -0700138 private static final String TAG = "DisplayManagerService";
Jeff Brownbd6e1502012-08-28 03:27:37 -0700139 private static final boolean DEBUG = false;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700140
Jeff Brownbbd28a22012-09-20 16:47:15 -0700141 // When this system property is set to 0, WFD is forcibly disabled on boot.
142 // When this system property is set to 1, WFD is forcibly enabled on boot.
143 // Otherwise WFD is enabled according to the value of config_enableWifiDisplay.
144 private static final String FORCE_WIFI_DISPLAY_ENABLE = "persist.debug.wfd.enable";
145
Jeff Brownbd6e1502012-08-28 03:27:37 -0700146 private static final long WAIT_FOR_DEFAULT_DISPLAY_TIMEOUT = 10000;
147
Santos Cordonc22c5632017-06-21 16:03:49 -0700148 private static final int MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS = 1;
Jeff Brownbd6e1502012-08-28 03:27:37 -0700149 private static final int MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS = 2;
150 private static final int MSG_DELIVER_DISPLAY_EVENT = 3;
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700151 private static final int MSG_REQUEST_TRAVERSAL = 4;
Jeff Brownd728bf52012-09-08 18:05:28 -0700152 private static final int MSG_UPDATE_VIEWPORT = 5;
Kenny Guy22bd0442017-10-26 00:15:54 +0100153 private static final int MSG_REGISTER_BRIGHTNESS_TRACKER = 6;
Michael Wrighteef0e132017-11-21 17:57:52 +0000154 private static final int MSG_LOAD_BRIGHTNESS_CONFIGURATION = 7;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700155
Jeff Brownb880d882014-02-10 19:47:07 -0800156 private final Context mContext;
Jeff Brownbd6e1502012-08-28 03:27:37 -0700157 private final DisplayManagerHandler mHandler;
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700158 private final Handler mUiHandler;
159 private final DisplayAdapterListener mDisplayAdapterListener;
Jeff Brown4ccb8232014-01-16 22:16:42 -0800160 private WindowManagerInternal mWindowManagerInternal;
161 private InputManagerInternal mInputManagerInternal;
Michael Wrightc39d47a2014-07-08 18:07:36 -0700162 private IMediaProjectionManager mProjectionService;
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700163
164 // The synchronization root for the display manager.
165 // This lock guards most of the display manager's state.
Craig Mautner0bf6ec92012-12-18 08:33:27 -0800166 // NOTE: This is synchronized on while holding WindowManagerService.mWindowMap so never call
167 // into WindowManagerService methods that require mWindowMap while holding this unless you are
168 // very very sure that no deadlock can occur.
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700169 private final SyncRoot mSyncRoot = new SyncRoot();
170
171 // True if in safe mode.
172 // This option may disable certain display adapters.
173 public boolean mSafeMode;
174
175 // True if we are in a special boot mode where only core applications and
176 // services should be started. This option may disable certain display adapters.
177 public boolean mOnlyCore;
178
Jeff Brown27f1d672012-10-17 18:32:34 -0700179 // True if the display manager service should pretend there is only one display
180 // and only tell applications about the existence of the default logical display.
181 // The display manager can still mirror content to secondary displays but applications
182 // cannot present unique content on those displays.
183 // Used for demonstration purposes only.
184 private final boolean mSingleDisplayDemoMode;
185
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700186 // All callback records indexed by calling process id.
187 public final SparseArray<CallbackRecord> mCallbacks =
Jeff Brownbd6e1502012-08-28 03:27:37 -0700188 new SparseArray<CallbackRecord>();
Jeff Brownfa25bf52012-07-23 19:26:30 -0700189
Jeff Brownbd6e1502012-08-28 03:27:37 -0700190 // List of all currently registered display adapters.
191 private final ArrayList<DisplayAdapter> mDisplayAdapters = new ArrayList<DisplayAdapter>();
192
193 // List of all currently connected display devices.
194 private final ArrayList<DisplayDevice> mDisplayDevices = new ArrayList<DisplayDevice>();
195
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700196 // List of all logical displays indexed by logical display id.
197 private final SparseArray<LogicalDisplay> mLogicalDisplays =
198 new SparseArray<LogicalDisplay>();
Jeff Brownbd6e1502012-08-28 03:27:37 -0700199 private int mNextNonDefaultDisplayId = Display.DEFAULT_DISPLAY + 1;
200
Jeff Brown7f3994e2012-12-04 14:04:28 -0800201 // List of all display transaction listeners.
202 private final CopyOnWriteArrayList<DisplayTransactionListener> mDisplayTransactionListeners =
203 new CopyOnWriteArrayList<DisplayTransactionListener>();
204
Jeff Brownad9ef192014-04-08 17:26:30 -0700205 // Display power controller.
206 private DisplayPowerController mDisplayPowerController;
207
Jeff Brown037c33e2014-04-09 00:31:55 -0700208 // The overall display state, independent of changes that might influence one
209 // display or another in particular.
Jeff Brown5d6443b2015-04-10 20:15:01 -0700210 private int mGlobalDisplayState = Display.STATE_ON;
211
212 // The overall display brightness.
213 // For now, this only applies to the built-in display but we may split it up eventually.
214 private int mGlobalDisplayBrightness = PowerManager.BRIGHTNESS_DEFAULT;
Jeff Brown9e316a12012-10-08 19:17:06 -0700215
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700216 // Set to true when there are pending display changes that have yet to be applied
217 // to the surface flinger state.
218 private boolean mPendingTraversal;
Jeff Brownbd6e1502012-08-28 03:27:37 -0700219
Jeff Browne08ae382012-09-07 20:36:36 -0700220 // The Wifi display adapter, or null if not registered.
221 private WifiDisplayAdapter mWifiDisplayAdapter;
222
Jeff Brownce468a32013-11-21 16:42:03 -0800223 // The number of active wifi display scan requests.
224 private int mWifiDisplayScanRequestCount;
225
Jeff Browna506a6e2013-06-04 00:02:38 -0700226 // The virtual display adapter, or null if not registered.
227 private VirtualDisplayAdapter mVirtualDisplayAdapter;
228
Michael Wrighteef0e132017-11-21 17:57:52 +0000229 // The User ID of the current user
230 private @UserIdInt int mCurrentUserId;
231
Michael Wrighteedcbf12017-08-16 23:14:54 +0100232 // The stable device screen height and width. These are not tied to a specific display, even
233 // the default display, because they need to be stable over the course of the device's entire
234 // life, even if the default display changes (e.g. a new monitor is plugged into a PC-like
235 // device).
236 private Point mStableDisplaySize = new Point();
237
Jeff Brownd728bf52012-09-08 18:05:28 -0700238 // Viewports of the default display and the display that should receive touch
239 // input from an external source. Used by the input system.
240 private final DisplayViewport mDefaultViewport = new DisplayViewport();
241 private final DisplayViewport mExternalTouchViewport = new DisplayViewport();
Santos Cordonee8931e2017-04-05 10:31:15 -0700242 private final ArrayList<DisplayViewport> mVirtualTouchViewports = new ArrayList<>();
Jeff Brownd728bf52012-09-08 18:05:28 -0700243
Jeff Brown89d55462012-09-19 11:33:42 -0700244 // Persistent data store for all internal settings maintained by the display manager service.
245 private final PersistentDataStore mPersistentDataStore = new PersistentDataStore();
246
Jeff Brownbd6e1502012-08-28 03:27:37 -0700247 // Temporary callback list, used when sending display events to applications.
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700248 // May be used outside of the lock but only on the handler thread.
249 private final ArrayList<CallbackRecord> mTempCallbacks = new ArrayList<CallbackRecord>();
Jeff Brownbd6e1502012-08-28 03:27:37 -0700250
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700251 // Temporary display info, used for comparing display configurations.
252 private final DisplayInfo mTempDisplayInfo = new DisplayInfo();
253
Jeff Brownd728bf52012-09-08 18:05:28 -0700254 // Temporary viewports, used when sending new viewport information to the
255 // input system. May be used outside of the lock but only on the handler thread.
256 private final DisplayViewport mTempDefaultViewport = new DisplayViewport();
257 private final DisplayViewport mTempExternalTouchViewport = new DisplayViewport();
Santos Cordonee8931e2017-04-05 10:31:15 -0700258 private final ArrayList<DisplayViewport> mTempVirtualTouchViewports = new ArrayList<>();
Jeff Brownd728bf52012-09-08 18:05:28 -0700259
Damien Bargiacchi4364bbf2016-11-01 21:44:20 -0700260 // The default color mode for default displays. Overrides the usual
261 // Display.Display.COLOR_MODE_DEFAULT for displays with the
262 // DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY flag set.
263 private final int mDefaultDisplayDefaultColorMode;
264
Jeff Browne75926d2014-09-18 15:24:49 -0700265 // Temporary list of deferred work to perform when setting the display state.
266 // Only used by requestDisplayState. The field is self-synchronized and only
267 // intended for use inside of the requestGlobalDisplayStateInternal function.
268 private final ArrayList<Runnable> mTempDisplayStateWorkQueue = new ArrayList<Runnable>();
269
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800270 // Lists of UIDs that are present on the displays. Maps displayId -> array of UIDs.
271 private final SparseArray<IntArray> mDisplayAccessUIDs = new SparseArray<>();
272
Santos Cordonee8931e2017-04-05 10:31:15 -0700273 private final Injector mInjector;
274
Jeff Brownb880d882014-02-10 19:47:07 -0800275 public DisplayManagerService(Context context) {
Santos Cordonee8931e2017-04-05 10:31:15 -0700276 this(context, new Injector());
277 }
278
279 @VisibleForTesting
280 DisplayManagerService(Context context, Injector injector) {
Jeff Brownb880d882014-02-10 19:47:07 -0800281 super(context);
Santos Cordonee8931e2017-04-05 10:31:15 -0700282 mInjector = injector;
Jeff Brownb880d882014-02-10 19:47:07 -0800283 mContext = context;
Jeff Brown4ccb8232014-01-16 22:16:42 -0800284 mHandler = new DisplayManagerHandler(DisplayThread.get().getLooper());
Dianne Hackborn8d044e82013-04-30 17:24:15 -0700285 mUiHandler = UiThread.getHandler();
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700286 mDisplayAdapterListener = new DisplayAdapterListener();
Jeff Brown27f1d672012-10-17 18:32:34 -0700287 mSingleDisplayDemoMode = SystemProperties.getBoolean("persist.demo.singledisplay", false);
Damien Bargiacchi4364bbf2016-11-01 21:44:20 -0700288 mDefaultDisplayDefaultColorMode = mContext.getResources().getInteger(
Michael Wrighteef0e132017-11-21 17:57:52 +0000289 com.android.internal.R.integer.config_defaultDisplayDefaultColorMode);
Jeff Brown5d6443b2015-04-10 20:15:01 -0700290
291 PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
292 mGlobalDisplayBrightness = pm.getDefaultScreenBrightnessSetting();
Michael Wrighteef0e132017-11-21 17:57:52 +0000293 mCurrentUserId = UserHandle.USER_SYSTEM;
Joel Fernandes2d314e12017-04-04 16:32:15 -0700294 }
295
296 public void setupSchedulerPolicies() {
Jorim Jaggied7993b2017-03-28 18:50:01 +0100297 // android.display and android.anim is critical to user experience and we should make sure
Michael Wrighteef0e132017-11-21 17:57:52 +0000298 // it is not in the default foregroup groups, add it to top-app to make sure it uses all
299 // the cores and scheduling settings for top-app when it runs.
Jorim Jaggied7993b2017-03-28 18:50:01 +0100300 Process.setThreadGroupAndCpuset(DisplayThread.get().getThreadId(),
301 Process.THREAD_GROUP_TOP_APP);
302 Process.setThreadGroupAndCpuset(AnimationThread.get().getThreadId(),
303 Process.THREAD_GROUP_TOP_APP);
Jorim Jaggi21c39a72017-10-20 15:47:51 +0200304 Process.setThreadGroupAndCpuset(SurfaceAnimationThread.get().getThreadId(),
305 Process.THREAD_GROUP_TOP_APP);
Craig Mautner4f67ba62012-08-02 11:23:00 -0700306 }
307
Jeff Brown4ccb8232014-01-16 22:16:42 -0800308 @Override
Jeff Brown4ccb8232014-01-16 22:16:42 -0800309 public void onStart() {
Michael Wright1c9977b2016-07-12 13:30:10 -0700310 // We need to pre-load the persistent data store so it's ready before the default display
311 // adapter is up so that we have it's configuration. We could load it lazily, but since
312 // we're going to have to read it in eventually we may as well do it here rather than after
Santos Cordonc22c5632017-06-21 16:03:49 -0700313 // we've waited for the display to register itself with us.
Michael Wrighteedcbf12017-08-16 23:14:54 +0100314 synchronized(mSyncRoot) {
315 mPersistentDataStore.loadIfNeeded();
316 loadStableDisplayValuesLocked();
317 }
Santos Cordonc22c5632017-06-21 16:03:49 -0700318 mHandler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS);
Jeff Brown4ccb8232014-01-16 22:16:42 -0800319
320 publishBinderService(Context.DISPLAY_SERVICE, new BinderService(),
321 true /*allowIsolated*/);
322 publishLocalService(DisplayManagerInternal.class, new LocalService());
Justin Klaassen22eb1992016-07-11 20:52:23 -0700323 publishLocalService(DisplayTransformManager.class, new DisplayTransformManager());
Jeff Brown4ccb8232014-01-16 22:16:42 -0800324 }
325
326 @Override
327 public void onBootPhase(int phase) {
328 if (phase == PHASE_WAIT_FOR_DEFAULT_DISPLAY) {
329 synchronized (mSyncRoot) {
Santos Cordonc22c5632017-06-21 16:03:49 -0700330 long timeout = SystemClock.uptimeMillis()
331 + mInjector.getDefaultDisplayDelayTimeout();
332 while (mLogicalDisplays.get(Display.DEFAULT_DISPLAY) == null ||
333 mVirtualDisplayAdapter == null) {
Jeff Brown4ccb8232014-01-16 22:16:42 -0800334 long delay = timeout - SystemClock.uptimeMillis();
335 if (delay <= 0) {
336 throw new RuntimeException("Timeout waiting for default display "
Santos Cordonc22c5632017-06-21 16:03:49 -0700337 + "to be initialized. DefaultDisplay="
338 + mLogicalDisplays.get(Display.DEFAULT_DISPLAY)
339 + ", mVirtualDisplayAdapter=" + mVirtualDisplayAdapter);
Jeff Brown4ccb8232014-01-16 22:16:42 -0800340 }
341 if (DEBUG) {
342 Slog.d(TAG, "waitForDefaultDisplay: waiting, timeout=" + delay);
343 }
344 try {
345 mSyncRoot.wait(delay);
346 } catch (InterruptedException ex) {
347 }
Jeff Brownbd6e1502012-08-28 03:27:37 -0700348 }
349 }
350 }
Jeff Brownbd6e1502012-08-28 03:27:37 -0700351 }
352
Michael Wrighteef0e132017-11-21 17:57:52 +0000353 @Override
354 public void onSwitchUser(@UserIdInt int newUserId) {
355 final int userSerial = getUserManager().getUserSerialNumber(newUserId);
356 synchronized (mSyncRoot) {
357 if (mCurrentUserId != newUserId) {
358 mCurrentUserId = newUserId;
359 BrightnessConfiguration config =
360 mPersistentDataStore.getBrightnessConfiguration(userSerial);
361 mDisplayPowerController.setBrightnessConfiguration(config);
362 }
Peeyush Agarwalcc155dd2018-01-10 11:51:33 +0000363 mDisplayPowerController.onSwitchUser(newUserId);
Michael Wrighteef0e132017-11-21 17:57:52 +0000364 }
365 }
366
Jeff Brown4ccb8232014-01-16 22:16:42 -0800367 // TODO: Use dependencies or a boot phase
368 public void windowManagerAndInputReady() {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700369 synchronized (mSyncRoot) {
Jeff Brown4ccb8232014-01-16 22:16:42 -0800370 mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
371 mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);
Craig Mautner65d11b32012-10-01 13:59:52 -0700372 scheduleTraversalLocked(false);
Jeff Brownd728bf52012-09-08 18:05:28 -0700373 }
374 }
375
376 /**
Jeff Brownbd6e1502012-08-28 03:27:37 -0700377 * Called when the system is ready to go.
378 */
379 public void systemReady(boolean safeMode, boolean onlyCore) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700380 synchronized (mSyncRoot) {
Jeff Brownbd6e1502012-08-28 03:27:37 -0700381 mSafeMode = safeMode;
382 mOnlyCore = onlyCore;
383 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700384
Jeff Brownbd6e1502012-08-28 03:27:37 -0700385 mHandler.sendEmptyMessage(MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS);
Kenny Guy22bd0442017-10-26 00:15:54 +0100386 mHandler.sendEmptyMessage(MSG_REGISTER_BRIGHTNESS_TRACKER);
Jeff Brownbd6e1502012-08-28 03:27:37 -0700387 }
388
Santos Cordonee8931e2017-04-05 10:31:15 -0700389 @VisibleForTesting
390 Handler getDisplayHandler() {
391 return mHandler;
392 }
393
Michael Wrighteedcbf12017-08-16 23:14:54 +0100394 private void loadStableDisplayValuesLocked() {
395 final Point size = mPersistentDataStore.getStableDisplaySize();
396 if (size.x > 0 && size.y > 0) {
397 // Just set these values directly so we don't write the display persistent data again
398 // unnecessarily
399 mStableDisplaySize.set(size.x, size.y);
400 } else {
401 final Resources res = mContext.getResources();
402 final int width = res.getInteger(
403 com.android.internal.R.integer.config_stableDeviceDisplayWidth);
404 final int height = res.getInteger(
405 com.android.internal.R.integer.config_stableDeviceDisplayHeight);
406 if (width > 0 && height > 0) {
407 setStableDisplaySizeLocked(width, height);
408 }
409 }
410 }
411
412 private Point getStableDisplaySizeInternal() {
413 Point r = new Point();
414 synchronized (mSyncRoot) {
415 if (mStableDisplaySize.x > 0 && mStableDisplaySize.y > 0) {
416 r.set(mStableDisplaySize.x, mStableDisplaySize.y);
417 }
418 }
419 return r;
420 }
421
Jeff Brown4ccb8232014-01-16 22:16:42 -0800422 private void registerDisplayTransactionListenerInternal(
423 DisplayTransactionListener listener) {
Jeff Brown7f3994e2012-12-04 14:04:28 -0800424 // List is self-synchronized copy-on-write.
425 mDisplayTransactionListeners.add(listener);
426 }
427
Jeff Brown4ccb8232014-01-16 22:16:42 -0800428 private void unregisterDisplayTransactionListenerInternal(
429 DisplayTransactionListener listener) {
Jeff Brown7f3994e2012-12-04 14:04:28 -0800430 // List is self-synchronized copy-on-write.
431 mDisplayTransactionListeners.remove(listener);
432 }
433
Jeff Brown4ccb8232014-01-16 22:16:42 -0800434 private void setDisplayInfoOverrideFromWindowManagerInternal(
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700435 int displayId, DisplayInfo info) {
436 synchronized (mSyncRoot) {
Jeff Brownbd6e1502012-08-28 03:27:37 -0700437 LogicalDisplay display = mLogicalDisplays.get(displayId);
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700438 if (display != null) {
Jeff Brownef981a42013-08-07 14:13:37 -0700439 if (display.setDisplayInfoOverrideFromWindowManagerLocked(info)) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700440 sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_CHANGED);
Craig Mautner65d11b32012-10-01 13:59:52 -0700441 scheduleTraversalLocked(false);
Jeff Brownbd6e1502012-08-28 03:27:37 -0700442 }
Jeff Brownbd6e1502012-08-28 03:27:37 -0700443 }
444 }
445 }
446
Andrii Kuliancd097992017-03-23 18:31:59 -0700447 /**
448 * @see DisplayManagerInternal#getNonOverrideDisplayInfo(int, DisplayInfo)
449 */
450 private void getNonOverrideDisplayInfoInternal(int displayId, DisplayInfo outInfo) {
451 synchronized (mSyncRoot) {
452 final LogicalDisplay display = mLogicalDisplays.get(displayId);
453 if (display != null) {
454 display.getNonOverrideDisplayInfoLocked(outInfo);
455 }
456 }
457 }
458
Santos Cordonee8931e2017-04-05 10:31:15 -0700459 @VisibleForTesting
460 void performTraversalInTransactionFromWindowManagerInternal() {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700461 synchronized (mSyncRoot) {
462 if (!mPendingTraversal) {
463 return;
Jeff Brownbd6e1502012-08-28 03:27:37 -0700464 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700465 mPendingTraversal = false;
466
467 performTraversalInTransactionLocked();
Jeff Brownbd6e1502012-08-28 03:27:37 -0700468 }
Jeff Brown7f3994e2012-12-04 14:04:28 -0800469
470 // List is self-synchronized copy-on-write.
471 for (DisplayTransactionListener listener : mDisplayTransactionListeners) {
472 listener.onDisplayTransaction();
473 }
Jeff Brownbd6e1502012-08-28 03:27:37 -0700474 }
475
Jeff Brown5d6443b2015-04-10 20:15:01 -0700476 private void requestGlobalDisplayStateInternal(int state, int brightness) {
477 if (state == Display.STATE_UNKNOWN) {
478 state = Display.STATE_ON;
479 }
480 if (state == Display.STATE_OFF) {
481 brightness = PowerManager.BRIGHTNESS_OFF;
482 } else if (brightness < 0) {
483 brightness = PowerManager.BRIGHTNESS_DEFAULT;
484 } else if (brightness > PowerManager.BRIGHTNESS_ON) {
485 brightness = PowerManager.BRIGHTNESS_ON;
486 }
487
Jeff Browne75926d2014-09-18 15:24:49 -0700488 synchronized (mTempDisplayStateWorkQueue) {
489 try {
490 // Update the display state within the lock.
Jeff Brown8e5d33e2015-06-10 13:05:50 -0700491 // Note that we do not need to schedule traversals here although it
492 // may happen as a side-effect of displays changing state.
Jeff Browne75926d2014-09-18 15:24:49 -0700493 synchronized (mSyncRoot) {
Jeff Brown5d6443b2015-04-10 20:15:01 -0700494 if (mGlobalDisplayState == state
495 && mGlobalDisplayBrightness == brightness) {
496 return; // no change
Jeff Browne75926d2014-09-18 15:24:49 -0700497 }
Jeff Brown5d6443b2015-04-10 20:15:01 -0700498
499 Trace.traceBegin(Trace.TRACE_TAG_POWER, "requestGlobalDisplayState("
500 + Display.stateToString(state)
501 + ", brightness=" + brightness + ")");
502 mGlobalDisplayState = state;
503 mGlobalDisplayBrightness = brightness;
Jeff Brown8e5d33e2015-06-10 13:05:50 -0700504 applyGlobalDisplayStateLocked(mTempDisplayStateWorkQueue);
Jeff Browne75926d2014-09-18 15:24:49 -0700505 }
506
507 // Setting the display power state can take hundreds of milliseconds
508 // to complete so we defer the most expensive part of the work until
509 // after we have exited the critical section to avoid blocking other
510 // threads for a long time.
511 for (int i = 0; i < mTempDisplayStateWorkQueue.size(); i++) {
512 mTempDisplayStateWorkQueue.get(i).run();
513 }
Jeff Brown5d6443b2015-04-10 20:15:01 -0700514 Trace.traceEnd(Trace.TRACE_TAG_POWER);
Jeff Browne75926d2014-09-18 15:24:49 -0700515 } finally {
516 mTempDisplayStateWorkQueue.clear();
Jeff Brown9e316a12012-10-08 19:17:06 -0700517 }
518 }
519 }
520
Jeff Brown4ccb8232014-01-16 22:16:42 -0800521 private DisplayInfo getDisplayInfoInternal(int displayId, int callingUid) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700522 synchronized (mSyncRoot) {
Jeff Brown4ccb8232014-01-16 22:16:42 -0800523 LogicalDisplay display = mLogicalDisplays.get(displayId);
524 if (display != null) {
525 DisplayInfo info = display.getDisplayInfoLocked();
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800526 if (info.hasAccess(callingUid)
527 || isUidPresentOnDisplayInternal(callingUid, displayId)) {
Jeff Brown4ccb8232014-01-16 22:16:42 -0800528 return info;
529 }
530 }
531 return null;
532 }
533 }
534
535 private int[] getDisplayIdsInternal(int callingUid) {
536 synchronized (mSyncRoot) {
537 final int count = mLogicalDisplays.size();
538 int[] displayIds = new int[count];
539 int n = 0;
540 for (int i = 0; i < count; i++) {
541 LogicalDisplay display = mLogicalDisplays.valueAt(i);
542 DisplayInfo info = display.getDisplayInfoLocked();
543 if (info.hasAccess(callingUid)) {
544 displayIds[n++] = mLogicalDisplays.keyAt(i);
545 }
546 }
547 if (n != count) {
548 displayIds = Arrays.copyOfRange(displayIds, 0, n);
549 }
550 return displayIds;
551 }
552 }
553
554 private void registerCallbackInternal(IDisplayManagerCallback callback, int callingPid) {
555 synchronized (mSyncRoot) {
Jeff Brownbd6e1502012-08-28 03:27:37 -0700556 if (mCallbacks.get(callingPid) != null) {
557 throw new SecurityException("The calling process has already "
558 + "registered an IDisplayManagerCallback.");
Jeff Brown64a55af2012-08-26 02:47:39 -0700559 }
560
Jeff Brownbd6e1502012-08-28 03:27:37 -0700561 CallbackRecord record = new CallbackRecord(callingPid, callback);
562 try {
563 IBinder binder = callback.asBinder();
564 binder.linkToDeath(record, 0);
565 } catch (RemoteException ex) {
566 // give up
567 throw new RuntimeException(ex);
568 }
569
570 mCallbacks.put(callingPid, record);
571 }
572 }
573
Jeff Brownce468a32013-11-21 16:42:03 -0800574 private void onCallbackDied(CallbackRecord record) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700575 synchronized (mSyncRoot) {
Jeff Brownce468a32013-11-21 16:42:03 -0800576 mCallbacks.remove(record.mPid);
577 stopWifiDisplayScanLocked(record);
Jeff Brownbd6e1502012-08-28 03:27:37 -0700578 }
579 }
580
Jeff Brown4ccb8232014-01-16 22:16:42 -0800581 private void startWifiDisplayScanInternal(int callingPid) {
582 synchronized (mSyncRoot) {
583 CallbackRecord record = mCallbacks.get(callingPid);
584 if (record == null) {
585 throw new IllegalStateException("The calling process has not "
586 + "registered an IDisplayManagerCallback.");
Jeff Browne08ae382012-09-07 20:36:36 -0700587 }
Jeff Brown4ccb8232014-01-16 22:16:42 -0800588 startWifiDisplayScanLocked(record);
Jeff Browne08ae382012-09-07 20:36:36 -0700589 }
590 }
591
Jeff Brownce468a32013-11-21 16:42:03 -0800592 private void startWifiDisplayScanLocked(CallbackRecord record) {
593 if (!record.mWifiDisplayScanRequested) {
594 record.mWifiDisplayScanRequested = true;
595 if (mWifiDisplayScanRequestCount++ == 0) {
596 if (mWifiDisplayAdapter != null) {
597 mWifiDisplayAdapter.requestStartScanLocked();
598 }
599 }
600 }
601 }
602
Jeff Brown4ccb8232014-01-16 22:16:42 -0800603 private void stopWifiDisplayScanInternal(int callingPid) {
604 synchronized (mSyncRoot) {
605 CallbackRecord record = mCallbacks.get(callingPid);
606 if (record == null) {
607 throw new IllegalStateException("The calling process has not "
608 + "registered an IDisplayManagerCallback.");
Jeff Brownce468a32013-11-21 16:42:03 -0800609 }
Jeff Brown4ccb8232014-01-16 22:16:42 -0800610 stopWifiDisplayScanLocked(record);
Jeff Brownce468a32013-11-21 16:42:03 -0800611 }
612 }
613
614 private void stopWifiDisplayScanLocked(CallbackRecord record) {
615 if (record.mWifiDisplayScanRequested) {
616 record.mWifiDisplayScanRequested = false;
617 if (--mWifiDisplayScanRequestCount == 0) {
618 if (mWifiDisplayAdapter != null) {
619 mWifiDisplayAdapter.requestStopScanLocked();
620 }
621 } else if (mWifiDisplayScanRequestCount < 0) {
Dianne Hackborn8d051722014-10-01 14:59:58 -0700622 Slog.wtf(TAG, "mWifiDisplayScanRequestCount became negative: "
Jeff Brownce468a32013-11-21 16:42:03 -0800623 + mWifiDisplayScanRequestCount);
624 mWifiDisplayScanRequestCount = 0;
625 }
626 }
627 }
628
Jeff Brown4ccb8232014-01-16 22:16:42 -0800629 private void connectWifiDisplayInternal(String address) {
630 synchronized (mSyncRoot) {
631 if (mWifiDisplayAdapter != null) {
632 mWifiDisplayAdapter.requestConnectLocked(address);
Jeff Browne08ae382012-09-07 20:36:36 -0700633 }
Jeff Browne08ae382012-09-07 20:36:36 -0700634 }
635 }
636
Jeff Brown4ccb8232014-01-16 22:16:42 -0800637 private void pauseWifiDisplayInternal() {
638 synchronized (mSyncRoot) {
639 if (mWifiDisplayAdapter != null) {
640 mWifiDisplayAdapter.requestPauseLocked();
Chong Zhang1f3ecaa2013-05-03 15:55:36 -0700641 }
Chong Zhang1f3ecaa2013-05-03 15:55:36 -0700642 }
643 }
644
Jeff Brown4ccb8232014-01-16 22:16:42 -0800645 private void resumeWifiDisplayInternal() {
646 synchronized (mSyncRoot) {
647 if (mWifiDisplayAdapter != null) {
648 mWifiDisplayAdapter.requestResumeLocked();
Chong Zhang1f3ecaa2013-05-03 15:55:36 -0700649 }
Chong Zhang1f3ecaa2013-05-03 15:55:36 -0700650 }
651 }
652
Jeff Brown4ccb8232014-01-16 22:16:42 -0800653 private void disconnectWifiDisplayInternal() {
654 synchronized (mSyncRoot) {
655 if (mWifiDisplayAdapter != null) {
656 mWifiDisplayAdapter.requestDisconnectLocked();
Jeff Browne08ae382012-09-07 20:36:36 -0700657 }
Jeff Browne08ae382012-09-07 20:36:36 -0700658 }
659 }
660
Jeff Brown4ccb8232014-01-16 22:16:42 -0800661 private void renameWifiDisplayInternal(String address, String alias) {
662 synchronized (mSyncRoot) {
663 if (mWifiDisplayAdapter != null) {
664 mWifiDisplayAdapter.requestRenameLocked(address, alias);
Jeff Brown89d55462012-09-19 11:33:42 -0700665 }
Jeff Brown89d55462012-09-19 11:33:42 -0700666 }
667 }
668
Jeff Brown4ccb8232014-01-16 22:16:42 -0800669 private void forgetWifiDisplayInternal(String address) {
670 synchronized (mSyncRoot) {
671 if (mWifiDisplayAdapter != null) {
672 mWifiDisplayAdapter.requestForgetLocked(address);
Jeff Brown89d55462012-09-19 11:33:42 -0700673 }
Jeff Brown89d55462012-09-19 11:33:42 -0700674 }
675 }
676
Jeff Brown4ccb8232014-01-16 22:16:42 -0800677 private WifiDisplayStatus getWifiDisplayStatusInternal() {
678 synchronized (mSyncRoot) {
679 if (mWifiDisplayAdapter != null) {
680 return mWifiDisplayAdapter.getWifiDisplayStatusLocked();
Jeff Browne08ae382012-09-07 20:36:36 -0700681 }
Jeff Brown4ccb8232014-01-16 22:16:42 -0800682 return new WifiDisplayStatus();
Jeff Browne08ae382012-09-07 20:36:36 -0700683 }
684 }
685
Michael Wright1c9977b2016-07-12 13:30:10 -0700686 private void requestColorModeInternal(int displayId, int colorMode) {
Michael Wright58e829f2015-09-15 00:13:26 +0100687 synchronized (mSyncRoot) {
688 LogicalDisplay display = mLogicalDisplays.get(displayId);
689 if (display != null &&
Michael Wright1c9977b2016-07-12 13:30:10 -0700690 display.getRequestedColorModeLocked() != colorMode) {
691 display.setRequestedColorModeLocked(colorMode);
Michael Wright58e829f2015-09-15 00:13:26 +0100692 scheduleTraversalLocked(false);
693 }
694 }
695 }
696
Michael Wright75ee9fc2014-09-01 19:55:22 -0700697 private int createVirtualDisplayInternal(IVirtualDisplayCallback callback,
Santos Cordonee8931e2017-04-05 10:31:15 -0700698 IMediaProjection projection, int callingUid, String packageName, String name, int width,
699 int height, int densityDpi, Surface surface, int flags, String uniqueId) {
Jeff Brown4ccb8232014-01-16 22:16:42 -0800700 synchronized (mSyncRoot) {
701 if (mVirtualDisplayAdapter == null) {
702 Slog.w(TAG, "Rejecting request to create private virtual display "
703 + "because the virtual display adapter is not available.");
704 return -1;
Jeff Brown7d00aff2013-08-02 19:03:49 -0700705 }
Jeff Brown4ccb8232014-01-16 22:16:42 -0800706
707 DisplayDevice device = mVirtualDisplayAdapter.createVirtualDisplayLocked(
Santos Cordonee8931e2017-04-05 10:31:15 -0700708 callback, projection, callingUid, packageName, name, width, height, densityDpi,
709 surface, flags, uniqueId);
Jeff Brown4ccb8232014-01-16 22:16:42 -0800710 if (device == null) {
711 return -1;
Jeff Brown7d00aff2013-08-02 19:03:49 -0700712 }
Jeff Browna506a6e2013-06-04 00:02:38 -0700713
Jeff Brown4ccb8232014-01-16 22:16:42 -0800714 handleDisplayDeviceAddedLocked(device);
715 LogicalDisplay display = findLogicalDisplayForDeviceLocked(device);
716 if (display != null) {
717 return display.getDisplayIdLocked();
Jeff Browna506a6e2013-06-04 00:02:38 -0700718 }
Jeff Brown4ccb8232014-01-16 22:16:42 -0800719
720 // Something weird happened and the logical display was not created.
721 Slog.w(TAG, "Rejecting request to create virtual display "
722 + "because the logical display was not created.");
Michael Wright75ee9fc2014-09-01 19:55:22 -0700723 mVirtualDisplayAdapter.releaseVirtualDisplayLocked(callback.asBinder());
Jeff Brown4ccb8232014-01-16 22:16:42 -0800724 handleDisplayDeviceRemovedLocked(device);
Jeff Browna506a6e2013-06-04 00:02:38 -0700725 }
726 return -1;
727 }
728
Michael Wright01e840f2014-06-26 16:03:25 -0700729 private void resizeVirtualDisplayInternal(IBinder appToken,
730 int width, int height, int densityDpi) {
731 synchronized (mSyncRoot) {
732 if (mVirtualDisplayAdapter == null) {
733 return;
734 }
735
736 mVirtualDisplayAdapter.resizeVirtualDisplayLocked(appToken, width, height, densityDpi);
737 }
738 }
739
Jeff Brown92207df2014-04-16 13:16:07 -0700740 private void setVirtualDisplaySurfaceInternal(IBinder appToken, Surface surface) {
741 synchronized (mSyncRoot) {
742 if (mVirtualDisplayAdapter == null) {
743 return;
744 }
745
746 mVirtualDisplayAdapter.setVirtualDisplaySurfaceLocked(appToken, surface);
747 }
748 }
749
Jeff Brown4ccb8232014-01-16 22:16:42 -0800750 private void releaseVirtualDisplayInternal(IBinder appToken) {
751 synchronized (mSyncRoot) {
752 if (mVirtualDisplayAdapter == null) {
753 return;
Jeff Browna506a6e2013-06-04 00:02:38 -0700754 }
Jeff Browna506a6e2013-06-04 00:02:38 -0700755
Jeff Brown4ccb8232014-01-16 22:16:42 -0800756 DisplayDevice device =
757 mVirtualDisplayAdapter.releaseVirtualDisplayLocked(appToken);
758 if (device != null) {
759 handleDisplayDeviceRemovedLocked(device);
Jeff Browna506a6e2013-06-04 00:02:38 -0700760 }
761 }
Jeff Browna506a6e2013-06-04 00:02:38 -0700762 }
763
Santos Cordonc22c5632017-06-21 16:03:49 -0700764 private void registerDefaultDisplayAdapters() {
765 // Register default display adapters.
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700766 synchronized (mSyncRoot) {
Santos Cordonc22c5632017-06-21 16:03:49 -0700767 // main display adapter
Mike Lockwoode63f6f72013-11-15 11:01:47 -0800768 registerDisplayAdapterLocked(new LocalDisplayAdapter(
769 mSyncRoot, mContext, mHandler, mDisplayAdapterListener));
Santos Cordonc22c5632017-06-21 16:03:49 -0700770
771 // Standalone VR devices rely on a virtual display as their primary display for
772 // 2D UI. We register virtual display adapter along side the main display adapter
773 // here so that it is ready by the time the system sends the home Intent for
774 // early apps like SetupWizard/Launcher. In particular, SUW is displayed using
775 // the virtual display inside VR before any VR-specific apps even run.
776 mVirtualDisplayAdapter = mInjector.getVirtualDisplayAdapter(mSyncRoot, mContext,
777 mHandler, mDisplayAdapterListener);
778 if (mVirtualDisplayAdapter != null) {
779 registerDisplayAdapterLocked(mVirtualDisplayAdapter);
780 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700781 }
782 }
783
784 private void registerAdditionalDisplayAdapters() {
785 synchronized (mSyncRoot) {
786 if (shouldRegisterNonEssentialDisplayAdaptersLocked()) {
Jeff Brown89d55462012-09-19 11:33:42 -0700787 registerOverlayDisplayAdapterLocked();
788 registerWifiDisplayAdapterLocked();
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700789 }
790 }
791 }
792
Jeff Brown89d55462012-09-19 11:33:42 -0700793 private void registerOverlayDisplayAdapterLocked() {
794 registerDisplayAdapterLocked(new OverlayDisplayAdapter(
795 mSyncRoot, mContext, mHandler, mDisplayAdapterListener, mUiHandler));
796 }
797
798 private void registerWifiDisplayAdapterLocked() {
799 if (mContext.getResources().getBoolean(
Jeff Brownbbd28a22012-09-20 16:47:15 -0700800 com.android.internal.R.bool.config_enableWifiDisplay)
801 || SystemProperties.getInt(FORCE_WIFI_DISPLAY_ENABLE, -1) == 1) {
Jeff Brown89d55462012-09-19 11:33:42 -0700802 mWifiDisplayAdapter = new WifiDisplayAdapter(
803 mSyncRoot, mContext, mHandler, mDisplayAdapterListener,
804 mPersistentDataStore);
805 registerDisplayAdapterLocked(mWifiDisplayAdapter);
806 }
807 }
808
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700809 private boolean shouldRegisterNonEssentialDisplayAdaptersLocked() {
810 // In safe mode, we disable non-essential display adapters to give the user
811 // an opportunity to fix broken settings or other problems that might affect
812 // system stability.
813 // In only-core mode, we disable non-essential display adapters to minimize
814 // the number of dependencies that are started while in this mode and to
815 // prevent problems that might occur due to the device being encrypted.
816 return !mSafeMode && !mOnlyCore;
817 }
818
819 private void registerDisplayAdapterLocked(DisplayAdapter adapter) {
820 mDisplayAdapters.add(adapter);
821 adapter.registerLocked();
822 }
823
Jeff Brownbd6e1502012-08-28 03:27:37 -0700824 private void handleDisplayDeviceAdded(DisplayDevice device) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700825 synchronized (mSyncRoot) {
Jeff Browna506a6e2013-06-04 00:02:38 -0700826 handleDisplayDeviceAddedLocked(device);
Jeff Brownbd6e1502012-08-28 03:27:37 -0700827 }
828 }
829
Jeff Browna506a6e2013-06-04 00:02:38 -0700830 private void handleDisplayDeviceAddedLocked(DisplayDevice device) {
Jeff Brown10acf6d2015-04-14 14:20:47 -0700831 DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
Jeff Browna506a6e2013-06-04 00:02:38 -0700832 if (mDisplayDevices.contains(device)) {
Jeff Brown10acf6d2015-04-14 14:20:47 -0700833 Slog.w(TAG, "Attempted to add already added display device: " + info);
Jeff Browna506a6e2013-06-04 00:02:38 -0700834 return;
835 }
836
Jeff Brown10acf6d2015-04-14 14:20:47 -0700837 Slog.i(TAG, "Display device added: " + info);
838 device.mDebugLastLoggedDeviceInfo = info;
Jeff Browna506a6e2013-06-04 00:02:38 -0700839
840 mDisplayDevices.add(device);
Michael Wright1c9977b2016-07-12 13:30:10 -0700841 LogicalDisplay display = addLogicalDisplayLocked(device);
Jeff Brown0033a862014-10-08 12:06:39 -0700842 Runnable work = updateDisplayStateLocked(device);
843 if (work != null) {
844 work.run();
845 }
Jeff Browna506a6e2013-06-04 00:02:38 -0700846 scheduleTraversalLocked(false);
847 }
848
Jeff Brownbd6e1502012-08-28 03:27:37 -0700849 private void handleDisplayDeviceChanged(DisplayDevice device) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700850 synchronized (mSyncRoot) {
Jeff Brown10acf6d2015-04-14 14:20:47 -0700851 DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
Jeff Brownbd6e1502012-08-28 03:27:37 -0700852 if (!mDisplayDevices.contains(device)) {
Jeff Brown10acf6d2015-04-14 14:20:47 -0700853 Slog.w(TAG, "Attempted to change non-existent display device: " + info);
Jeff Brownbd6e1502012-08-28 03:27:37 -0700854 return;
855 }
856
Jeff Brown10acf6d2015-04-14 14:20:47 -0700857 int diff = device.mDebugLastLoggedDeviceInfo.diff(info);
858 if (diff == DisplayDeviceInfo.DIFF_STATE) {
859 Slog.i(TAG, "Display device changed state: \"" + info.name
860 + "\", " + Display.stateToString(info.state));
861 } else if (diff != 0) {
862 Slog.i(TAG, "Display device changed: " + info);
863 }
Michael Wright1c9977b2016-07-12 13:30:10 -0700864 if ((diff & DisplayDeviceInfo.DIFF_COLOR_MODE) != 0) {
865 try {
866 mPersistentDataStore.setColorMode(device, info.colorMode);
867 } finally {
868 mPersistentDataStore.saveIfNeeded();
869 }
870 }
Jeff Brown10acf6d2015-04-14 14:20:47 -0700871 device.mDebugLastLoggedDeviceInfo = info;
Jeff Browne87bf032012-09-20 18:30:13 -0700872
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700873 device.applyPendingDisplayDeviceInfoChangesLocked();
874 if (updateLogicalDisplaysLocked()) {
Craig Mautner65d11b32012-10-01 13:59:52 -0700875 scheduleTraversalLocked(false);
Jeff Brown64a55af2012-08-26 02:47:39 -0700876 }
877 }
878 }
879
Jeff Brownbd6e1502012-08-28 03:27:37 -0700880 private void handleDisplayDeviceRemoved(DisplayDevice device) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700881 synchronized (mSyncRoot) {
Jeff Browna506a6e2013-06-04 00:02:38 -0700882 handleDisplayDeviceRemovedLocked(device);
883 }
884 }
Jeff Brown8e5d33e2015-06-10 13:05:50 -0700885
Jeff Browna506a6e2013-06-04 00:02:38 -0700886 private void handleDisplayDeviceRemovedLocked(DisplayDevice device) {
Jeff Brown10acf6d2015-04-14 14:20:47 -0700887 DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
Jeff Browna506a6e2013-06-04 00:02:38 -0700888 if (!mDisplayDevices.remove(device)) {
Jeff Brown10acf6d2015-04-14 14:20:47 -0700889 Slog.w(TAG, "Attempted to remove non-existent display device: " + info);
Jeff Browna506a6e2013-06-04 00:02:38 -0700890 return;
891 }
892
Jeff Brown10acf6d2015-04-14 14:20:47 -0700893 Slog.i(TAG, "Display device removed: " + info);
894 device.mDebugLastLoggedDeviceInfo = info;
Jeff Browna506a6e2013-06-04 00:02:38 -0700895
Jeff Browna506a6e2013-06-04 00:02:38 -0700896 updateLogicalDisplaysLocked();
897 scheduleTraversalLocked(false);
898 }
899
Jeff Brown8e5d33e2015-06-10 13:05:50 -0700900 private void applyGlobalDisplayStateLocked(List<Runnable> workQueue) {
Jeff Browna506a6e2013-06-04 00:02:38 -0700901 final int count = mDisplayDevices.size();
902 for (int i = 0; i < count; i++) {
903 DisplayDevice device = mDisplayDevices.get(i);
Jeff Browne75926d2014-09-18 15:24:49 -0700904 Runnable runnable = updateDisplayStateLocked(device);
905 if (runnable != null) {
906 workQueue.add(runnable);
907 }
Jeff Browna506a6e2013-06-04 00:02:38 -0700908 }
909 }
910
Jeff Browne75926d2014-09-18 15:24:49 -0700911 private Runnable updateDisplayStateLocked(DisplayDevice device) {
Jeff Browna506a6e2013-06-04 00:02:38 -0700912 // Blank or unblank the display immediately to match the state requested
Jeff Brown037c33e2014-04-09 00:31:55 -0700913 // by the display power controller (if known).
Jeff Browna506a6e2013-06-04 00:02:38 -0700914 DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
915 if ((info.flags & DisplayDeviceInfo.FLAG_NEVER_BLANK) == 0) {
Jeff Brown5d6443b2015-04-10 20:15:01 -0700916 return device.requestDisplayStateLocked(mGlobalDisplayState, mGlobalDisplayBrightness);
Craig Mautner4f67ba62012-08-02 11:23:00 -0700917 }
Jeff Browne75926d2014-09-18 15:24:49 -0700918 return null;
Craig Mautner4f67ba62012-08-02 11:23:00 -0700919 }
920
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700921 // Adds a new logical display based on the given display device.
922 // Sends notifications if needed.
Michael Wright1c9977b2016-07-12 13:30:10 -0700923 private LogicalDisplay addLogicalDisplayLocked(DisplayDevice device) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700924 DisplayDeviceInfo deviceInfo = device.getDisplayDeviceInfoLocked();
925 boolean isDefault = (deviceInfo.flags
926 & DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY) != 0;
927 if (isDefault && mLogicalDisplays.get(Display.DEFAULT_DISPLAY) != null) {
928 Slog.w(TAG, "Ignoring attempt to add a second default display: " + deviceInfo);
929 isDefault = false;
930 }
931
Jeff Brown27f1d672012-10-17 18:32:34 -0700932 if (!isDefault && mSingleDisplayDemoMode) {
933 Slog.i(TAG, "Not creating a logical display for a secondary display "
934 + " because single display demo mode is enabled: " + deviceInfo);
Michael Wright1c9977b2016-07-12 13:30:10 -0700935 return null;
Jeff Brown27f1d672012-10-17 18:32:34 -0700936 }
937
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700938 final int displayId = assignDisplayIdLocked(isDefault);
939 final int layerStack = assignLayerStackLocked(displayId);
940
Jeff Brownd728bf52012-09-08 18:05:28 -0700941 LogicalDisplay display = new LogicalDisplay(displayId, layerStack, device);
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700942 display.updateLocked(mDisplayDevices);
943 if (!display.isValidLocked()) {
944 // This should never happen currently.
945 Slog.w(TAG, "Ignoring display device because the logical display "
946 + "created from it was not considered valid: " + deviceInfo);
Michael Wright1c9977b2016-07-12 13:30:10 -0700947 return null;
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700948 }
949
Michael Wrighteedcbf12017-08-16 23:14:54 +0100950 configureColorModeLocked(display, device);
951 if (isDefault) {
952 recordStableDisplayStatsIfNeededLocked(display);
953 }
954
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700955 mLogicalDisplays.put(displayId, display);
956
957 // Wake up waitForDefaultDisplay.
958 if (isDefault) {
959 mSyncRoot.notifyAll();
960 }
961
962 sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_ADDED);
Michael Wright1c9977b2016-07-12 13:30:10 -0700963 return display;
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700964 }
965
966 private int assignDisplayIdLocked(boolean isDefault) {
967 return isDefault ? Display.DEFAULT_DISPLAY : mNextNonDefaultDisplayId++;
968 }
969
970 private int assignLayerStackLocked(int displayId) {
971 // Currently layer stacks and display ids are the same.
972 // This need not be the case.
973 return displayId;
974 }
975
Michael Wrighteedcbf12017-08-16 23:14:54 +0100976 private void configureColorModeLocked(LogicalDisplay display, DisplayDevice device) {
977 if (display.getPrimaryDisplayDeviceLocked() == device) {
978 int colorMode = mPersistentDataStore.getColorMode(device);
979 if (colorMode == Display.COLOR_MODE_INVALID) {
980 if ((device.getDisplayDeviceInfoLocked().flags
981 & DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY) != 0) {
982 colorMode = mDefaultDisplayDefaultColorMode;
983 } else {
984 colorMode = Display.COLOR_MODE_DEFAULT;
985 }
986 }
987 display.setRequestedColorModeLocked(colorMode);
988 }
989 }
990
991 // If we've never recorded stable device stats for this device before and they aren't
992 // explicitly configured, go ahead and record the stable device stats now based on the status
993 // of the default display at first boot.
994 private void recordStableDisplayStatsIfNeededLocked(LogicalDisplay d) {
995 if (mStableDisplaySize.x <= 0 && mStableDisplaySize.y <= 0) {
996 DisplayInfo info = d.getDisplayInfoLocked();
997 setStableDisplaySizeLocked(info.getNaturalWidth(), info.getNaturalHeight());
998 }
999 }
1000
1001 private void setStableDisplaySizeLocked(int width, int height) {
1002 mStableDisplaySize = new Point(width, height);
1003 try {
1004 mPersistentDataStore.setStableDisplaySize(mStableDisplaySize);
1005 } finally {
1006 mPersistentDataStore.saveIfNeeded();
1007 }
1008 }
1009
Michael Wrighteef0e132017-11-21 17:57:52 +00001010 private void setBrightnessConfigurationForUserInternal(
Kenny Guy05ce8092018-01-17 13:44:20 +00001011 @NonNull BrightnessConfiguration c, @UserIdInt int userId,
1012 @Nullable String packageName) {
Michael Wrighteef0e132017-11-21 17:57:52 +00001013 final int userSerial = getUserManager().getUserSerialNumber(userId);
1014 synchronized (mSyncRoot) {
1015 try {
Kenny Guy05ce8092018-01-17 13:44:20 +00001016 mPersistentDataStore.setBrightnessConfigurationForUser(c, userSerial,
1017 packageName);
Michael Wrighteef0e132017-11-21 17:57:52 +00001018 } finally {
1019 mPersistentDataStore.saveIfNeeded();
1020 }
1021 if (userId == mCurrentUserId) {
1022 mDisplayPowerController.setBrightnessConfiguration(c);
1023 }
1024 }
1025 }
1026
1027 private void loadBrightnessConfiguration() {
1028 synchronized (mSyncRoot) {
1029 final int userSerial = getUserManager().getUserSerialNumber(mCurrentUserId);
1030 BrightnessConfiguration config =
1031 mPersistentDataStore.getBrightnessConfiguration(userSerial);
1032 mDisplayPowerController.setBrightnessConfiguration(config);
1033 }
1034 }
1035
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001036 // Updates all existing logical displays given the current set of display devices.
1037 // Removes invalid logical displays.
1038 // Sends notifications if needed.
1039 private boolean updateLogicalDisplaysLocked() {
1040 boolean changed = false;
1041 for (int i = mLogicalDisplays.size(); i-- > 0; ) {
1042 final int displayId = mLogicalDisplays.keyAt(i);
1043 LogicalDisplay display = mLogicalDisplays.valueAt(i);
1044
1045 mTempDisplayInfo.copyFrom(display.getDisplayInfoLocked());
1046 display.updateLocked(mDisplayDevices);
1047 if (!display.isValidLocked()) {
1048 mLogicalDisplays.removeAt(i);
1049 sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_REMOVED);
1050 changed = true;
1051 } else if (!mTempDisplayInfo.equals(display.getDisplayInfoLocked())) {
1052 sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_CHANGED);
1053 changed = true;
1054 }
1055 }
1056 return changed;
1057 }
1058
1059 private void performTraversalInTransactionLocked() {
Jeff Brownd728bf52012-09-08 18:05:28 -07001060 // Clear all viewports before configuring displays so that we can keep
1061 // track of which ones we have configured.
1062 clearViewportsLocked();
1063
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001064 // Configure each display device.
1065 final int count = mDisplayDevices.size();
1066 for (int i = 0; i < count; i++) {
1067 DisplayDevice device = mDisplayDevices.get(i);
1068 configureDisplayInTransactionLocked(device);
1069 device.performTraversalInTransactionLocked();
1070 }
Jeff Brownd728bf52012-09-08 18:05:28 -07001071
1072 // Tell the input system about these new viewports.
Jeff Brown4ccb8232014-01-16 22:16:42 -08001073 if (mInputManagerInternal != null) {
Jeff Brownd728bf52012-09-08 18:05:28 -07001074 mHandler.sendEmptyMessage(MSG_UPDATE_VIEWPORT);
1075 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001076 }
1077
Michael Wright3f145a22014-07-22 19:46:03 -07001078 private void setDisplayPropertiesInternal(int displayId, boolean hasContent,
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -07001079 float requestedRefreshRate, int requestedModeId, boolean inTraversal) {
Craig Mautner722285e2012-09-07 13:55:58 -07001080 synchronized (mSyncRoot) {
1081 LogicalDisplay display = mLogicalDisplays.get(displayId);
Michael Wright3f145a22014-07-22 19:46:03 -07001082 if (display == null) {
1083 return;
1084 }
1085 if (display.hasContentLocked() != hasContent) {
Jeff Brown33041bd2013-08-02 21:11:14 -07001086 if (DEBUG) {
1087 Slog.d(TAG, "Display " + displayId + " hasContent flag changed: "
1088 + "hasContent=" + hasContent + ", inTraversal=" + inTraversal);
1089 }
1090
Craig Mautner722285e2012-09-07 13:55:58 -07001091 display.setHasContentLocked(hasContent);
Craig Mautner65d11b32012-10-01 13:59:52 -07001092 scheduleTraversalLocked(inTraversal);
Craig Mautner722285e2012-09-07 13:55:58 -07001093 }
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -07001094 if (requestedModeId == 0 && requestedRefreshRate != 0) {
1095 // Scan supported modes returned by display.getInfo() to find a mode with the same
1096 // size as the default display mode but with the specified refresh rate instead.
1097 requestedModeId = display.getDisplayInfoLocked().findDefaultModeByRefreshRate(
1098 requestedRefreshRate);
1099 }
1100 if (display.getRequestedModeIdLocked() != requestedModeId) {
Michael Wright3f145a22014-07-22 19:46:03 -07001101 if (DEBUG) {
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -07001102 Slog.d(TAG, "Display " + displayId + " switching to mode " + requestedModeId);
Michael Wright3f145a22014-07-22 19:46:03 -07001103 }
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -07001104 display.setRequestedModeIdLocked(requestedModeId);
Michael Wright3f145a22014-07-22 19:46:03 -07001105 scheduleTraversalLocked(inTraversal);
1106 }
Craig Mautner722285e2012-09-07 13:55:58 -07001107 }
Jeff Brownd728bf52012-09-08 18:05:28 -07001108 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001109
Filip Gruszczynskid2e86402015-02-19 13:05:03 -08001110 private void setDisplayOffsetsInternal(int displayId, int x, int y) {
1111 synchronized (mSyncRoot) {
1112 LogicalDisplay display = mLogicalDisplays.get(displayId);
1113 if (display == null) {
1114 return;
1115 }
1116 if (display.getDisplayOffsetXLocked() != x
1117 || display.getDisplayOffsetYLocked() != y) {
1118 if (DEBUG) {
1119 Slog.d(TAG, "Display " + displayId + " burn-in offset set to ("
1120 + x + ", " + y + ")");
1121 }
1122 display.setDisplayOffsetsLocked(x, y);
1123 scheduleTraversalLocked(false);
1124 }
1125 }
1126 }
1127
Andrii Kulianfb1bf692017-01-17 11:17:34 -08001128 // Updates the lists of UIDs that are present on displays.
1129 private void setDisplayAccessUIDsInternal(SparseArray<IntArray> newDisplayAccessUIDs) {
1130 synchronized (mSyncRoot) {
1131 mDisplayAccessUIDs.clear();
1132 for (int i = newDisplayAccessUIDs.size() - 1; i >= 0; i--) {
1133 mDisplayAccessUIDs.append(newDisplayAccessUIDs.keyAt(i),
1134 newDisplayAccessUIDs.valueAt(i));
1135 }
1136 }
1137 }
1138
1139 // Checks if provided UID's content is present on the display and UID has access to it.
1140 private boolean isUidPresentOnDisplayInternal(int uid, int displayId) {
1141 synchronized (mSyncRoot) {
1142 final IntArray displayUIDs = mDisplayAccessUIDs.get(displayId);
1143 return displayUIDs != null && displayUIDs.indexOf(uid) != -1;
1144 }
1145 }
1146
Jeff Brownd728bf52012-09-08 18:05:28 -07001147 private void clearViewportsLocked() {
1148 mDefaultViewport.valid = false;
1149 mExternalTouchViewport.valid = false;
Santos Cordonee8931e2017-04-05 10:31:15 -07001150 mVirtualTouchViewports.clear();
Craig Mautner722285e2012-09-07 13:55:58 -07001151 }
1152
1153 private void configureDisplayInTransactionLocked(DisplayDevice device) {
Jeff Brownd14c8c92014-01-07 18:13:09 -08001154 final DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
1155 final boolean ownContent = (info.flags & DisplayDeviceInfo.FLAG_OWN_CONTENT_ONLY) != 0;
Jeff Browna506a6e2013-06-04 00:02:38 -07001156
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001157 // Find the logical display that the display device is showing.
Jeff Brownd14c8c92014-01-07 18:13:09 -08001158 // Certain displays only ever show their own content.
Craig Mautner722285e2012-09-07 13:55:58 -07001159 LogicalDisplay display = findLogicalDisplayForDeviceLocked(device);
Jeff Brownd14c8c92014-01-07 18:13:09 -08001160 if (!ownContent) {
Jeff Browna506a6e2013-06-04 00:02:38 -07001161 if (display != null && !display.hasContentLocked()) {
1162 // If the display does not have any content of its own, then
1163 // automatically mirror the default logical display contents.
1164 display = null;
1165 }
1166 if (display == null) {
1167 display = mLogicalDisplays.get(Display.DEFAULT_DISPLAY);
1168 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001169 }
1170
1171 // Apply the logical display configuration to the display device.
1172 if (display == null) {
1173 // TODO: no logical display for the device, blank it
Jeff Brownd728bf52012-09-08 18:05:28 -07001174 Slog.w(TAG, "Missing logical display to use for physical display device: "
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001175 + device.getDisplayDeviceInfoLocked());
Jeff Brownd728bf52012-09-08 18:05:28 -07001176 return;
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001177 }
Jeff Brown037c33e2014-04-09 00:31:55 -07001178 display.configureDisplayInTransactionLocked(device, info.state == Display.STATE_OFF);
Jeff Brownd728bf52012-09-08 18:05:28 -07001179
1180 // Update the viewports if needed.
Jeff Brownd728bf52012-09-08 18:05:28 -07001181 if (!mDefaultViewport.valid
1182 && (info.flags & DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY) != 0) {
1183 setViewportLocked(mDefaultViewport, display, device);
1184 }
1185 if (!mExternalTouchViewport.valid
1186 && info.touch == DisplayDeviceInfo.TOUCH_EXTERNAL) {
1187 setViewportLocked(mExternalTouchViewport, display, device);
1188 }
Santos Cordonee8931e2017-04-05 10:31:15 -07001189
1190 if (info.touch == DisplayDeviceInfo.TOUCH_VIRTUAL && !TextUtils.isEmpty(info.uniqueId)) {
1191 final DisplayViewport viewport = getVirtualTouchViewportLocked(info.uniqueId);
1192 setViewportLocked(viewport, display, device);
1193 }
1194 }
1195
1196 /** Gets the virtual device viewport or creates it if not yet created. */
1197 private DisplayViewport getVirtualTouchViewportLocked(@NonNull String uniqueId) {
1198 DisplayViewport viewport;
1199 final int count = mVirtualTouchViewports.size();
1200 for (int i = 0; i < count; i++) {
1201 viewport = mVirtualTouchViewports.get(i);
1202 if (uniqueId.equals(viewport.uniqueId)) {
1203 return viewport;
1204 }
1205 }
1206
1207 viewport = new DisplayViewport();
1208 viewport.uniqueId = uniqueId;
1209 mVirtualTouchViewports.add(viewport);
1210 return viewport;
Jeff Brownd728bf52012-09-08 18:05:28 -07001211 }
1212
1213 private static void setViewportLocked(DisplayViewport viewport,
1214 LogicalDisplay display, DisplayDevice device) {
1215 viewport.valid = true;
1216 viewport.displayId = display.getDisplayIdLocked();
1217 device.populateViewportLocked(viewport);
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001218 }
1219
1220 private LogicalDisplay findLogicalDisplayForDeviceLocked(DisplayDevice device) {
1221 final int count = mLogicalDisplays.size();
1222 for (int i = 0; i < count; i++) {
1223 LogicalDisplay display = mLogicalDisplays.valueAt(i);
1224 if (display.getPrimaryDisplayDeviceLocked() == device) {
1225 return display;
1226 }
1227 }
1228 return null;
1229 }
1230
Jeff Brownbd6e1502012-08-28 03:27:37 -07001231 private void sendDisplayEventLocked(int displayId, int event) {
1232 Message msg = mHandler.obtainMessage(MSG_DELIVER_DISPLAY_EVENT, displayId, event);
1233 mHandler.sendMessage(msg);
1234 }
1235
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001236 // Requests that performTraversalsInTransactionFromWindowManager be called at a
1237 // later time to apply changes to surfaces and displays.
Craig Mautner65d11b32012-10-01 13:59:52 -07001238 private void scheduleTraversalLocked(boolean inTraversal) {
Jeff Brown4ccb8232014-01-16 22:16:42 -08001239 if (!mPendingTraversal && mWindowManagerInternal != null) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001240 mPendingTraversal = true;
Craig Mautner65d11b32012-10-01 13:59:52 -07001241 if (!inTraversal) {
1242 mHandler.sendEmptyMessage(MSG_REQUEST_TRAVERSAL);
1243 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001244 }
1245 }
1246
1247 // Runs on Handler thread.
1248 // Delivers display event notifications to callbacks.
Jeff Brownbd6e1502012-08-28 03:27:37 -07001249 private void deliverDisplayEvent(int displayId, int event) {
1250 if (DEBUG) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001251 Slog.d(TAG, "Delivering display event: displayId="
1252 + displayId + ", event=" + event);
Jeff Brownfa25bf52012-07-23 19:26:30 -07001253 }
Jeff Brownfa25bf52012-07-23 19:26:30 -07001254
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001255 // Grab the lock and copy the callbacks.
Jeff Brownbd6e1502012-08-28 03:27:37 -07001256 final int count;
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001257 synchronized (mSyncRoot) {
Jeff Brownbd6e1502012-08-28 03:27:37 -07001258 count = mCallbacks.size();
1259 mTempCallbacks.clear();
1260 for (int i = 0; i < count; i++) {
1261 mTempCallbacks.add(mCallbacks.valueAt(i));
Craig Mautner4f67ba62012-08-02 11:23:00 -07001262 }
Jeff Brownbd6e1502012-08-28 03:27:37 -07001263 }
Craig Mautner4f67ba62012-08-02 11:23:00 -07001264
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001265 // After releasing the lock, send the notifications out.
Jeff Brownbd6e1502012-08-28 03:27:37 -07001266 for (int i = 0; i < count; i++) {
1267 mTempCallbacks.get(i).notifyDisplayEventAsync(displayId, event);
1268 }
1269 mTempCallbacks.clear();
Craig Mautner4f67ba62012-08-02 11:23:00 -07001270 }
1271
Michael Wrightc39d47a2014-07-08 18:07:36 -07001272 private IMediaProjectionManager getProjectionService() {
1273 if (mProjectionService == null) {
1274 IBinder b = ServiceManager.getService(Context.MEDIA_PROJECTION_SERVICE);
1275 mProjectionService = IMediaProjectionManager.Stub.asInterface(b);
1276 }
1277 return mProjectionService;
1278 }
1279
Michael Wrighteef0e132017-11-21 17:57:52 +00001280 private UserManager getUserManager() {
1281 return mContext.getSystemService(UserManager.class);
1282 }
1283
Jeff Brown4ccb8232014-01-16 22:16:42 -08001284 private void dumpInternal(PrintWriter pw) {
Jeff Brownbd6e1502012-08-28 03:27:37 -07001285 pw.println("DISPLAY MANAGER (dumpsys display)");
Jeff Brownfa25bf52012-07-23 19:26:30 -07001286
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001287 synchronized (mSyncRoot) {
Jeff Brown9e316a12012-10-08 19:17:06 -07001288 pw.println(" mOnlyCode=" + mOnlyCore);
1289 pw.println(" mSafeMode=" + mSafeMode);
1290 pw.println(" mPendingTraversal=" + mPendingTraversal);
Jeff Brown037c33e2014-04-09 00:31:55 -07001291 pw.println(" mGlobalDisplayState=" + Display.stateToString(mGlobalDisplayState));
Jeff Brown9e316a12012-10-08 19:17:06 -07001292 pw.println(" mNextNonDefaultDisplayId=" + mNextNonDefaultDisplayId);
1293 pw.println(" mDefaultViewport=" + mDefaultViewport);
1294 pw.println(" mExternalTouchViewport=" + mExternalTouchViewport);
Santos Cordonee8931e2017-04-05 10:31:15 -07001295 pw.println(" mVirtualTouchViewports=" + mVirtualTouchViewports);
Damien Bargiacchi4364bbf2016-11-01 21:44:20 -07001296 pw.println(" mDefaultDisplayDefaultColorMode=" + mDefaultDisplayDefaultColorMode);
Jeff Brown27f1d672012-10-17 18:32:34 -07001297 pw.println(" mSingleDisplayDemoMode=" + mSingleDisplayDemoMode);
Jeff Brownce468a32013-11-21 16:42:03 -08001298 pw.println(" mWifiDisplayScanRequestCount=" + mWifiDisplayScanRequestCount);
Michael Wrighteedcbf12017-08-16 23:14:54 +01001299 pw.println(" mStableDisplaySize=" + mStableDisplaySize);
1300
Jeff Brown9e316a12012-10-08 19:17:06 -07001301
Jeff Brownbd6e1502012-08-28 03:27:37 -07001302 IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001303 ipw.increaseIndent();
Jeff Brownbd6e1502012-08-28 03:27:37 -07001304
1305 pw.println();
1306 pw.println("Display Adapters: size=" + mDisplayAdapters.size());
Jeff Brown848c2dc2012-08-19 20:18:08 -07001307 for (DisplayAdapter adapter : mDisplayAdapters) {
Jeff Brownbd6e1502012-08-28 03:27:37 -07001308 pw.println(" " + adapter.getName());
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001309 adapter.dumpLocked(ipw);
Jeff Brown848c2dc2012-08-19 20:18:08 -07001310 }
Craig Mautner9de49362012-08-02 14:30:30 -07001311
Jeff Brownbd6e1502012-08-28 03:27:37 -07001312 pw.println();
1313 pw.println("Display Devices: size=" + mDisplayDevices.size());
1314 for (DisplayDevice device : mDisplayDevices) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001315 pw.println(" " + device.getDisplayDeviceInfoLocked());
1316 device.dumpLocked(ipw);
Jeff Brownbd6e1502012-08-28 03:27:37 -07001317 }
1318
1319 final int logicalDisplayCount = mLogicalDisplays.size();
1320 pw.println();
1321 pw.println("Logical Displays: size=" + logicalDisplayCount);
1322 for (int i = 0; i < logicalDisplayCount; i++) {
1323 int displayId = mLogicalDisplays.keyAt(i);
1324 LogicalDisplay display = mLogicalDisplays.valueAt(i);
1325 pw.println(" Display " + displayId + ":");
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001326 display.dumpLocked(ipw);
Jeff Brownbd6e1502012-08-28 03:27:37 -07001327 }
Jeff Brownce468a32013-11-21 16:42:03 -08001328
1329 final int callbackCount = mCallbacks.size();
1330 pw.println();
1331 pw.println("Callbacks: size=" + callbackCount);
1332 for (int i = 0; i < callbackCount; i++) {
1333 CallbackRecord callback = mCallbacks.valueAt(i);
1334 pw.println(" " + i + ": mPid=" + callback.mPid
1335 + ", mWifiDisplayScanRequested=" + callback.mWifiDisplayScanRequested);
1336 }
Jeff Brownad9ef192014-04-08 17:26:30 -07001337
1338 if (mDisplayPowerController != null) {
1339 mDisplayPowerController.dump(pw);
1340 }
Michael Wright1c9977b2016-07-12 13:30:10 -07001341
1342 pw.println();
1343 mPersistentDataStore.dump(pw);
Jeff Brownbd6e1502012-08-28 03:27:37 -07001344 }
1345 }
1346
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001347 /**
1348 * This is the object that everything in the display manager locks on.
1349 * We make it an inner class within the {@link DisplayManagerService} to so that it is
1350 * clear that the object belongs to the display manager service and that it is
1351 * a unique object with a special purpose.
1352 */
1353 public static final class SyncRoot {
1354 }
1355
Santos Cordonee8931e2017-04-05 10:31:15 -07001356 @VisibleForTesting
1357 static class Injector {
1358 VirtualDisplayAdapter getVirtualDisplayAdapter(SyncRoot syncRoot, Context context,
1359 Handler handler, DisplayAdapter.Listener displayAdapterListener) {
1360 return new VirtualDisplayAdapter(syncRoot, context, handler, displayAdapterListener);
1361 }
Santos Cordonc22c5632017-06-21 16:03:49 -07001362
1363 long getDefaultDisplayDelayTimeout() {
1364 return WAIT_FOR_DEFAULT_DISPLAY_TIMEOUT;
1365 }
Santos Cordonee8931e2017-04-05 10:31:15 -07001366 }
1367
Alex Sakhartchouk879d24f2017-06-20 22:01:19 -04001368 @VisibleForTesting
1369 DisplayDeviceInfo getDisplayDeviceInfoInternal(int displayId) {
1370 synchronized (mSyncRoot) {
1371 LogicalDisplay display = mLogicalDisplays.get(displayId);
1372 if (display != null) {
1373 DisplayDevice displayDevice = display.getPrimaryDisplayDeviceLocked();
1374 return displayDevice.getDisplayDeviceInfoLocked();
1375 }
1376 return null;
1377 }
1378 }
1379
Jeff Brownbd6e1502012-08-28 03:27:37 -07001380 private final class DisplayManagerHandler extends Handler {
1381 public DisplayManagerHandler(Looper looper) {
1382 super(looper, null, true /*async*/);
Jeff Brown848c2dc2012-08-19 20:18:08 -07001383 }
Jeff Brownbf5740e2012-08-19 23:20:02 -07001384
Jeff Brownbd6e1502012-08-28 03:27:37 -07001385 @Override
1386 public void handleMessage(Message msg) {
1387 switch (msg.what) {
Santos Cordonc22c5632017-06-21 16:03:49 -07001388 case MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS:
1389 registerDefaultDisplayAdapters();
Jeff Brownbd6e1502012-08-28 03:27:37 -07001390 break;
1391
1392 case MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS:
1393 registerAdditionalDisplayAdapters();
1394 break;
1395
1396 case MSG_DELIVER_DISPLAY_EVENT:
1397 deliverDisplayEvent(msg.arg1, msg.arg2);
1398 break;
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001399
1400 case MSG_REQUEST_TRAVERSAL:
Jeff Brown4ccb8232014-01-16 22:16:42 -08001401 mWindowManagerInternal.requestTraversalFromDisplayManager();
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001402 break;
Jeff Brownd728bf52012-09-08 18:05:28 -07001403
1404 case MSG_UPDATE_VIEWPORT: {
1405 synchronized (mSyncRoot) {
1406 mTempDefaultViewport.copyFrom(mDefaultViewport);
1407 mTempExternalTouchViewport.copyFrom(mExternalTouchViewport);
Santos Cordonee8931e2017-04-05 10:31:15 -07001408 if (!mTempVirtualTouchViewports.equals(mVirtualTouchViewports)) {
1409 mTempVirtualTouchViewports.clear();
1410 for (DisplayViewport d : mVirtualTouchViewports) {
1411 mTempVirtualTouchViewports.add(d.makeCopy());
1412 }
1413 }
Jeff Brownd728bf52012-09-08 18:05:28 -07001414 }
Santos Cordonee8931e2017-04-05 10:31:15 -07001415 mInputManagerInternal.setDisplayViewports(mTempDefaultViewport,
1416 mTempExternalTouchViewport, mTempVirtualTouchViewports);
Jeff Brownd728bf52012-09-08 18:05:28 -07001417 break;
1418 }
Kenny Guy22bd0442017-10-26 00:15:54 +01001419
Michael Wrighteef0e132017-11-21 17:57:52 +00001420 case MSG_LOAD_BRIGHTNESS_CONFIGURATION:
1421 loadBrightnessConfiguration();
1422 break;
Jeff Brownbd6e1502012-08-28 03:27:37 -07001423 }
1424 }
1425 }
1426
1427 private final class DisplayAdapterListener implements DisplayAdapter.Listener {
1428 @Override
1429 public void onDisplayDeviceEvent(DisplayDevice device, int event) {
1430 switch (event) {
1431 case DisplayAdapter.DISPLAY_DEVICE_EVENT_ADDED:
1432 handleDisplayDeviceAdded(device);
1433 break;
1434
1435 case DisplayAdapter.DISPLAY_DEVICE_EVENT_CHANGED:
1436 handleDisplayDeviceChanged(device);
1437 break;
1438
1439 case DisplayAdapter.DISPLAY_DEVICE_EVENT_REMOVED:
1440 handleDisplayDeviceRemoved(device);
1441 break;
1442 }
1443 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001444
1445 @Override
1446 public void onTraversalRequested() {
1447 synchronized (mSyncRoot) {
Craig Mautner65d11b32012-10-01 13:59:52 -07001448 scheduleTraversalLocked(false);
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001449 }
1450 }
Jeff Brownbd6e1502012-08-28 03:27:37 -07001451 }
1452
1453 private final class CallbackRecord implements DeathRecipient {
Jeff Brownce468a32013-11-21 16:42:03 -08001454 public final int mPid;
Jeff Brownbd6e1502012-08-28 03:27:37 -07001455 private final IDisplayManagerCallback mCallback;
1456
Jeff Brownce468a32013-11-21 16:42:03 -08001457 public boolean mWifiDisplayScanRequested;
1458
Jeff Brownbd6e1502012-08-28 03:27:37 -07001459 public CallbackRecord(int pid, IDisplayManagerCallback callback) {
1460 mPid = pid;
1461 mCallback = callback;
1462 }
1463
1464 @Override
1465 public void binderDied() {
1466 if (DEBUG) {
1467 Slog.d(TAG, "Display listener for pid " + mPid + " died.");
1468 }
Jeff Brownce468a32013-11-21 16:42:03 -08001469 onCallbackDied(this);
Jeff Brownbd6e1502012-08-28 03:27:37 -07001470 }
1471
1472 public void notifyDisplayEventAsync(int displayId, int event) {
1473 try {
1474 mCallback.onDisplayEvent(displayId, event);
1475 } catch (RemoteException ex) {
1476 Slog.w(TAG, "Failed to notify process "
1477 + mPid + " that displays changed, assuming it died.", ex);
1478 binderDied();
1479 }
1480 }
1481 }
Jeff Brown4ccb8232014-01-16 22:16:42 -08001482
Santos Cordonee8931e2017-04-05 10:31:15 -07001483 @VisibleForTesting
1484 final class BinderService extends IDisplayManager.Stub {
Jeff Brown4ccb8232014-01-16 22:16:42 -08001485 /**
1486 * Returns information about the specified logical display.
1487 *
1488 * @param displayId The logical display id.
1489 * @return The logical display info, or null if the display does not exist. The
1490 * returned object must be treated as immutable.
1491 */
1492 @Override // Binder call
1493 public DisplayInfo getDisplayInfo(int displayId) {
1494 final int callingUid = Binder.getCallingUid();
1495 final long token = Binder.clearCallingIdentity();
1496 try {
1497 return getDisplayInfoInternal(displayId, callingUid);
1498 } finally {
1499 Binder.restoreCallingIdentity(token);
1500 }
1501 }
1502
1503 /**
1504 * Returns the list of all display ids.
1505 */
1506 @Override // Binder call
1507 public int[] getDisplayIds() {
1508 final int callingUid = Binder.getCallingUid();
1509 final long token = Binder.clearCallingIdentity();
1510 try {
1511 return getDisplayIdsInternal(callingUid);
1512 } finally {
1513 Binder.restoreCallingIdentity(token);
1514 }
1515 }
1516
Michael Wrighteedcbf12017-08-16 23:14:54 +01001517 /**
1518 * Returns the stable device display size, in pixels.
1519 */
1520 @Override // Binder call
1521 public Point getStableDisplaySize() {
1522 final long token = Binder.clearCallingIdentity();
1523 try {
1524 return getStableDisplaySizeInternal();
1525 } finally {
1526 Binder.restoreCallingIdentity(token);
1527 }
1528 }
1529
Jeff Brown4ccb8232014-01-16 22:16:42 -08001530 @Override // Binder call
1531 public void registerCallback(IDisplayManagerCallback callback) {
1532 if (callback == null) {
1533 throw new IllegalArgumentException("listener must not be null");
1534 }
1535
1536 final int callingPid = Binder.getCallingPid();
1537 final long token = Binder.clearCallingIdentity();
1538 try {
1539 registerCallbackInternal(callback, callingPid);
1540 } finally {
1541 Binder.restoreCallingIdentity(token);
1542 }
1543 }
1544
1545 @Override // Binder call
1546 public void startWifiDisplayScan() {
1547 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
1548 "Permission required to start wifi display scans");
1549
1550 final int callingPid = Binder.getCallingPid();
1551 final long token = Binder.clearCallingIdentity();
1552 try {
1553 startWifiDisplayScanInternal(callingPid);
1554 } finally {
1555 Binder.restoreCallingIdentity(token);
1556 }
1557 }
1558
1559 @Override // Binder call
1560 public void stopWifiDisplayScan() {
1561 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
1562 "Permission required to stop wifi display scans");
1563
1564 final int callingPid = Binder.getCallingPid();
1565 final long token = Binder.clearCallingIdentity();
1566 try {
1567 stopWifiDisplayScanInternal(callingPid);
1568 } finally {
1569 Binder.restoreCallingIdentity(token);
1570 }
1571 }
1572
1573 @Override // Binder call
1574 public void connectWifiDisplay(String address) {
1575 if (address == null) {
1576 throw new IllegalArgumentException("address must not be null");
1577 }
1578 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
1579 "Permission required to connect to a wifi display");
1580
1581 final long token = Binder.clearCallingIdentity();
1582 try {
1583 connectWifiDisplayInternal(address);
1584 } finally {
1585 Binder.restoreCallingIdentity(token);
1586 }
1587 }
1588
1589 @Override // Binder call
1590 public void disconnectWifiDisplay() {
1591 // This request does not require special permissions.
1592 // Any app can request disconnection from the currently active wifi display.
1593 // This exception should no longer be needed once wifi display control moves
1594 // to the media router service.
1595
1596 final long token = Binder.clearCallingIdentity();
1597 try {
1598 disconnectWifiDisplayInternal();
1599 } finally {
1600 Binder.restoreCallingIdentity(token);
1601 }
1602 }
1603
1604 @Override // Binder call
1605 public void renameWifiDisplay(String address, String alias) {
1606 if (address == null) {
1607 throw new IllegalArgumentException("address must not be null");
1608 }
1609 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
1610 "Permission required to rename to a wifi display");
1611
1612 final long token = Binder.clearCallingIdentity();
1613 try {
1614 renameWifiDisplayInternal(address, alias);
1615 } finally {
1616 Binder.restoreCallingIdentity(token);
1617 }
1618 }
1619
1620 @Override // Binder call
1621 public void forgetWifiDisplay(String address) {
1622 if (address == null) {
1623 throw new IllegalArgumentException("address must not be null");
1624 }
1625 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
1626 "Permission required to forget to a wifi display");
1627
1628 final long token = Binder.clearCallingIdentity();
1629 try {
1630 forgetWifiDisplayInternal(address);
1631 } finally {
1632 Binder.restoreCallingIdentity(token);
1633 }
1634 }
1635
1636 @Override // Binder call
1637 public void pauseWifiDisplay() {
1638 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
1639 "Permission required to pause a wifi display session");
1640
1641 final long token = Binder.clearCallingIdentity();
1642 try {
1643 pauseWifiDisplayInternal();
1644 } finally {
1645 Binder.restoreCallingIdentity(token);
1646 }
1647 }
1648
1649 @Override // Binder call
1650 public void resumeWifiDisplay() {
1651 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
1652 "Permission required to resume a wifi display session");
1653
1654 final long token = Binder.clearCallingIdentity();
1655 try {
1656 resumeWifiDisplayInternal();
1657 } finally {
1658 Binder.restoreCallingIdentity(token);
1659 }
1660 }
1661
1662 @Override // Binder call
1663 public WifiDisplayStatus getWifiDisplayStatus() {
1664 // This request does not require special permissions.
1665 // Any app can get information about available wifi displays.
1666
1667 final long token = Binder.clearCallingIdentity();
1668 try {
1669 return getWifiDisplayStatusInternal();
1670 } finally {
1671 Binder.restoreCallingIdentity(token);
1672 }
1673 }
1674
1675 @Override // Binder call
Michael Wright1c9977b2016-07-12 13:30:10 -07001676 public void requestColorMode(int displayId, int colorMode) {
Michael Wright58e829f2015-09-15 00:13:26 +01001677 mContext.enforceCallingOrSelfPermission(
Michael Wright1c9977b2016-07-12 13:30:10 -07001678 Manifest.permission.CONFIGURE_DISPLAY_COLOR_MODE,
1679 "Permission required to change the display color mode");
Michael Wright58e829f2015-09-15 00:13:26 +01001680 final long token = Binder.clearCallingIdentity();
1681 try {
Michael Wright1c9977b2016-07-12 13:30:10 -07001682 requestColorModeInternal(displayId, colorMode);
Michael Wright58e829f2015-09-15 00:13:26 +01001683 } finally {
1684 Binder.restoreCallingIdentity(token);
1685 }
1686 }
1687
1688 @Override // Binder call
Michael Wright75ee9fc2014-09-01 19:55:22 -07001689 public int createVirtualDisplay(IVirtualDisplayCallback callback,
Michael Wrightc39d47a2014-07-08 18:07:36 -07001690 IMediaProjection projection, String packageName, String name,
Santos Cordonee8931e2017-04-05 10:31:15 -07001691 int width, int height, int densityDpi, Surface surface, int flags,
1692 String uniqueId) {
Jeff Brown4ccb8232014-01-16 22:16:42 -08001693 final int callingUid = Binder.getCallingUid();
1694 if (!validatePackageName(callingUid, packageName)) {
1695 throw new SecurityException("packageName must match the calling uid");
1696 }
Michael Wright75ee9fc2014-09-01 19:55:22 -07001697 if (callback == null) {
Jeff Brown4ccb8232014-01-16 22:16:42 -08001698 throw new IllegalArgumentException("appToken must not be null");
1699 }
1700 if (TextUtils.isEmpty(name)) {
1701 throw new IllegalArgumentException("name must be non-null and non-empty");
1702 }
1703 if (width <= 0 || height <= 0 || densityDpi <= 0) {
1704 throw new IllegalArgumentException("width, height, and densityDpi must be "
1705 + "greater than 0");
1706 }
Pablo Ceballoseb3370d2016-08-31 15:00:17 -07001707 if (surface != null && surface.isSingleBuffered()) {
Pablo Ceballosaff2f942016-07-29 14:49:55 -07001708 throw new IllegalArgumentException("Surface can't be single-buffered");
1709 }
Michael Wrightc39d47a2014-07-08 18:07:36 -07001710
Andrii Kulianfc8f82b2017-01-26 13:17:27 -08001711 if ((flags & VIRTUAL_DISPLAY_FLAG_PUBLIC) != 0) {
1712 flags |= VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR;
1713
1714 // Public displays can't be allowed to show content when locked.
Andrii Kulian7211d2e2017-01-27 15:58:05 -08001715 if ((flags & VIRTUAL_DISPLAY_FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD) != 0) {
Andrii Kulianfc8f82b2017-01-26 13:17:27 -08001716 throw new IllegalArgumentException(
1717 "Public display must not be marked as SHOW_WHEN_LOCKED_INSECURE");
1718 }
Michael Wright6720be42014-07-29 19:14:16 -07001719 }
Andrii Kulianfc8f82b2017-01-26 13:17:27 -08001720 if ((flags & VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY) != 0) {
1721 flags &= ~VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR;
Michael Wright6720be42014-07-29 19:14:16 -07001722 }
1723
Michael Wrightc39d47a2014-07-08 18:07:36 -07001724 if (projection != null) {
1725 try {
1726 if (!getProjectionService().isValidMediaProjection(projection)) {
1727 throw new SecurityException("Invalid media projection");
1728 }
Michael Wright6720be42014-07-29 19:14:16 -07001729 flags = projection.applyVirtualDisplayFlags(flags);
Michael Wrightc39d47a2014-07-08 18:07:36 -07001730 } catch (RemoteException e) {
Michael Wright6720be42014-07-29 19:14:16 -07001731 throw new SecurityException("unable to validate media projection or flags");
Michael Wrightc39d47a2014-07-08 18:07:36 -07001732 }
1733 }
1734
Michael Wright6720be42014-07-29 19:14:16 -07001735 if (callingUid != Process.SYSTEM_UID &&
Andrii Kulianfc8f82b2017-01-26 13:17:27 -08001736 (flags & VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR) != 0) {
Michael Wrightc39d47a2014-07-08 18:07:36 -07001737 if (!canProjectVideo(projection)) {
1738 throw new SecurityException("Requires CAPTURE_VIDEO_OUTPUT or "
1739 + "CAPTURE_SECURE_VIDEO_OUTPUT permission, or an appropriate "
1740 + "MediaProjection token in order to create a screen sharing virtual "
1741 + "display.");
1742 }
1743 }
Andrii Kulianfc8f82b2017-01-26 13:17:27 -08001744 if ((flags & VIRTUAL_DISPLAY_FLAG_SECURE) != 0) {
Michael Wrightc39d47a2014-07-08 18:07:36 -07001745 if (!canProjectSecureVideo(projection)) {
Jeff Brown4ccb8232014-01-16 22:16:42 -08001746 throw new SecurityException("Requires CAPTURE_SECURE_VIDEO_OUTPUT "
Michael Wrightc39d47a2014-07-08 18:07:36 -07001747 + "or an appropriate MediaProjection token to create a "
1748 + "secure virtual display.");
Jeff Brown4ccb8232014-01-16 22:16:42 -08001749 }
1750 }
1751
1752 final long token = Binder.clearCallingIdentity();
1753 try {
Santos Cordonee8931e2017-04-05 10:31:15 -07001754 return createVirtualDisplayInternal(callback, projection, callingUid, packageName,
1755 name, width, height, densityDpi, surface, flags, uniqueId);
Jeff Brown4ccb8232014-01-16 22:16:42 -08001756 } finally {
1757 Binder.restoreCallingIdentity(token);
1758 }
1759 }
1760
1761 @Override // Binder call
Michael Wright75ee9fc2014-09-01 19:55:22 -07001762 public void resizeVirtualDisplay(IVirtualDisplayCallback callback,
Michael Wright01e840f2014-06-26 16:03:25 -07001763 int width, int height, int densityDpi) {
1764 final long token = Binder.clearCallingIdentity();
1765 try {
Michael Wright75ee9fc2014-09-01 19:55:22 -07001766 resizeVirtualDisplayInternal(callback.asBinder(), width, height, densityDpi);
Michael Wright01e840f2014-06-26 16:03:25 -07001767 } finally {
1768 Binder.restoreCallingIdentity(token);
1769 }
1770 }
1771
1772 @Override // Binder call
Michael Wright75ee9fc2014-09-01 19:55:22 -07001773 public void setVirtualDisplaySurface(IVirtualDisplayCallback callback, Surface surface) {
Pablo Ceballoseb3370d2016-08-31 15:00:17 -07001774 if (surface != null && surface.isSingleBuffered()) {
1775 throw new IllegalArgumentException("Surface can't be single-buffered");
1776 }
Jeff Brown92207df2014-04-16 13:16:07 -07001777 final long token = Binder.clearCallingIdentity();
1778 try {
Michael Wright75ee9fc2014-09-01 19:55:22 -07001779 setVirtualDisplaySurfaceInternal(callback.asBinder(), surface);
Jeff Brown92207df2014-04-16 13:16:07 -07001780 } finally {
1781 Binder.restoreCallingIdentity(token);
1782 }
1783 }
1784
1785 @Override // Binder call
Michael Wright75ee9fc2014-09-01 19:55:22 -07001786 public void releaseVirtualDisplay(IVirtualDisplayCallback callback) {
Jeff Brown4ccb8232014-01-16 22:16:42 -08001787 final long token = Binder.clearCallingIdentity();
1788 try {
Michael Wright75ee9fc2014-09-01 19:55:22 -07001789 releaseVirtualDisplayInternal(callback.asBinder());
Jeff Brown4ccb8232014-01-16 22:16:42 -08001790 } finally {
1791 Binder.restoreCallingIdentity(token);
1792 }
1793 }
1794
1795 @Override // Binder call
1796 public void dump(FileDescriptor fd, final PrintWriter pw, String[] args) {
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -06001797 if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
Jeff Brown4ccb8232014-01-16 22:16:42 -08001798
1799 final long token = Binder.clearCallingIdentity();
1800 try {
1801 dumpInternal(pw);
1802 } finally {
1803 Binder.restoreCallingIdentity(token);
1804 }
1805 }
1806
Kenny Guy22bd0442017-10-26 00:15:54 +01001807 @Override // Binder call
Kenny Guy29aa30e2017-11-30 13:43:46 +00001808 public ParceledListSlice<BrightnessChangeEvent> getBrightnessEvents(String callingPackage) {
Kenny Guy22bd0442017-10-26 00:15:54 +01001809 mContext.enforceCallingOrSelfPermission(
1810 Manifest.permission.BRIGHTNESS_SLIDER_USAGE,
1811 "Permission to read brightness events.");
Kenny Guy29aa30e2017-11-30 13:43:46 +00001812
1813 final int callingUid = Binder.getCallingUid();
1814 AppOpsManager appOpsManager = mContext.getSystemService(AppOpsManager.class);
1815 final int mode = appOpsManager.checkOp(AppOpsManager.OP_GET_USAGE_STATS,
1816 callingUid, callingPackage);
1817 final boolean hasUsageStats;
1818 if (mode == AppOpsManager.MODE_DEFAULT) {
1819 // The default behavior here is to check if PackageManager has given the app
1820 // permission.
1821 hasUsageStats = mContext.checkCallingPermission(
1822 Manifest.permission.PACKAGE_USAGE_STATS)
1823 == PackageManager.PERMISSION_GRANTED;
1824 } else {
1825 hasUsageStats = mode == AppOpsManager.MODE_ALLOWED;
1826 }
1827
1828 final int userId = UserHandle.getUserId(callingUid);
Kenny Guy22bd0442017-10-26 00:15:54 +01001829 final long token = Binder.clearCallingIdentity();
1830 try {
Michael Wright144aac92017-12-21 18:37:41 +00001831 synchronized (mSyncRoot) {
1832 return mDisplayPowerController.getBrightnessEvents(userId, hasUsageStats);
1833 }
Kenny Guy22bd0442017-10-26 00:15:54 +01001834 } finally {
1835 Binder.restoreCallingIdentity(token);
1836 }
1837 }
1838
Michael Wrighteef0e132017-11-21 17:57:52 +00001839 @Override // Binder call
Peeyush Agarwalcc155dd2018-01-10 11:51:33 +00001840 public ParceledListSlice<AmbientBrightnessDayStats> getAmbientBrightnessStats() {
1841 mContext.enforceCallingOrSelfPermission(
1842 Manifest.permission.ACCESS_AMBIENT_LIGHT_STATS,
1843 "Permission required to to access ambient light stats.");
1844 final int callingUid = Binder.getCallingUid();
1845 final int userId = UserHandle.getUserId(callingUid);
1846 final long token = Binder.clearCallingIdentity();
1847 try {
1848 synchronized (mSyncRoot) {
1849 return mDisplayPowerController.getAmbientBrightnessStats(userId);
1850 }
1851 } finally {
1852 Binder.restoreCallingIdentity(token);
1853 }
1854 }
1855
1856 @Override // Binder call
Michael Wrighteef0e132017-11-21 17:57:52 +00001857 public void setBrightnessConfigurationForUser(
Kenny Guy05ce8092018-01-17 13:44:20 +00001858 BrightnessConfiguration c, @UserIdInt int userId, String packageName) {
Michael Wrighteef0e132017-11-21 17:57:52 +00001859 mContext.enforceCallingOrSelfPermission(
1860 Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS,
1861 "Permission required to change the display's brightness configuration");
1862 if (userId != UserHandle.getCallingUserId()) {
1863 mContext.enforceCallingOrSelfPermission(
1864 Manifest.permission.INTERACT_ACROSS_USERS,
1865 "Permission required to change the display brightness"
1866 + " configuration of another user");
1867 }
Kenny Guy05ce8092018-01-17 13:44:20 +00001868 if (packageName != null && !validatePackageName(getCallingUid(), packageName)) {
1869 packageName = null;
1870 }
Michael Wrighteef0e132017-11-21 17:57:52 +00001871 final long token = Binder.clearCallingIdentity();
1872 try {
Kenny Guy05ce8092018-01-17 13:44:20 +00001873 setBrightnessConfigurationForUserInternal(c, userId, packageName);
Michael Wrighteef0e132017-11-21 17:57:52 +00001874 } finally {
1875 Binder.restoreCallingIdentity(token);
1876 }
1877 }
1878
Michael Wrightd8460232018-01-16 18:04:59 +00001879 @Override // Binder call
Kenny Guy6d1009f2018-03-14 14:28:23 +00001880 public BrightnessConfiguration getBrightnessConfigurationForUser(int userId) {
1881 mContext.enforceCallingOrSelfPermission(
1882 Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS,
1883 "Permission required to read the display's brightness configuration");
1884 if (userId != UserHandle.getCallingUserId()) {
1885 mContext.enforceCallingOrSelfPermission(
1886 Manifest.permission.INTERACT_ACROSS_USERS,
1887 "Permission required to read the display brightness"
1888 + " configuration of another user");
1889 }
1890 final long token = Binder.clearCallingIdentity();
1891 try {
1892 final int userSerial = getUserManager().getUserSerialNumber(userId);
1893 synchronized (mSyncRoot) {
1894 BrightnessConfiguration config =
1895 mPersistentDataStore.getBrightnessConfiguration(userSerial);
1896 if (config == null) {
1897 config = mDisplayPowerController.getDefaultBrightnessConfiguration();
1898 }
1899 return config;
1900 }
1901 } finally {
1902 Binder.restoreCallingIdentity(token);
1903 }
1904 }
1905
1906 @Override // Binder call
1907 public BrightnessConfiguration getDefaultBrightnessConfiguration() {
1908 mContext.enforceCallingOrSelfPermission(
1909 Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS,
1910 "Permission required to read the display's default brightness configuration");
1911 final long token = Binder.clearCallingIdentity();
1912 try {
1913 synchronized (mSyncRoot) {
1914 return mDisplayPowerController.getDefaultBrightnessConfiguration();
1915 }
1916 } finally {
1917 Binder.restoreCallingIdentity(token);
1918 }
1919 }
1920
1921 @Override // Binder call
Michael Wrightd8460232018-01-16 18:04:59 +00001922 public void setTemporaryBrightness(int brightness) {
1923 mContext.enforceCallingOrSelfPermission(
1924 Manifest.permission.CONTROL_DISPLAY_BRIGHTNESS,
1925 "Permission required to set the display's brightness");
1926 final long token = Binder.clearCallingIdentity();
1927 try {
1928 synchronized (mSyncRoot) {
1929 mDisplayPowerController.setTemporaryBrightness(brightness);
1930 }
1931 } finally {
1932 Binder.restoreCallingIdentity(token);
1933 }
1934 }
1935
1936 @Override // Binder call
1937 public void setTemporaryAutoBrightnessAdjustment(float adjustment) {
1938 mContext.enforceCallingOrSelfPermission(
1939 Manifest.permission.CONTROL_DISPLAY_BRIGHTNESS,
1940 "Permission required to set the display's auto brightness adjustment");
1941 final long token = Binder.clearCallingIdentity();
1942 try {
1943 synchronized (mSyncRoot) {
1944 mDisplayPowerController.setTemporaryAutoBrightnessAdjustment(adjustment);
1945 }
1946 } finally {
1947 Binder.restoreCallingIdentity(token);
1948 }
1949 }
1950
Jeff Brown4ccb8232014-01-16 22:16:42 -08001951 private boolean validatePackageName(int uid, String packageName) {
1952 if (packageName != null) {
1953 String[] packageNames = mContext.getPackageManager().getPackagesForUid(uid);
1954 if (packageNames != null) {
1955 for (String n : packageNames) {
1956 if (n.equals(packageName)) {
1957 return true;
1958 }
1959 }
1960 }
1961 }
1962 return false;
1963 }
Michael Wrightc39d47a2014-07-08 18:07:36 -07001964
1965 private boolean canProjectVideo(IMediaProjection projection) {
1966 if (projection != null) {
1967 try {
1968 if (projection.canProjectVideo()) {
1969 return true;
1970 }
1971 } catch (RemoteException e) {
1972 Slog.e(TAG, "Unable to query projection service for permissions", e);
1973 }
1974 }
1975 if (mContext.checkCallingPermission(
1976 android.Manifest.permission.CAPTURE_VIDEO_OUTPUT)
Michael Wright0ccc2b02014-07-24 18:20:41 -07001977 == PackageManager.PERMISSION_GRANTED) {
Michael Wrightc39d47a2014-07-08 18:07:36 -07001978 return true;
1979 }
1980 return canProjectSecureVideo(projection);
1981 }
1982
1983 private boolean canProjectSecureVideo(IMediaProjection projection) {
1984 if (projection != null) {
1985 try {
1986 if (projection.canProjectSecureVideo()){
1987 return true;
1988 }
1989 } catch (RemoteException e) {
1990 Slog.e(TAG, "Unable to query projection service for permissions", e);
1991 }
1992 }
1993 return mContext.checkCallingPermission(
1994 android.Manifest.permission.CAPTURE_SECURE_VIDEO_OUTPUT)
Michael Wright0ccc2b02014-07-24 18:20:41 -07001995 == PackageManager.PERMISSION_GRANTED;
Michael Wrightc39d47a2014-07-08 18:07:36 -07001996 }
Jeff Brown4ccb8232014-01-16 22:16:42 -08001997 }
1998
1999 private final class LocalService extends DisplayManagerInternal {
2000 @Override
Jeff Brown037c33e2014-04-09 00:31:55 -07002001 public void initPowerManagement(final DisplayPowerCallbacks callbacks, Handler handler,
Jeff Brownad9ef192014-04-08 17:26:30 -07002002 SensorManager sensorManager) {
2003 synchronized (mSyncRoot) {
Jeff Brown037c33e2014-04-09 00:31:55 -07002004 DisplayBlanker blanker = new DisplayBlanker() {
2005 @Override
Jeff Brown5d6443b2015-04-10 20:15:01 -07002006 public void requestDisplayState(int state, int brightness) {
Jeff Brown037c33e2014-04-09 00:31:55 -07002007 // The order of operations is important for legacy reasons.
2008 if (state == Display.STATE_OFF) {
Jeff Brown5d6443b2015-04-10 20:15:01 -07002009 requestGlobalDisplayStateInternal(state, brightness);
Jeff Brown037c33e2014-04-09 00:31:55 -07002010 }
2011
2012 callbacks.onDisplayStateChange(state);
2013
2014 if (state != Display.STATE_OFF) {
Jeff Brown5d6443b2015-04-10 20:15:01 -07002015 requestGlobalDisplayStateInternal(state, brightness);
Jeff Brown037c33e2014-04-09 00:31:55 -07002016 }
2017 }
2018 };
Jeff Brownad9ef192014-04-08 17:26:30 -07002019 mDisplayPowerController = new DisplayPowerController(
Jeff Brown037c33e2014-04-09 00:31:55 -07002020 mContext, callbacks, handler, sensorManager, blanker);
Jeff Brownad9ef192014-04-08 17:26:30 -07002021 }
Michael Wrighteef0e132017-11-21 17:57:52 +00002022
2023 mHandler.sendEmptyMessage(MSG_LOAD_BRIGHTNESS_CONFIGURATION);
Jeff Brownad9ef192014-04-08 17:26:30 -07002024 }
2025
2026 @Override
2027 public boolean requestPowerState(DisplayPowerRequest request,
2028 boolean waitForNegativeProximity) {
Michael Wrighteef0e132017-11-21 17:57:52 +00002029 synchronized (mSyncRoot) {
2030 return mDisplayPowerController.requestPowerState(request,
2031 waitForNegativeProximity);
2032 }
Jeff Brownad9ef192014-04-08 17:26:30 -07002033 }
2034
2035 @Override
2036 public boolean isProximitySensorAvailable() {
Michael Wrighteef0e132017-11-21 17:57:52 +00002037 synchronized (mSyncRoot) {
2038 return mDisplayPowerController.isProximitySensorAvailable();
2039 }
Jeff Brownad9ef192014-04-08 17:26:30 -07002040 }
2041
2042 @Override
Jeff Brown4ccb8232014-01-16 22:16:42 -08002043 public DisplayInfo getDisplayInfo(int displayId) {
2044 return getDisplayInfoInternal(displayId, Process.myUid());
2045 }
2046
2047 @Override
2048 public void registerDisplayTransactionListener(DisplayTransactionListener listener) {
2049 if (listener == null) {
2050 throw new IllegalArgumentException("listener must not be null");
2051 }
2052
2053 registerDisplayTransactionListenerInternal(listener);
2054 }
2055
2056 @Override
2057 public void unregisterDisplayTransactionListener(DisplayTransactionListener listener) {
2058 if (listener == null) {
2059 throw new IllegalArgumentException("listener must not be null");
2060 }
2061
2062 unregisterDisplayTransactionListenerInternal(listener);
2063 }
2064
2065 @Override
2066 public void setDisplayInfoOverrideFromWindowManager(int displayId, DisplayInfo info) {
2067 setDisplayInfoOverrideFromWindowManagerInternal(displayId, info);
2068 }
2069
2070 @Override
Andrii Kuliancd097992017-03-23 18:31:59 -07002071 public void getNonOverrideDisplayInfo(int displayId, DisplayInfo outInfo) {
2072 getNonOverrideDisplayInfoInternal(displayId, outInfo);
2073 }
2074
2075 @Override
Jeff Brown4ccb8232014-01-16 22:16:42 -08002076 public void performTraversalInTransactionFromWindowManager() {
2077 performTraversalInTransactionFromWindowManagerInternal();
2078 }
2079
2080 @Override
Michael Wright3f145a22014-07-22 19:46:03 -07002081 public void setDisplayProperties(int displayId, boolean hasContent,
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -07002082 float requestedRefreshRate, int requestedMode, boolean inTraversal) {
2083 setDisplayPropertiesInternal(displayId, hasContent, requestedRefreshRate,
2084 requestedMode, inTraversal);
Jeff Brown4ccb8232014-01-16 22:16:42 -08002085 }
Filip Gruszczynskid2e86402015-02-19 13:05:03 -08002086
2087 @Override
2088 public void setDisplayOffsets(int displayId, int x, int y) {
2089 setDisplayOffsetsInternal(displayId, x, y);
2090 }
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002091
2092 @Override
2093 public void setDisplayAccessUIDs(SparseArray<IntArray> newDisplayAccessUIDs) {
2094 setDisplayAccessUIDsInternal(newDisplayAccessUIDs);
2095 }
2096
2097 @Override
2098 public boolean isUidPresentOnDisplay(int uid, int displayId) {
2099 return isUidPresentOnDisplayInternal(uid, displayId);
2100 }
Kenny Guycfe7b702017-11-14 21:04:58 +00002101
2102 @Override
Peeyush Agarwalcc155dd2018-01-10 11:51:33 +00002103 public void persistBrightnessTrackerState() {
Michael Wright144aac92017-12-21 18:37:41 +00002104 synchronized (mSyncRoot) {
Peeyush Agarwalcc155dd2018-01-10 11:51:33 +00002105 mDisplayPowerController.persistBrightnessTrackerState();
Michael Wright144aac92017-12-21 18:37:41 +00002106 }
Kenny Guycfe7b702017-11-14 21:04:58 +00002107 }
Adrian Roose1d68cd2018-01-17 12:54:50 +01002108
2109 @Override
2110 public void onOverlayChanged() {
2111 synchronized (mSyncRoot) {
Adrian Roos898ec382018-01-17 12:54:50 +01002112 for (int i = 0; i < mDisplayDevices.size(); i++) {
2113 mDisplayDevices.get(i).onOverlayChangedLocked();
Adrian Roose1d68cd2018-01-17 12:54:50 +01002114 }
2115 }
2116 }
Jeff Brown4ccb8232014-01-16 22:16:42 -08002117 }
Jeff Brownfa25bf52012-07-23 19:26:30 -07002118}