blob: 3afbf661f97e28fd8a8f57caf21a7b6e4176f13e [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
Chilun67a379b2019-04-11 19:49:42 +080019import static android.Manifest.permission.CAPTURE_SECURE_VIDEO_OUTPUT;
20import static android.Manifest.permission.CAPTURE_VIDEO_OUTPUT;
21import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
Andrii Kulianfc8f82b2017-01-26 13:17:27 -080022import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR;
Chilun67a379b2019-04-11 19:49:42 +080023import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD;
Andrii Kulianfc8f82b2017-01-26 13:17:27 -080024import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY;
25import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC;
26import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE;
Chilun67a379b2019-04-11 19:49:42 +080027import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS;
Siarhei Vishniakou2eb0f8f2018-07-06 23:30:12 +010028import static android.hardware.display.DisplayViewport.VIEWPORT_EXTERNAL;
29import static android.hardware.display.DisplayViewport.VIEWPORT_INTERNAL;
30import static android.hardware.display.DisplayViewport.VIEWPORT_VIRTUAL;
Jeff Brownbd6e1502012-08-28 03:27:37 -070031
Jeff Brownfa25bf52012-07-23 19:26:30 -070032import android.Manifest;
Santos Cordonee8931e2017-04-05 10:31:15 -070033import android.annotation.NonNull;
Kenny Guy05ce8092018-01-17 13:44:20 +000034import android.annotation.Nullable;
Michael Wrighteef0e132017-11-21 17:57:52 +000035import android.annotation.UserIdInt;
Kenny Guy29aa30e2017-11-30 13:43:46 +000036import android.app.AppOpsManager;
Jeff Brownfa25bf52012-07-23 19:26:30 -070037import android.content.Context;
38import android.content.pm.PackageManager;
Kenny Guy22bd0442017-10-26 00:15:54 +010039import android.content.pm.ParceledListSlice;
Michael Wrighteedcbf12017-08-16 23:14:54 +010040import android.content.res.Resources;
Dan Gittik122df862018-03-28 16:59:22 +010041import android.content.res.TypedArray;
Galia Peycheva088d7c02019-12-13 11:27:23 +010042import android.database.ContentObserver;
Peiyong Lin277eaff2019-01-16 16:18:22 -080043import android.graphics.ColorSpace;
Michael Wrighteedcbf12017-08-16 23:14:54 +010044import android.graphics.Point;
Robert Carr5c52b132019-02-15 15:48:11 -080045import android.graphics.Rect;
Jeff Brownad9ef192014-04-08 17:26:30 -070046import android.hardware.SensorManager;
Peeyush Agarwalcc155dd2018-01-10 11:51:33 +000047import android.hardware.display.AmbientBrightnessDayStats;
Kenny Guy22bd0442017-10-26 00:15:54 +010048import android.hardware.display.BrightnessChangeEvent;
Michael Wrighteef0e132017-11-21 17:57:52 +000049import android.hardware.display.BrightnessConfiguration;
Dan Gittik122df862018-03-28 16:59:22 +010050import android.hardware.display.Curve;
Jeff Brownbd6e1502012-08-28 03:27:37 -070051import android.hardware.display.DisplayManagerGlobal;
Jeff Brown4ccb8232014-01-16 22:16:42 -080052import android.hardware.display.DisplayManagerInternal;
Jeff Brown4ccb8232014-01-16 22:16:42 -080053import android.hardware.display.DisplayManagerInternal.DisplayTransactionListener;
Siarhei Vishniakou2eb0f8f2018-07-06 23:30:12 +010054import android.hardware.display.DisplayViewport;
Kevin DuBoisbf76b11b2018-09-04 09:14:15 -070055import android.hardware.display.DisplayedContentSample;
56import android.hardware.display.DisplayedContentSamplingAttributes;
Jeff Brownfa25bf52012-07-23 19:26:30 -070057import android.hardware.display.IDisplayManager;
Jeff Brownbd6e1502012-08-28 03:27:37 -070058import android.hardware.display.IDisplayManagerCallback;
Michael Wright75ee9fc2014-09-01 19:55:22 -070059import android.hardware.display.IVirtualDisplayCallback;
b0202.jung925435c2020-01-08 18:46:59 +090060import android.hardware.display.VirtualDisplayConfig;
Jeff Browne08ae382012-09-07 20:36:36 -070061import android.hardware.display.WifiDisplayStatus;
Jeff Brown4ccb8232014-01-16 22:16:42 -080062import android.hardware.input.InputManagerInternal;
Michael Wrightc39d47a2014-07-08 18:07:36 -070063import android.media.projection.IMediaProjection;
64import android.media.projection.IMediaProjectionManager;
Galia Peycheva088d7c02019-12-13 11:27:23 +010065import android.net.Uri;
Jeff Brownfa25bf52012-07-23 19:26:30 -070066import android.os.Binder;
Jeff Brownbd6e1502012-08-28 03:27:37 -070067import android.os.Handler;
Jeff Brown64a55af2012-08-26 02:47:39 -070068import android.os.IBinder;
Jeff Brown4ccb8232014-01-16 22:16:42 -080069import android.os.IBinder.DeathRecipient;
Jeff Brownbd6e1502012-08-28 03:27:37 -070070import android.os.Looper;
71import android.os.Message;
Jeff Brown5d6443b2015-04-10 20:15:01 -070072import android.os.PowerManager;
Craig Mautner4504de52013-12-20 09:06:56 -080073import android.os.Process;
Jeff Brownbd6e1502012-08-28 03:27:37 -070074import android.os.RemoteException;
Dan Gittik7a32fba2018-03-28 12:19:38 +010075import android.os.ResultReceiver;
Michael Wrightc39d47a2014-07-08 18:07:36 -070076import android.os.ServiceManager;
Dan Gittik7a32fba2018-03-28 12:19:38 +010077import android.os.ShellCallback;
Jeff Brownbd6e1502012-08-28 03:27:37 -070078import android.os.SystemClock;
Jeff Brownfa25bf52012-07-23 19:26:30 -070079import android.os.SystemProperties;
Jeff Brown5d6443b2015-04-10 20:15:01 -070080import android.os.Trace;
Kenny Guy22bd0442017-10-26 00:15:54 +010081import android.os.UserHandle;
Michael Wrighteef0e132017-11-21 17:57:52 +000082import android.os.UserManager;
Galia Peycheva088d7c02019-12-13 11:27:23 +010083import android.provider.Settings;
Jeff Browna506a6e2013-06-04 00:02:38 -070084import android.text.TextUtils;
Andrii Kulianfb1bf692017-01-17 11:17:34 -080085import android.util.IntArray;
Dan Gittik122df862018-03-28 16:59:22 +010086import android.util.Pair;
Jeff Brownbd6e1502012-08-28 03:27:37 -070087import android.util.Slog;
88import android.util.SparseArray;
Dan Gittik122df862018-03-28 16:59:22 +010089import android.util.Spline;
Jeff Brownfa25bf52012-07-23 19:26:30 -070090import android.view.Display;
91import android.view.DisplayInfo;
Jeff Browna506a6e2013-06-04 00:02:38 -070092import android.view.Surface;
Robert Carrae606b42018-02-15 15:36:23 -080093import android.view.SurfaceControl;
Jeff Browna506a6e2013-06-04 00:02:38 -070094
Siarhei Vishniakou2eb0f8f2018-07-06 23:30:12 +010095import com.android.internal.annotations.GuardedBy;
96import com.android.internal.annotations.VisibleForTesting;
97import com.android.internal.util.DumpUtils;
98import com.android.internal.util.IndentingPrintWriter;
Jorim Jaggied7993b2017-03-28 18:50:01 +010099import com.android.server.AnimationThread;
Jeff Brown4ccb8232014-01-16 22:16:42 -0800100import com.android.server.DisplayThread;
101import com.android.server.LocalServices;
102import com.android.server.SystemService;
Dianne Hackborn8d044e82013-04-30 17:24:15 -0700103import com.android.server.UiThread;
Jorim Jaggi21c39a72017-10-20 15:47:51 +0200104import com.android.server.wm.SurfaceAnimationThread;
Siarhei Vishniakou2eb0f8f2018-07-06 23:30:12 +0100105import com.android.server.wm.WindowManagerInternal;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700106
107import java.io.FileDescriptor;
108import java.io.PrintWriter;
109import java.util.ArrayList;
Jeff Browna506a6e2013-06-04 00:02:38 -0700110import java.util.Arrays;
Jeff Browne75926d2014-09-18 15:24:49 -0700111import java.util.List;
Jeff Brown7f3994e2012-12-04 14:04:28 -0800112import java.util.concurrent.CopyOnWriteArrayList;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700113
114/**
Jeff Brownbd6e1502012-08-28 03:27:37 -0700115 * Manages attached displays.
Jeff Brownfa25bf52012-07-23 19:26:30 -0700116 * <p>
Jeff Brownbd6e1502012-08-28 03:27:37 -0700117 * The {@link DisplayManagerService} manages the global lifecycle of displays,
118 * decides how to configure logical displays based on the physical display devices currently
119 * attached, sends notifications to the system and to applications when the state
120 * changes, and so on.
121 * </p><p>
122 * The display manager service relies on a collection of {@link DisplayAdapter} components,
123 * for discovering and configuring physical display devices attached to the system.
124 * There are separate display adapters for each manner that devices are attached:
Dominik Laskowski26290bb2020-01-15 16:09:55 -0800125 * one display adapter for physical displays, one for simulated non-functional
Jeff Brownbd6e1502012-08-28 03:27:37 -0700126 * displays when the system is headless, one for simulated overlay displays used for
127 * development, one for wifi displays, etc.
128 * </p><p>
129 * Display adapters are only weakly coupled to the display manager service.
130 * Display adapters communicate changes in display device state to the display manager
Craig Mautner722285e2012-09-07 13:55:58 -0700131 * service asynchronously via a {@link DisplayAdapter.Listener} registered
Jeff Brownbd6e1502012-08-28 03:27:37 -0700132 * by the display manager service. This separation of concerns is important for
133 * two main reasons. First, it neatly encapsulates the responsibilities of these
134 * two classes: display adapters handle individual display devices whereas
135 * the display manager service handles the global state. Second, it eliminates
136 * the potential for deadlocks resulting from asynchronous display device discovery.
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700137 * </p>
138 *
139 * <h3>Synchronization</h3>
140 * <p>
141 * Because the display manager may be accessed by multiple threads, the synchronization
142 * story gets a little complicated. In particular, the window manager may call into
143 * the display manager while holding a surface transaction with the expectation that
144 * it can apply changes immediately. Unfortunately, that means we can't just do
145 * everything asynchronously (*grump*).
Jeff Brownbd6e1502012-08-28 03:27:37 -0700146 * </p><p>
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700147 * To make this work, all of the objects that belong to the display manager must
148 * use the same lock. We call this lock the synchronization root and it has a unique
149 * type {@link DisplayManagerService.SyncRoot}. Methods that require this lock are
150 * named with the "Locked" suffix.
151 * </p><p>
152 * Where things get tricky is that the display manager is not allowed to make
153 * any potentially reentrant calls, especially into the window manager. We generally
154 * avoid this by making all potentially reentrant out-calls asynchronous.
Jeff Brownfa25bf52012-07-23 19:26:30 -0700155 * </p>
156 */
Jeff Brown4ccb8232014-01-16 22:16:42 -0800157public final class DisplayManagerService extends SystemService {
Jeff Brownfa25bf52012-07-23 19:26:30 -0700158 private static final String TAG = "DisplayManagerService";
Jeff Brownbd6e1502012-08-28 03:27:37 -0700159 private static final boolean DEBUG = false;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700160
Jeff Brownbbd28a22012-09-20 16:47:15 -0700161 // When this system property is set to 0, WFD is forcibly disabled on boot.
162 // When this system property is set to 1, WFD is forcibly enabled on boot.
163 // Otherwise WFD is enabled according to the value of config_enableWifiDisplay.
164 private static final String FORCE_WIFI_DISPLAY_ENABLE = "persist.debug.wfd.enable";
165
Adrian Roos9ee5dff2018-08-22 20:19:49 +0200166 private static final String PROP_DEFAULT_DISPLAY_TOP_INSET = "persist.sys.displayinset.top";
167
Jeff Brownbd6e1502012-08-28 03:27:37 -0700168 private static final long WAIT_FOR_DEFAULT_DISPLAY_TIMEOUT = 10000;
169
Santos Cordonc22c5632017-06-21 16:03:49 -0700170 private static final int MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS = 1;
Jeff Brownbd6e1502012-08-28 03:27:37 -0700171 private static final int MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS = 2;
172 private static final int MSG_DELIVER_DISPLAY_EVENT = 3;
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700173 private static final int MSG_REQUEST_TRAVERSAL = 4;
Jeff Brownd728bf52012-09-08 18:05:28 -0700174 private static final int MSG_UPDATE_VIEWPORT = 5;
Michael Wrighta3dab232019-02-22 16:54:21 +0000175 private static final int MSG_LOAD_BRIGHTNESS_CONFIGURATION = 6;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700176
Jeff Brownb880d882014-02-10 19:47:07 -0800177 private final Context mContext;
Jeff Brownbd6e1502012-08-28 03:27:37 -0700178 private final DisplayManagerHandler mHandler;
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700179 private final Handler mUiHandler;
180 private final DisplayAdapterListener mDisplayAdapterListener;
Michael Wrighta3dab232019-02-22 16:54:21 +0000181 private final DisplayModeDirector mDisplayModeDirector;
Jeff Brown4ccb8232014-01-16 22:16:42 -0800182 private WindowManagerInternal mWindowManagerInternal;
183 private InputManagerInternal mInputManagerInternal;
Michael Wrightc39d47a2014-07-08 18:07:36 -0700184 private IMediaProjectionManager mProjectionService;
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700185
186 // The synchronization root for the display manager.
187 // This lock guards most of the display manager's state.
Craig Mautner0bf6ec92012-12-18 08:33:27 -0800188 // NOTE: This is synchronized on while holding WindowManagerService.mWindowMap so never call
189 // into WindowManagerService methods that require mWindowMap while holding this unless you are
190 // very very sure that no deadlock can occur.
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700191 private final SyncRoot mSyncRoot = new SyncRoot();
192
193 // True if in safe mode.
194 // This option may disable certain display adapters.
195 public boolean mSafeMode;
196
197 // True if we are in a special boot mode where only core applications and
198 // services should be started. This option may disable certain display adapters.
199 public boolean mOnlyCore;
200
Jeff Brown27f1d672012-10-17 18:32:34 -0700201 // True if the display manager service should pretend there is only one display
202 // and only tell applications about the existence of the default logical display.
203 // The display manager can still mirror content to secondary displays but applications
204 // cannot present unique content on those displays.
205 // Used for demonstration purposes only.
206 private final boolean mSingleDisplayDemoMode;
207
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700208 // All callback records indexed by calling process id.
209 public final SparseArray<CallbackRecord> mCallbacks =
Jeff Brownbd6e1502012-08-28 03:27:37 -0700210 new SparseArray<CallbackRecord>();
Jeff Brownfa25bf52012-07-23 19:26:30 -0700211
Jeff Brownbd6e1502012-08-28 03:27:37 -0700212 // List of all currently registered display adapters.
213 private final ArrayList<DisplayAdapter> mDisplayAdapters = new ArrayList<DisplayAdapter>();
214
215 // List of all currently connected display devices.
216 private final ArrayList<DisplayDevice> mDisplayDevices = new ArrayList<DisplayDevice>();
217
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700218 // List of all logical displays indexed by logical display id.
Tim Murray890ceb52020-01-30 10:12:40 -0800219 // Any modification to mLogicalDisplays must invalidate the DisplayManagerGlobal cache.
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700220 private final SparseArray<LogicalDisplay> mLogicalDisplays =
221 new SparseArray<LogicalDisplay>();
Jeff Brownbd6e1502012-08-28 03:27:37 -0700222 private int mNextNonDefaultDisplayId = Display.DEFAULT_DISPLAY + 1;
223
Jeff Brown7f3994e2012-12-04 14:04:28 -0800224 // List of all display transaction listeners.
225 private final CopyOnWriteArrayList<DisplayTransactionListener> mDisplayTransactionListeners =
226 new CopyOnWriteArrayList<DisplayTransactionListener>();
227
Jeff Brownad9ef192014-04-08 17:26:30 -0700228 // Display power controller.
229 private DisplayPowerController mDisplayPowerController;
230
Jeff Brown037c33e2014-04-09 00:31:55 -0700231 // The overall display state, independent of changes that might influence one
232 // display or another in particular.
Jeff Brown5d6443b2015-04-10 20:15:01 -0700233 private int mGlobalDisplayState = Display.STATE_ON;
234
235 // The overall display brightness.
Dominik Laskowski26290bb2020-01-15 16:09:55 -0800236 // For now, this only applies to the default display but we may split it up eventually.
Fiona Campbelld4eb2952019-11-04 17:19:56 +0000237 private float mGlobalDisplayBrightness;
Jeff Brown9e316a12012-10-08 19:17:06 -0700238
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700239 // Set to true when there are pending display changes that have yet to be applied
240 // to the surface flinger state.
241 private boolean mPendingTraversal;
Jeff Brownbd6e1502012-08-28 03:27:37 -0700242
Jeff Browne08ae382012-09-07 20:36:36 -0700243 // The Wifi display adapter, or null if not registered.
244 private WifiDisplayAdapter mWifiDisplayAdapter;
245
Jeff Brownce468a32013-11-21 16:42:03 -0800246 // The number of active wifi display scan requests.
247 private int mWifiDisplayScanRequestCount;
248
Jeff Browna506a6e2013-06-04 00:02:38 -0700249 // The virtual display adapter, or null if not registered.
250 private VirtualDisplayAdapter mVirtualDisplayAdapter;
251
Michael Wrighteef0e132017-11-21 17:57:52 +0000252 // The User ID of the current user
253 private @UserIdInt int mCurrentUserId;
254
Michael Wrighteedcbf12017-08-16 23:14:54 +0100255 // The stable device screen height and width. These are not tied to a specific display, even
256 // the default display, because they need to be stable over the course of the device's entire
257 // life, even if the default display changes (e.g. a new monitor is plugged into a PC-like
258 // device).
259 private Point mStableDisplaySize = new Point();
260
Winson72dbe7e2019-04-29 14:55:30 -0700261 // Whether the system has finished booting or not.
262 private boolean mSystemReady;
263
Adrian Roos9ee5dff2018-08-22 20:19:49 +0200264 // The top inset of the default display.
265 // This gets persisted so that the boot animation knows how to transition from the display's
266 // full size to the size configured by the user. Right now we only persist and animate the top
267 // inset, but theoretically we could do it for all of them.
268 private int mDefaultDisplayTopInset;
269
Jeff Brownd728bf52012-09-08 18:05:28 -0700270 // Viewports of the default display and the display that should receive touch
271 // input from an external source. Used by the input system.
Siarhei Vishniakou2eb0f8f2018-07-06 23:30:12 +0100272 @GuardedBy("mSyncRoot")
273 private final ArrayList<DisplayViewport> mViewports = new ArrayList<>();
Jeff Brownd728bf52012-09-08 18:05:28 -0700274
Jeff Brown89d55462012-09-19 11:33:42 -0700275 // Persistent data store for all internal settings maintained by the display manager service.
276 private final PersistentDataStore mPersistentDataStore = new PersistentDataStore();
277
Jeff Brownbd6e1502012-08-28 03:27:37 -0700278 // Temporary callback list, used when sending display events to applications.
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700279 // May be used outside of the lock but only on the handler thread.
280 private final ArrayList<CallbackRecord> mTempCallbacks = new ArrayList<CallbackRecord>();
Jeff Brownbd6e1502012-08-28 03:27:37 -0700281
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700282 // Temporary display info, used for comparing display configurations.
283 private final DisplayInfo mTempDisplayInfo = new DisplayInfo();
284
Jeff Brownd728bf52012-09-08 18:05:28 -0700285 // Temporary viewports, used when sending new viewport information to the
286 // input system. May be used outside of the lock but only on the handler thread.
Siarhei Vishniakou2eb0f8f2018-07-06 23:30:12 +0100287 private final ArrayList<DisplayViewport> mTempViewports = new ArrayList<>();
Jeff Brownd728bf52012-09-08 18:05:28 -0700288
Damien Bargiacchi4364bbf2016-11-01 21:44:20 -0700289 // The default color mode for default displays. Overrides the usual
290 // Display.Display.COLOR_MODE_DEFAULT for displays with the
291 // DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY flag set.
292 private final int mDefaultDisplayDefaultColorMode;
293
Jeff Browne75926d2014-09-18 15:24:49 -0700294 // Temporary list of deferred work to perform when setting the display state.
295 // Only used by requestDisplayState. The field is self-synchronized and only
296 // intended for use inside of the requestGlobalDisplayStateInternal function.
297 private final ArrayList<Runnable> mTempDisplayStateWorkQueue = new ArrayList<Runnable>();
298
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800299 // Lists of UIDs that are present on the displays. Maps displayId -> array of UIDs.
300 private final SparseArray<IntArray> mDisplayAccessUIDs = new SparseArray<>();
301
Santos Cordonee8931e2017-04-05 10:31:15 -0700302 private final Injector mInjector;
303
Dan Gittik122df862018-03-28 16:59:22 +0100304 // The minimum brightness curve, which guarantess that any brightness curve that dips below it
305 // is rejected by the system.
306 private final Curve mMinimumBrightnessCurve;
307 private final Spline mMinimumBrightnessSpline;
Peiyong Lin277eaff2019-01-16 16:18:22 -0800308 private final ColorSpace mWideColorSpace;
Dan Gittik122df862018-03-28 16:59:22 +0100309
Long Lingbc841b02019-07-03 16:43:15 -0700310 private SensorManager mSensorManager;
311
Galia Peycheva088d7c02019-12-13 11:27:23 +0100312 // Whether minimal post processing is allowed by the user.
313 @GuardedBy("mSyncRoot")
314 private boolean mMinimalPostProcessingAllowed;
315
316 // Receives notifications about changes to Settings.
317 private SettingsObserver mSettingsObserver;
318
Jeff Brownb880d882014-02-10 19:47:07 -0800319 public DisplayManagerService(Context context) {
Santos Cordonee8931e2017-04-05 10:31:15 -0700320 this(context, new Injector());
321 }
322
323 @VisibleForTesting
324 DisplayManagerService(Context context, Injector injector) {
Jeff Brownb880d882014-02-10 19:47:07 -0800325 super(context);
Santos Cordonee8931e2017-04-05 10:31:15 -0700326 mInjector = injector;
Jeff Brownb880d882014-02-10 19:47:07 -0800327 mContext = context;
Jeff Brown4ccb8232014-01-16 22:16:42 -0800328 mHandler = new DisplayManagerHandler(DisplayThread.get().getLooper());
Dianne Hackborn8d044e82013-04-30 17:24:15 -0700329 mUiHandler = UiThread.getHandler();
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700330 mDisplayAdapterListener = new DisplayAdapterListener();
Michael Wrighta3dab232019-02-22 16:54:21 +0000331 mDisplayModeDirector = new DisplayModeDirector(context, mHandler);
Jeff Brown27f1d672012-10-17 18:32:34 -0700332 mSingleDisplayDemoMode = SystemProperties.getBoolean("persist.demo.singledisplay", false);
Dan Gittik122df862018-03-28 16:59:22 +0100333 Resources resources = mContext.getResources();
Damien Bargiacchi4364bbf2016-11-01 21:44:20 -0700334 mDefaultDisplayDefaultColorMode = mContext.getResources().getInteger(
Michael Wrighteef0e132017-11-21 17:57:52 +0000335 com.android.internal.R.integer.config_defaultDisplayDefaultColorMode);
Adrian Roos9ee5dff2018-08-22 20:19:49 +0200336 mDefaultDisplayTopInset = SystemProperties.getInt(PROP_DEFAULT_DISPLAY_TOP_INSET, -1);
Dan Gittik122df862018-03-28 16:59:22 +0100337 float[] lux = getFloatArray(resources.obtainTypedArray(
338 com.android.internal.R.array.config_minimumBrightnessCurveLux));
339 float[] nits = getFloatArray(resources.obtainTypedArray(
340 com.android.internal.R.array.config_minimumBrightnessCurveNits));
341 mMinimumBrightnessCurve = new Curve(lux, nits);
342 mMinimumBrightnessSpline = Spline.createSpline(lux, nits);
Jeff Brown5d6443b2015-04-10 20:15:01 -0700343
Michael Wrighta3dab232019-02-22 16:54:21 +0000344 PowerManager pm = mContext.getSystemService(PowerManager.class);
Fiona Campbelld4eb2952019-11-04 17:19:56 +0000345 mGlobalDisplayBrightness = pm.getBrightnessConstraint(
346 PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_DEFAULT);
Michael Wrighteef0e132017-11-21 17:57:52 +0000347 mCurrentUserId = UserHandle.USER_SYSTEM;
Peiyong Lin277eaff2019-01-16 16:18:22 -0800348 ColorSpace[] colorSpaces = SurfaceControl.getCompositionColorSpaces();
349 mWideColorSpace = colorSpaces[1];
Winson72dbe7e2019-04-29 14:55:30 -0700350
351 mSystemReady = false;
Joel Fernandes2d314e12017-04-04 16:32:15 -0700352 }
353
354 public void setupSchedulerPolicies() {
Jorim Jaggied7993b2017-03-28 18:50:01 +0100355 // android.display and android.anim is critical to user experience and we should make sure
Michael Wrighteef0e132017-11-21 17:57:52 +0000356 // it is not in the default foregroup groups, add it to top-app to make sure it uses all
357 // the cores and scheduling settings for top-app when it runs.
Jorim Jaggied7993b2017-03-28 18:50:01 +0100358 Process.setThreadGroupAndCpuset(DisplayThread.get().getThreadId(),
359 Process.THREAD_GROUP_TOP_APP);
360 Process.setThreadGroupAndCpuset(AnimationThread.get().getThreadId(),
361 Process.THREAD_GROUP_TOP_APP);
Jorim Jaggi21c39a72017-10-20 15:47:51 +0200362 Process.setThreadGroupAndCpuset(SurfaceAnimationThread.get().getThreadId(),
363 Process.THREAD_GROUP_TOP_APP);
Craig Mautner4f67ba62012-08-02 11:23:00 -0700364 }
365
Jeff Brown4ccb8232014-01-16 22:16:42 -0800366 @Override
Jeff Brown4ccb8232014-01-16 22:16:42 -0800367 public void onStart() {
Michael Wright1c9977b2016-07-12 13:30:10 -0700368 // We need to pre-load the persistent data store so it's ready before the default display
369 // adapter is up so that we have it's configuration. We could load it lazily, but since
370 // 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 -0700371 // we've waited for the display to register itself with us.
Michael Wrighta3dab232019-02-22 16:54:21 +0000372 synchronized (mSyncRoot) {
373 mPersistentDataStore.loadIfNeeded();
374 loadStableDisplayValuesLocked();
Michael Wrighteedcbf12017-08-16 23:14:54 +0100375 }
Santos Cordonc22c5632017-06-21 16:03:49 -0700376 mHandler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS);
Jeff Brown4ccb8232014-01-16 22:16:42 -0800377
Tim Murray890ceb52020-01-30 10:12:40 -0800378 // If there was a runtime restart then we may have stale caches left around, so we need to
379 // make sure to invalidate them upon every start.
380 DisplayManagerGlobal.invalidateLocalDisplayInfoCaches();
381
Jeff Brown4ccb8232014-01-16 22:16:42 -0800382 publishBinderService(Context.DISPLAY_SERVICE, new BinderService(),
383 true /*allowIsolated*/);
384 publishLocalService(DisplayManagerInternal.class, new LocalService());
385 }
386
387 @Override
388 public void onBootPhase(int phase) {
389 if (phase == PHASE_WAIT_FOR_DEFAULT_DISPLAY) {
390 synchronized (mSyncRoot) {
Santos Cordonc22c5632017-06-21 16:03:49 -0700391 long timeout = SystemClock.uptimeMillis()
392 + mInjector.getDefaultDisplayDelayTimeout();
393 while (mLogicalDisplays.get(Display.DEFAULT_DISPLAY) == null ||
394 mVirtualDisplayAdapter == null) {
Jeff Brown4ccb8232014-01-16 22:16:42 -0800395 long delay = timeout - SystemClock.uptimeMillis();
396 if (delay <= 0) {
397 throw new RuntimeException("Timeout waiting for default display "
Santos Cordonc22c5632017-06-21 16:03:49 -0700398 + "to be initialized. DefaultDisplay="
399 + mLogicalDisplays.get(Display.DEFAULT_DISPLAY)
400 + ", mVirtualDisplayAdapter=" + mVirtualDisplayAdapter);
Jeff Brown4ccb8232014-01-16 22:16:42 -0800401 }
402 if (DEBUG) {
403 Slog.d(TAG, "waitForDefaultDisplay: waiting, timeout=" + delay);
404 }
405 try {
406 mSyncRoot.wait(delay);
407 } catch (InterruptedException ex) {
408 }
Jeff Brownbd6e1502012-08-28 03:27:37 -0700409 }
410 }
411 }
Jeff Brownbd6e1502012-08-28 03:27:37 -0700412 }
413
Michael Wrighteef0e132017-11-21 17:57:52 +0000414 @Override
415 public void onSwitchUser(@UserIdInt int newUserId) {
416 final int userSerial = getUserManager().getUserSerialNumber(newUserId);
417 synchronized (mSyncRoot) {
418 if (mCurrentUserId != newUserId) {
419 mCurrentUserId = newUserId;
420 BrightnessConfiguration config =
421 mPersistentDataStore.getBrightnessConfiguration(userSerial);
422 mDisplayPowerController.setBrightnessConfiguration(config);
Galia Peycheva088d7c02019-12-13 11:27:23 +0100423 handleSettingsChange();
Michael Wrighteef0e132017-11-21 17:57:52 +0000424 }
Peeyush Agarwalcc155dd2018-01-10 11:51:33 +0000425 mDisplayPowerController.onSwitchUser(newUserId);
Michael Wrighteef0e132017-11-21 17:57:52 +0000426 }
427 }
428
Jeff Brown4ccb8232014-01-16 22:16:42 -0800429 // TODO: Use dependencies or a boot phase
430 public void windowManagerAndInputReady() {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700431 synchronized (mSyncRoot) {
Jeff Brown4ccb8232014-01-16 22:16:42 -0800432 mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
433 mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);
Craig Mautner65d11b32012-10-01 13:59:52 -0700434 scheduleTraversalLocked(false);
Jeff Brownd728bf52012-09-08 18:05:28 -0700435 }
436 }
437
438 /**
Jeff Brownbd6e1502012-08-28 03:27:37 -0700439 * Called when the system is ready to go.
440 */
441 public void systemReady(boolean safeMode, boolean onlyCore) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700442 synchronized (mSyncRoot) {
Jeff Brownbd6e1502012-08-28 03:27:37 -0700443 mSafeMode = safeMode;
444 mOnlyCore = onlyCore;
Winson72dbe7e2019-04-29 14:55:30 -0700445 mSystemReady = true;
446 // Just in case the top inset changed before the system was ready. At this point, any
447 // relevant configuration should be in place.
448 recordTopInsetLocked(mLogicalDisplays.get(Display.DEFAULT_DISPLAY));
Galia Peycheva088d7c02019-12-13 11:27:23 +0100449
450 updateSettingsLocked();
Jeff Brownbd6e1502012-08-28 03:27:37 -0700451 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700452
Ana Kruleca74a8642019-11-14 00:51:00 +0100453 mDisplayModeDirector.setDesiredDisplayModeSpecsListener(
454 new DesiredDisplayModeSpecsObserver());
Long Lingbc841b02019-07-03 16:43:15 -0700455 mDisplayModeDirector.start(mSensorManager);
Michael Wrighta3dab232019-02-22 16:54:21 +0000456
Jeff Brownbd6e1502012-08-28 03:27:37 -0700457 mHandler.sendEmptyMessage(MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS);
Galia Peycheva088d7c02019-12-13 11:27:23 +0100458
459 mSettingsObserver = new SettingsObserver();
Jeff Brownbd6e1502012-08-28 03:27:37 -0700460 }
461
Santos Cordonee8931e2017-04-05 10:31:15 -0700462 @VisibleForTesting
463 Handler getDisplayHandler() {
464 return mHandler;
465 }
466
Michael Wrighteedcbf12017-08-16 23:14:54 +0100467 private void loadStableDisplayValuesLocked() {
468 final Point size = mPersistentDataStore.getStableDisplaySize();
469 if (size.x > 0 && size.y > 0) {
470 // Just set these values directly so we don't write the display persistent data again
471 // unnecessarily
472 mStableDisplaySize.set(size.x, size.y);
473 } else {
474 final Resources res = mContext.getResources();
475 final int width = res.getInteger(
476 com.android.internal.R.integer.config_stableDeviceDisplayWidth);
477 final int height = res.getInteger(
478 com.android.internal.R.integer.config_stableDeviceDisplayHeight);
479 if (width > 0 && height > 0) {
480 setStableDisplaySizeLocked(width, height);
481 }
482 }
483 }
484
485 private Point getStableDisplaySizeInternal() {
486 Point r = new Point();
487 synchronized (mSyncRoot) {
488 if (mStableDisplaySize.x > 0 && mStableDisplaySize.y > 0) {
489 r.set(mStableDisplaySize.x, mStableDisplaySize.y);
490 }
491 }
492 return r;
493 }
494
Jeff Brown4ccb8232014-01-16 22:16:42 -0800495 private void registerDisplayTransactionListenerInternal(
496 DisplayTransactionListener listener) {
Jeff Brown7f3994e2012-12-04 14:04:28 -0800497 // List is self-synchronized copy-on-write.
498 mDisplayTransactionListeners.add(listener);
499 }
500
Jeff Brown4ccb8232014-01-16 22:16:42 -0800501 private void unregisterDisplayTransactionListenerInternal(
502 DisplayTransactionListener listener) {
Jeff Brown7f3994e2012-12-04 14:04:28 -0800503 // List is self-synchronized copy-on-write.
504 mDisplayTransactionListeners.remove(listener);
505 }
506
Jeff Brown4ccb8232014-01-16 22:16:42 -0800507 private void setDisplayInfoOverrideFromWindowManagerInternal(
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700508 int displayId, DisplayInfo info) {
509 synchronized (mSyncRoot) {
Jeff Brownbd6e1502012-08-28 03:27:37 -0700510 LogicalDisplay display = mLogicalDisplays.get(displayId);
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700511 if (display != null) {
Jeff Brownef981a42013-08-07 14:13:37 -0700512 if (display.setDisplayInfoOverrideFromWindowManagerLocked(info)) {
Adrian Roos9ee5dff2018-08-22 20:19:49 +0200513 handleLogicalDisplayChanged(displayId, display);
Craig Mautner65d11b32012-10-01 13:59:52 -0700514 scheduleTraversalLocked(false);
Jeff Brownbd6e1502012-08-28 03:27:37 -0700515 }
Jeff Brownbd6e1502012-08-28 03:27:37 -0700516 }
517 }
518 }
519
Andrii Kuliancd097992017-03-23 18:31:59 -0700520 /**
521 * @see DisplayManagerInternal#getNonOverrideDisplayInfo(int, DisplayInfo)
522 */
523 private void getNonOverrideDisplayInfoInternal(int displayId, DisplayInfo outInfo) {
524 synchronized (mSyncRoot) {
525 final LogicalDisplay display = mLogicalDisplays.get(displayId);
526 if (display != null) {
527 display.getNonOverrideDisplayInfoLocked(outInfo);
528 }
529 }
530 }
531
Santos Cordonee8931e2017-04-05 10:31:15 -0700532 @VisibleForTesting
Robert Carrae606b42018-02-15 15:36:23 -0800533 void performTraversalInternal(SurfaceControl.Transaction t) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700534 synchronized (mSyncRoot) {
535 if (!mPendingTraversal) {
536 return;
Jeff Brownbd6e1502012-08-28 03:27:37 -0700537 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700538 mPendingTraversal = false;
539
Robert Carrae606b42018-02-15 15:36:23 -0800540 performTraversalLocked(t);
Jeff Brownbd6e1502012-08-28 03:27:37 -0700541 }
Jeff Brown7f3994e2012-12-04 14:04:28 -0800542
543 // List is self-synchronized copy-on-write.
544 for (DisplayTransactionListener listener : mDisplayTransactionListeners) {
Vishnu Naire86bd982018-11-28 13:23:17 -0800545 listener.onDisplayTransaction(t);
Jeff Brown7f3994e2012-12-04 14:04:28 -0800546 }
Jeff Brownbd6e1502012-08-28 03:27:37 -0700547 }
548
Fiona Campbelld4eb2952019-11-04 17:19:56 +0000549 private void requestGlobalDisplayStateInternal(int state, float brightnessState) {
Jeff Brown5d6443b2015-04-10 20:15:01 -0700550 if (state == Display.STATE_UNKNOWN) {
551 state = Display.STATE_ON;
552 }
553 if (state == Display.STATE_OFF) {
Fiona Campbelld4eb2952019-11-04 17:19:56 +0000554 brightnessState = PowerManager.BRIGHTNESS_OFF_FLOAT;
555 } else if (brightnessState < PowerManager.BRIGHTNESS_MIN || Float.isNaN(brightnessState)) {
556 brightnessState = PowerManager.BRIGHTNESS_INVALID_FLOAT;
557 } else if (brightnessState > PowerManager.BRIGHTNESS_MAX) {
558 brightnessState = PowerManager.BRIGHTNESS_MAX;
Jeff Brown5d6443b2015-04-10 20:15:01 -0700559 }
560
Jeff Browne75926d2014-09-18 15:24:49 -0700561 synchronized (mTempDisplayStateWorkQueue) {
562 try {
563 // Update the display state within the lock.
Jeff Brown8e5d33e2015-06-10 13:05:50 -0700564 // Note that we do not need to schedule traversals here although it
565 // may happen as a side-effect of displays changing state.
Jeff Browne75926d2014-09-18 15:24:49 -0700566 synchronized (mSyncRoot) {
Jeff Brown5d6443b2015-04-10 20:15:01 -0700567 if (mGlobalDisplayState == state
Fiona Campbelld4eb2952019-11-04 17:19:56 +0000568 && mGlobalDisplayBrightness == brightnessState) {
Jeff Brown5d6443b2015-04-10 20:15:01 -0700569 return; // no change
Jeff Browne75926d2014-09-18 15:24:49 -0700570 }
Jeff Brown5d6443b2015-04-10 20:15:01 -0700571
572 Trace.traceBegin(Trace.TRACE_TAG_POWER, "requestGlobalDisplayState("
573 + Display.stateToString(state)
Fiona Campbelld4eb2952019-11-04 17:19:56 +0000574 + ", brightness=" + brightnessState + ")");
Jeff Brown5d6443b2015-04-10 20:15:01 -0700575 mGlobalDisplayState = state;
Fiona Campbelld4eb2952019-11-04 17:19:56 +0000576 mGlobalDisplayBrightness = brightnessState;
Jeff Brown8e5d33e2015-06-10 13:05:50 -0700577 applyGlobalDisplayStateLocked(mTempDisplayStateWorkQueue);
Jeff Browne75926d2014-09-18 15:24:49 -0700578 }
579
580 // Setting the display power state can take hundreds of milliseconds
581 // to complete so we defer the most expensive part of the work until
582 // after we have exited the critical section to avoid blocking other
583 // threads for a long time.
584 for (int i = 0; i < mTempDisplayStateWorkQueue.size(); i++) {
585 mTempDisplayStateWorkQueue.get(i).run();
586 }
Jeff Brown5d6443b2015-04-10 20:15:01 -0700587 Trace.traceEnd(Trace.TRACE_TAG_POWER);
Jeff Browne75926d2014-09-18 15:24:49 -0700588 } finally {
589 mTempDisplayStateWorkQueue.clear();
Jeff Brown9e316a12012-10-08 19:17:06 -0700590 }
591 }
592 }
593
Galia Peycheva088d7c02019-12-13 11:27:23 +0100594 private class SettingsObserver extends ContentObserver {
595 SettingsObserver() {
596 super(mHandler);
597
598 mContext.getContentResolver().registerContentObserver(
599 Settings.Secure.getUriFor(
600 Settings.Secure.MINIMAL_POST_PROCESSING_ALLOWED), false, this);
601 }
602
603 @Override
604 public void onChange(boolean selfChange, Uri uri) {
605 handleSettingsChange();
606 }
607 }
608
609 private void handleSettingsChange() {
610 synchronized (mSyncRoot) {
611 updateSettingsLocked();
612 scheduleTraversalLocked(false);
613 }
614 }
615
616 private void updateSettingsLocked() {
617 mMinimalPostProcessingAllowed = Settings.Secure.getIntForUser(mContext.getContentResolver(),
618 Settings.Secure.MINIMAL_POST_PROCESSING_ALLOWED, 1, UserHandle.USER_CURRENT) != 0;
619 }
620
Jeff Brown4ccb8232014-01-16 22:16:42 -0800621 private DisplayInfo getDisplayInfoInternal(int displayId, int callingUid) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700622 synchronized (mSyncRoot) {
Jeff Brown4ccb8232014-01-16 22:16:42 -0800623 LogicalDisplay display = mLogicalDisplays.get(displayId);
624 if (display != null) {
625 DisplayInfo info = display.getDisplayInfoLocked();
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800626 if (info.hasAccess(callingUid)
627 || isUidPresentOnDisplayInternal(callingUid, displayId)) {
Jeff Brown4ccb8232014-01-16 22:16:42 -0800628 return info;
629 }
630 }
631 return null;
632 }
633 }
634
635 private int[] getDisplayIdsInternal(int callingUid) {
636 synchronized (mSyncRoot) {
637 final int count = mLogicalDisplays.size();
638 int[] displayIds = new int[count];
639 int n = 0;
640 for (int i = 0; i < count; i++) {
641 LogicalDisplay display = mLogicalDisplays.valueAt(i);
642 DisplayInfo info = display.getDisplayInfoLocked();
643 if (info.hasAccess(callingUid)) {
644 displayIds[n++] = mLogicalDisplays.keyAt(i);
645 }
646 }
647 if (n != count) {
648 displayIds = Arrays.copyOfRange(displayIds, 0, n);
649 }
650 return displayIds;
651 }
652 }
653
654 private void registerCallbackInternal(IDisplayManagerCallback callback, int callingPid) {
655 synchronized (mSyncRoot) {
Jeff Brownbd6e1502012-08-28 03:27:37 -0700656 if (mCallbacks.get(callingPid) != null) {
657 throw new SecurityException("The calling process has already "
658 + "registered an IDisplayManagerCallback.");
Jeff Brown64a55af2012-08-26 02:47:39 -0700659 }
660
Jeff Brownbd6e1502012-08-28 03:27:37 -0700661 CallbackRecord record = new CallbackRecord(callingPid, callback);
662 try {
663 IBinder binder = callback.asBinder();
664 binder.linkToDeath(record, 0);
665 } catch (RemoteException ex) {
666 // give up
667 throw new RuntimeException(ex);
668 }
669
670 mCallbacks.put(callingPid, record);
671 }
672 }
673
Jeff Brownce468a32013-11-21 16:42:03 -0800674 private void onCallbackDied(CallbackRecord record) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700675 synchronized (mSyncRoot) {
Jeff Brownce468a32013-11-21 16:42:03 -0800676 mCallbacks.remove(record.mPid);
677 stopWifiDisplayScanLocked(record);
Jeff Brownbd6e1502012-08-28 03:27:37 -0700678 }
679 }
680
Jeff Brown4ccb8232014-01-16 22:16:42 -0800681 private void startWifiDisplayScanInternal(int callingPid) {
682 synchronized (mSyncRoot) {
683 CallbackRecord record = mCallbacks.get(callingPid);
684 if (record == null) {
685 throw new IllegalStateException("The calling process has not "
686 + "registered an IDisplayManagerCallback.");
Jeff Browne08ae382012-09-07 20:36:36 -0700687 }
Jeff Brown4ccb8232014-01-16 22:16:42 -0800688 startWifiDisplayScanLocked(record);
Jeff Browne08ae382012-09-07 20:36:36 -0700689 }
690 }
691
Jeff Brownce468a32013-11-21 16:42:03 -0800692 private void startWifiDisplayScanLocked(CallbackRecord record) {
693 if (!record.mWifiDisplayScanRequested) {
694 record.mWifiDisplayScanRequested = true;
695 if (mWifiDisplayScanRequestCount++ == 0) {
696 if (mWifiDisplayAdapter != null) {
697 mWifiDisplayAdapter.requestStartScanLocked();
698 }
699 }
700 }
701 }
702
Jeff Brown4ccb8232014-01-16 22:16:42 -0800703 private void stopWifiDisplayScanInternal(int callingPid) {
704 synchronized (mSyncRoot) {
705 CallbackRecord record = mCallbacks.get(callingPid);
706 if (record == null) {
707 throw new IllegalStateException("The calling process has not "
708 + "registered an IDisplayManagerCallback.");
Jeff Brownce468a32013-11-21 16:42:03 -0800709 }
Jeff Brown4ccb8232014-01-16 22:16:42 -0800710 stopWifiDisplayScanLocked(record);
Jeff Brownce468a32013-11-21 16:42:03 -0800711 }
712 }
713
714 private void stopWifiDisplayScanLocked(CallbackRecord record) {
715 if (record.mWifiDisplayScanRequested) {
716 record.mWifiDisplayScanRequested = false;
717 if (--mWifiDisplayScanRequestCount == 0) {
718 if (mWifiDisplayAdapter != null) {
719 mWifiDisplayAdapter.requestStopScanLocked();
720 }
721 } else if (mWifiDisplayScanRequestCount < 0) {
Dianne Hackborn8d051722014-10-01 14:59:58 -0700722 Slog.wtf(TAG, "mWifiDisplayScanRequestCount became negative: "
Jeff Brownce468a32013-11-21 16:42:03 -0800723 + mWifiDisplayScanRequestCount);
724 mWifiDisplayScanRequestCount = 0;
725 }
726 }
727 }
728
Jeff Brown4ccb8232014-01-16 22:16:42 -0800729 private void connectWifiDisplayInternal(String address) {
730 synchronized (mSyncRoot) {
731 if (mWifiDisplayAdapter != null) {
732 mWifiDisplayAdapter.requestConnectLocked(address);
Jeff Browne08ae382012-09-07 20:36:36 -0700733 }
Jeff Browne08ae382012-09-07 20:36:36 -0700734 }
735 }
736
Jeff Brown4ccb8232014-01-16 22:16:42 -0800737 private void pauseWifiDisplayInternal() {
738 synchronized (mSyncRoot) {
739 if (mWifiDisplayAdapter != null) {
740 mWifiDisplayAdapter.requestPauseLocked();
Chong Zhang1f3ecaa2013-05-03 15:55:36 -0700741 }
Chong Zhang1f3ecaa2013-05-03 15:55:36 -0700742 }
743 }
744
Jeff Brown4ccb8232014-01-16 22:16:42 -0800745 private void resumeWifiDisplayInternal() {
746 synchronized (mSyncRoot) {
747 if (mWifiDisplayAdapter != null) {
748 mWifiDisplayAdapter.requestResumeLocked();
Chong Zhang1f3ecaa2013-05-03 15:55:36 -0700749 }
Chong Zhang1f3ecaa2013-05-03 15:55:36 -0700750 }
751 }
752
Jeff Brown4ccb8232014-01-16 22:16:42 -0800753 private void disconnectWifiDisplayInternal() {
754 synchronized (mSyncRoot) {
755 if (mWifiDisplayAdapter != null) {
756 mWifiDisplayAdapter.requestDisconnectLocked();
Jeff Browne08ae382012-09-07 20:36:36 -0700757 }
Jeff Browne08ae382012-09-07 20:36:36 -0700758 }
759 }
760
Jeff Brown4ccb8232014-01-16 22:16:42 -0800761 private void renameWifiDisplayInternal(String address, String alias) {
762 synchronized (mSyncRoot) {
763 if (mWifiDisplayAdapter != null) {
764 mWifiDisplayAdapter.requestRenameLocked(address, alias);
Jeff Brown89d55462012-09-19 11:33:42 -0700765 }
Jeff Brown89d55462012-09-19 11:33:42 -0700766 }
767 }
768
Jeff Brown4ccb8232014-01-16 22:16:42 -0800769 private void forgetWifiDisplayInternal(String address) {
770 synchronized (mSyncRoot) {
771 if (mWifiDisplayAdapter != null) {
772 mWifiDisplayAdapter.requestForgetLocked(address);
Jeff Brown89d55462012-09-19 11:33:42 -0700773 }
Jeff Brown89d55462012-09-19 11:33:42 -0700774 }
775 }
776
Jeff Brown4ccb8232014-01-16 22:16:42 -0800777 private WifiDisplayStatus getWifiDisplayStatusInternal() {
778 synchronized (mSyncRoot) {
779 if (mWifiDisplayAdapter != null) {
780 return mWifiDisplayAdapter.getWifiDisplayStatusLocked();
Jeff Browne08ae382012-09-07 20:36:36 -0700781 }
Jeff Brown4ccb8232014-01-16 22:16:42 -0800782 return new WifiDisplayStatus();
Jeff Browne08ae382012-09-07 20:36:36 -0700783 }
784 }
785
Michael Wright1c9977b2016-07-12 13:30:10 -0700786 private void requestColorModeInternal(int displayId, int colorMode) {
Michael Wright58e829f2015-09-15 00:13:26 +0100787 synchronized (mSyncRoot) {
788 LogicalDisplay display = mLogicalDisplays.get(displayId);
789 if (display != null &&
Michael Wright1c9977b2016-07-12 13:30:10 -0700790 display.getRequestedColorModeLocked() != colorMode) {
791 display.setRequestedColorModeLocked(colorMode);
Michael Wright58e829f2015-09-15 00:13:26 +0100792 scheduleTraversalLocked(false);
793 }
794 }
795 }
796
Michael Wright75ee9fc2014-09-01 19:55:22 -0700797 private int createVirtualDisplayInternal(IVirtualDisplayCallback callback,
b0202.jung925435c2020-01-08 18:46:59 +0900798 IMediaProjection projection, int callingUid, String packageName, Surface surface,
799 int flags, VirtualDisplayConfig virtualDisplayConfig) {
Jeff Brown4ccb8232014-01-16 22:16:42 -0800800 synchronized (mSyncRoot) {
801 if (mVirtualDisplayAdapter == null) {
802 Slog.w(TAG, "Rejecting request to create private virtual display "
803 + "because the virtual display adapter is not available.");
804 return -1;
Jeff Brown7d00aff2013-08-02 19:03:49 -0700805 }
Jeff Brown4ccb8232014-01-16 22:16:42 -0800806
807 DisplayDevice device = mVirtualDisplayAdapter.createVirtualDisplayLocked(
b0202.jung925435c2020-01-08 18:46:59 +0900808 callback, projection, callingUid, packageName, surface, flags,
809 virtualDisplayConfig);
Jeff Brown4ccb8232014-01-16 22:16:42 -0800810 if (device == null) {
811 return -1;
Jeff Brown7d00aff2013-08-02 19:03:49 -0700812 }
Jeff Browna506a6e2013-06-04 00:02:38 -0700813
Jeff Brown4ccb8232014-01-16 22:16:42 -0800814 handleDisplayDeviceAddedLocked(device);
815 LogicalDisplay display = findLogicalDisplayForDeviceLocked(device);
816 if (display != null) {
817 return display.getDisplayIdLocked();
Jeff Browna506a6e2013-06-04 00:02:38 -0700818 }
Jeff Brown4ccb8232014-01-16 22:16:42 -0800819
820 // Something weird happened and the logical display was not created.
821 Slog.w(TAG, "Rejecting request to create virtual display "
822 + "because the logical display was not created.");
Michael Wright75ee9fc2014-09-01 19:55:22 -0700823 mVirtualDisplayAdapter.releaseVirtualDisplayLocked(callback.asBinder());
Jeff Brown4ccb8232014-01-16 22:16:42 -0800824 handleDisplayDeviceRemovedLocked(device);
Jeff Browna506a6e2013-06-04 00:02:38 -0700825 }
826 return -1;
827 }
828
Michael Wright01e840f2014-06-26 16:03:25 -0700829 private void resizeVirtualDisplayInternal(IBinder appToken,
830 int width, int height, int densityDpi) {
831 synchronized (mSyncRoot) {
832 if (mVirtualDisplayAdapter == null) {
833 return;
834 }
835
836 mVirtualDisplayAdapter.resizeVirtualDisplayLocked(appToken, width, height, densityDpi);
837 }
838 }
839
Jeff Brown92207df2014-04-16 13:16:07 -0700840 private void setVirtualDisplaySurfaceInternal(IBinder appToken, Surface surface) {
841 synchronized (mSyncRoot) {
842 if (mVirtualDisplayAdapter == null) {
843 return;
844 }
845
846 mVirtualDisplayAdapter.setVirtualDisplaySurfaceLocked(appToken, surface);
847 }
848 }
849
Jeff Brown4ccb8232014-01-16 22:16:42 -0800850 private void releaseVirtualDisplayInternal(IBinder appToken) {
851 synchronized (mSyncRoot) {
852 if (mVirtualDisplayAdapter == null) {
853 return;
Jeff Browna506a6e2013-06-04 00:02:38 -0700854 }
Jeff Browna506a6e2013-06-04 00:02:38 -0700855
Jeff Brown4ccb8232014-01-16 22:16:42 -0800856 DisplayDevice device =
857 mVirtualDisplayAdapter.releaseVirtualDisplayLocked(appToken);
858 if (device != null) {
859 handleDisplayDeviceRemovedLocked(device);
Jeff Browna506a6e2013-06-04 00:02:38 -0700860 }
861 }
Jeff Browna506a6e2013-06-04 00:02:38 -0700862 }
863
chaviwda4c6942018-11-07 15:52:56 -0800864 private void setVirtualDisplayStateInternal(IBinder appToken, boolean isOn) {
865 synchronized (mSyncRoot) {
866 if (mVirtualDisplayAdapter == null) {
867 return;
868 }
869
870 mVirtualDisplayAdapter.setVirtualDisplayStateLocked(appToken, isOn);
871 }
872 }
873
Santos Cordonc22c5632017-06-21 16:03:49 -0700874 private void registerDefaultDisplayAdapters() {
875 // Register default display adapters.
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700876 synchronized (mSyncRoot) {
Santos Cordonc22c5632017-06-21 16:03:49 -0700877 // main display adapter
Mike Lockwoode63f6f72013-11-15 11:01:47 -0800878 registerDisplayAdapterLocked(new LocalDisplayAdapter(
879 mSyncRoot, mContext, mHandler, mDisplayAdapterListener));
Santos Cordonc22c5632017-06-21 16:03:49 -0700880
881 // Standalone VR devices rely on a virtual display as their primary display for
882 // 2D UI. We register virtual display adapter along side the main display adapter
883 // here so that it is ready by the time the system sends the home Intent for
884 // early apps like SetupWizard/Launcher. In particular, SUW is displayed using
885 // the virtual display inside VR before any VR-specific apps even run.
886 mVirtualDisplayAdapter = mInjector.getVirtualDisplayAdapter(mSyncRoot, mContext,
887 mHandler, mDisplayAdapterListener);
888 if (mVirtualDisplayAdapter != null) {
889 registerDisplayAdapterLocked(mVirtualDisplayAdapter);
890 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700891 }
892 }
893
894 private void registerAdditionalDisplayAdapters() {
895 synchronized (mSyncRoot) {
896 if (shouldRegisterNonEssentialDisplayAdaptersLocked()) {
Jeff Brown89d55462012-09-19 11:33:42 -0700897 registerOverlayDisplayAdapterLocked();
898 registerWifiDisplayAdapterLocked();
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700899 }
900 }
901 }
902
Jeff Brown89d55462012-09-19 11:33:42 -0700903 private void registerOverlayDisplayAdapterLocked() {
904 registerDisplayAdapterLocked(new OverlayDisplayAdapter(
905 mSyncRoot, mContext, mHandler, mDisplayAdapterListener, mUiHandler));
906 }
907
908 private void registerWifiDisplayAdapterLocked() {
909 if (mContext.getResources().getBoolean(
Jeff Brownbbd28a22012-09-20 16:47:15 -0700910 com.android.internal.R.bool.config_enableWifiDisplay)
911 || SystemProperties.getInt(FORCE_WIFI_DISPLAY_ENABLE, -1) == 1) {
Jeff Brown89d55462012-09-19 11:33:42 -0700912 mWifiDisplayAdapter = new WifiDisplayAdapter(
913 mSyncRoot, mContext, mHandler, mDisplayAdapterListener,
914 mPersistentDataStore);
915 registerDisplayAdapterLocked(mWifiDisplayAdapter);
916 }
917 }
918
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700919 private boolean shouldRegisterNonEssentialDisplayAdaptersLocked() {
920 // In safe mode, we disable non-essential display adapters to give the user
921 // an opportunity to fix broken settings or other problems that might affect
922 // system stability.
923 // In only-core mode, we disable non-essential display adapters to minimize
924 // the number of dependencies that are started while in this mode and to
925 // prevent problems that might occur due to the device being encrypted.
926 return !mSafeMode && !mOnlyCore;
927 }
928
929 private void registerDisplayAdapterLocked(DisplayAdapter adapter) {
930 mDisplayAdapters.add(adapter);
931 adapter.registerLocked();
932 }
933
Jeff Brownbd6e1502012-08-28 03:27:37 -0700934 private void handleDisplayDeviceAdded(DisplayDevice device) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700935 synchronized (mSyncRoot) {
Jeff Browna506a6e2013-06-04 00:02:38 -0700936 handleDisplayDeviceAddedLocked(device);
Jeff Brownbd6e1502012-08-28 03:27:37 -0700937 }
938 }
939
Jeff Browna506a6e2013-06-04 00:02:38 -0700940 private void handleDisplayDeviceAddedLocked(DisplayDevice device) {
Jeff Brown10acf6d2015-04-14 14:20:47 -0700941 DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
Jeff Browna506a6e2013-06-04 00:02:38 -0700942 if (mDisplayDevices.contains(device)) {
Jeff Brown10acf6d2015-04-14 14:20:47 -0700943 Slog.w(TAG, "Attempted to add already added display device: " + info);
Jeff Browna506a6e2013-06-04 00:02:38 -0700944 return;
945 }
946
Jeff Brown10acf6d2015-04-14 14:20:47 -0700947 Slog.i(TAG, "Display device added: " + info);
948 device.mDebugLastLoggedDeviceInfo = info;
Jeff Browna506a6e2013-06-04 00:02:38 -0700949
950 mDisplayDevices.add(device);
Michael Wright1c9977b2016-07-12 13:30:10 -0700951 LogicalDisplay display = addLogicalDisplayLocked(device);
Jeff Brown0033a862014-10-08 12:06:39 -0700952 Runnable work = updateDisplayStateLocked(device);
953 if (work != null) {
954 work.run();
955 }
Jeff Browna506a6e2013-06-04 00:02:38 -0700956 scheduleTraversalLocked(false);
957 }
958
Jeff Brownbd6e1502012-08-28 03:27:37 -0700959 private void handleDisplayDeviceChanged(DisplayDevice device) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700960 synchronized (mSyncRoot) {
Jeff Brown10acf6d2015-04-14 14:20:47 -0700961 DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
Jeff Brownbd6e1502012-08-28 03:27:37 -0700962 if (!mDisplayDevices.contains(device)) {
Jeff Brown10acf6d2015-04-14 14:20:47 -0700963 Slog.w(TAG, "Attempted to change non-existent display device: " + info);
Jeff Brownbd6e1502012-08-28 03:27:37 -0700964 return;
965 }
966
Jeff Brown10acf6d2015-04-14 14:20:47 -0700967 int diff = device.mDebugLastLoggedDeviceInfo.diff(info);
968 if (diff == DisplayDeviceInfo.DIFF_STATE) {
969 Slog.i(TAG, "Display device changed state: \"" + info.name
970 + "\", " + Display.stateToString(info.state));
971 } else if (diff != 0) {
972 Slog.i(TAG, "Display device changed: " + info);
973 }
Michael Wright1c9977b2016-07-12 13:30:10 -0700974 if ((diff & DisplayDeviceInfo.DIFF_COLOR_MODE) != 0) {
975 try {
976 mPersistentDataStore.setColorMode(device, info.colorMode);
977 } finally {
978 mPersistentDataStore.saveIfNeeded();
979 }
980 }
Jeff Brown10acf6d2015-04-14 14:20:47 -0700981 device.mDebugLastLoggedDeviceInfo = info;
Jeff Browne87bf032012-09-20 18:30:13 -0700982
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700983 device.applyPendingDisplayDeviceInfoChangesLocked();
984 if (updateLogicalDisplaysLocked()) {
Craig Mautner65d11b32012-10-01 13:59:52 -0700985 scheduleTraversalLocked(false);
Jeff Brown64a55af2012-08-26 02:47:39 -0700986 }
987 }
988 }
989
Jeff Brownbd6e1502012-08-28 03:27:37 -0700990 private void handleDisplayDeviceRemoved(DisplayDevice device) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700991 synchronized (mSyncRoot) {
Jeff Browna506a6e2013-06-04 00:02:38 -0700992 handleDisplayDeviceRemovedLocked(device);
993 }
994 }
Jeff Brown8e5d33e2015-06-10 13:05:50 -0700995
Jeff Browna506a6e2013-06-04 00:02:38 -0700996 private void handleDisplayDeviceRemovedLocked(DisplayDevice device) {
Jeff Brown10acf6d2015-04-14 14:20:47 -0700997 DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
Jeff Browna506a6e2013-06-04 00:02:38 -0700998 if (!mDisplayDevices.remove(device)) {
Jeff Brown10acf6d2015-04-14 14:20:47 -0700999 Slog.w(TAG, "Attempted to remove non-existent display device: " + info);
Jeff Browna506a6e2013-06-04 00:02:38 -07001000 return;
1001 }
1002
Jeff Brown10acf6d2015-04-14 14:20:47 -07001003 Slog.i(TAG, "Display device removed: " + info);
1004 device.mDebugLastLoggedDeviceInfo = info;
Jeff Browna506a6e2013-06-04 00:02:38 -07001005
Jeff Browna506a6e2013-06-04 00:02:38 -07001006 updateLogicalDisplaysLocked();
1007 scheduleTraversalLocked(false);
1008 }
1009
Adrian Roos9ee5dff2018-08-22 20:19:49 +02001010 private void handleLogicalDisplayChanged(int displayId, @NonNull LogicalDisplay display) {
1011 if (displayId == Display.DEFAULT_DISPLAY) {
1012 recordTopInsetLocked(display);
1013 }
Tim Murray890ceb52020-01-30 10:12:40 -08001014 // We don't bother invalidating the display info caches here because any changes to the
1015 // display info will trigger a cache invalidation inside of LogicalDisplay before we hit
1016 // this point.
Adrian Roos9ee5dff2018-08-22 20:19:49 +02001017 sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_CHANGED);
1018 }
1019
Tim Murray890ceb52020-01-30 10:12:40 -08001020 private void handleLogicalDisplayRemoved(int displayId) {
1021 DisplayManagerGlobal.invalidateLocalDisplayInfoCaches();
1022 sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_REMOVED);
1023 }
1024
Jeff Brown8e5d33e2015-06-10 13:05:50 -07001025 private void applyGlobalDisplayStateLocked(List<Runnable> workQueue) {
Jeff Browna506a6e2013-06-04 00:02:38 -07001026 final int count = mDisplayDevices.size();
1027 for (int i = 0; i < count; i++) {
1028 DisplayDevice device = mDisplayDevices.get(i);
Jeff Browne75926d2014-09-18 15:24:49 -07001029 Runnable runnable = updateDisplayStateLocked(device);
1030 if (runnable != null) {
1031 workQueue.add(runnable);
1032 }
Jeff Browna506a6e2013-06-04 00:02:38 -07001033 }
1034 }
1035
Jeff Browne75926d2014-09-18 15:24:49 -07001036 private Runnable updateDisplayStateLocked(DisplayDevice device) {
Jeff Browna506a6e2013-06-04 00:02:38 -07001037 // Blank or unblank the display immediately to match the state requested
Jeff Brown037c33e2014-04-09 00:31:55 -07001038 // by the display power controller (if known).
Jeff Browna506a6e2013-06-04 00:02:38 -07001039 DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
1040 if ((info.flags & DisplayDeviceInfo.FLAG_NEVER_BLANK) == 0) {
Fiona Campbelld4eb2952019-11-04 17:19:56 +00001041 return device.requestDisplayStateLocked(
1042 mGlobalDisplayState, mGlobalDisplayBrightness);
Craig Mautner4f67ba62012-08-02 11:23:00 -07001043 }
Jeff Browne75926d2014-09-18 15:24:49 -07001044 return null;
Craig Mautner4f67ba62012-08-02 11:23:00 -07001045 }
1046
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001047 // Adds a new logical display based on the given display device.
1048 // Sends notifications if needed.
Michael Wright1c9977b2016-07-12 13:30:10 -07001049 private LogicalDisplay addLogicalDisplayLocked(DisplayDevice device) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001050 DisplayDeviceInfo deviceInfo = device.getDisplayDeviceInfoLocked();
1051 boolean isDefault = (deviceInfo.flags
1052 & DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY) != 0;
1053 if (isDefault && mLogicalDisplays.get(Display.DEFAULT_DISPLAY) != null) {
1054 Slog.w(TAG, "Ignoring attempt to add a second default display: " + deviceInfo);
1055 isDefault = false;
1056 }
1057
Jeff Brown27f1d672012-10-17 18:32:34 -07001058 if (!isDefault && mSingleDisplayDemoMode) {
1059 Slog.i(TAG, "Not creating a logical display for a secondary display "
1060 + " because single display demo mode is enabled: " + deviceInfo);
Michael Wright1c9977b2016-07-12 13:30:10 -07001061 return null;
Jeff Brown27f1d672012-10-17 18:32:34 -07001062 }
1063
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001064 final int displayId = assignDisplayIdLocked(isDefault);
1065 final int layerStack = assignLayerStackLocked(displayId);
1066
Jeff Brownd728bf52012-09-08 18:05:28 -07001067 LogicalDisplay display = new LogicalDisplay(displayId, layerStack, device);
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001068 display.updateLocked(mDisplayDevices);
1069 if (!display.isValidLocked()) {
1070 // This should never happen currently.
1071 Slog.w(TAG, "Ignoring display device because the logical display "
1072 + "created from it was not considered valid: " + deviceInfo);
Michael Wright1c9977b2016-07-12 13:30:10 -07001073 return null;
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001074 }
1075
Michael Wrighteedcbf12017-08-16 23:14:54 +01001076 configureColorModeLocked(display, device);
1077 if (isDefault) {
1078 recordStableDisplayStatsIfNeededLocked(display);
Adrian Roos9ee5dff2018-08-22 20:19:49 +02001079 recordTopInsetLocked(display);
Michael Wrighteedcbf12017-08-16 23:14:54 +01001080 }
1081
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001082 mLogicalDisplays.put(displayId, display);
Tim Murray890ceb52020-01-30 10:12:40 -08001083 DisplayManagerGlobal.invalidateLocalDisplayInfoCaches();
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001084
1085 // Wake up waitForDefaultDisplay.
1086 if (isDefault) {
1087 mSyncRoot.notifyAll();
1088 }
1089
1090 sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_ADDED);
Michael Wright1c9977b2016-07-12 13:30:10 -07001091 return display;
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001092 }
1093
1094 private int assignDisplayIdLocked(boolean isDefault) {
1095 return isDefault ? Display.DEFAULT_DISPLAY : mNextNonDefaultDisplayId++;
1096 }
1097
1098 private int assignLayerStackLocked(int displayId) {
1099 // Currently layer stacks and display ids are the same.
1100 // This need not be the case.
1101 return displayId;
1102 }
1103
Michael Wrighteedcbf12017-08-16 23:14:54 +01001104 private void configureColorModeLocked(LogicalDisplay display, DisplayDevice device) {
1105 if (display.getPrimaryDisplayDeviceLocked() == device) {
1106 int colorMode = mPersistentDataStore.getColorMode(device);
1107 if (colorMode == Display.COLOR_MODE_INVALID) {
1108 if ((device.getDisplayDeviceInfoLocked().flags
1109 & DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY) != 0) {
1110 colorMode = mDefaultDisplayDefaultColorMode;
1111 } else {
1112 colorMode = Display.COLOR_MODE_DEFAULT;
1113 }
1114 }
1115 display.setRequestedColorModeLocked(colorMode);
1116 }
1117 }
1118
1119 // If we've never recorded stable device stats for this device before and they aren't
1120 // explicitly configured, go ahead and record the stable device stats now based on the status
1121 // of the default display at first boot.
1122 private void recordStableDisplayStatsIfNeededLocked(LogicalDisplay d) {
1123 if (mStableDisplaySize.x <= 0 && mStableDisplaySize.y <= 0) {
1124 DisplayInfo info = d.getDisplayInfoLocked();
1125 setStableDisplaySizeLocked(info.getNaturalWidth(), info.getNaturalHeight());
1126 }
1127 }
1128
Adrian Roos9ee5dff2018-08-22 20:19:49 +02001129 private void recordTopInsetLocked(@Nullable LogicalDisplay d) {
Winson72dbe7e2019-04-29 14:55:30 -07001130 // We must only persist the inset after boot has completed, otherwise we will end up
1131 // overwriting the persisted value before the masking flag has been loaded from the
1132 // resource overlay.
1133 if (!mSystemReady || d == null) {
Adrian Roos9ee5dff2018-08-22 20:19:49 +02001134 return;
1135 }
1136 int topInset = d.getInsets().top;
1137 if (topInset == mDefaultDisplayTopInset) {
1138 return;
1139 }
1140 mDefaultDisplayTopInset = topInset;
1141 SystemProperties.set(PROP_DEFAULT_DISPLAY_TOP_INSET, Integer.toString(topInset));
1142 }
1143
Michael Wrighteedcbf12017-08-16 23:14:54 +01001144 private void setStableDisplaySizeLocked(int width, int height) {
1145 mStableDisplaySize = new Point(width, height);
1146 try {
1147 mPersistentDataStore.setStableDisplaySize(mStableDisplaySize);
1148 } finally {
1149 mPersistentDataStore.saveIfNeeded();
1150 }
1151 }
1152
Dan Gittik122df862018-03-28 16:59:22 +01001153 @VisibleForTesting
1154 Curve getMinimumBrightnessCurveInternal() {
1155 return mMinimumBrightnessCurve;
1156 }
1157
Peiyong Lin277eaff2019-01-16 16:18:22 -08001158 int getPreferredWideGamutColorSpaceIdInternal() {
1159 return mWideColorSpace.getId();
1160 }
1161
Michael Wrighteef0e132017-11-21 17:57:52 +00001162 private void setBrightnessConfigurationForUserInternal(
Dan Gittik7a32fba2018-03-28 12:19:38 +01001163 @Nullable BrightnessConfiguration c, @UserIdInt int userId,
Kenny Guy05ce8092018-01-17 13:44:20 +00001164 @Nullable String packageName) {
Dan Gittik122df862018-03-28 16:59:22 +01001165 validateBrightnessConfiguration(c);
Michael Wrighteef0e132017-11-21 17:57:52 +00001166 final int userSerial = getUserManager().getUserSerialNumber(userId);
1167 synchronized (mSyncRoot) {
1168 try {
Kenny Guy05ce8092018-01-17 13:44:20 +00001169 mPersistentDataStore.setBrightnessConfigurationForUser(c, userSerial,
1170 packageName);
Michael Wrighteef0e132017-11-21 17:57:52 +00001171 } finally {
1172 mPersistentDataStore.saveIfNeeded();
1173 }
1174 if (userId == mCurrentUserId) {
1175 mDisplayPowerController.setBrightnessConfiguration(c);
1176 }
1177 }
1178 }
1179
Dan Gittik122df862018-03-28 16:59:22 +01001180 @VisibleForTesting
1181 void validateBrightnessConfiguration(BrightnessConfiguration config) {
1182 if (config == null) {
1183 return;
1184 }
1185 if (isBrightnessConfigurationTooDark(config)) {
1186 throw new IllegalArgumentException("brightness curve is too dark");
1187 }
1188 }
1189
1190 private boolean isBrightnessConfigurationTooDark(BrightnessConfiguration config) {
1191 Pair<float[], float[]> curve = config.getCurve();
1192 float[] lux = curve.first;
1193 float[] nits = curve.second;
1194 for (int i = 0; i < lux.length; i++) {
1195 if (nits[i] < mMinimumBrightnessSpline.interpolate(lux[i])) {
1196 return true;
1197 }
1198 }
1199 return false;
1200 }
1201
Michael Wrighteef0e132017-11-21 17:57:52 +00001202 private void loadBrightnessConfiguration() {
1203 synchronized (mSyncRoot) {
1204 final int userSerial = getUserManager().getUserSerialNumber(mCurrentUserId);
1205 BrightnessConfiguration config =
1206 mPersistentDataStore.getBrightnessConfiguration(userSerial);
1207 mDisplayPowerController.setBrightnessConfiguration(config);
1208 }
1209 }
1210
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001211 // Updates all existing logical displays given the current set of display devices.
1212 // Removes invalid logical displays.
1213 // Sends notifications if needed.
1214 private boolean updateLogicalDisplaysLocked() {
1215 boolean changed = false;
1216 for (int i = mLogicalDisplays.size(); i-- > 0; ) {
1217 final int displayId = mLogicalDisplays.keyAt(i);
1218 LogicalDisplay display = mLogicalDisplays.valueAt(i);
1219
1220 mTempDisplayInfo.copyFrom(display.getDisplayInfoLocked());
1221 display.updateLocked(mDisplayDevices);
1222 if (!display.isValidLocked()) {
1223 mLogicalDisplays.removeAt(i);
Tim Murray890ceb52020-01-30 10:12:40 -08001224 handleLogicalDisplayRemoved(displayId);
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001225 changed = true;
1226 } else if (!mTempDisplayInfo.equals(display.getDisplayInfoLocked())) {
Adrian Roos9ee5dff2018-08-22 20:19:49 +02001227 handleLogicalDisplayChanged(displayId, display);
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001228 changed = true;
1229 }
1230 }
1231 return changed;
1232 }
1233
Robert Carrae606b42018-02-15 15:36:23 -08001234 private void performTraversalLocked(SurfaceControl.Transaction t) {
Jeff Brownd728bf52012-09-08 18:05:28 -07001235 // Clear all viewports before configuring displays so that we can keep
1236 // track of which ones we have configured.
1237 clearViewportsLocked();
1238
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001239 // Configure each display device.
1240 final int count = mDisplayDevices.size();
1241 for (int i = 0; i < count; i++) {
1242 DisplayDevice device = mDisplayDevices.get(i);
Robert Carrae606b42018-02-15 15:36:23 -08001243 configureDisplayLocked(t, device);
1244 device.performTraversalLocked(t);
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001245 }
Jeff Brownd728bf52012-09-08 18:05:28 -07001246
1247 // Tell the input system about these new viewports.
Jeff Brown4ccb8232014-01-16 22:16:42 -08001248 if (mInputManagerInternal != null) {
Jeff Brownd728bf52012-09-08 18:05:28 -07001249 mHandler.sendEmptyMessage(MSG_UPDATE_VIEWPORT);
1250 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001251 }
1252
Michael Wright3f145a22014-07-22 19:46:03 -07001253 private void setDisplayPropertiesInternal(int displayId, boolean hasContent,
Galia Peycheva088d7c02019-12-13 11:27:23 +01001254 float requestedRefreshRate, int requestedModeId, boolean preferMinimalPostProcessing,
Galia Peycheva056b3ee2019-06-26 14:05:12 +02001255 boolean inTraversal) {
Craig Mautner722285e2012-09-07 13:55:58 -07001256 synchronized (mSyncRoot) {
1257 LogicalDisplay display = mLogicalDisplays.get(displayId);
Michael Wright3f145a22014-07-22 19:46:03 -07001258 if (display == null) {
1259 return;
1260 }
Galia Peycheva056b3ee2019-06-26 14:05:12 +02001261
1262 boolean shouldScheduleTraversal = false;
1263
Michael Wright3f145a22014-07-22 19:46:03 -07001264 if (display.hasContentLocked() != hasContent) {
Jeff Brown33041bd2013-08-02 21:11:14 -07001265 if (DEBUG) {
1266 Slog.d(TAG, "Display " + displayId + " hasContent flag changed: "
1267 + "hasContent=" + hasContent + ", inTraversal=" + inTraversal);
1268 }
1269
Craig Mautner722285e2012-09-07 13:55:58 -07001270 display.setHasContentLocked(hasContent);
Galia Peycheva056b3ee2019-06-26 14:05:12 +02001271 shouldScheduleTraversal = true;
Craig Mautner722285e2012-09-07 13:55:58 -07001272 }
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -07001273 if (requestedModeId == 0 && requestedRefreshRate != 0) {
1274 // Scan supported modes returned by display.getInfo() to find a mode with the same
1275 // size as the default display mode but with the specified refresh rate instead.
1276 requestedModeId = display.getDisplayInfoLocked().findDefaultModeByRefreshRate(
1277 requestedRefreshRate);
1278 }
Michael Wrighta3dab232019-02-22 16:54:21 +00001279 mDisplayModeDirector.getAppRequestObserver().setAppRequestedMode(
1280 displayId, requestedModeId);
Galia Peycheva056b3ee2019-06-26 14:05:12 +02001281
Galia Peycheva088d7c02019-12-13 11:27:23 +01001282 if (display.getDisplayInfoLocked().minimalPostProcessingSupported) {
1283 boolean mppRequest = mMinimalPostProcessingAllowed && preferMinimalPostProcessing;
Galia Peycheva056b3ee2019-06-26 14:05:12 +02001284
Galia Peycheva088d7c02019-12-13 11:27:23 +01001285 if (display.getRequestedMinimalPostProcessingLocked() != mppRequest) {
1286 display.setRequestedMinimalPostProcessingLocked(mppRequest);
1287 shouldScheduleTraversal = true;
1288 }
Galia Peycheva056b3ee2019-06-26 14:05:12 +02001289 }
1290
1291 if (shouldScheduleTraversal) {
1292 scheduleTraversalLocked(inTraversal);
1293 }
Craig Mautner722285e2012-09-07 13:55:58 -07001294 }
Jeff Brownd728bf52012-09-08 18:05:28 -07001295 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001296
Filip Gruszczynskid2e86402015-02-19 13:05:03 -08001297 private void setDisplayOffsetsInternal(int displayId, int x, int y) {
1298 synchronized (mSyncRoot) {
1299 LogicalDisplay display = mLogicalDisplays.get(displayId);
1300 if (display == null) {
1301 return;
1302 }
1303 if (display.getDisplayOffsetXLocked() != x
1304 || display.getDisplayOffsetYLocked() != y) {
1305 if (DEBUG) {
1306 Slog.d(TAG, "Display " + displayId + " burn-in offset set to ("
1307 + x + ", " + y + ")");
1308 }
1309 display.setDisplayOffsetsLocked(x, y);
1310 scheduleTraversalLocked(false);
1311 }
1312 }
1313 }
1314
Sam Lin4c3ac2b2019-02-18 04:50:26 -08001315 private void setDisplayScalingDisabledInternal(int displayId, boolean disable) {
1316 synchronized (mSyncRoot) {
1317 final LogicalDisplay display = mLogicalDisplays.get(displayId);
1318 if (display == null) {
1319 return;
1320 }
1321 if (display.isDisplayScalingDisabled() != disable) {
1322 if (DEBUG) {
1323 Slog.d(TAG, "Display " + displayId + " content scaling disabled = " + disable);
1324 }
1325 display.setDisplayScalingDisabledLocked(disable);
1326 scheduleTraversalLocked(false);
1327 }
1328 }
1329 }
1330
Andrii Kulianfb1bf692017-01-17 11:17:34 -08001331 // Updates the lists of UIDs that are present on displays.
1332 private void setDisplayAccessUIDsInternal(SparseArray<IntArray> newDisplayAccessUIDs) {
1333 synchronized (mSyncRoot) {
1334 mDisplayAccessUIDs.clear();
1335 for (int i = newDisplayAccessUIDs.size() - 1; i >= 0; i--) {
1336 mDisplayAccessUIDs.append(newDisplayAccessUIDs.keyAt(i),
1337 newDisplayAccessUIDs.valueAt(i));
1338 }
1339 }
1340 }
1341
1342 // Checks if provided UID's content is present on the display and UID has access to it.
1343 private boolean isUidPresentOnDisplayInternal(int uid, int displayId) {
1344 synchronized (mSyncRoot) {
1345 final IntArray displayUIDs = mDisplayAccessUIDs.get(displayId);
1346 return displayUIDs != null && displayUIDs.indexOf(uid) != -1;
1347 }
1348 }
1349
Dominik Laskowskie912ae32019-01-26 11:19:36 -08001350 @Nullable
1351 private IBinder getDisplayToken(int displayId) {
1352 synchronized (mSyncRoot) {
1353 final LogicalDisplay display = mLogicalDisplays.get(displayId);
1354 if (display != null) {
1355 final DisplayDevice device = display.getPrimaryDisplayDeviceLocked();
1356 if (device != null) {
1357 return device.getDisplayTokenLocked();
1358 }
1359 }
1360 }
1361
1362 return null;
1363 }
1364
Robert Carr66b5664f2019-04-02 14:18:56 -07001365 private SurfaceControl.ScreenshotGraphicBuffer screenshotInternal(int displayId) {
Vinit Nayak627ac302020-01-13 15:50:10 -08001366 synchronized (mSyncRoot) {
1367 final IBinder token = getDisplayToken(displayId);
1368 if (token == null) {
1369 return null;
1370 }
1371 final LogicalDisplay logicalDisplay = mLogicalDisplays.get(displayId);
1372 if (logicalDisplay == null) {
1373 return null;
1374 }
1375
1376 final DisplayInfo displayInfo = logicalDisplay.getDisplayInfoLocked();
1377 return SurfaceControl.screenshotToBufferWithSecureLayersUnsafe(token, new Rect(),
1378 displayInfo.getNaturalWidth(), displayInfo.getNaturalHeight(),
1379 false /* useIdentityTransform */, 0 /* rotation */);
Dominik Laskowskie912ae32019-01-26 11:19:36 -08001380 }
Dominik Laskowskie912ae32019-01-26 11:19:36 -08001381 }
1382
Kevin DuBoisbf76b11b2018-09-04 09:14:15 -07001383 @VisibleForTesting
1384 DisplayedContentSamplingAttributes getDisplayedContentSamplingAttributesInternal(
1385 int displayId) {
Dominik Laskowskie912ae32019-01-26 11:19:36 -08001386 final IBinder token = getDisplayToken(displayId);
1387 if (token == null) {
1388 return null;
1389 }
1390 return SurfaceControl.getDisplayedContentSamplingAttributes(token);
Kevin DuBoisbf76b11b2018-09-04 09:14:15 -07001391 }
1392
1393 @VisibleForTesting
1394 boolean setDisplayedContentSamplingEnabledInternal(
1395 int displayId, boolean enable, int componentMask, int maxFrames) {
Dominik Laskowskie912ae32019-01-26 11:19:36 -08001396 final IBinder token = getDisplayToken(displayId);
1397 if (token == null) {
1398 return false;
1399 }
Kevin DuBoisbf76b11b2018-09-04 09:14:15 -07001400 return SurfaceControl.setDisplayedContentSamplingEnabled(
Dominik Laskowskie912ae32019-01-26 11:19:36 -08001401 token, enable, componentMask, maxFrames);
Kevin DuBoisbf76b11b2018-09-04 09:14:15 -07001402 }
1403
1404 @VisibleForTesting
1405 DisplayedContentSample getDisplayedContentSampleInternal(int displayId,
1406 long maxFrames, long timestamp) {
Dominik Laskowskie912ae32019-01-26 11:19:36 -08001407 final IBinder token = getDisplayToken(displayId);
1408 if (token == null) {
1409 return null;
1410 }
1411 return SurfaceControl.getDisplayedContentSample(token, maxFrames, timestamp);
Kevin DuBoisbf76b11b2018-09-04 09:14:15 -07001412 }
1413
Santos Cordonc4fd8e62019-12-18 13:01:05 +00001414 void resetBrightnessConfiguration() {
1415 setBrightnessConfigurationForUserInternal(null, mContext.getUserId(),
1416 mContext.getPackageName());
1417 }
1418
1419 void setAutoBrightnessLoggingEnabled(boolean enabled) {
1420 if (mDisplayPowerController != null) {
1421 synchronized (mSyncRoot) {
1422 mDisplayPowerController.setAutoBrightnessLoggingEnabled(enabled);
1423 }
1424 }
1425 }
1426
1427 void setDisplayWhiteBalanceLoggingEnabled(boolean enabled) {
1428 if (mDisplayPowerController != null) {
1429 synchronized (mSyncRoot) {
1430 mDisplayPowerController.setDisplayWhiteBalanceLoggingEnabled(enabled);
1431 }
1432 }
1433 }
1434
1435 void setAmbientColorTemperatureOverride(float cct) {
1436 if (mDisplayPowerController != null) {
1437 synchronized (mSyncRoot) {
1438 mDisplayPowerController.setAmbientColorTemperatureOverride(cct);
1439 }
1440 }
1441 }
1442
Ana Kruleca74a8642019-11-14 00:51:00 +01001443 private void onDesiredDisplayModeSpecsChangedInternal() {
Michael Wrighta3dab232019-02-22 16:54:21 +00001444 boolean changed = false;
1445 synchronized (mSyncRoot) {
1446 final int count = mLogicalDisplays.size();
1447 for (int i = 0; i < count; i++) {
1448 LogicalDisplay display = mLogicalDisplays.valueAt(i);
1449 int displayId = mLogicalDisplays.keyAt(i);
Ana Kruleca74a8642019-11-14 00:51:00 +01001450 DisplayModeDirector.DesiredDisplayModeSpecs desiredDisplayModeSpecs =
1451 mDisplayModeDirector.getDesiredDisplayModeSpecs(displayId);
1452 DisplayModeDirector.DesiredDisplayModeSpecs existingDesiredDisplayModeSpecs =
1453 display.getDesiredDisplayModeSpecsLocked();
1454 if (DEBUG) {
1455 Slog.i(TAG,
1456 "Comparing display specs: " + desiredDisplayModeSpecs
1457 + ", existing: " + existingDesiredDisplayModeSpecs);
1458 }
1459 if (!desiredDisplayModeSpecs.equals(existingDesiredDisplayModeSpecs)) {
1460 display.setDesiredDisplayModeSpecsLocked(desiredDisplayModeSpecs);
Michael Wrighta3dab232019-02-22 16:54:21 +00001461 changed = true;
1462 }
1463 }
1464 if (changed) {
1465 scheduleTraversalLocked(false);
1466 }
1467 }
1468 }
1469
Jeff Brownd728bf52012-09-08 18:05:28 -07001470 private void clearViewportsLocked() {
Siarhei Vishniakou2eb0f8f2018-07-06 23:30:12 +01001471 mViewports.clear();
Craig Mautner722285e2012-09-07 13:55:58 -07001472 }
1473
Robert Carrae606b42018-02-15 15:36:23 -08001474 private void configureDisplayLocked(SurfaceControl.Transaction t, DisplayDevice device) {
Jeff Brownd14c8c92014-01-07 18:13:09 -08001475 final DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
1476 final boolean ownContent = (info.flags & DisplayDeviceInfo.FLAG_OWN_CONTENT_ONLY) != 0;
Jeff Browna506a6e2013-06-04 00:02:38 -07001477
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001478 // Find the logical display that the display device is showing.
Jeff Brownd14c8c92014-01-07 18:13:09 -08001479 // Certain displays only ever show their own content.
Craig Mautner722285e2012-09-07 13:55:58 -07001480 LogicalDisplay display = findLogicalDisplayForDeviceLocked(device);
Jeff Brownd14c8c92014-01-07 18:13:09 -08001481 if (!ownContent) {
Jeff Browna506a6e2013-06-04 00:02:38 -07001482 if (display != null && !display.hasContentLocked()) {
1483 // If the display does not have any content of its own, then
b0202.jung925435c2020-01-08 18:46:59 +09001484 // automatically mirror the requested logical display contents if possible.
1485 display = mLogicalDisplays.get(device.getDisplayIdToMirrorLocked());
Jeff Browna506a6e2013-06-04 00:02:38 -07001486 }
1487 if (display == null) {
1488 display = mLogicalDisplays.get(Display.DEFAULT_DISPLAY);
1489 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001490 }
1491
1492 // Apply the logical display configuration to the display device.
1493 if (display == null) {
1494 // TODO: no logical display for the device, blank it
Jeff Brownd728bf52012-09-08 18:05:28 -07001495 Slog.w(TAG, "Missing logical display to use for physical display device: "
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001496 + device.getDisplayDeviceInfoLocked());
Jeff Brownd728bf52012-09-08 18:05:28 -07001497 return;
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001498 }
Robert Carrae606b42018-02-15 15:36:23 -08001499 display.configureDisplayLocked(t, device, info.state == Display.STATE_OFF);
Arthur Hung41e81e72018-10-31 18:04:56 +08001500 final int viewportType;
Siarhei Vishniakou2eb0f8f2018-07-06 23:30:12 +01001501 // Update the corresponding viewport.
Siarhei Vishniakou2eb0f8f2018-07-06 23:30:12 +01001502 if ((info.flags & DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY) != 0) {
Arthur Hung41e81e72018-10-31 18:04:56 +08001503 viewportType = VIEWPORT_INTERNAL;
1504 } else if (info.touch == DisplayDeviceInfo.TOUCH_EXTERNAL) {
1505 viewportType = VIEWPORT_EXTERNAL;
1506 } else if (info.touch == DisplayDeviceInfo.TOUCH_VIRTUAL
1507 && !TextUtils.isEmpty(info.uniqueId)) {
1508 viewportType = VIEWPORT_VIRTUAL;
1509 } else {
Arthur Hung46c4e582019-02-12 15:55:28 +08001510 Slog.i(TAG, "Display " + info + " does not support input device matching.");
Arthur Hung41e81e72018-10-31 18:04:56 +08001511 return;
Jeff Brownd728bf52012-09-08 18:05:28 -07001512 }
Santos Cordonee8931e2017-04-05 10:31:15 -07001513
Arthur Hung41e81e72018-10-31 18:04:56 +08001514 populateViewportLocked(viewportType, display.getDisplayIdLocked(), device, info.uniqueId);
Siarhei Vishniakou2eb0f8f2018-07-06 23:30:12 +01001515 }
1516
1517 /**
1518 * Get internal or external viewport. Create it if does not currently exist.
1519 * @param viewportType - either INTERNAL or EXTERNAL
1520 * @return the viewport with the requested type
1521 */
Arthur Hung41e81e72018-10-31 18:04:56 +08001522 private DisplayViewport getViewportLocked(int viewportType, String uniqueId) {
1523 if (viewportType != VIEWPORT_INTERNAL && viewportType != VIEWPORT_EXTERNAL
1524 && viewportType != VIEWPORT_VIRTUAL) {
Siarhei Vishniakou2eb0f8f2018-07-06 23:30:12 +01001525 Slog.wtf(TAG, "Cannot call getViewportByTypeLocked for type "
1526 + DisplayViewport.typeToString(viewportType));
1527 return null;
1528 }
Arthur Hung41e81e72018-10-31 18:04:56 +08001529
1530 // Only allow a single INTERNAL or EXTERNAL viewport by forcing their uniqueIds
1531 // to be identical (in particular, empty).
1532 // TODO (b/116824030) allow multiple EXTERNAL viewports and remove this function.
1533 if (viewportType != VIEWPORT_VIRTUAL) {
1534 uniqueId = "";
1535 }
1536
Siarhei Vishniakou2eb0f8f2018-07-06 23:30:12 +01001537 DisplayViewport viewport;
1538 final int count = mViewports.size();
1539 for (int i = 0; i < count; i++) {
1540 viewport = mViewports.get(i);
Arthur Hung41e81e72018-10-31 18:04:56 +08001541 if (viewport.type == viewportType && uniqueId.equals(viewport.uniqueId)) {
Siarhei Vishniakou2eb0f8f2018-07-06 23:30:12 +01001542 return viewport;
1543 }
1544 }
1545
Arthur Hung41e81e72018-10-31 18:04:56 +08001546 // Creates the viewport if none exists.
Siarhei Vishniakou2eb0f8f2018-07-06 23:30:12 +01001547 viewport = new DisplayViewport();
1548 viewport.type = viewportType;
Arthur Hung41e81e72018-10-31 18:04:56 +08001549 viewport.uniqueId = uniqueId;
Siarhei Vishniakou2eb0f8f2018-07-06 23:30:12 +01001550 mViewports.add(viewport);
1551 return viewport;
1552 }
1553
Arthur Hung41e81e72018-10-31 18:04:56 +08001554 private void populateViewportLocked(int viewportType,
1555 int displayId, DisplayDevice device, String uniqueId) {
1556 final DisplayViewport viewport = getViewportLocked(viewportType, uniqueId);
Jeff Brownd728bf52012-09-08 18:05:28 -07001557 device.populateViewportLocked(viewport);
Arthur Hung41e81e72018-10-31 18:04:56 +08001558 viewport.valid = true;
1559 viewport.displayId = displayId;
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001560 }
1561
1562 private LogicalDisplay findLogicalDisplayForDeviceLocked(DisplayDevice device) {
1563 final int count = mLogicalDisplays.size();
1564 for (int i = 0; i < count; i++) {
1565 LogicalDisplay display = mLogicalDisplays.valueAt(i);
1566 if (display.getPrimaryDisplayDeviceLocked() == device) {
1567 return display;
1568 }
1569 }
1570 return null;
1571 }
1572
Jeff Brownbd6e1502012-08-28 03:27:37 -07001573 private void sendDisplayEventLocked(int displayId, int event) {
1574 Message msg = mHandler.obtainMessage(MSG_DELIVER_DISPLAY_EVENT, displayId, event);
1575 mHandler.sendMessage(msg);
1576 }
1577
Robert Carrae606b42018-02-15 15:36:23 -08001578 // Requests that performTraversals be called at a
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001579 // later time to apply changes to surfaces and displays.
Craig Mautner65d11b32012-10-01 13:59:52 -07001580 private void scheduleTraversalLocked(boolean inTraversal) {
Jeff Brown4ccb8232014-01-16 22:16:42 -08001581 if (!mPendingTraversal && mWindowManagerInternal != null) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001582 mPendingTraversal = true;
Craig Mautner65d11b32012-10-01 13:59:52 -07001583 if (!inTraversal) {
1584 mHandler.sendEmptyMessage(MSG_REQUEST_TRAVERSAL);
1585 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001586 }
1587 }
1588
1589 // Runs on Handler thread.
1590 // Delivers display event notifications to callbacks.
Jeff Brownbd6e1502012-08-28 03:27:37 -07001591 private void deliverDisplayEvent(int displayId, int event) {
1592 if (DEBUG) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001593 Slog.d(TAG, "Delivering display event: displayId="
1594 + displayId + ", event=" + event);
Jeff Brownfa25bf52012-07-23 19:26:30 -07001595 }
Jeff Brownfa25bf52012-07-23 19:26:30 -07001596
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001597 // Grab the lock and copy the callbacks.
Jeff Brownbd6e1502012-08-28 03:27:37 -07001598 final int count;
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001599 synchronized (mSyncRoot) {
Jeff Brownbd6e1502012-08-28 03:27:37 -07001600 count = mCallbacks.size();
1601 mTempCallbacks.clear();
1602 for (int i = 0; i < count; i++) {
1603 mTempCallbacks.add(mCallbacks.valueAt(i));
Craig Mautner4f67ba62012-08-02 11:23:00 -07001604 }
Jeff Brownbd6e1502012-08-28 03:27:37 -07001605 }
Craig Mautner4f67ba62012-08-02 11:23:00 -07001606
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001607 // After releasing the lock, send the notifications out.
Jeff Brownbd6e1502012-08-28 03:27:37 -07001608 for (int i = 0; i < count; i++) {
1609 mTempCallbacks.get(i).notifyDisplayEventAsync(displayId, event);
1610 }
1611 mTempCallbacks.clear();
Craig Mautner4f67ba62012-08-02 11:23:00 -07001612 }
1613
Michael Wrightc39d47a2014-07-08 18:07:36 -07001614 private IMediaProjectionManager getProjectionService() {
1615 if (mProjectionService == null) {
1616 IBinder b = ServiceManager.getService(Context.MEDIA_PROJECTION_SERVICE);
1617 mProjectionService = IMediaProjectionManager.Stub.asInterface(b);
1618 }
1619 return mProjectionService;
1620 }
1621
Michael Wrighteef0e132017-11-21 17:57:52 +00001622 private UserManager getUserManager() {
1623 return mContext.getSystemService(UserManager.class);
1624 }
1625
Jeff Brown4ccb8232014-01-16 22:16:42 -08001626 private void dumpInternal(PrintWriter pw) {
Jeff Brownbd6e1502012-08-28 03:27:37 -07001627 pw.println("DISPLAY MANAGER (dumpsys display)");
Jeff Brownfa25bf52012-07-23 19:26:30 -07001628
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001629 synchronized (mSyncRoot) {
Jeff Brown9e316a12012-10-08 19:17:06 -07001630 pw.println(" mOnlyCode=" + mOnlyCore);
1631 pw.println(" mSafeMode=" + mSafeMode);
1632 pw.println(" mPendingTraversal=" + mPendingTraversal);
Jeff Brown037c33e2014-04-09 00:31:55 -07001633 pw.println(" mGlobalDisplayState=" + Display.stateToString(mGlobalDisplayState));
Jeff Brown9e316a12012-10-08 19:17:06 -07001634 pw.println(" mNextNonDefaultDisplayId=" + mNextNonDefaultDisplayId);
Siarhei Vishniakou2eb0f8f2018-07-06 23:30:12 +01001635 pw.println(" mViewports=" + mViewports);
Damien Bargiacchi4364bbf2016-11-01 21:44:20 -07001636 pw.println(" mDefaultDisplayDefaultColorMode=" + mDefaultDisplayDefaultColorMode);
Jeff Brown27f1d672012-10-17 18:32:34 -07001637 pw.println(" mSingleDisplayDemoMode=" + mSingleDisplayDemoMode);
Jeff Brownce468a32013-11-21 16:42:03 -08001638 pw.println(" mWifiDisplayScanRequestCount=" + mWifiDisplayScanRequestCount);
Michael Wrighteedcbf12017-08-16 23:14:54 +01001639 pw.println(" mStableDisplaySize=" + mStableDisplaySize);
Kenny Guy2047db92019-02-21 13:04:05 +00001640 pw.println(" mMinimumBrightnessCurve=" + mMinimumBrightnessCurve);
Jeff Brown9e316a12012-10-08 19:17:06 -07001641
Jeff Brownbd6e1502012-08-28 03:27:37 -07001642 IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001643 ipw.increaseIndent();
Jeff Brownbd6e1502012-08-28 03:27:37 -07001644
1645 pw.println();
1646 pw.println("Display Adapters: size=" + mDisplayAdapters.size());
Jeff Brown848c2dc2012-08-19 20:18:08 -07001647 for (DisplayAdapter adapter : mDisplayAdapters) {
Jeff Brownbd6e1502012-08-28 03:27:37 -07001648 pw.println(" " + adapter.getName());
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001649 adapter.dumpLocked(ipw);
Jeff Brown848c2dc2012-08-19 20:18:08 -07001650 }
Craig Mautner9de49362012-08-02 14:30:30 -07001651
Jeff Brownbd6e1502012-08-28 03:27:37 -07001652 pw.println();
1653 pw.println("Display Devices: size=" + mDisplayDevices.size());
1654 for (DisplayDevice device : mDisplayDevices) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001655 pw.println(" " + device.getDisplayDeviceInfoLocked());
1656 device.dumpLocked(ipw);
Jeff Brownbd6e1502012-08-28 03:27:37 -07001657 }
1658
1659 final int logicalDisplayCount = mLogicalDisplays.size();
1660 pw.println();
1661 pw.println("Logical Displays: size=" + logicalDisplayCount);
1662 for (int i = 0; i < logicalDisplayCount; i++) {
1663 int displayId = mLogicalDisplays.keyAt(i);
1664 LogicalDisplay display = mLogicalDisplays.valueAt(i);
1665 pw.println(" Display " + displayId + ":");
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001666 display.dumpLocked(ipw);
Jeff Brownbd6e1502012-08-28 03:27:37 -07001667 }
Jeff Brownce468a32013-11-21 16:42:03 -08001668
Michael Wrighta3dab232019-02-22 16:54:21 +00001669 pw.println();
1670 mDisplayModeDirector.dump(pw);
1671
Jeff Brownce468a32013-11-21 16:42:03 -08001672 final int callbackCount = mCallbacks.size();
1673 pw.println();
1674 pw.println("Callbacks: size=" + callbackCount);
1675 for (int i = 0; i < callbackCount; i++) {
1676 CallbackRecord callback = mCallbacks.valueAt(i);
1677 pw.println(" " + i + ": mPid=" + callback.mPid
1678 + ", mWifiDisplayScanRequested=" + callback.mWifiDisplayScanRequested);
1679 }
Jeff Brownad9ef192014-04-08 17:26:30 -07001680
1681 if (mDisplayPowerController != null) {
1682 mDisplayPowerController.dump(pw);
1683 }
Michael Wright1c9977b2016-07-12 13:30:10 -07001684
1685 pw.println();
1686 mPersistentDataStore.dump(pw);
Jeff Brownbd6e1502012-08-28 03:27:37 -07001687 }
1688 }
1689
Dan Gittik122df862018-03-28 16:59:22 +01001690 private static float[] getFloatArray(TypedArray array) {
1691 int length = array.length();
1692 float[] floatArray = new float[length];
1693 for (int i = 0; i < length; i++) {
1694 floatArray[i] = array.getFloat(i, Float.NaN);
1695 }
1696 array.recycle();
1697 return floatArray;
1698 }
1699
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001700 /**
1701 * This is the object that everything in the display manager locks on.
1702 * We make it an inner class within the {@link DisplayManagerService} to so that it is
1703 * clear that the object belongs to the display manager service and that it is
1704 * a unique object with a special purpose.
1705 */
1706 public static final class SyncRoot {
1707 }
1708
Santos Cordonee8931e2017-04-05 10:31:15 -07001709 @VisibleForTesting
1710 static class Injector {
1711 VirtualDisplayAdapter getVirtualDisplayAdapter(SyncRoot syncRoot, Context context,
1712 Handler handler, DisplayAdapter.Listener displayAdapterListener) {
1713 return new VirtualDisplayAdapter(syncRoot, context, handler, displayAdapterListener);
1714 }
Santos Cordonc22c5632017-06-21 16:03:49 -07001715
1716 long getDefaultDisplayDelayTimeout() {
1717 return WAIT_FOR_DEFAULT_DISPLAY_TIMEOUT;
1718 }
Santos Cordonee8931e2017-04-05 10:31:15 -07001719 }
1720
Alex Sakhartchouk879d24f2017-06-20 22:01:19 -04001721 @VisibleForTesting
1722 DisplayDeviceInfo getDisplayDeviceInfoInternal(int displayId) {
1723 synchronized (mSyncRoot) {
1724 LogicalDisplay display = mLogicalDisplays.get(displayId);
1725 if (display != null) {
1726 DisplayDevice displayDevice = display.getPrimaryDisplayDeviceLocked();
1727 return displayDevice.getDisplayDeviceInfoLocked();
1728 }
1729 return null;
1730 }
1731 }
1732
b0202.jung925435c2020-01-08 18:46:59 +09001733 @VisibleForTesting
1734 int getDisplayIdToMirrorInternal(int displayId) {
1735 synchronized (mSyncRoot) {
1736 LogicalDisplay display = mLogicalDisplays.get(displayId);
1737 if (display != null) {
1738 DisplayDevice displayDevice = display.getPrimaryDisplayDeviceLocked();
1739 return displayDevice.getDisplayIdToMirrorLocked();
1740 }
1741 return Display.INVALID_DISPLAY;
1742 }
1743 }
1744
1745 @VisibleForTesting
1746 Surface getVirtualDisplaySurfaceInternal(IBinder appToken) {
1747 synchronized (mSyncRoot) {
1748 if (mVirtualDisplayAdapter == null) {
1749 return null;
1750 }
1751 return mVirtualDisplayAdapter.getVirtualDisplaySurfaceLocked(appToken);
1752 }
1753 }
1754
Jeff Brownbd6e1502012-08-28 03:27:37 -07001755 private final class DisplayManagerHandler extends Handler {
1756 public DisplayManagerHandler(Looper looper) {
1757 super(looper, null, true /*async*/);
Jeff Brown848c2dc2012-08-19 20:18:08 -07001758 }
Jeff Brownbf5740e2012-08-19 23:20:02 -07001759
Jeff Brownbd6e1502012-08-28 03:27:37 -07001760 @Override
1761 public void handleMessage(Message msg) {
1762 switch (msg.what) {
Santos Cordonc22c5632017-06-21 16:03:49 -07001763 case MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS:
1764 registerDefaultDisplayAdapters();
Jeff Brownbd6e1502012-08-28 03:27:37 -07001765 break;
1766
1767 case MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS:
1768 registerAdditionalDisplayAdapters();
1769 break;
1770
1771 case MSG_DELIVER_DISPLAY_EVENT:
1772 deliverDisplayEvent(msg.arg1, msg.arg2);
1773 break;
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001774
1775 case MSG_REQUEST_TRAVERSAL:
Jeff Brown4ccb8232014-01-16 22:16:42 -08001776 mWindowManagerInternal.requestTraversalFromDisplayManager();
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001777 break;
Jeff Brownd728bf52012-09-08 18:05:28 -07001778
1779 case MSG_UPDATE_VIEWPORT: {
Siarhei Vishniakou2eb0f8f2018-07-06 23:30:12 +01001780 final boolean changed;
Jeff Brownd728bf52012-09-08 18:05:28 -07001781 synchronized (mSyncRoot) {
Siarhei Vishniakou2eb0f8f2018-07-06 23:30:12 +01001782 changed = !mTempViewports.equals(mViewports);
1783 if (changed) {
1784 mTempViewports.clear();
1785 for (DisplayViewport d : mViewports) {
1786 mTempViewports.add(d.makeCopy());
1787 }
Santos Cordonee8931e2017-04-05 10:31:15 -07001788 }
Jeff Brownd728bf52012-09-08 18:05:28 -07001789 }
Siarhei Vishniakou2eb0f8f2018-07-06 23:30:12 +01001790 if (changed) {
1791 mInputManagerInternal.setDisplayViewports(mTempViewports);
1792 }
Jeff Brownd728bf52012-09-08 18:05:28 -07001793 break;
1794 }
Kenny Guy22bd0442017-10-26 00:15:54 +01001795
Michael Wrighteef0e132017-11-21 17:57:52 +00001796 case MSG_LOAD_BRIGHTNESS_CONFIGURATION:
1797 loadBrightnessConfiguration();
1798 break;
Jeff Brownbd6e1502012-08-28 03:27:37 -07001799 }
1800 }
1801 }
1802
1803 private final class DisplayAdapterListener implements DisplayAdapter.Listener {
1804 @Override
1805 public void onDisplayDeviceEvent(DisplayDevice device, int event) {
1806 switch (event) {
1807 case DisplayAdapter.DISPLAY_DEVICE_EVENT_ADDED:
1808 handleDisplayDeviceAdded(device);
1809 break;
1810
1811 case DisplayAdapter.DISPLAY_DEVICE_EVENT_CHANGED:
1812 handleDisplayDeviceChanged(device);
1813 break;
1814
1815 case DisplayAdapter.DISPLAY_DEVICE_EVENT_REMOVED:
1816 handleDisplayDeviceRemoved(device);
1817 break;
1818 }
1819 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001820
1821 @Override
1822 public void onTraversalRequested() {
1823 synchronized (mSyncRoot) {
Craig Mautner65d11b32012-10-01 13:59:52 -07001824 scheduleTraversalLocked(false);
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001825 }
1826 }
Jeff Brownbd6e1502012-08-28 03:27:37 -07001827 }
1828
1829 private final class CallbackRecord implements DeathRecipient {
Jeff Brownce468a32013-11-21 16:42:03 -08001830 public final int mPid;
Jeff Brownbd6e1502012-08-28 03:27:37 -07001831 private final IDisplayManagerCallback mCallback;
1832
Jeff Brownce468a32013-11-21 16:42:03 -08001833 public boolean mWifiDisplayScanRequested;
1834
Jeff Brownbd6e1502012-08-28 03:27:37 -07001835 public CallbackRecord(int pid, IDisplayManagerCallback callback) {
1836 mPid = pid;
1837 mCallback = callback;
1838 }
1839
1840 @Override
1841 public void binderDied() {
1842 if (DEBUG) {
1843 Slog.d(TAG, "Display listener for pid " + mPid + " died.");
1844 }
Jeff Brownce468a32013-11-21 16:42:03 -08001845 onCallbackDied(this);
Jeff Brownbd6e1502012-08-28 03:27:37 -07001846 }
1847
1848 public void notifyDisplayEventAsync(int displayId, int event) {
1849 try {
1850 mCallback.onDisplayEvent(displayId, event);
1851 } catch (RemoteException ex) {
1852 Slog.w(TAG, "Failed to notify process "
1853 + mPid + " that displays changed, assuming it died.", ex);
1854 binderDied();
1855 }
1856 }
1857 }
Jeff Brown4ccb8232014-01-16 22:16:42 -08001858
Santos Cordonee8931e2017-04-05 10:31:15 -07001859 @VisibleForTesting
1860 final class BinderService extends IDisplayManager.Stub {
Jeff Brown4ccb8232014-01-16 22:16:42 -08001861 /**
1862 * Returns information about the specified logical display.
1863 *
1864 * @param displayId The logical display id.
lumarkec75b422019-01-07 15:58:38 +08001865 * @return The logical display info, return {@code null} if the display does not exist or
1866 * the calling UID isn't present on the display. The returned object must be treated as
1867 * immutable.
Jeff Brown4ccb8232014-01-16 22:16:42 -08001868 */
1869 @Override // Binder call
1870 public DisplayInfo getDisplayInfo(int displayId) {
1871 final int callingUid = Binder.getCallingUid();
1872 final long token = Binder.clearCallingIdentity();
1873 try {
1874 return getDisplayInfoInternal(displayId, callingUid);
1875 } finally {
1876 Binder.restoreCallingIdentity(token);
1877 }
1878 }
1879
1880 /**
1881 * Returns the list of all display ids.
1882 */
1883 @Override // Binder call
1884 public int[] getDisplayIds() {
1885 final int callingUid = Binder.getCallingUid();
1886 final long token = Binder.clearCallingIdentity();
1887 try {
1888 return getDisplayIdsInternal(callingUid);
1889 } finally {
1890 Binder.restoreCallingIdentity(token);
1891 }
1892 }
1893
lumarkec75b422019-01-07 15:58:38 +08001894 @Override // Binder call
1895 public boolean isUidPresentOnDisplay(int uid, int displayId) {
1896 final long token = Binder.clearCallingIdentity();
1897 try {
1898 return isUidPresentOnDisplayInternal(uid, displayId);
1899 } finally {
1900 Binder.restoreCallingIdentity(token);
1901 }
1902 }
1903
Michael Wrighteedcbf12017-08-16 23:14:54 +01001904 /**
1905 * Returns the stable device display size, in pixels.
1906 */
1907 @Override // Binder call
1908 public Point getStableDisplaySize() {
1909 final long token = Binder.clearCallingIdentity();
1910 try {
1911 return getStableDisplaySizeInternal();
1912 } finally {
1913 Binder.restoreCallingIdentity(token);
1914 }
1915 }
1916
Jeff Brown4ccb8232014-01-16 22:16:42 -08001917 @Override // Binder call
1918 public void registerCallback(IDisplayManagerCallback callback) {
1919 if (callback == null) {
1920 throw new IllegalArgumentException("listener must not be null");
1921 }
1922
1923 final int callingPid = Binder.getCallingPid();
1924 final long token = Binder.clearCallingIdentity();
1925 try {
1926 registerCallbackInternal(callback, callingPid);
1927 } finally {
1928 Binder.restoreCallingIdentity(token);
1929 }
1930 }
1931
1932 @Override // Binder call
1933 public void startWifiDisplayScan() {
1934 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
1935 "Permission required to start wifi display scans");
1936
1937 final int callingPid = Binder.getCallingPid();
1938 final long token = Binder.clearCallingIdentity();
1939 try {
1940 startWifiDisplayScanInternal(callingPid);
1941 } finally {
1942 Binder.restoreCallingIdentity(token);
1943 }
1944 }
1945
1946 @Override // Binder call
1947 public void stopWifiDisplayScan() {
1948 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
1949 "Permission required to stop wifi display scans");
1950
1951 final int callingPid = Binder.getCallingPid();
1952 final long token = Binder.clearCallingIdentity();
1953 try {
1954 stopWifiDisplayScanInternal(callingPid);
1955 } finally {
1956 Binder.restoreCallingIdentity(token);
1957 }
1958 }
1959
1960 @Override // Binder call
1961 public void connectWifiDisplay(String address) {
1962 if (address == null) {
1963 throw new IllegalArgumentException("address must not be null");
1964 }
1965 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
1966 "Permission required to connect to a wifi display");
1967
1968 final long token = Binder.clearCallingIdentity();
1969 try {
1970 connectWifiDisplayInternal(address);
1971 } finally {
1972 Binder.restoreCallingIdentity(token);
1973 }
1974 }
1975
1976 @Override // Binder call
1977 public void disconnectWifiDisplay() {
1978 // This request does not require special permissions.
1979 // Any app can request disconnection from the currently active wifi display.
1980 // This exception should no longer be needed once wifi display control moves
1981 // to the media router service.
1982
1983 final long token = Binder.clearCallingIdentity();
1984 try {
1985 disconnectWifiDisplayInternal();
1986 } finally {
1987 Binder.restoreCallingIdentity(token);
1988 }
1989 }
1990
1991 @Override // Binder call
1992 public void renameWifiDisplay(String address, String alias) {
1993 if (address == null) {
1994 throw new IllegalArgumentException("address must not be null");
1995 }
1996 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
1997 "Permission required to rename to a wifi display");
1998
1999 final long token = Binder.clearCallingIdentity();
2000 try {
2001 renameWifiDisplayInternal(address, alias);
2002 } finally {
2003 Binder.restoreCallingIdentity(token);
2004 }
2005 }
2006
2007 @Override // Binder call
2008 public void forgetWifiDisplay(String address) {
2009 if (address == null) {
2010 throw new IllegalArgumentException("address must not be null");
2011 }
2012 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
2013 "Permission required to forget to a wifi display");
2014
2015 final long token = Binder.clearCallingIdentity();
2016 try {
2017 forgetWifiDisplayInternal(address);
2018 } finally {
2019 Binder.restoreCallingIdentity(token);
2020 }
2021 }
2022
2023 @Override // Binder call
2024 public void pauseWifiDisplay() {
2025 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
2026 "Permission required to pause a wifi display session");
2027
2028 final long token = Binder.clearCallingIdentity();
2029 try {
2030 pauseWifiDisplayInternal();
2031 } finally {
2032 Binder.restoreCallingIdentity(token);
2033 }
2034 }
2035
2036 @Override // Binder call
2037 public void resumeWifiDisplay() {
2038 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
2039 "Permission required to resume a wifi display session");
2040
2041 final long token = Binder.clearCallingIdentity();
2042 try {
2043 resumeWifiDisplayInternal();
2044 } finally {
2045 Binder.restoreCallingIdentity(token);
2046 }
2047 }
2048
2049 @Override // Binder call
2050 public WifiDisplayStatus getWifiDisplayStatus() {
2051 // This request does not require special permissions.
2052 // Any app can get information about available wifi displays.
2053
2054 final long token = Binder.clearCallingIdentity();
2055 try {
2056 return getWifiDisplayStatusInternal();
2057 } finally {
2058 Binder.restoreCallingIdentity(token);
2059 }
2060 }
2061
2062 @Override // Binder call
Michael Wright1c9977b2016-07-12 13:30:10 -07002063 public void requestColorMode(int displayId, int colorMode) {
Michael Wright58e829f2015-09-15 00:13:26 +01002064 mContext.enforceCallingOrSelfPermission(
Michael Wright1c9977b2016-07-12 13:30:10 -07002065 Manifest.permission.CONFIGURE_DISPLAY_COLOR_MODE,
2066 "Permission required to change the display color mode");
Michael Wright58e829f2015-09-15 00:13:26 +01002067 final long token = Binder.clearCallingIdentity();
2068 try {
Michael Wright1c9977b2016-07-12 13:30:10 -07002069 requestColorModeInternal(displayId, colorMode);
Michael Wright58e829f2015-09-15 00:13:26 +01002070 } finally {
2071 Binder.restoreCallingIdentity(token);
2072 }
2073 }
2074
2075 @Override // Binder call
b0202.jung925435c2020-01-08 18:46:59 +09002076 public int createVirtualDisplay(VirtualDisplayConfig virtualDisplayConfig,
2077 IVirtualDisplayCallback callback, IMediaProjection projection, String packageName) {
Jeff Brown4ccb8232014-01-16 22:16:42 -08002078 final int callingUid = Binder.getCallingUid();
2079 if (!validatePackageName(callingUid, packageName)) {
2080 throw new SecurityException("packageName must match the calling uid");
2081 }
Michael Wright75ee9fc2014-09-01 19:55:22 -07002082 if (callback == null) {
Jeff Brown4ccb8232014-01-16 22:16:42 -08002083 throw new IllegalArgumentException("appToken must not be null");
2084 }
b0202.jung925435c2020-01-08 18:46:59 +09002085 if (virtualDisplayConfig == null) {
2086 throw new IllegalArgumentException("virtualDisplayConfig must not be null");
Jeff Brown4ccb8232014-01-16 22:16:42 -08002087 }
b0202.jung925435c2020-01-08 18:46:59 +09002088 final Surface surface = virtualDisplayConfig.getSurface();
2089 int flags = virtualDisplayConfig.getFlags();
2090
Pablo Ceballoseb3370d2016-08-31 15:00:17 -07002091 if (surface != null && surface.isSingleBuffered()) {
Pablo Ceballosaff2f942016-07-29 14:49:55 -07002092 throw new IllegalArgumentException("Surface can't be single-buffered");
2093 }
Michael Wrightc39d47a2014-07-08 18:07:36 -07002094
Andrii Kulianfc8f82b2017-01-26 13:17:27 -08002095 if ((flags & VIRTUAL_DISPLAY_FLAG_PUBLIC) != 0) {
2096 flags |= VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR;
2097
2098 // Public displays can't be allowed to show content when locked.
Andrii Kulian7211d2e2017-01-27 15:58:05 -08002099 if ((flags & VIRTUAL_DISPLAY_FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD) != 0) {
Andrii Kulianfc8f82b2017-01-26 13:17:27 -08002100 throw new IllegalArgumentException(
2101 "Public display must not be marked as SHOW_WHEN_LOCKED_INSECURE");
2102 }
Michael Wright6720be42014-07-29 19:14:16 -07002103 }
Andrii Kulianfc8f82b2017-01-26 13:17:27 -08002104 if ((flags & VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY) != 0) {
2105 flags &= ~VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR;
Michael Wright6720be42014-07-29 19:14:16 -07002106 }
2107
Michael Wrightc39d47a2014-07-08 18:07:36 -07002108 if (projection != null) {
2109 try {
2110 if (!getProjectionService().isValidMediaProjection(projection)) {
2111 throw new SecurityException("Invalid media projection");
2112 }
Michael Wright6720be42014-07-29 19:14:16 -07002113 flags = projection.applyVirtualDisplayFlags(flags);
Michael Wrightc39d47a2014-07-08 18:07:36 -07002114 } catch (RemoteException e) {
Michael Wright6720be42014-07-29 19:14:16 -07002115 throw new SecurityException("unable to validate media projection or flags");
Michael Wrightc39d47a2014-07-08 18:07:36 -07002116 }
2117 }
2118
Michael Wright6720be42014-07-29 19:14:16 -07002119 if (callingUid != Process.SYSTEM_UID &&
Andrii Kulianfc8f82b2017-01-26 13:17:27 -08002120 (flags & VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR) != 0) {
Michael Wrightc39d47a2014-07-08 18:07:36 -07002121 if (!canProjectVideo(projection)) {
2122 throw new SecurityException("Requires CAPTURE_VIDEO_OUTPUT or "
2123 + "CAPTURE_SECURE_VIDEO_OUTPUT permission, or an appropriate "
2124 + "MediaProjection token in order to create a screen sharing virtual "
2125 + "display.");
2126 }
2127 }
Santos Cordonb6992f22018-01-30 14:51:20 -08002128 if (callingUid != Process.SYSTEM_UID && (flags & VIRTUAL_DISPLAY_FLAG_SECURE) != 0) {
Michael Wrightc39d47a2014-07-08 18:07:36 -07002129 if (!canProjectSecureVideo(projection)) {
Jeff Brown4ccb8232014-01-16 22:16:42 -08002130 throw new SecurityException("Requires CAPTURE_SECURE_VIDEO_OUTPUT "
Michael Wrightc39d47a2014-07-08 18:07:36 -07002131 + "or an appropriate MediaProjection token to create a "
2132 + "secure virtual display.");
Jeff Brown4ccb8232014-01-16 22:16:42 -08002133 }
2134 }
2135
Chilun67a379b2019-04-11 19:49:42 +08002136 // Sometimes users can have sensitive information in system decoration windows. An app
2137 // could create a virtual display with system decorations support and read the user info
2138 // from the surface.
2139 // We should only allow adding flag VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS
2140 // to virtual displays that are owned by the system.
2141 if (callingUid != Process.SYSTEM_UID
2142 && (flags & VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS) != 0) {
2143 if (!checkCallingPermission(INTERNAL_SYSTEM_WINDOW, "createVirtualDisplay()")) {
2144 throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission");
2145 }
2146 }
2147
Jeff Brown4ccb8232014-01-16 22:16:42 -08002148 final long token = Binder.clearCallingIdentity();
2149 try {
Santos Cordonee8931e2017-04-05 10:31:15 -07002150 return createVirtualDisplayInternal(callback, projection, callingUid, packageName,
b0202.jung925435c2020-01-08 18:46:59 +09002151 surface, flags, virtualDisplayConfig);
Jeff Brown4ccb8232014-01-16 22:16:42 -08002152 } finally {
2153 Binder.restoreCallingIdentity(token);
2154 }
2155 }
2156
2157 @Override // Binder call
Michael Wright75ee9fc2014-09-01 19:55:22 -07002158 public void resizeVirtualDisplay(IVirtualDisplayCallback callback,
Michael Wright01e840f2014-06-26 16:03:25 -07002159 int width, int height, int densityDpi) {
Jeff Chang01baf6c2019-08-20 16:21:25 +08002160 if (width <= 0 || height <= 0 || densityDpi <= 0) {
2161 throw new IllegalArgumentException("width, height, and densityDpi must be "
2162 + "greater than 0");
2163 }
Michael Wright01e840f2014-06-26 16:03:25 -07002164 final long token = Binder.clearCallingIdentity();
2165 try {
Michael Wright75ee9fc2014-09-01 19:55:22 -07002166 resizeVirtualDisplayInternal(callback.asBinder(), width, height, densityDpi);
Michael Wright01e840f2014-06-26 16:03:25 -07002167 } finally {
2168 Binder.restoreCallingIdentity(token);
2169 }
2170 }
2171
2172 @Override // Binder call
Michael Wright75ee9fc2014-09-01 19:55:22 -07002173 public void setVirtualDisplaySurface(IVirtualDisplayCallback callback, Surface surface) {
Pablo Ceballoseb3370d2016-08-31 15:00:17 -07002174 if (surface != null && surface.isSingleBuffered()) {
2175 throw new IllegalArgumentException("Surface can't be single-buffered");
2176 }
Jeff Brown92207df2014-04-16 13:16:07 -07002177 final long token = Binder.clearCallingIdentity();
2178 try {
Michael Wright75ee9fc2014-09-01 19:55:22 -07002179 setVirtualDisplaySurfaceInternal(callback.asBinder(), surface);
Jeff Brown92207df2014-04-16 13:16:07 -07002180 } finally {
2181 Binder.restoreCallingIdentity(token);
2182 }
2183 }
2184
2185 @Override // Binder call
Michael Wright75ee9fc2014-09-01 19:55:22 -07002186 public void releaseVirtualDisplay(IVirtualDisplayCallback callback) {
Jeff Brown4ccb8232014-01-16 22:16:42 -08002187 final long token = Binder.clearCallingIdentity();
2188 try {
Michael Wright75ee9fc2014-09-01 19:55:22 -07002189 releaseVirtualDisplayInternal(callback.asBinder());
Jeff Brown4ccb8232014-01-16 22:16:42 -08002190 } finally {
2191 Binder.restoreCallingIdentity(token);
2192 }
2193 }
2194
2195 @Override // Binder call
chaviwda4c6942018-11-07 15:52:56 -08002196 public void setVirtualDisplayState(IVirtualDisplayCallback callback, boolean isOn) {
2197 final long token = Binder.clearCallingIdentity();
2198 try {
2199 setVirtualDisplayStateInternal(callback.asBinder(), isOn);
2200 } finally {
2201 Binder.restoreCallingIdentity(token);
2202 }
2203 }
2204
2205 @Override // Binder call
Jeff Brown4ccb8232014-01-16 22:16:42 -08002206 public void dump(FileDescriptor fd, final PrintWriter pw, String[] args) {
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -06002207 if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
Jeff Brown4ccb8232014-01-16 22:16:42 -08002208
2209 final long token = Binder.clearCallingIdentity();
2210 try {
2211 dumpInternal(pw);
2212 } finally {
2213 Binder.restoreCallingIdentity(token);
2214 }
2215 }
2216
Kenny Guy22bd0442017-10-26 00:15:54 +01002217 @Override // Binder call
Kenny Guy29aa30e2017-11-30 13:43:46 +00002218 public ParceledListSlice<BrightnessChangeEvent> getBrightnessEvents(String callingPackage) {
Kenny Guy22bd0442017-10-26 00:15:54 +01002219 mContext.enforceCallingOrSelfPermission(
2220 Manifest.permission.BRIGHTNESS_SLIDER_USAGE,
2221 "Permission to read brightness events.");
Kenny Guy29aa30e2017-11-30 13:43:46 +00002222
2223 final int callingUid = Binder.getCallingUid();
2224 AppOpsManager appOpsManager = mContext.getSystemService(AppOpsManager.class);
Jeff Sharkeyd9311192018-04-16 16:50:34 +00002225 final int mode = appOpsManager.noteOp(AppOpsManager.OP_GET_USAGE_STATS,
Kenny Guy29aa30e2017-11-30 13:43:46 +00002226 callingUid, callingPackage);
2227 final boolean hasUsageStats;
2228 if (mode == AppOpsManager.MODE_DEFAULT) {
2229 // The default behavior here is to check if PackageManager has given the app
2230 // permission.
2231 hasUsageStats = mContext.checkCallingPermission(
2232 Manifest.permission.PACKAGE_USAGE_STATS)
2233 == PackageManager.PERMISSION_GRANTED;
2234 } else {
2235 hasUsageStats = mode == AppOpsManager.MODE_ALLOWED;
2236 }
2237
2238 final int userId = UserHandle.getUserId(callingUid);
Kenny Guy22bd0442017-10-26 00:15:54 +01002239 final long token = Binder.clearCallingIdentity();
2240 try {
Michael Wright144aac92017-12-21 18:37:41 +00002241 synchronized (mSyncRoot) {
2242 return mDisplayPowerController.getBrightnessEvents(userId, hasUsageStats);
2243 }
Kenny Guy22bd0442017-10-26 00:15:54 +01002244 } finally {
2245 Binder.restoreCallingIdentity(token);
2246 }
2247 }
2248
Michael Wrighteef0e132017-11-21 17:57:52 +00002249 @Override // Binder call
Peeyush Agarwalcc155dd2018-01-10 11:51:33 +00002250 public ParceledListSlice<AmbientBrightnessDayStats> getAmbientBrightnessStats() {
2251 mContext.enforceCallingOrSelfPermission(
2252 Manifest.permission.ACCESS_AMBIENT_LIGHT_STATS,
2253 "Permission required to to access ambient light stats.");
2254 final int callingUid = Binder.getCallingUid();
2255 final int userId = UserHandle.getUserId(callingUid);
2256 final long token = Binder.clearCallingIdentity();
2257 try {
2258 synchronized (mSyncRoot) {
2259 return mDisplayPowerController.getAmbientBrightnessStats(userId);
2260 }
2261 } finally {
2262 Binder.restoreCallingIdentity(token);
2263 }
2264 }
2265
2266 @Override // Binder call
Michael Wrighteef0e132017-11-21 17:57:52 +00002267 public void setBrightnessConfigurationForUser(
Kenny Guy05ce8092018-01-17 13:44:20 +00002268 BrightnessConfiguration c, @UserIdInt int userId, String packageName) {
Michael Wrighteef0e132017-11-21 17:57:52 +00002269 mContext.enforceCallingOrSelfPermission(
2270 Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS,
2271 "Permission required to change the display's brightness configuration");
2272 if (userId != UserHandle.getCallingUserId()) {
2273 mContext.enforceCallingOrSelfPermission(
2274 Manifest.permission.INTERACT_ACROSS_USERS,
2275 "Permission required to change the display brightness"
2276 + " configuration of another user");
2277 }
Kenny Guy05ce8092018-01-17 13:44:20 +00002278 if (packageName != null && !validatePackageName(getCallingUid(), packageName)) {
2279 packageName = null;
2280 }
Michael Wrighteef0e132017-11-21 17:57:52 +00002281 final long token = Binder.clearCallingIdentity();
2282 try {
Kenny Guy05ce8092018-01-17 13:44:20 +00002283 setBrightnessConfigurationForUserInternal(c, userId, packageName);
Michael Wrighteef0e132017-11-21 17:57:52 +00002284 } finally {
2285 Binder.restoreCallingIdentity(token);
2286 }
2287 }
2288
Michael Wrightd8460232018-01-16 18:04:59 +00002289 @Override // Binder call
Kenny Guy6d1009f2018-03-14 14:28:23 +00002290 public BrightnessConfiguration getBrightnessConfigurationForUser(int userId) {
2291 mContext.enforceCallingOrSelfPermission(
2292 Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS,
2293 "Permission required to read the display's brightness configuration");
2294 if (userId != UserHandle.getCallingUserId()) {
2295 mContext.enforceCallingOrSelfPermission(
2296 Manifest.permission.INTERACT_ACROSS_USERS,
2297 "Permission required to read the display brightness"
2298 + " configuration of another user");
2299 }
2300 final long token = Binder.clearCallingIdentity();
2301 try {
2302 final int userSerial = getUserManager().getUserSerialNumber(userId);
2303 synchronized (mSyncRoot) {
2304 BrightnessConfiguration config =
2305 mPersistentDataStore.getBrightnessConfiguration(userSerial);
2306 if (config == null) {
2307 config = mDisplayPowerController.getDefaultBrightnessConfiguration();
2308 }
2309 return config;
2310 }
2311 } finally {
2312 Binder.restoreCallingIdentity(token);
2313 }
2314 }
2315
2316 @Override // Binder call
2317 public BrightnessConfiguration getDefaultBrightnessConfiguration() {
2318 mContext.enforceCallingOrSelfPermission(
2319 Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS,
2320 "Permission required to read the display's default brightness configuration");
2321 final long token = Binder.clearCallingIdentity();
2322 try {
2323 synchronized (mSyncRoot) {
2324 return mDisplayPowerController.getDefaultBrightnessConfiguration();
2325 }
2326 } finally {
2327 Binder.restoreCallingIdentity(token);
2328 }
2329 }
2330
2331 @Override // Binder call
Galia Peycheva35f900a2020-01-09 14:31:05 +01002332 public boolean isMinimalPostProcessingRequested(int displayId) {
2333 synchronized (mSyncRoot) {
2334 return mLogicalDisplays.get(displayId).getRequestedMinimalPostProcessingLocked();
2335 }
2336 }
2337
2338 @Override // Binder call
Fiona Campbelld4eb2952019-11-04 17:19:56 +00002339 public void setTemporaryBrightness(float brightness) {
Michael Wrightd8460232018-01-16 18:04:59 +00002340 mContext.enforceCallingOrSelfPermission(
2341 Manifest.permission.CONTROL_DISPLAY_BRIGHTNESS,
2342 "Permission required to set the display's brightness");
2343 final long token = Binder.clearCallingIdentity();
2344 try {
2345 synchronized (mSyncRoot) {
2346 mDisplayPowerController.setTemporaryBrightness(brightness);
2347 }
2348 } finally {
2349 Binder.restoreCallingIdentity(token);
2350 }
2351 }
2352
2353 @Override // Binder call
2354 public void setTemporaryAutoBrightnessAdjustment(float adjustment) {
2355 mContext.enforceCallingOrSelfPermission(
2356 Manifest.permission.CONTROL_DISPLAY_BRIGHTNESS,
2357 "Permission required to set the display's auto brightness adjustment");
2358 final long token = Binder.clearCallingIdentity();
2359 try {
2360 synchronized (mSyncRoot) {
2361 mDisplayPowerController.setTemporaryAutoBrightnessAdjustment(adjustment);
2362 }
2363 } finally {
2364 Binder.restoreCallingIdentity(token);
2365 }
2366 }
2367
Dan Gittik7a32fba2018-03-28 12:19:38 +01002368 @Override // Binder call
2369 public void onShellCommand(FileDescriptor in, FileDescriptor out,
2370 FileDescriptor err, String[] args, ShellCallback callback,
2371 ResultReceiver resultReceiver) {
Santos Cordonc4fd8e62019-12-18 13:01:05 +00002372 new DisplayManagerShellCommand(DisplayManagerService.this).exec(this, in, out, err,
2373 args, callback, resultReceiver);
Dan Gittik7a32fba2018-03-28 12:19:38 +01002374 }
2375
Dan Gittik122df862018-03-28 16:59:22 +01002376 @Override // Binder call
2377 public Curve getMinimumBrightnessCurve() {
2378 final long token = Binder.clearCallingIdentity();
2379 try {
2380 return getMinimumBrightnessCurveInternal();
2381 } finally {
2382 Binder.restoreCallingIdentity(token);
2383 }
2384 }
2385
Peiyong Lin277eaff2019-01-16 16:18:22 -08002386 @Override // Binder call
2387 public int getPreferredWideGamutColorSpaceId() {
2388 final long token = Binder.clearCallingIdentity();
2389 try {
2390 return getPreferredWideGamutColorSpaceIdInternal();
2391 } finally {
2392 Binder.restoreCallingIdentity(token);
2393 }
2394 }
2395
Jeff Brown4ccb8232014-01-16 22:16:42 -08002396 private boolean validatePackageName(int uid, String packageName) {
2397 if (packageName != null) {
2398 String[] packageNames = mContext.getPackageManager().getPackagesForUid(uid);
2399 if (packageNames != null) {
2400 for (String n : packageNames) {
2401 if (n.equals(packageName)) {
2402 return true;
2403 }
2404 }
2405 }
2406 }
2407 return false;
2408 }
Michael Wrightc39d47a2014-07-08 18:07:36 -07002409
2410 private boolean canProjectVideo(IMediaProjection projection) {
2411 if (projection != null) {
2412 try {
2413 if (projection.canProjectVideo()) {
2414 return true;
2415 }
2416 } catch (RemoteException e) {
2417 Slog.e(TAG, "Unable to query projection service for permissions", e);
2418 }
2419 }
Chilun67a379b2019-04-11 19:49:42 +08002420 if (checkCallingPermission(CAPTURE_VIDEO_OUTPUT, "canProjectVideo()")) {
Michael Wrightc39d47a2014-07-08 18:07:36 -07002421 return true;
2422 }
2423 return canProjectSecureVideo(projection);
2424 }
2425
2426 private boolean canProjectSecureVideo(IMediaProjection projection) {
2427 if (projection != null) {
2428 try {
2429 if (projection.canProjectSecureVideo()){
2430 return true;
2431 }
2432 } catch (RemoteException e) {
2433 Slog.e(TAG, "Unable to query projection service for permissions", e);
2434 }
2435 }
Chilun67a379b2019-04-11 19:49:42 +08002436 return checkCallingPermission(CAPTURE_SECURE_VIDEO_OUTPUT, "canProjectSecureVideo()");
2437 }
2438
2439 private boolean checkCallingPermission(String permission, String func) {
2440 if (mContext.checkCallingPermission(permission) == PackageManager.PERMISSION_GRANTED) {
2441 return true;
2442 }
2443 final String msg = "Permission Denial: " + func + " from pid=" + Binder.getCallingPid()
2444 + ", uid=" + Binder.getCallingUid() + " requires " + permission;
2445 Slog.w(TAG, msg);
2446 return false;
Michael Wrightc39d47a2014-07-08 18:07:36 -07002447 }
Jeff Brown4ccb8232014-01-16 22:16:42 -08002448 }
2449
2450 private final class LocalService extends DisplayManagerInternal {
Galia Peycheva056b3ee2019-06-26 14:05:12 +02002451
Jeff Brown4ccb8232014-01-16 22:16:42 -08002452 @Override
Jeff Brown037c33e2014-04-09 00:31:55 -07002453 public void initPowerManagement(final DisplayPowerCallbacks callbacks, Handler handler,
Jeff Brownad9ef192014-04-08 17:26:30 -07002454 SensorManager sensorManager) {
2455 synchronized (mSyncRoot) {
Jeff Brown037c33e2014-04-09 00:31:55 -07002456 DisplayBlanker blanker = new DisplayBlanker() {
2457 @Override
Fiona Campbelld4eb2952019-11-04 17:19:56 +00002458 public void requestDisplayState(int state, float brightness) {
Jeff Brown037c33e2014-04-09 00:31:55 -07002459 // The order of operations is important for legacy reasons.
2460 if (state == Display.STATE_OFF) {
Jeff Brown5d6443b2015-04-10 20:15:01 -07002461 requestGlobalDisplayStateInternal(state, brightness);
Jeff Brown037c33e2014-04-09 00:31:55 -07002462 }
2463
2464 callbacks.onDisplayStateChange(state);
2465
2466 if (state != Display.STATE_OFF) {
Jeff Brown5d6443b2015-04-10 20:15:01 -07002467 requestGlobalDisplayStateInternal(state, brightness);
Jeff Brown037c33e2014-04-09 00:31:55 -07002468 }
2469 }
2470 };
Jeff Brownad9ef192014-04-08 17:26:30 -07002471 mDisplayPowerController = new DisplayPowerController(
Jeff Brown037c33e2014-04-09 00:31:55 -07002472 mContext, callbacks, handler, sensorManager, blanker);
Long Lingbc841b02019-07-03 16:43:15 -07002473 mSensorManager = sensorManager;
Jeff Brownad9ef192014-04-08 17:26:30 -07002474 }
Michael Wrighteef0e132017-11-21 17:57:52 +00002475
2476 mHandler.sendEmptyMessage(MSG_LOAD_BRIGHTNESS_CONFIGURATION);
Jeff Brownad9ef192014-04-08 17:26:30 -07002477 }
2478
2479 @Override
2480 public boolean requestPowerState(DisplayPowerRequest request,
2481 boolean waitForNegativeProximity) {
Michael Wrighteef0e132017-11-21 17:57:52 +00002482 synchronized (mSyncRoot) {
2483 return mDisplayPowerController.requestPowerState(request,
2484 waitForNegativeProximity);
2485 }
Jeff Brownad9ef192014-04-08 17:26:30 -07002486 }
2487
2488 @Override
2489 public boolean isProximitySensorAvailable() {
Michael Wrighteef0e132017-11-21 17:57:52 +00002490 synchronized (mSyncRoot) {
2491 return mDisplayPowerController.isProximitySensorAvailable();
2492 }
Jeff Brownad9ef192014-04-08 17:26:30 -07002493 }
2494
2495 @Override
Robert Carr66b5664f2019-04-02 14:18:56 -07002496 public SurfaceControl.ScreenshotGraphicBuffer screenshot(int displayId) {
2497 return screenshotInternal(displayId);
Riddle Hsu654a6f92018-07-13 22:59:36 +08002498 }
2499
2500 @Override
Jeff Brown4ccb8232014-01-16 22:16:42 -08002501 public DisplayInfo getDisplayInfo(int displayId) {
2502 return getDisplayInfoInternal(displayId, Process.myUid());
2503 }
2504
2505 @Override
2506 public void registerDisplayTransactionListener(DisplayTransactionListener listener) {
2507 if (listener == null) {
2508 throw new IllegalArgumentException("listener must not be null");
2509 }
2510
2511 registerDisplayTransactionListenerInternal(listener);
2512 }
2513
2514 @Override
2515 public void unregisterDisplayTransactionListener(DisplayTransactionListener listener) {
2516 if (listener == null) {
2517 throw new IllegalArgumentException("listener must not be null");
2518 }
2519
2520 unregisterDisplayTransactionListenerInternal(listener);
2521 }
2522
2523 @Override
2524 public void setDisplayInfoOverrideFromWindowManager(int displayId, DisplayInfo info) {
2525 setDisplayInfoOverrideFromWindowManagerInternal(displayId, info);
2526 }
2527
2528 @Override
Andrii Kuliancd097992017-03-23 18:31:59 -07002529 public void getNonOverrideDisplayInfo(int displayId, DisplayInfo outInfo) {
2530 getNonOverrideDisplayInfoInternal(displayId, outInfo);
2531 }
2532
2533 @Override
Robert Carrae606b42018-02-15 15:36:23 -08002534 public void performTraversal(SurfaceControl.Transaction t) {
2535 performTraversalInternal(t);
Jeff Brown4ccb8232014-01-16 22:16:42 -08002536 }
2537
2538 @Override
Michael Wright3f145a22014-07-22 19:46:03 -07002539 public void setDisplayProperties(int displayId, boolean hasContent,
Galia Peycheva056b3ee2019-06-26 14:05:12 +02002540 float requestedRefreshRate, int requestedMode,
2541 boolean requestedMinimalPostProcessing, boolean inTraversal) {
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -07002542 setDisplayPropertiesInternal(displayId, hasContent, requestedRefreshRate,
Galia Peycheva056b3ee2019-06-26 14:05:12 +02002543 requestedMode, requestedMinimalPostProcessing, inTraversal);
Jeff Brown4ccb8232014-01-16 22:16:42 -08002544 }
Filip Gruszczynskid2e86402015-02-19 13:05:03 -08002545
2546 @Override
2547 public void setDisplayOffsets(int displayId, int x, int y) {
2548 setDisplayOffsetsInternal(displayId, x, y);
2549 }
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002550
2551 @Override
Sam Lin4c3ac2b2019-02-18 04:50:26 -08002552 public void setDisplayScalingDisabled(int displayId, boolean disableScaling) {
2553 setDisplayScalingDisabledInternal(displayId, disableScaling);
2554 }
2555
2556 @Override
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002557 public void setDisplayAccessUIDs(SparseArray<IntArray> newDisplayAccessUIDs) {
2558 setDisplayAccessUIDsInternal(newDisplayAccessUIDs);
2559 }
2560
2561 @Override
Peeyush Agarwalcc155dd2018-01-10 11:51:33 +00002562 public void persistBrightnessTrackerState() {
Michael Wright144aac92017-12-21 18:37:41 +00002563 synchronized (mSyncRoot) {
Peeyush Agarwalcc155dd2018-01-10 11:51:33 +00002564 mDisplayPowerController.persistBrightnessTrackerState();
Michael Wright144aac92017-12-21 18:37:41 +00002565 }
Kenny Guycfe7b702017-11-14 21:04:58 +00002566 }
Adrian Roose1d68cd2018-01-17 12:54:50 +01002567
2568 @Override
2569 public void onOverlayChanged() {
2570 synchronized (mSyncRoot) {
Adrian Roos898ec382018-01-17 12:54:50 +01002571 for (int i = 0; i < mDisplayDevices.size(); i++) {
2572 mDisplayDevices.get(i).onOverlayChangedLocked();
Adrian Roose1d68cd2018-01-17 12:54:50 +01002573 }
2574 }
2575 }
Kevin DuBoisbf76b11b2018-09-04 09:14:15 -07002576
2577 @Override
2578 public DisplayedContentSamplingAttributes getDisplayedContentSamplingAttributes(
2579 int displayId) {
2580 return getDisplayedContentSamplingAttributesInternal(displayId);
2581 }
2582
2583 @Override
2584 public boolean setDisplayedContentSamplingEnabled(
2585 int displayId, boolean enable, int componentMask, int maxFrames) {
2586 return setDisplayedContentSamplingEnabledInternal(
2587 displayId, enable, componentMask, maxFrames);
2588 }
2589
2590 @Override
2591 public DisplayedContentSample getDisplayedContentSample(int displayId,
2592 long maxFrames, long timestamp) {
2593 return getDisplayedContentSampleInternal(displayId, maxFrames, timestamp);
2594 }
2595
Jeff Brown4ccb8232014-01-16 22:16:42 -08002596 }
Michael Wrighta3dab232019-02-22 16:54:21 +00002597
Ana Kruleca74a8642019-11-14 00:51:00 +01002598 class DesiredDisplayModeSpecsObserver
2599 implements DisplayModeDirector.DesiredDisplayModeSpecsListener {
2600 public void onDesiredDisplayModeSpecsChanged() {
2601 onDesiredDisplayModeSpecsChangedInternal();
Michael Wrighta3dab232019-02-22 16:54:21 +00002602 }
2603 }
Jeff Brownfa25bf52012-07-23 19:26:30 -07002604}