blob: 99341d1c96ae05298f4a6b8abbd2c9d7a7995147 [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;
Peiyong Lin277eaff2019-01-16 16:18:22 -080042import android.graphics.ColorSpace;
Michael Wrighteedcbf12017-08-16 23:14:54 +010043import android.graphics.Point;
Robert Carr5c52b132019-02-15 15:48:11 -080044import android.graphics.Rect;
Jeff Brownad9ef192014-04-08 17:26:30 -070045import android.hardware.SensorManager;
Peeyush Agarwalcc155dd2018-01-10 11:51:33 +000046import android.hardware.display.AmbientBrightnessDayStats;
Kenny Guy22bd0442017-10-26 00:15:54 +010047import android.hardware.display.BrightnessChangeEvent;
Michael Wrighteef0e132017-11-21 17:57:52 +000048import android.hardware.display.BrightnessConfiguration;
Dan Gittik122df862018-03-28 16:59:22 +010049import android.hardware.display.Curve;
Jeff Brownbd6e1502012-08-28 03:27:37 -070050import android.hardware.display.DisplayManagerGlobal;
Jeff Brown4ccb8232014-01-16 22:16:42 -080051import android.hardware.display.DisplayManagerInternal;
Jeff Brown4ccb8232014-01-16 22:16:42 -080052import android.hardware.display.DisplayManagerInternal.DisplayTransactionListener;
Siarhei Vishniakou2eb0f8f2018-07-06 23:30:12 +010053import android.hardware.display.DisplayViewport;
Kevin DuBoisbf76b11b2018-09-04 09:14:15 -070054import android.hardware.display.DisplayedContentSample;
55import android.hardware.display.DisplayedContentSamplingAttributes;
Jeff Brownfa25bf52012-07-23 19:26:30 -070056import android.hardware.display.IDisplayManager;
Jeff Brownbd6e1502012-08-28 03:27:37 -070057import android.hardware.display.IDisplayManagerCallback;
Michael Wright75ee9fc2014-09-01 19:55:22 -070058import android.hardware.display.IVirtualDisplayCallback;
Jeff Browne08ae382012-09-07 20:36:36 -070059import android.hardware.display.WifiDisplayStatus;
Jeff Brown4ccb8232014-01-16 22:16:42 -080060import android.hardware.input.InputManagerInternal;
Michael Wrightc39d47a2014-07-08 18:07:36 -070061import android.media.projection.IMediaProjection;
62import android.media.projection.IMediaProjectionManager;
Jeff Brownfa25bf52012-07-23 19:26:30 -070063import android.os.Binder;
Jeff Brownbd6e1502012-08-28 03:27:37 -070064import android.os.Handler;
Jeff Brown64a55af2012-08-26 02:47:39 -070065import android.os.IBinder;
Jeff Brown4ccb8232014-01-16 22:16:42 -080066import android.os.IBinder.DeathRecipient;
Jeff Brownbd6e1502012-08-28 03:27:37 -070067import android.os.Looper;
68import android.os.Message;
Jeff Brown5d6443b2015-04-10 20:15:01 -070069import android.os.PowerManager;
Craig Mautner4504de52013-12-20 09:06:56 -080070import android.os.Process;
Jeff Brownbd6e1502012-08-28 03:27:37 -070071import android.os.RemoteException;
Dan Gittik7a32fba2018-03-28 12:19:38 +010072import android.os.ResultReceiver;
Michael Wrightc39d47a2014-07-08 18:07:36 -070073import android.os.ServiceManager;
Dan Gittik7a32fba2018-03-28 12:19:38 +010074import android.os.ShellCallback;
Jeff Brownbd6e1502012-08-28 03:27:37 -070075import android.os.SystemClock;
Jeff Brownfa25bf52012-07-23 19:26:30 -070076import android.os.SystemProperties;
Jeff Brown5d6443b2015-04-10 20:15:01 -070077import android.os.Trace;
Kenny Guy22bd0442017-10-26 00:15:54 +010078import android.os.UserHandle;
Michael Wrighteef0e132017-11-21 17:57:52 +000079import android.os.UserManager;
Dan Gittik7a32fba2018-03-28 12:19:38 +010080import android.provider.Settings;
Jeff Browna506a6e2013-06-04 00:02:38 -070081import android.text.TextUtils;
Andrii Kulianfb1bf692017-01-17 11:17:34 -080082import android.util.IntArray;
Dan Gittik122df862018-03-28 16:59:22 +010083import android.util.Pair;
Jeff Brownbd6e1502012-08-28 03:27:37 -070084import android.util.Slog;
85import android.util.SparseArray;
Dan Gittik122df862018-03-28 16:59:22 +010086import android.util.Spline;
Jeff Brownfa25bf52012-07-23 19:26:30 -070087import android.view.Display;
88import android.view.DisplayInfo;
Jeff Browna506a6e2013-06-04 00:02:38 -070089import android.view.Surface;
Robert Carrae606b42018-02-15 15:36:23 -080090import android.view.SurfaceControl;
Jeff Browna506a6e2013-06-04 00:02:38 -070091
Siarhei Vishniakou2eb0f8f2018-07-06 23:30:12 +010092import com.android.internal.annotations.GuardedBy;
93import com.android.internal.annotations.VisibleForTesting;
94import com.android.internal.util.DumpUtils;
95import com.android.internal.util.IndentingPrintWriter;
Jorim Jaggied7993b2017-03-28 18:50:01 +010096import com.android.server.AnimationThread;
Jeff Brown4ccb8232014-01-16 22:16:42 -080097import com.android.server.DisplayThread;
98import com.android.server.LocalServices;
99import com.android.server.SystemService;
Dianne Hackborn8d044e82013-04-30 17:24:15 -0700100import com.android.server.UiThread;
Jorim Jaggi21c39a72017-10-20 15:47:51 +0200101import com.android.server.wm.SurfaceAnimationThread;
Siarhei Vishniakou2eb0f8f2018-07-06 23:30:12 +0100102import com.android.server.wm.WindowManagerInternal;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700103
104import java.io.FileDescriptor;
105import java.io.PrintWriter;
106import java.util.ArrayList;
Jeff Browna506a6e2013-06-04 00:02:38 -0700107import java.util.Arrays;
Jeff Browne75926d2014-09-18 15:24:49 -0700108import java.util.List;
Jeff Brown7f3994e2012-12-04 14:04:28 -0800109import java.util.concurrent.CopyOnWriteArrayList;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700110
111/**
Jeff Brownbd6e1502012-08-28 03:27:37 -0700112 * Manages attached displays.
Jeff Brownfa25bf52012-07-23 19:26:30 -0700113 * <p>
Jeff Brownbd6e1502012-08-28 03:27:37 -0700114 * The {@link DisplayManagerService} manages the global lifecycle of displays,
115 * decides how to configure logical displays based on the physical display devices currently
116 * attached, sends notifications to the system and to applications when the state
117 * changes, and so on.
118 * </p><p>
119 * The display manager service relies on a collection of {@link DisplayAdapter} components,
120 * for discovering and configuring physical display devices attached to the system.
121 * There are separate display adapters for each manner that devices are attached:
122 * one display adapter for built-in local displays, one for simulated non-functional
123 * displays when the system is headless, one for simulated overlay displays used for
124 * development, one for wifi displays, etc.
125 * </p><p>
126 * Display adapters are only weakly coupled to the display manager service.
127 * Display adapters communicate changes in display device state to the display manager
Craig Mautner722285e2012-09-07 13:55:58 -0700128 * service asynchronously via a {@link DisplayAdapter.Listener} registered
Jeff Brownbd6e1502012-08-28 03:27:37 -0700129 * by the display manager service. This separation of concerns is important for
130 * two main reasons. First, it neatly encapsulates the responsibilities of these
131 * two classes: display adapters handle individual display devices whereas
132 * the display manager service handles the global state. Second, it eliminates
133 * the potential for deadlocks resulting from asynchronous display device discovery.
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700134 * </p>
135 *
136 * <h3>Synchronization</h3>
137 * <p>
138 * Because the display manager may be accessed by multiple threads, the synchronization
139 * story gets a little complicated. In particular, the window manager may call into
140 * the display manager while holding a surface transaction with the expectation that
141 * it can apply changes immediately. Unfortunately, that means we can't just do
142 * everything asynchronously (*grump*).
Jeff Brownbd6e1502012-08-28 03:27:37 -0700143 * </p><p>
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700144 * To make this work, all of the objects that belong to the display manager must
145 * use the same lock. We call this lock the synchronization root and it has a unique
146 * type {@link DisplayManagerService.SyncRoot}. Methods that require this lock are
147 * named with the "Locked" suffix.
148 * </p><p>
149 * Where things get tricky is that the display manager is not allowed to make
150 * any potentially reentrant calls, especially into the window manager. We generally
151 * avoid this by making all potentially reentrant out-calls asynchronous.
Jeff Brownfa25bf52012-07-23 19:26:30 -0700152 * </p>
153 */
Jeff Brown4ccb8232014-01-16 22:16:42 -0800154public final class DisplayManagerService extends SystemService {
Jeff Brownfa25bf52012-07-23 19:26:30 -0700155 private static final String TAG = "DisplayManagerService";
Jeff Brownbd6e1502012-08-28 03:27:37 -0700156 private static final boolean DEBUG = false;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700157
Jeff Brownbbd28a22012-09-20 16:47:15 -0700158 // When this system property is set to 0, WFD is forcibly disabled on boot.
159 // When this system property is set to 1, WFD is forcibly enabled on boot.
160 // Otherwise WFD is enabled according to the value of config_enableWifiDisplay.
161 private static final String FORCE_WIFI_DISPLAY_ENABLE = "persist.debug.wfd.enable";
162
Adrian Roos9ee5dff2018-08-22 20:19:49 +0200163 private static final String PROP_DEFAULT_DISPLAY_TOP_INSET = "persist.sys.displayinset.top";
164
Jeff Brownbd6e1502012-08-28 03:27:37 -0700165 private static final long WAIT_FOR_DEFAULT_DISPLAY_TIMEOUT = 10000;
166
Santos Cordonc22c5632017-06-21 16:03:49 -0700167 private static final int MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS = 1;
Jeff Brownbd6e1502012-08-28 03:27:37 -0700168 private static final int MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS = 2;
169 private static final int MSG_DELIVER_DISPLAY_EVENT = 3;
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700170 private static final int MSG_REQUEST_TRAVERSAL = 4;
Jeff Brownd728bf52012-09-08 18:05:28 -0700171 private static final int MSG_UPDATE_VIEWPORT = 5;
Michael Wrighta3dab232019-02-22 16:54:21 +0000172 private static final int MSG_LOAD_BRIGHTNESS_CONFIGURATION = 6;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700173
Jeff Brownb880d882014-02-10 19:47:07 -0800174 private final Context mContext;
Jeff Brownbd6e1502012-08-28 03:27:37 -0700175 private final DisplayManagerHandler mHandler;
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700176 private final Handler mUiHandler;
177 private final DisplayAdapterListener mDisplayAdapterListener;
Michael Wrighta3dab232019-02-22 16:54:21 +0000178 private final DisplayModeDirector mDisplayModeDirector;
Jeff Brown4ccb8232014-01-16 22:16:42 -0800179 private WindowManagerInternal mWindowManagerInternal;
180 private InputManagerInternal mInputManagerInternal;
Michael Wrightc39d47a2014-07-08 18:07:36 -0700181 private IMediaProjectionManager mProjectionService;
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700182
183 // The synchronization root for the display manager.
184 // This lock guards most of the display manager's state.
Craig Mautner0bf6ec92012-12-18 08:33:27 -0800185 // NOTE: This is synchronized on while holding WindowManagerService.mWindowMap so never call
186 // into WindowManagerService methods that require mWindowMap while holding this unless you are
187 // very very sure that no deadlock can occur.
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700188 private final SyncRoot mSyncRoot = new SyncRoot();
189
190 // True if in safe mode.
191 // This option may disable certain display adapters.
192 public boolean mSafeMode;
193
194 // True if we are in a special boot mode where only core applications and
195 // services should be started. This option may disable certain display adapters.
196 public boolean mOnlyCore;
197
Jeff Brown27f1d672012-10-17 18:32:34 -0700198 // True if the display manager service should pretend there is only one display
199 // and only tell applications about the existence of the default logical display.
200 // The display manager can still mirror content to secondary displays but applications
201 // cannot present unique content on those displays.
202 // Used for demonstration purposes only.
203 private final boolean mSingleDisplayDemoMode;
204
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700205 // All callback records indexed by calling process id.
206 public final SparseArray<CallbackRecord> mCallbacks =
Jeff Brownbd6e1502012-08-28 03:27:37 -0700207 new SparseArray<CallbackRecord>();
Jeff Brownfa25bf52012-07-23 19:26:30 -0700208
Jeff Brownbd6e1502012-08-28 03:27:37 -0700209 // List of all currently registered display adapters.
210 private final ArrayList<DisplayAdapter> mDisplayAdapters = new ArrayList<DisplayAdapter>();
211
212 // List of all currently connected display devices.
213 private final ArrayList<DisplayDevice> mDisplayDevices = new ArrayList<DisplayDevice>();
214
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700215 // List of all logical displays indexed by logical display id.
216 private final SparseArray<LogicalDisplay> mLogicalDisplays =
217 new SparseArray<LogicalDisplay>();
Jeff Brownbd6e1502012-08-28 03:27:37 -0700218 private int mNextNonDefaultDisplayId = Display.DEFAULT_DISPLAY + 1;
219
Jeff Brown7f3994e2012-12-04 14:04:28 -0800220 // List of all display transaction listeners.
221 private final CopyOnWriteArrayList<DisplayTransactionListener> mDisplayTransactionListeners =
222 new CopyOnWriteArrayList<DisplayTransactionListener>();
223
Jeff Brownad9ef192014-04-08 17:26:30 -0700224 // Display power controller.
225 private DisplayPowerController mDisplayPowerController;
226
Jeff Brown037c33e2014-04-09 00:31:55 -0700227 // The overall display state, independent of changes that might influence one
228 // display or another in particular.
Jeff Brown5d6443b2015-04-10 20:15:01 -0700229 private int mGlobalDisplayState = Display.STATE_ON;
230
231 // The overall display brightness.
232 // For now, this only applies to the built-in display but we may split it up eventually.
233 private int mGlobalDisplayBrightness = PowerManager.BRIGHTNESS_DEFAULT;
Jeff Brown9e316a12012-10-08 19:17:06 -0700234
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700235 // Set to true when there are pending display changes that have yet to be applied
236 // to the surface flinger state.
237 private boolean mPendingTraversal;
Jeff Brownbd6e1502012-08-28 03:27:37 -0700238
Jeff Browne08ae382012-09-07 20:36:36 -0700239 // The Wifi display adapter, or null if not registered.
240 private WifiDisplayAdapter mWifiDisplayAdapter;
241
Jeff Brownce468a32013-11-21 16:42:03 -0800242 // The number of active wifi display scan requests.
243 private int mWifiDisplayScanRequestCount;
244
Jeff Browna506a6e2013-06-04 00:02:38 -0700245 // The virtual display adapter, or null if not registered.
246 private VirtualDisplayAdapter mVirtualDisplayAdapter;
247
Michael Wrighteef0e132017-11-21 17:57:52 +0000248 // The User ID of the current user
249 private @UserIdInt int mCurrentUserId;
250
Michael Wrighteedcbf12017-08-16 23:14:54 +0100251 // The stable device screen height and width. These are not tied to a specific display, even
252 // the default display, because they need to be stable over the course of the device's entire
253 // life, even if the default display changes (e.g. a new monitor is plugged into a PC-like
254 // device).
255 private Point mStableDisplaySize = new Point();
256
Winson72dbe7e2019-04-29 14:55:30 -0700257 // Whether the system has finished booting or not.
258 private boolean mSystemReady;
259
Adrian Roos9ee5dff2018-08-22 20:19:49 +0200260 // The top inset of the default display.
261 // This gets persisted so that the boot animation knows how to transition from the display's
262 // full size to the size configured by the user. Right now we only persist and animate the top
263 // inset, but theoretically we could do it for all of them.
264 private int mDefaultDisplayTopInset;
265
Jeff Brownd728bf52012-09-08 18:05:28 -0700266 // Viewports of the default display and the display that should receive touch
267 // input from an external source. Used by the input system.
Siarhei Vishniakou2eb0f8f2018-07-06 23:30:12 +0100268 @GuardedBy("mSyncRoot")
269 private final ArrayList<DisplayViewport> mViewports = new ArrayList<>();
Jeff Brownd728bf52012-09-08 18:05:28 -0700270
Jeff Brown89d55462012-09-19 11:33:42 -0700271 // Persistent data store for all internal settings maintained by the display manager service.
272 private final PersistentDataStore mPersistentDataStore = new PersistentDataStore();
273
Jeff Brownbd6e1502012-08-28 03:27:37 -0700274 // Temporary callback list, used when sending display events to applications.
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700275 // May be used outside of the lock but only on the handler thread.
276 private final ArrayList<CallbackRecord> mTempCallbacks = new ArrayList<CallbackRecord>();
Jeff Brownbd6e1502012-08-28 03:27:37 -0700277
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700278 // Temporary display info, used for comparing display configurations.
279 private final DisplayInfo mTempDisplayInfo = new DisplayInfo();
280
Jeff Brownd728bf52012-09-08 18:05:28 -0700281 // Temporary viewports, used when sending new viewport information to the
282 // input system. May be used outside of the lock but only on the handler thread.
Siarhei Vishniakou2eb0f8f2018-07-06 23:30:12 +0100283 private final ArrayList<DisplayViewport> mTempViewports = new ArrayList<>();
Jeff Brownd728bf52012-09-08 18:05:28 -0700284
Damien Bargiacchi4364bbf2016-11-01 21:44:20 -0700285 // The default color mode for default displays. Overrides the usual
286 // Display.Display.COLOR_MODE_DEFAULT for displays with the
287 // DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY flag set.
288 private final int mDefaultDisplayDefaultColorMode;
289
Jeff Browne75926d2014-09-18 15:24:49 -0700290 // Temporary list of deferred work to perform when setting the display state.
291 // Only used by requestDisplayState. The field is self-synchronized and only
292 // intended for use inside of the requestGlobalDisplayStateInternal function.
293 private final ArrayList<Runnable> mTempDisplayStateWorkQueue = new ArrayList<Runnable>();
294
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800295 // Lists of UIDs that are present on the displays. Maps displayId -> array of UIDs.
296 private final SparseArray<IntArray> mDisplayAccessUIDs = new SparseArray<>();
297
Santos Cordonee8931e2017-04-05 10:31:15 -0700298 private final Injector mInjector;
299
Dan Gittik122df862018-03-28 16:59:22 +0100300 // The minimum brightness curve, which guarantess that any brightness curve that dips below it
301 // is rejected by the system.
302 private final Curve mMinimumBrightnessCurve;
303 private final Spline mMinimumBrightnessSpline;
Peiyong Lin277eaff2019-01-16 16:18:22 -0800304 private final ColorSpace mWideColorSpace;
Dan Gittik122df862018-03-28 16:59:22 +0100305
Jeff Brownb880d882014-02-10 19:47:07 -0800306 public DisplayManagerService(Context context) {
Santos Cordonee8931e2017-04-05 10:31:15 -0700307 this(context, new Injector());
308 }
309
310 @VisibleForTesting
311 DisplayManagerService(Context context, Injector injector) {
Jeff Brownb880d882014-02-10 19:47:07 -0800312 super(context);
Santos Cordonee8931e2017-04-05 10:31:15 -0700313 mInjector = injector;
Jeff Brownb880d882014-02-10 19:47:07 -0800314 mContext = context;
Jeff Brown4ccb8232014-01-16 22:16:42 -0800315 mHandler = new DisplayManagerHandler(DisplayThread.get().getLooper());
Dianne Hackborn8d044e82013-04-30 17:24:15 -0700316 mUiHandler = UiThread.getHandler();
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700317 mDisplayAdapterListener = new DisplayAdapterListener();
Michael Wrighta3dab232019-02-22 16:54:21 +0000318 mDisplayModeDirector = new DisplayModeDirector(context, mHandler);
Jeff Brown27f1d672012-10-17 18:32:34 -0700319 mSingleDisplayDemoMode = SystemProperties.getBoolean("persist.demo.singledisplay", false);
Dan Gittik122df862018-03-28 16:59:22 +0100320 Resources resources = mContext.getResources();
Damien Bargiacchi4364bbf2016-11-01 21:44:20 -0700321 mDefaultDisplayDefaultColorMode = mContext.getResources().getInteger(
Michael Wrighteef0e132017-11-21 17:57:52 +0000322 com.android.internal.R.integer.config_defaultDisplayDefaultColorMode);
Adrian Roos9ee5dff2018-08-22 20:19:49 +0200323 mDefaultDisplayTopInset = SystemProperties.getInt(PROP_DEFAULT_DISPLAY_TOP_INSET, -1);
Dan Gittik122df862018-03-28 16:59:22 +0100324 float[] lux = getFloatArray(resources.obtainTypedArray(
325 com.android.internal.R.array.config_minimumBrightnessCurveLux));
326 float[] nits = getFloatArray(resources.obtainTypedArray(
327 com.android.internal.R.array.config_minimumBrightnessCurveNits));
328 mMinimumBrightnessCurve = new Curve(lux, nits);
329 mMinimumBrightnessSpline = Spline.createSpline(lux, nits);
Jeff Brown5d6443b2015-04-10 20:15:01 -0700330
Michael Wrighta3dab232019-02-22 16:54:21 +0000331 PowerManager pm = mContext.getSystemService(PowerManager.class);
Jeff Brown5d6443b2015-04-10 20:15:01 -0700332 mGlobalDisplayBrightness = pm.getDefaultScreenBrightnessSetting();
Michael Wrighteef0e132017-11-21 17:57:52 +0000333 mCurrentUserId = UserHandle.USER_SYSTEM;
Peiyong Lin277eaff2019-01-16 16:18:22 -0800334 ColorSpace[] colorSpaces = SurfaceControl.getCompositionColorSpaces();
335 mWideColorSpace = colorSpaces[1];
Winson72dbe7e2019-04-29 14:55:30 -0700336
337 mSystemReady = false;
Joel Fernandes2d314e12017-04-04 16:32:15 -0700338 }
339
340 public void setupSchedulerPolicies() {
Jorim Jaggied7993b2017-03-28 18:50:01 +0100341 // android.display and android.anim is critical to user experience and we should make sure
Michael Wrighteef0e132017-11-21 17:57:52 +0000342 // it is not in the default foregroup groups, add it to top-app to make sure it uses all
343 // the cores and scheduling settings for top-app when it runs.
Jorim Jaggied7993b2017-03-28 18:50:01 +0100344 Process.setThreadGroupAndCpuset(DisplayThread.get().getThreadId(),
345 Process.THREAD_GROUP_TOP_APP);
346 Process.setThreadGroupAndCpuset(AnimationThread.get().getThreadId(),
347 Process.THREAD_GROUP_TOP_APP);
Jorim Jaggi21c39a72017-10-20 15:47:51 +0200348 Process.setThreadGroupAndCpuset(SurfaceAnimationThread.get().getThreadId(),
349 Process.THREAD_GROUP_TOP_APP);
Craig Mautner4f67ba62012-08-02 11:23:00 -0700350 }
351
Jeff Brown4ccb8232014-01-16 22:16:42 -0800352 @Override
Jeff Brown4ccb8232014-01-16 22:16:42 -0800353 public void onStart() {
Michael Wright1c9977b2016-07-12 13:30:10 -0700354 // We need to pre-load the persistent data store so it's ready before the default display
355 // adapter is up so that we have it's configuration. We could load it lazily, but since
356 // 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 -0700357 // we've waited for the display to register itself with us.
Michael Wrighta3dab232019-02-22 16:54:21 +0000358 synchronized (mSyncRoot) {
359 mPersistentDataStore.loadIfNeeded();
360 loadStableDisplayValuesLocked();
Michael Wrighteedcbf12017-08-16 23:14:54 +0100361 }
Santos Cordonc22c5632017-06-21 16:03:49 -0700362 mHandler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS);
Jeff Brown4ccb8232014-01-16 22:16:42 -0800363
364 publishBinderService(Context.DISPLAY_SERVICE, new BinderService(),
365 true /*allowIsolated*/);
366 publishLocalService(DisplayManagerInternal.class, new LocalService());
367 }
368
369 @Override
370 public void onBootPhase(int phase) {
371 if (phase == PHASE_WAIT_FOR_DEFAULT_DISPLAY) {
372 synchronized (mSyncRoot) {
Santos Cordonc22c5632017-06-21 16:03:49 -0700373 long timeout = SystemClock.uptimeMillis()
374 + mInjector.getDefaultDisplayDelayTimeout();
375 while (mLogicalDisplays.get(Display.DEFAULT_DISPLAY) == null ||
376 mVirtualDisplayAdapter == null) {
Jeff Brown4ccb8232014-01-16 22:16:42 -0800377 long delay = timeout - SystemClock.uptimeMillis();
378 if (delay <= 0) {
379 throw new RuntimeException("Timeout waiting for default display "
Santos Cordonc22c5632017-06-21 16:03:49 -0700380 + "to be initialized. DefaultDisplay="
381 + mLogicalDisplays.get(Display.DEFAULT_DISPLAY)
382 + ", mVirtualDisplayAdapter=" + mVirtualDisplayAdapter);
Jeff Brown4ccb8232014-01-16 22:16:42 -0800383 }
384 if (DEBUG) {
385 Slog.d(TAG, "waitForDefaultDisplay: waiting, timeout=" + delay);
386 }
387 try {
388 mSyncRoot.wait(delay);
389 } catch (InterruptedException ex) {
390 }
Jeff Brownbd6e1502012-08-28 03:27:37 -0700391 }
392 }
393 }
Jeff Brownbd6e1502012-08-28 03:27:37 -0700394 }
395
Michael Wrighteef0e132017-11-21 17:57:52 +0000396 @Override
397 public void onSwitchUser(@UserIdInt int newUserId) {
398 final int userSerial = getUserManager().getUserSerialNumber(newUserId);
399 synchronized (mSyncRoot) {
400 if (mCurrentUserId != newUserId) {
401 mCurrentUserId = newUserId;
402 BrightnessConfiguration config =
403 mPersistentDataStore.getBrightnessConfiguration(userSerial);
404 mDisplayPowerController.setBrightnessConfiguration(config);
405 }
Peeyush Agarwalcc155dd2018-01-10 11:51:33 +0000406 mDisplayPowerController.onSwitchUser(newUserId);
Michael Wrighteef0e132017-11-21 17:57:52 +0000407 }
408 }
409
Jeff Brown4ccb8232014-01-16 22:16:42 -0800410 // TODO: Use dependencies or a boot phase
411 public void windowManagerAndInputReady() {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700412 synchronized (mSyncRoot) {
Jeff Brown4ccb8232014-01-16 22:16:42 -0800413 mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
414 mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);
Craig Mautner65d11b32012-10-01 13:59:52 -0700415 scheduleTraversalLocked(false);
Jeff Brownd728bf52012-09-08 18:05:28 -0700416 }
417 }
418
419 /**
Jeff Brownbd6e1502012-08-28 03:27:37 -0700420 * Called when the system is ready to go.
421 */
422 public void systemReady(boolean safeMode, boolean onlyCore) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700423 synchronized (mSyncRoot) {
Jeff Brownbd6e1502012-08-28 03:27:37 -0700424 mSafeMode = safeMode;
425 mOnlyCore = onlyCore;
Winson72dbe7e2019-04-29 14:55:30 -0700426 mSystemReady = true;
427 // Just in case the top inset changed before the system was ready. At this point, any
428 // relevant configuration should be in place.
429 recordTopInsetLocked(mLogicalDisplays.get(Display.DEFAULT_DISPLAY));
Jeff Brownbd6e1502012-08-28 03:27:37 -0700430 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700431
Michael Wrighta3dab232019-02-22 16:54:21 +0000432 mDisplayModeDirector.setListener(new AllowedDisplayModeObserver());
433 mDisplayModeDirector.start();
434
Jeff Brownbd6e1502012-08-28 03:27:37 -0700435 mHandler.sendEmptyMessage(MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS);
436 }
437
Santos Cordonee8931e2017-04-05 10:31:15 -0700438 @VisibleForTesting
439 Handler getDisplayHandler() {
440 return mHandler;
441 }
442
Michael Wrighteedcbf12017-08-16 23:14:54 +0100443 private void loadStableDisplayValuesLocked() {
444 final Point size = mPersistentDataStore.getStableDisplaySize();
445 if (size.x > 0 && size.y > 0) {
446 // Just set these values directly so we don't write the display persistent data again
447 // unnecessarily
448 mStableDisplaySize.set(size.x, size.y);
449 } else {
450 final Resources res = mContext.getResources();
451 final int width = res.getInteger(
452 com.android.internal.R.integer.config_stableDeviceDisplayWidth);
453 final int height = res.getInteger(
454 com.android.internal.R.integer.config_stableDeviceDisplayHeight);
455 if (width > 0 && height > 0) {
456 setStableDisplaySizeLocked(width, height);
457 }
458 }
459 }
460
461 private Point getStableDisplaySizeInternal() {
462 Point r = new Point();
463 synchronized (mSyncRoot) {
464 if (mStableDisplaySize.x > 0 && mStableDisplaySize.y > 0) {
465 r.set(mStableDisplaySize.x, mStableDisplaySize.y);
466 }
467 }
468 return r;
469 }
470
Jeff Brown4ccb8232014-01-16 22:16:42 -0800471 private void registerDisplayTransactionListenerInternal(
472 DisplayTransactionListener listener) {
Jeff Brown7f3994e2012-12-04 14:04:28 -0800473 // List is self-synchronized copy-on-write.
474 mDisplayTransactionListeners.add(listener);
475 }
476
Jeff Brown4ccb8232014-01-16 22:16:42 -0800477 private void unregisterDisplayTransactionListenerInternal(
478 DisplayTransactionListener listener) {
Jeff Brown7f3994e2012-12-04 14:04:28 -0800479 // List is self-synchronized copy-on-write.
480 mDisplayTransactionListeners.remove(listener);
481 }
482
Jeff Brown4ccb8232014-01-16 22:16:42 -0800483 private void setDisplayInfoOverrideFromWindowManagerInternal(
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700484 int displayId, DisplayInfo info) {
485 synchronized (mSyncRoot) {
Jeff Brownbd6e1502012-08-28 03:27:37 -0700486 LogicalDisplay display = mLogicalDisplays.get(displayId);
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700487 if (display != null) {
Jeff Brownef981a42013-08-07 14:13:37 -0700488 if (display.setDisplayInfoOverrideFromWindowManagerLocked(info)) {
Adrian Roos9ee5dff2018-08-22 20:19:49 +0200489 handleLogicalDisplayChanged(displayId, display);
Craig Mautner65d11b32012-10-01 13:59:52 -0700490 scheduleTraversalLocked(false);
Jeff Brownbd6e1502012-08-28 03:27:37 -0700491 }
Jeff Brownbd6e1502012-08-28 03:27:37 -0700492 }
493 }
494 }
495
Andrii Kuliancd097992017-03-23 18:31:59 -0700496 /**
497 * @see DisplayManagerInternal#getNonOverrideDisplayInfo(int, DisplayInfo)
498 */
499 private void getNonOverrideDisplayInfoInternal(int displayId, DisplayInfo outInfo) {
500 synchronized (mSyncRoot) {
501 final LogicalDisplay display = mLogicalDisplays.get(displayId);
502 if (display != null) {
503 display.getNonOverrideDisplayInfoLocked(outInfo);
504 }
505 }
506 }
507
Santos Cordonee8931e2017-04-05 10:31:15 -0700508 @VisibleForTesting
Robert Carrae606b42018-02-15 15:36:23 -0800509 void performTraversalInternal(SurfaceControl.Transaction t) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700510 synchronized (mSyncRoot) {
511 if (!mPendingTraversal) {
512 return;
Jeff Brownbd6e1502012-08-28 03:27:37 -0700513 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700514 mPendingTraversal = false;
515
Robert Carrae606b42018-02-15 15:36:23 -0800516 performTraversalLocked(t);
Jeff Brownbd6e1502012-08-28 03:27:37 -0700517 }
Jeff Brown7f3994e2012-12-04 14:04:28 -0800518
519 // List is self-synchronized copy-on-write.
520 for (DisplayTransactionListener listener : mDisplayTransactionListeners) {
Vishnu Naire86bd982018-11-28 13:23:17 -0800521 listener.onDisplayTransaction(t);
Jeff Brown7f3994e2012-12-04 14:04:28 -0800522 }
Jeff Brownbd6e1502012-08-28 03:27:37 -0700523 }
524
Jeff Brown5d6443b2015-04-10 20:15:01 -0700525 private void requestGlobalDisplayStateInternal(int state, int brightness) {
526 if (state == Display.STATE_UNKNOWN) {
527 state = Display.STATE_ON;
528 }
529 if (state == Display.STATE_OFF) {
530 brightness = PowerManager.BRIGHTNESS_OFF;
531 } else if (brightness < 0) {
532 brightness = PowerManager.BRIGHTNESS_DEFAULT;
533 } else if (brightness > PowerManager.BRIGHTNESS_ON) {
534 brightness = PowerManager.BRIGHTNESS_ON;
535 }
536
Jeff Browne75926d2014-09-18 15:24:49 -0700537 synchronized (mTempDisplayStateWorkQueue) {
538 try {
539 // Update the display state within the lock.
Jeff Brown8e5d33e2015-06-10 13:05:50 -0700540 // Note that we do not need to schedule traversals here although it
541 // may happen as a side-effect of displays changing state.
Jeff Browne75926d2014-09-18 15:24:49 -0700542 synchronized (mSyncRoot) {
Jeff Brown5d6443b2015-04-10 20:15:01 -0700543 if (mGlobalDisplayState == state
544 && mGlobalDisplayBrightness == brightness) {
545 return; // no change
Jeff Browne75926d2014-09-18 15:24:49 -0700546 }
Jeff Brown5d6443b2015-04-10 20:15:01 -0700547
548 Trace.traceBegin(Trace.TRACE_TAG_POWER, "requestGlobalDisplayState("
549 + Display.stateToString(state)
550 + ", brightness=" + brightness + ")");
551 mGlobalDisplayState = state;
552 mGlobalDisplayBrightness = brightness;
Jeff Brown8e5d33e2015-06-10 13:05:50 -0700553 applyGlobalDisplayStateLocked(mTempDisplayStateWorkQueue);
Jeff Browne75926d2014-09-18 15:24:49 -0700554 }
555
556 // Setting the display power state can take hundreds of milliseconds
557 // to complete so we defer the most expensive part of the work until
558 // after we have exited the critical section to avoid blocking other
559 // threads for a long time.
560 for (int i = 0; i < mTempDisplayStateWorkQueue.size(); i++) {
561 mTempDisplayStateWorkQueue.get(i).run();
562 }
Jeff Brown5d6443b2015-04-10 20:15:01 -0700563 Trace.traceEnd(Trace.TRACE_TAG_POWER);
Jeff Browne75926d2014-09-18 15:24:49 -0700564 } finally {
565 mTempDisplayStateWorkQueue.clear();
Jeff Brown9e316a12012-10-08 19:17:06 -0700566 }
567 }
568 }
569
Jeff Brown4ccb8232014-01-16 22:16:42 -0800570 private DisplayInfo getDisplayInfoInternal(int displayId, int callingUid) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700571 synchronized (mSyncRoot) {
Jeff Brown4ccb8232014-01-16 22:16:42 -0800572 LogicalDisplay display = mLogicalDisplays.get(displayId);
573 if (display != null) {
574 DisplayInfo info = display.getDisplayInfoLocked();
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800575 if (info.hasAccess(callingUid)
576 || isUidPresentOnDisplayInternal(callingUid, displayId)) {
Jeff Brown4ccb8232014-01-16 22:16:42 -0800577 return info;
578 }
579 }
580 return null;
581 }
582 }
583
584 private int[] getDisplayIdsInternal(int callingUid) {
585 synchronized (mSyncRoot) {
586 final int count = mLogicalDisplays.size();
587 int[] displayIds = new int[count];
588 int n = 0;
589 for (int i = 0; i < count; i++) {
590 LogicalDisplay display = mLogicalDisplays.valueAt(i);
591 DisplayInfo info = display.getDisplayInfoLocked();
592 if (info.hasAccess(callingUid)) {
593 displayIds[n++] = mLogicalDisplays.keyAt(i);
594 }
595 }
596 if (n != count) {
597 displayIds = Arrays.copyOfRange(displayIds, 0, n);
598 }
599 return displayIds;
600 }
601 }
602
603 private void registerCallbackInternal(IDisplayManagerCallback callback, int callingPid) {
604 synchronized (mSyncRoot) {
Jeff Brownbd6e1502012-08-28 03:27:37 -0700605 if (mCallbacks.get(callingPid) != null) {
606 throw new SecurityException("The calling process has already "
607 + "registered an IDisplayManagerCallback.");
Jeff Brown64a55af2012-08-26 02:47:39 -0700608 }
609
Jeff Brownbd6e1502012-08-28 03:27:37 -0700610 CallbackRecord record = new CallbackRecord(callingPid, callback);
611 try {
612 IBinder binder = callback.asBinder();
613 binder.linkToDeath(record, 0);
614 } catch (RemoteException ex) {
615 // give up
616 throw new RuntimeException(ex);
617 }
618
619 mCallbacks.put(callingPid, record);
620 }
621 }
622
Jeff Brownce468a32013-11-21 16:42:03 -0800623 private void onCallbackDied(CallbackRecord record) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700624 synchronized (mSyncRoot) {
Jeff Brownce468a32013-11-21 16:42:03 -0800625 mCallbacks.remove(record.mPid);
626 stopWifiDisplayScanLocked(record);
Jeff Brownbd6e1502012-08-28 03:27:37 -0700627 }
628 }
629
Jeff Brown4ccb8232014-01-16 22:16:42 -0800630 private void startWifiDisplayScanInternal(int callingPid) {
631 synchronized (mSyncRoot) {
632 CallbackRecord record = mCallbacks.get(callingPid);
633 if (record == null) {
634 throw new IllegalStateException("The calling process has not "
635 + "registered an IDisplayManagerCallback.");
Jeff Browne08ae382012-09-07 20:36:36 -0700636 }
Jeff Brown4ccb8232014-01-16 22:16:42 -0800637 startWifiDisplayScanLocked(record);
Jeff Browne08ae382012-09-07 20:36:36 -0700638 }
639 }
640
Jeff Brownce468a32013-11-21 16:42:03 -0800641 private void startWifiDisplayScanLocked(CallbackRecord record) {
642 if (!record.mWifiDisplayScanRequested) {
643 record.mWifiDisplayScanRequested = true;
644 if (mWifiDisplayScanRequestCount++ == 0) {
645 if (mWifiDisplayAdapter != null) {
646 mWifiDisplayAdapter.requestStartScanLocked();
647 }
648 }
649 }
650 }
651
Jeff Brown4ccb8232014-01-16 22:16:42 -0800652 private void stopWifiDisplayScanInternal(int callingPid) {
653 synchronized (mSyncRoot) {
654 CallbackRecord record = mCallbacks.get(callingPid);
655 if (record == null) {
656 throw new IllegalStateException("The calling process has not "
657 + "registered an IDisplayManagerCallback.");
Jeff Brownce468a32013-11-21 16:42:03 -0800658 }
Jeff Brown4ccb8232014-01-16 22:16:42 -0800659 stopWifiDisplayScanLocked(record);
Jeff Brownce468a32013-11-21 16:42:03 -0800660 }
661 }
662
663 private void stopWifiDisplayScanLocked(CallbackRecord record) {
664 if (record.mWifiDisplayScanRequested) {
665 record.mWifiDisplayScanRequested = false;
666 if (--mWifiDisplayScanRequestCount == 0) {
667 if (mWifiDisplayAdapter != null) {
668 mWifiDisplayAdapter.requestStopScanLocked();
669 }
670 } else if (mWifiDisplayScanRequestCount < 0) {
Dianne Hackborn8d051722014-10-01 14:59:58 -0700671 Slog.wtf(TAG, "mWifiDisplayScanRequestCount became negative: "
Jeff Brownce468a32013-11-21 16:42:03 -0800672 + mWifiDisplayScanRequestCount);
673 mWifiDisplayScanRequestCount = 0;
674 }
675 }
676 }
677
Jeff Brown4ccb8232014-01-16 22:16:42 -0800678 private void connectWifiDisplayInternal(String address) {
679 synchronized (mSyncRoot) {
680 if (mWifiDisplayAdapter != null) {
681 mWifiDisplayAdapter.requestConnectLocked(address);
Jeff Browne08ae382012-09-07 20:36:36 -0700682 }
Jeff Browne08ae382012-09-07 20:36:36 -0700683 }
684 }
685
Jeff Brown4ccb8232014-01-16 22:16:42 -0800686 private void pauseWifiDisplayInternal() {
687 synchronized (mSyncRoot) {
688 if (mWifiDisplayAdapter != null) {
689 mWifiDisplayAdapter.requestPauseLocked();
Chong Zhang1f3ecaa2013-05-03 15:55:36 -0700690 }
Chong Zhang1f3ecaa2013-05-03 15:55:36 -0700691 }
692 }
693
Jeff Brown4ccb8232014-01-16 22:16:42 -0800694 private void resumeWifiDisplayInternal() {
695 synchronized (mSyncRoot) {
696 if (mWifiDisplayAdapter != null) {
697 mWifiDisplayAdapter.requestResumeLocked();
Chong Zhang1f3ecaa2013-05-03 15:55:36 -0700698 }
Chong Zhang1f3ecaa2013-05-03 15:55:36 -0700699 }
700 }
701
Jeff Brown4ccb8232014-01-16 22:16:42 -0800702 private void disconnectWifiDisplayInternal() {
703 synchronized (mSyncRoot) {
704 if (mWifiDisplayAdapter != null) {
705 mWifiDisplayAdapter.requestDisconnectLocked();
Jeff Browne08ae382012-09-07 20:36:36 -0700706 }
Jeff Browne08ae382012-09-07 20:36:36 -0700707 }
708 }
709
Jeff Brown4ccb8232014-01-16 22:16:42 -0800710 private void renameWifiDisplayInternal(String address, String alias) {
711 synchronized (mSyncRoot) {
712 if (mWifiDisplayAdapter != null) {
713 mWifiDisplayAdapter.requestRenameLocked(address, alias);
Jeff Brown89d55462012-09-19 11:33:42 -0700714 }
Jeff Brown89d55462012-09-19 11:33:42 -0700715 }
716 }
717
Jeff Brown4ccb8232014-01-16 22:16:42 -0800718 private void forgetWifiDisplayInternal(String address) {
719 synchronized (mSyncRoot) {
720 if (mWifiDisplayAdapter != null) {
721 mWifiDisplayAdapter.requestForgetLocked(address);
Jeff Brown89d55462012-09-19 11:33:42 -0700722 }
Jeff Brown89d55462012-09-19 11:33:42 -0700723 }
724 }
725
Jeff Brown4ccb8232014-01-16 22:16:42 -0800726 private WifiDisplayStatus getWifiDisplayStatusInternal() {
727 synchronized (mSyncRoot) {
728 if (mWifiDisplayAdapter != null) {
729 return mWifiDisplayAdapter.getWifiDisplayStatusLocked();
Jeff Browne08ae382012-09-07 20:36:36 -0700730 }
Jeff Brown4ccb8232014-01-16 22:16:42 -0800731 return new WifiDisplayStatus();
Jeff Browne08ae382012-09-07 20:36:36 -0700732 }
733 }
734
Michael Wright1c9977b2016-07-12 13:30:10 -0700735 private void requestColorModeInternal(int displayId, int colorMode) {
Michael Wright58e829f2015-09-15 00:13:26 +0100736 synchronized (mSyncRoot) {
737 LogicalDisplay display = mLogicalDisplays.get(displayId);
738 if (display != null &&
Michael Wright1c9977b2016-07-12 13:30:10 -0700739 display.getRequestedColorModeLocked() != colorMode) {
740 display.setRequestedColorModeLocked(colorMode);
Michael Wright58e829f2015-09-15 00:13:26 +0100741 scheduleTraversalLocked(false);
742 }
743 }
744 }
745
Michael Wright75ee9fc2014-09-01 19:55:22 -0700746 private int createVirtualDisplayInternal(IVirtualDisplayCallback callback,
Santos Cordonee8931e2017-04-05 10:31:15 -0700747 IMediaProjection projection, int callingUid, String packageName, String name, int width,
748 int height, int densityDpi, Surface surface, int flags, String uniqueId) {
Jeff Brown4ccb8232014-01-16 22:16:42 -0800749 synchronized (mSyncRoot) {
750 if (mVirtualDisplayAdapter == null) {
751 Slog.w(TAG, "Rejecting request to create private virtual display "
752 + "because the virtual display adapter is not available.");
753 return -1;
Jeff Brown7d00aff2013-08-02 19:03:49 -0700754 }
Jeff Brown4ccb8232014-01-16 22:16:42 -0800755
756 DisplayDevice device = mVirtualDisplayAdapter.createVirtualDisplayLocked(
Santos Cordonee8931e2017-04-05 10:31:15 -0700757 callback, projection, callingUid, packageName, name, width, height, densityDpi,
758 surface, flags, uniqueId);
Jeff Brown4ccb8232014-01-16 22:16:42 -0800759 if (device == null) {
760 return -1;
Jeff Brown7d00aff2013-08-02 19:03:49 -0700761 }
Jeff Browna506a6e2013-06-04 00:02:38 -0700762
Jeff Brown4ccb8232014-01-16 22:16:42 -0800763 handleDisplayDeviceAddedLocked(device);
764 LogicalDisplay display = findLogicalDisplayForDeviceLocked(device);
765 if (display != null) {
766 return display.getDisplayIdLocked();
Jeff Browna506a6e2013-06-04 00:02:38 -0700767 }
Jeff Brown4ccb8232014-01-16 22:16:42 -0800768
769 // Something weird happened and the logical display was not created.
770 Slog.w(TAG, "Rejecting request to create virtual display "
771 + "because the logical display was not created.");
Michael Wright75ee9fc2014-09-01 19:55:22 -0700772 mVirtualDisplayAdapter.releaseVirtualDisplayLocked(callback.asBinder());
Jeff Brown4ccb8232014-01-16 22:16:42 -0800773 handleDisplayDeviceRemovedLocked(device);
Jeff Browna506a6e2013-06-04 00:02:38 -0700774 }
775 return -1;
776 }
777
Michael Wright01e840f2014-06-26 16:03:25 -0700778 private void resizeVirtualDisplayInternal(IBinder appToken,
779 int width, int height, int densityDpi) {
780 synchronized (mSyncRoot) {
781 if (mVirtualDisplayAdapter == null) {
782 return;
783 }
784
785 mVirtualDisplayAdapter.resizeVirtualDisplayLocked(appToken, width, height, densityDpi);
786 }
787 }
788
Jeff Brown92207df2014-04-16 13:16:07 -0700789 private void setVirtualDisplaySurfaceInternal(IBinder appToken, Surface surface) {
790 synchronized (mSyncRoot) {
791 if (mVirtualDisplayAdapter == null) {
792 return;
793 }
794
795 mVirtualDisplayAdapter.setVirtualDisplaySurfaceLocked(appToken, surface);
796 }
797 }
798
Jeff Brown4ccb8232014-01-16 22:16:42 -0800799 private void releaseVirtualDisplayInternal(IBinder appToken) {
800 synchronized (mSyncRoot) {
801 if (mVirtualDisplayAdapter == null) {
802 return;
Jeff Browna506a6e2013-06-04 00:02:38 -0700803 }
Jeff Browna506a6e2013-06-04 00:02:38 -0700804
Jeff Brown4ccb8232014-01-16 22:16:42 -0800805 DisplayDevice device =
806 mVirtualDisplayAdapter.releaseVirtualDisplayLocked(appToken);
807 if (device != null) {
808 handleDisplayDeviceRemovedLocked(device);
Jeff Browna506a6e2013-06-04 00:02:38 -0700809 }
810 }
Jeff Browna506a6e2013-06-04 00:02:38 -0700811 }
812
chaviwda4c6942018-11-07 15:52:56 -0800813 private void setVirtualDisplayStateInternal(IBinder appToken, boolean isOn) {
814 synchronized (mSyncRoot) {
815 if (mVirtualDisplayAdapter == null) {
816 return;
817 }
818
819 mVirtualDisplayAdapter.setVirtualDisplayStateLocked(appToken, isOn);
820 }
821 }
822
Santos Cordonc22c5632017-06-21 16:03:49 -0700823 private void registerDefaultDisplayAdapters() {
824 // Register default display adapters.
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700825 synchronized (mSyncRoot) {
Santos Cordonc22c5632017-06-21 16:03:49 -0700826 // main display adapter
Mike Lockwoode63f6f72013-11-15 11:01:47 -0800827 registerDisplayAdapterLocked(new LocalDisplayAdapter(
828 mSyncRoot, mContext, mHandler, mDisplayAdapterListener));
Santos Cordonc22c5632017-06-21 16:03:49 -0700829
830 // Standalone VR devices rely on a virtual display as their primary display for
831 // 2D UI. We register virtual display adapter along side the main display adapter
832 // here so that it is ready by the time the system sends the home Intent for
833 // early apps like SetupWizard/Launcher. In particular, SUW is displayed using
834 // the virtual display inside VR before any VR-specific apps even run.
835 mVirtualDisplayAdapter = mInjector.getVirtualDisplayAdapter(mSyncRoot, mContext,
836 mHandler, mDisplayAdapterListener);
837 if (mVirtualDisplayAdapter != null) {
838 registerDisplayAdapterLocked(mVirtualDisplayAdapter);
839 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700840 }
841 }
842
843 private void registerAdditionalDisplayAdapters() {
844 synchronized (mSyncRoot) {
845 if (shouldRegisterNonEssentialDisplayAdaptersLocked()) {
Jeff Brown89d55462012-09-19 11:33:42 -0700846 registerOverlayDisplayAdapterLocked();
847 registerWifiDisplayAdapterLocked();
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700848 }
849 }
850 }
851
Jeff Brown89d55462012-09-19 11:33:42 -0700852 private void registerOverlayDisplayAdapterLocked() {
853 registerDisplayAdapterLocked(new OverlayDisplayAdapter(
854 mSyncRoot, mContext, mHandler, mDisplayAdapterListener, mUiHandler));
855 }
856
857 private void registerWifiDisplayAdapterLocked() {
858 if (mContext.getResources().getBoolean(
Jeff Brownbbd28a22012-09-20 16:47:15 -0700859 com.android.internal.R.bool.config_enableWifiDisplay)
860 || SystemProperties.getInt(FORCE_WIFI_DISPLAY_ENABLE, -1) == 1) {
Jeff Brown89d55462012-09-19 11:33:42 -0700861 mWifiDisplayAdapter = new WifiDisplayAdapter(
862 mSyncRoot, mContext, mHandler, mDisplayAdapterListener,
863 mPersistentDataStore);
864 registerDisplayAdapterLocked(mWifiDisplayAdapter);
865 }
866 }
867
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700868 private boolean shouldRegisterNonEssentialDisplayAdaptersLocked() {
869 // In safe mode, we disable non-essential display adapters to give the user
870 // an opportunity to fix broken settings or other problems that might affect
871 // system stability.
872 // In only-core mode, we disable non-essential display adapters to minimize
873 // the number of dependencies that are started while in this mode and to
874 // prevent problems that might occur due to the device being encrypted.
875 return !mSafeMode && !mOnlyCore;
876 }
877
878 private void registerDisplayAdapterLocked(DisplayAdapter adapter) {
879 mDisplayAdapters.add(adapter);
880 adapter.registerLocked();
881 }
882
Jeff Brownbd6e1502012-08-28 03:27:37 -0700883 private void handleDisplayDeviceAdded(DisplayDevice device) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700884 synchronized (mSyncRoot) {
Jeff Browna506a6e2013-06-04 00:02:38 -0700885 handleDisplayDeviceAddedLocked(device);
Jeff Brownbd6e1502012-08-28 03:27:37 -0700886 }
887 }
888
Jeff Browna506a6e2013-06-04 00:02:38 -0700889 private void handleDisplayDeviceAddedLocked(DisplayDevice device) {
Jeff Brown10acf6d2015-04-14 14:20:47 -0700890 DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
Jeff Browna506a6e2013-06-04 00:02:38 -0700891 if (mDisplayDevices.contains(device)) {
Jeff Brown10acf6d2015-04-14 14:20:47 -0700892 Slog.w(TAG, "Attempted to add already added display device: " + info);
Jeff Browna506a6e2013-06-04 00:02:38 -0700893 return;
894 }
895
Jeff Brown10acf6d2015-04-14 14:20:47 -0700896 Slog.i(TAG, "Display device added: " + info);
897 device.mDebugLastLoggedDeviceInfo = info;
Jeff Browna506a6e2013-06-04 00:02:38 -0700898
899 mDisplayDevices.add(device);
Michael Wright1c9977b2016-07-12 13:30:10 -0700900 LogicalDisplay display = addLogicalDisplayLocked(device);
Jeff Brown0033a862014-10-08 12:06:39 -0700901 Runnable work = updateDisplayStateLocked(device);
902 if (work != null) {
903 work.run();
904 }
Jeff Browna506a6e2013-06-04 00:02:38 -0700905 scheduleTraversalLocked(false);
906 }
907
Jeff Brownbd6e1502012-08-28 03:27:37 -0700908 private void handleDisplayDeviceChanged(DisplayDevice device) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700909 synchronized (mSyncRoot) {
Jeff Brown10acf6d2015-04-14 14:20:47 -0700910 DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
Jeff Brownbd6e1502012-08-28 03:27:37 -0700911 if (!mDisplayDevices.contains(device)) {
Jeff Brown10acf6d2015-04-14 14:20:47 -0700912 Slog.w(TAG, "Attempted to change non-existent display device: " + info);
Jeff Brownbd6e1502012-08-28 03:27:37 -0700913 return;
914 }
915
Jeff Brown10acf6d2015-04-14 14:20:47 -0700916 int diff = device.mDebugLastLoggedDeviceInfo.diff(info);
917 if (diff == DisplayDeviceInfo.DIFF_STATE) {
918 Slog.i(TAG, "Display device changed state: \"" + info.name
919 + "\", " + Display.stateToString(info.state));
920 } else if (diff != 0) {
921 Slog.i(TAG, "Display device changed: " + info);
922 }
Michael Wright1c9977b2016-07-12 13:30:10 -0700923 if ((diff & DisplayDeviceInfo.DIFF_COLOR_MODE) != 0) {
924 try {
925 mPersistentDataStore.setColorMode(device, info.colorMode);
926 } finally {
927 mPersistentDataStore.saveIfNeeded();
928 }
929 }
Jeff Brown10acf6d2015-04-14 14:20:47 -0700930 device.mDebugLastLoggedDeviceInfo = info;
Jeff Browne87bf032012-09-20 18:30:13 -0700931
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700932 device.applyPendingDisplayDeviceInfoChangesLocked();
933 if (updateLogicalDisplaysLocked()) {
Craig Mautner65d11b32012-10-01 13:59:52 -0700934 scheduleTraversalLocked(false);
Jeff Brown64a55af2012-08-26 02:47:39 -0700935 }
936 }
937 }
938
Jeff Brownbd6e1502012-08-28 03:27:37 -0700939 private void handleDisplayDeviceRemoved(DisplayDevice device) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700940 synchronized (mSyncRoot) {
Jeff Browna506a6e2013-06-04 00:02:38 -0700941 handleDisplayDeviceRemovedLocked(device);
942 }
943 }
Jeff Brown8e5d33e2015-06-10 13:05:50 -0700944
Jeff Browna506a6e2013-06-04 00:02:38 -0700945 private void handleDisplayDeviceRemovedLocked(DisplayDevice device) {
Jeff Brown10acf6d2015-04-14 14:20:47 -0700946 DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
Jeff Browna506a6e2013-06-04 00:02:38 -0700947 if (!mDisplayDevices.remove(device)) {
Jeff Brown10acf6d2015-04-14 14:20:47 -0700948 Slog.w(TAG, "Attempted to remove non-existent display device: " + info);
Jeff Browna506a6e2013-06-04 00:02:38 -0700949 return;
950 }
951
Jeff Brown10acf6d2015-04-14 14:20:47 -0700952 Slog.i(TAG, "Display device removed: " + info);
953 device.mDebugLastLoggedDeviceInfo = info;
Jeff Browna506a6e2013-06-04 00:02:38 -0700954
Jeff Browna506a6e2013-06-04 00:02:38 -0700955 updateLogicalDisplaysLocked();
956 scheduleTraversalLocked(false);
957 }
958
Adrian Roos9ee5dff2018-08-22 20:19:49 +0200959 private void handleLogicalDisplayChanged(int displayId, @NonNull LogicalDisplay display) {
960 if (displayId == Display.DEFAULT_DISPLAY) {
961 recordTopInsetLocked(display);
962 }
963 sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_CHANGED);
964 }
965
Jeff Brown8e5d33e2015-06-10 13:05:50 -0700966 private void applyGlobalDisplayStateLocked(List<Runnable> workQueue) {
Jeff Browna506a6e2013-06-04 00:02:38 -0700967 final int count = mDisplayDevices.size();
968 for (int i = 0; i < count; i++) {
969 DisplayDevice device = mDisplayDevices.get(i);
Jeff Browne75926d2014-09-18 15:24:49 -0700970 Runnable runnable = updateDisplayStateLocked(device);
971 if (runnable != null) {
972 workQueue.add(runnable);
973 }
Jeff Browna506a6e2013-06-04 00:02:38 -0700974 }
975 }
976
Jeff Browne75926d2014-09-18 15:24:49 -0700977 private Runnable updateDisplayStateLocked(DisplayDevice device) {
Jeff Browna506a6e2013-06-04 00:02:38 -0700978 // Blank or unblank the display immediately to match the state requested
Jeff Brown037c33e2014-04-09 00:31:55 -0700979 // by the display power controller (if known).
Jeff Browna506a6e2013-06-04 00:02:38 -0700980 DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
981 if ((info.flags & DisplayDeviceInfo.FLAG_NEVER_BLANK) == 0) {
Jeff Brown5d6443b2015-04-10 20:15:01 -0700982 return device.requestDisplayStateLocked(mGlobalDisplayState, mGlobalDisplayBrightness);
Craig Mautner4f67ba62012-08-02 11:23:00 -0700983 }
Jeff Browne75926d2014-09-18 15:24:49 -0700984 return null;
Craig Mautner4f67ba62012-08-02 11:23:00 -0700985 }
986
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700987 // Adds a new logical display based on the given display device.
988 // Sends notifications if needed.
Michael Wright1c9977b2016-07-12 13:30:10 -0700989 private LogicalDisplay addLogicalDisplayLocked(DisplayDevice device) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700990 DisplayDeviceInfo deviceInfo = device.getDisplayDeviceInfoLocked();
991 boolean isDefault = (deviceInfo.flags
992 & DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY) != 0;
993 if (isDefault && mLogicalDisplays.get(Display.DEFAULT_DISPLAY) != null) {
994 Slog.w(TAG, "Ignoring attempt to add a second default display: " + deviceInfo);
995 isDefault = false;
996 }
997
Jeff Brown27f1d672012-10-17 18:32:34 -0700998 if (!isDefault && mSingleDisplayDemoMode) {
999 Slog.i(TAG, "Not creating a logical display for a secondary display "
1000 + " because single display demo mode is enabled: " + deviceInfo);
Michael Wright1c9977b2016-07-12 13:30:10 -07001001 return null;
Jeff Brown27f1d672012-10-17 18:32:34 -07001002 }
1003
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001004 final int displayId = assignDisplayIdLocked(isDefault);
1005 final int layerStack = assignLayerStackLocked(displayId);
1006
Jeff Brownd728bf52012-09-08 18:05:28 -07001007 LogicalDisplay display = new LogicalDisplay(displayId, layerStack, device);
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001008 display.updateLocked(mDisplayDevices);
1009 if (!display.isValidLocked()) {
1010 // This should never happen currently.
1011 Slog.w(TAG, "Ignoring display device because the logical display "
1012 + "created from it was not considered valid: " + deviceInfo);
Michael Wright1c9977b2016-07-12 13:30:10 -07001013 return null;
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001014 }
1015
Michael Wrighteedcbf12017-08-16 23:14:54 +01001016 configureColorModeLocked(display, device);
1017 if (isDefault) {
1018 recordStableDisplayStatsIfNeededLocked(display);
Adrian Roos9ee5dff2018-08-22 20:19:49 +02001019 recordTopInsetLocked(display);
Michael Wrighteedcbf12017-08-16 23:14:54 +01001020 }
1021
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001022 mLogicalDisplays.put(displayId, display);
1023
1024 // Wake up waitForDefaultDisplay.
1025 if (isDefault) {
1026 mSyncRoot.notifyAll();
1027 }
1028
1029 sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_ADDED);
Michael Wright1c9977b2016-07-12 13:30:10 -07001030 return display;
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001031 }
1032
1033 private int assignDisplayIdLocked(boolean isDefault) {
1034 return isDefault ? Display.DEFAULT_DISPLAY : mNextNonDefaultDisplayId++;
1035 }
1036
1037 private int assignLayerStackLocked(int displayId) {
1038 // Currently layer stacks and display ids are the same.
1039 // This need not be the case.
1040 return displayId;
1041 }
1042
Michael Wrighteedcbf12017-08-16 23:14:54 +01001043 private void configureColorModeLocked(LogicalDisplay display, DisplayDevice device) {
1044 if (display.getPrimaryDisplayDeviceLocked() == device) {
1045 int colorMode = mPersistentDataStore.getColorMode(device);
1046 if (colorMode == Display.COLOR_MODE_INVALID) {
1047 if ((device.getDisplayDeviceInfoLocked().flags
1048 & DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY) != 0) {
1049 colorMode = mDefaultDisplayDefaultColorMode;
1050 } else {
1051 colorMode = Display.COLOR_MODE_DEFAULT;
1052 }
1053 }
1054 display.setRequestedColorModeLocked(colorMode);
1055 }
1056 }
1057
1058 // If we've never recorded stable device stats for this device before and they aren't
1059 // explicitly configured, go ahead and record the stable device stats now based on the status
1060 // of the default display at first boot.
1061 private void recordStableDisplayStatsIfNeededLocked(LogicalDisplay d) {
1062 if (mStableDisplaySize.x <= 0 && mStableDisplaySize.y <= 0) {
1063 DisplayInfo info = d.getDisplayInfoLocked();
1064 setStableDisplaySizeLocked(info.getNaturalWidth(), info.getNaturalHeight());
1065 }
1066 }
1067
Adrian Roos9ee5dff2018-08-22 20:19:49 +02001068 private void recordTopInsetLocked(@Nullable LogicalDisplay d) {
Winson72dbe7e2019-04-29 14:55:30 -07001069 // We must only persist the inset after boot has completed, otherwise we will end up
1070 // overwriting the persisted value before the masking flag has been loaded from the
1071 // resource overlay.
1072 if (!mSystemReady || d == null) {
Adrian Roos9ee5dff2018-08-22 20:19:49 +02001073 return;
1074 }
1075 int topInset = d.getInsets().top;
1076 if (topInset == mDefaultDisplayTopInset) {
1077 return;
1078 }
1079 mDefaultDisplayTopInset = topInset;
1080 SystemProperties.set(PROP_DEFAULT_DISPLAY_TOP_INSET, Integer.toString(topInset));
1081 }
1082
Michael Wrighteedcbf12017-08-16 23:14:54 +01001083 private void setStableDisplaySizeLocked(int width, int height) {
1084 mStableDisplaySize = new Point(width, height);
1085 try {
1086 mPersistentDataStore.setStableDisplaySize(mStableDisplaySize);
1087 } finally {
1088 mPersistentDataStore.saveIfNeeded();
1089 }
1090 }
1091
Dan Gittik122df862018-03-28 16:59:22 +01001092 @VisibleForTesting
1093 Curve getMinimumBrightnessCurveInternal() {
1094 return mMinimumBrightnessCurve;
1095 }
1096
Peiyong Lin277eaff2019-01-16 16:18:22 -08001097 int getPreferredWideGamutColorSpaceIdInternal() {
1098 return mWideColorSpace.getId();
1099 }
1100
Michael Wrighteef0e132017-11-21 17:57:52 +00001101 private void setBrightnessConfigurationForUserInternal(
Dan Gittik7a32fba2018-03-28 12:19:38 +01001102 @Nullable BrightnessConfiguration c, @UserIdInt int userId,
Kenny Guy05ce8092018-01-17 13:44:20 +00001103 @Nullable String packageName) {
Dan Gittik122df862018-03-28 16:59:22 +01001104 validateBrightnessConfiguration(c);
Michael Wrighteef0e132017-11-21 17:57:52 +00001105 final int userSerial = getUserManager().getUserSerialNumber(userId);
1106 synchronized (mSyncRoot) {
1107 try {
Kenny Guy05ce8092018-01-17 13:44:20 +00001108 mPersistentDataStore.setBrightnessConfigurationForUser(c, userSerial,
1109 packageName);
Michael Wrighteef0e132017-11-21 17:57:52 +00001110 } finally {
1111 mPersistentDataStore.saveIfNeeded();
1112 }
1113 if (userId == mCurrentUserId) {
1114 mDisplayPowerController.setBrightnessConfiguration(c);
1115 }
1116 }
1117 }
1118
Dan Gittik122df862018-03-28 16:59:22 +01001119 @VisibleForTesting
1120 void validateBrightnessConfiguration(BrightnessConfiguration config) {
1121 if (config == null) {
1122 return;
1123 }
1124 if (isBrightnessConfigurationTooDark(config)) {
1125 throw new IllegalArgumentException("brightness curve is too dark");
1126 }
1127 }
1128
1129 private boolean isBrightnessConfigurationTooDark(BrightnessConfiguration config) {
1130 Pair<float[], float[]> curve = config.getCurve();
1131 float[] lux = curve.first;
1132 float[] nits = curve.second;
1133 for (int i = 0; i < lux.length; i++) {
1134 if (nits[i] < mMinimumBrightnessSpline.interpolate(lux[i])) {
1135 return true;
1136 }
1137 }
1138 return false;
1139 }
1140
Michael Wrighteef0e132017-11-21 17:57:52 +00001141 private void loadBrightnessConfiguration() {
1142 synchronized (mSyncRoot) {
1143 final int userSerial = getUserManager().getUserSerialNumber(mCurrentUserId);
1144 BrightnessConfiguration config =
1145 mPersistentDataStore.getBrightnessConfiguration(userSerial);
1146 mDisplayPowerController.setBrightnessConfiguration(config);
1147 }
1148 }
1149
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001150 // Updates all existing logical displays given the current set of display devices.
1151 // Removes invalid logical displays.
1152 // Sends notifications if needed.
1153 private boolean updateLogicalDisplaysLocked() {
1154 boolean changed = false;
1155 for (int i = mLogicalDisplays.size(); i-- > 0; ) {
1156 final int displayId = mLogicalDisplays.keyAt(i);
1157 LogicalDisplay display = mLogicalDisplays.valueAt(i);
1158
1159 mTempDisplayInfo.copyFrom(display.getDisplayInfoLocked());
1160 display.updateLocked(mDisplayDevices);
1161 if (!display.isValidLocked()) {
1162 mLogicalDisplays.removeAt(i);
1163 sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_REMOVED);
1164 changed = true;
1165 } else if (!mTempDisplayInfo.equals(display.getDisplayInfoLocked())) {
Adrian Roos9ee5dff2018-08-22 20:19:49 +02001166 handleLogicalDisplayChanged(displayId, display);
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001167 changed = true;
1168 }
1169 }
1170 return changed;
1171 }
1172
Robert Carrae606b42018-02-15 15:36:23 -08001173 private void performTraversalLocked(SurfaceControl.Transaction t) {
Jeff Brownd728bf52012-09-08 18:05:28 -07001174 // Clear all viewports before configuring displays so that we can keep
1175 // track of which ones we have configured.
1176 clearViewportsLocked();
1177
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001178 // Configure each display device.
1179 final int count = mDisplayDevices.size();
1180 for (int i = 0; i < count; i++) {
1181 DisplayDevice device = mDisplayDevices.get(i);
Robert Carrae606b42018-02-15 15:36:23 -08001182 configureDisplayLocked(t, device);
1183 device.performTraversalLocked(t);
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001184 }
Jeff Brownd728bf52012-09-08 18:05:28 -07001185
1186 // Tell the input system about these new viewports.
Jeff Brown4ccb8232014-01-16 22:16:42 -08001187 if (mInputManagerInternal != null) {
Jeff Brownd728bf52012-09-08 18:05:28 -07001188 mHandler.sendEmptyMessage(MSG_UPDATE_VIEWPORT);
1189 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001190 }
1191
Michael Wright3f145a22014-07-22 19:46:03 -07001192 private void setDisplayPropertiesInternal(int displayId, boolean hasContent,
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -07001193 float requestedRefreshRate, int requestedModeId, boolean inTraversal) {
Craig Mautner722285e2012-09-07 13:55:58 -07001194 synchronized (mSyncRoot) {
1195 LogicalDisplay display = mLogicalDisplays.get(displayId);
Michael Wright3f145a22014-07-22 19:46:03 -07001196 if (display == null) {
1197 return;
1198 }
1199 if (display.hasContentLocked() != hasContent) {
Jeff Brown33041bd2013-08-02 21:11:14 -07001200 if (DEBUG) {
1201 Slog.d(TAG, "Display " + displayId + " hasContent flag changed: "
1202 + "hasContent=" + hasContent + ", inTraversal=" + inTraversal);
1203 }
1204
Craig Mautner722285e2012-09-07 13:55:58 -07001205 display.setHasContentLocked(hasContent);
Craig Mautner65d11b32012-10-01 13:59:52 -07001206 scheduleTraversalLocked(inTraversal);
Craig Mautner722285e2012-09-07 13:55:58 -07001207 }
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -07001208 if (requestedModeId == 0 && requestedRefreshRate != 0) {
1209 // Scan supported modes returned by display.getInfo() to find a mode with the same
1210 // size as the default display mode but with the specified refresh rate instead.
1211 requestedModeId = display.getDisplayInfoLocked().findDefaultModeByRefreshRate(
1212 requestedRefreshRate);
1213 }
Michael Wrighta3dab232019-02-22 16:54:21 +00001214 mDisplayModeDirector.getAppRequestObserver().setAppRequestedMode(
1215 displayId, requestedModeId);
Craig Mautner722285e2012-09-07 13:55:58 -07001216 }
Jeff Brownd728bf52012-09-08 18:05:28 -07001217 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001218
Filip Gruszczynskid2e86402015-02-19 13:05:03 -08001219 private void setDisplayOffsetsInternal(int displayId, int x, int y) {
1220 synchronized (mSyncRoot) {
1221 LogicalDisplay display = mLogicalDisplays.get(displayId);
1222 if (display == null) {
1223 return;
1224 }
1225 if (display.getDisplayOffsetXLocked() != x
1226 || display.getDisplayOffsetYLocked() != y) {
1227 if (DEBUG) {
1228 Slog.d(TAG, "Display " + displayId + " burn-in offset set to ("
1229 + x + ", " + y + ")");
1230 }
1231 display.setDisplayOffsetsLocked(x, y);
1232 scheduleTraversalLocked(false);
1233 }
1234 }
1235 }
1236
Sam Lin4c3ac2b2019-02-18 04:50:26 -08001237 private void setDisplayScalingDisabledInternal(int displayId, boolean disable) {
1238 synchronized (mSyncRoot) {
1239 final LogicalDisplay display = mLogicalDisplays.get(displayId);
1240 if (display == null) {
1241 return;
1242 }
1243 if (display.isDisplayScalingDisabled() != disable) {
1244 if (DEBUG) {
1245 Slog.d(TAG, "Display " + displayId + " content scaling disabled = " + disable);
1246 }
1247 display.setDisplayScalingDisabledLocked(disable);
1248 scheduleTraversalLocked(false);
1249 }
1250 }
1251 }
1252
Andrii Kulianfb1bf692017-01-17 11:17:34 -08001253 // Updates the lists of UIDs that are present on displays.
1254 private void setDisplayAccessUIDsInternal(SparseArray<IntArray> newDisplayAccessUIDs) {
1255 synchronized (mSyncRoot) {
1256 mDisplayAccessUIDs.clear();
1257 for (int i = newDisplayAccessUIDs.size() - 1; i >= 0; i--) {
1258 mDisplayAccessUIDs.append(newDisplayAccessUIDs.keyAt(i),
1259 newDisplayAccessUIDs.valueAt(i));
1260 }
1261 }
1262 }
1263
1264 // Checks if provided UID's content is present on the display and UID has access to it.
1265 private boolean isUidPresentOnDisplayInternal(int uid, int displayId) {
1266 synchronized (mSyncRoot) {
1267 final IntArray displayUIDs = mDisplayAccessUIDs.get(displayId);
1268 return displayUIDs != null && displayUIDs.indexOf(uid) != -1;
1269 }
1270 }
1271
Dominik Laskowskie912ae32019-01-26 11:19:36 -08001272 @Nullable
1273 private IBinder getDisplayToken(int displayId) {
1274 synchronized (mSyncRoot) {
1275 final LogicalDisplay display = mLogicalDisplays.get(displayId);
1276 if (display != null) {
1277 final DisplayDevice device = display.getPrimaryDisplayDeviceLocked();
1278 if (device != null) {
1279 return device.getDisplayTokenLocked();
1280 }
1281 }
1282 }
1283
1284 return null;
1285 }
1286
Robert Carr66b5664f2019-04-02 14:18:56 -07001287 private SurfaceControl.ScreenshotGraphicBuffer screenshotInternal(int displayId) {
Dominik Laskowskie912ae32019-01-26 11:19:36 -08001288 final IBinder token = getDisplayToken(displayId);
1289 if (token == null) {
Robert Carr66b5664f2019-04-02 14:18:56 -07001290 return null;
Dominik Laskowskie912ae32019-01-26 11:19:36 -08001291 }
Robert Carr66b5664f2019-04-02 14:18:56 -07001292 return SurfaceControl.screenshotToBufferWithSecureLayersUnsafe(
Peiyong Line3e5efd2019-03-21 20:59:47 +00001293 token, new Rect(), 0 /* width */, 0 /* height */,
1294 false /* useIdentityTransform */, 0 /* rotation */);
Dominik Laskowskie912ae32019-01-26 11:19:36 -08001295 }
1296
Kevin DuBoisbf76b11b2018-09-04 09:14:15 -07001297 @VisibleForTesting
1298 DisplayedContentSamplingAttributes getDisplayedContentSamplingAttributesInternal(
1299 int displayId) {
Dominik Laskowskie912ae32019-01-26 11:19:36 -08001300 final IBinder token = getDisplayToken(displayId);
1301 if (token == null) {
1302 return null;
1303 }
1304 return SurfaceControl.getDisplayedContentSamplingAttributes(token);
Kevin DuBoisbf76b11b2018-09-04 09:14:15 -07001305 }
1306
1307 @VisibleForTesting
1308 boolean setDisplayedContentSamplingEnabledInternal(
1309 int displayId, boolean enable, int componentMask, int maxFrames) {
Dominik Laskowskie912ae32019-01-26 11:19:36 -08001310 final IBinder token = getDisplayToken(displayId);
1311 if (token == null) {
1312 return false;
1313 }
Kevin DuBoisbf76b11b2018-09-04 09:14:15 -07001314 return SurfaceControl.setDisplayedContentSamplingEnabled(
Dominik Laskowskie912ae32019-01-26 11:19:36 -08001315 token, enable, componentMask, maxFrames);
Kevin DuBoisbf76b11b2018-09-04 09:14:15 -07001316 }
1317
1318 @VisibleForTesting
1319 DisplayedContentSample getDisplayedContentSampleInternal(int displayId,
1320 long maxFrames, long timestamp) {
Dominik Laskowskie912ae32019-01-26 11:19:36 -08001321 final IBinder token = getDisplayToken(displayId);
1322 if (token == null) {
1323 return null;
1324 }
1325 return SurfaceControl.getDisplayedContentSample(token, maxFrames, timestamp);
Kevin DuBoisbf76b11b2018-09-04 09:14:15 -07001326 }
1327
Michael Wrighta3dab232019-02-22 16:54:21 +00001328 private void onAllowedDisplayModesChangedInternal() {
1329 boolean changed = false;
1330 synchronized (mSyncRoot) {
1331 final int count = mLogicalDisplays.size();
1332 for (int i = 0; i < count; i++) {
1333 LogicalDisplay display = mLogicalDisplays.valueAt(i);
1334 int displayId = mLogicalDisplays.keyAt(i);
1335 int[] allowedModes = mDisplayModeDirector.getAllowedModes(displayId);
1336 // Note that order is important here since not all display devices are capable of
1337 // automatically switching, so we do actually want to check for equality and not
1338 // just equivalent contents (regardless of order).
1339 if (!Arrays.equals(allowedModes, display.getAllowedDisplayModesLocked())) {
1340 display.setAllowedDisplayModesLocked(allowedModes);
1341 changed = true;
1342 }
1343 }
1344 if (changed) {
1345 scheduleTraversalLocked(false);
1346 }
1347 }
1348 }
1349
Jeff Brownd728bf52012-09-08 18:05:28 -07001350 private void clearViewportsLocked() {
Siarhei Vishniakou2eb0f8f2018-07-06 23:30:12 +01001351 mViewports.clear();
Craig Mautner722285e2012-09-07 13:55:58 -07001352 }
1353
Robert Carrae606b42018-02-15 15:36:23 -08001354 private void configureDisplayLocked(SurfaceControl.Transaction t, DisplayDevice device) {
Jeff Brownd14c8c92014-01-07 18:13:09 -08001355 final DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
1356 final boolean ownContent = (info.flags & DisplayDeviceInfo.FLAG_OWN_CONTENT_ONLY) != 0;
Jeff Browna506a6e2013-06-04 00:02:38 -07001357
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001358 // Find the logical display that the display device is showing.
Jeff Brownd14c8c92014-01-07 18:13:09 -08001359 // Certain displays only ever show their own content.
Craig Mautner722285e2012-09-07 13:55:58 -07001360 LogicalDisplay display = findLogicalDisplayForDeviceLocked(device);
Jeff Brownd14c8c92014-01-07 18:13:09 -08001361 if (!ownContent) {
Jeff Browna506a6e2013-06-04 00:02:38 -07001362 if (display != null && !display.hasContentLocked()) {
1363 // If the display does not have any content of its own, then
1364 // automatically mirror the default logical display contents.
1365 display = null;
1366 }
1367 if (display == null) {
1368 display = mLogicalDisplays.get(Display.DEFAULT_DISPLAY);
1369 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001370 }
1371
1372 // Apply the logical display configuration to the display device.
1373 if (display == null) {
1374 // TODO: no logical display for the device, blank it
Jeff Brownd728bf52012-09-08 18:05:28 -07001375 Slog.w(TAG, "Missing logical display to use for physical display device: "
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001376 + device.getDisplayDeviceInfoLocked());
Jeff Brownd728bf52012-09-08 18:05:28 -07001377 return;
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001378 }
Robert Carrae606b42018-02-15 15:36:23 -08001379 display.configureDisplayLocked(t, device, info.state == Display.STATE_OFF);
Arthur Hung41e81e72018-10-31 18:04:56 +08001380 final int viewportType;
Siarhei Vishniakou2eb0f8f2018-07-06 23:30:12 +01001381 // Update the corresponding viewport.
Siarhei Vishniakou2eb0f8f2018-07-06 23:30:12 +01001382 if ((info.flags & DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY) != 0) {
Arthur Hung41e81e72018-10-31 18:04:56 +08001383 viewportType = VIEWPORT_INTERNAL;
1384 } else if (info.touch == DisplayDeviceInfo.TOUCH_EXTERNAL) {
1385 viewportType = VIEWPORT_EXTERNAL;
1386 } else if (info.touch == DisplayDeviceInfo.TOUCH_VIRTUAL
1387 && !TextUtils.isEmpty(info.uniqueId)) {
1388 viewportType = VIEWPORT_VIRTUAL;
1389 } else {
Arthur Hung46c4e582019-02-12 15:55:28 +08001390 Slog.i(TAG, "Display " + info + " does not support input device matching.");
Arthur Hung41e81e72018-10-31 18:04:56 +08001391 return;
Jeff Brownd728bf52012-09-08 18:05:28 -07001392 }
Santos Cordonee8931e2017-04-05 10:31:15 -07001393
Arthur Hung41e81e72018-10-31 18:04:56 +08001394 populateViewportLocked(viewportType, display.getDisplayIdLocked(), device, info.uniqueId);
Siarhei Vishniakou2eb0f8f2018-07-06 23:30:12 +01001395 }
1396
1397 /**
1398 * Get internal or external viewport. Create it if does not currently exist.
1399 * @param viewportType - either INTERNAL or EXTERNAL
1400 * @return the viewport with the requested type
1401 */
Arthur Hung41e81e72018-10-31 18:04:56 +08001402 private DisplayViewport getViewportLocked(int viewportType, String uniqueId) {
1403 if (viewportType != VIEWPORT_INTERNAL && viewportType != VIEWPORT_EXTERNAL
1404 && viewportType != VIEWPORT_VIRTUAL) {
Siarhei Vishniakou2eb0f8f2018-07-06 23:30:12 +01001405 Slog.wtf(TAG, "Cannot call getViewportByTypeLocked for type "
1406 + DisplayViewport.typeToString(viewportType));
1407 return null;
1408 }
Arthur Hung41e81e72018-10-31 18:04:56 +08001409
1410 // Only allow a single INTERNAL or EXTERNAL viewport by forcing their uniqueIds
1411 // to be identical (in particular, empty).
1412 // TODO (b/116824030) allow multiple EXTERNAL viewports and remove this function.
1413 if (viewportType != VIEWPORT_VIRTUAL) {
1414 uniqueId = "";
1415 }
1416
Siarhei Vishniakou2eb0f8f2018-07-06 23:30:12 +01001417 DisplayViewport viewport;
1418 final int count = mViewports.size();
1419 for (int i = 0; i < count; i++) {
1420 viewport = mViewports.get(i);
Arthur Hung41e81e72018-10-31 18:04:56 +08001421 if (viewport.type == viewportType && uniqueId.equals(viewport.uniqueId)) {
Siarhei Vishniakou2eb0f8f2018-07-06 23:30:12 +01001422 return viewport;
1423 }
1424 }
1425
Arthur Hung41e81e72018-10-31 18:04:56 +08001426 // Creates the viewport if none exists.
Siarhei Vishniakou2eb0f8f2018-07-06 23:30:12 +01001427 viewport = new DisplayViewport();
1428 viewport.type = viewportType;
Arthur Hung41e81e72018-10-31 18:04:56 +08001429 viewport.uniqueId = uniqueId;
Siarhei Vishniakou2eb0f8f2018-07-06 23:30:12 +01001430 mViewports.add(viewport);
1431 return viewport;
1432 }
1433
Arthur Hung41e81e72018-10-31 18:04:56 +08001434 private void populateViewportLocked(int viewportType,
1435 int displayId, DisplayDevice device, String uniqueId) {
1436 final DisplayViewport viewport = getViewportLocked(viewportType, uniqueId);
Jeff Brownd728bf52012-09-08 18:05:28 -07001437 device.populateViewportLocked(viewport);
Arthur Hung41e81e72018-10-31 18:04:56 +08001438 viewport.valid = true;
1439 viewport.displayId = displayId;
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001440 }
1441
1442 private LogicalDisplay findLogicalDisplayForDeviceLocked(DisplayDevice device) {
1443 final int count = mLogicalDisplays.size();
1444 for (int i = 0; i < count; i++) {
1445 LogicalDisplay display = mLogicalDisplays.valueAt(i);
1446 if (display.getPrimaryDisplayDeviceLocked() == device) {
1447 return display;
1448 }
1449 }
1450 return null;
1451 }
1452
Jeff Brownbd6e1502012-08-28 03:27:37 -07001453 private void sendDisplayEventLocked(int displayId, int event) {
1454 Message msg = mHandler.obtainMessage(MSG_DELIVER_DISPLAY_EVENT, displayId, event);
1455 mHandler.sendMessage(msg);
1456 }
1457
Robert Carrae606b42018-02-15 15:36:23 -08001458 // Requests that performTraversals be called at a
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001459 // later time to apply changes to surfaces and displays.
Craig Mautner65d11b32012-10-01 13:59:52 -07001460 private void scheduleTraversalLocked(boolean inTraversal) {
Jeff Brown4ccb8232014-01-16 22:16:42 -08001461 if (!mPendingTraversal && mWindowManagerInternal != null) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001462 mPendingTraversal = true;
Craig Mautner65d11b32012-10-01 13:59:52 -07001463 if (!inTraversal) {
1464 mHandler.sendEmptyMessage(MSG_REQUEST_TRAVERSAL);
1465 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001466 }
1467 }
1468
1469 // Runs on Handler thread.
1470 // Delivers display event notifications to callbacks.
Jeff Brownbd6e1502012-08-28 03:27:37 -07001471 private void deliverDisplayEvent(int displayId, int event) {
1472 if (DEBUG) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001473 Slog.d(TAG, "Delivering display event: displayId="
1474 + displayId + ", event=" + event);
Jeff Brownfa25bf52012-07-23 19:26:30 -07001475 }
Jeff Brownfa25bf52012-07-23 19:26:30 -07001476
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001477 // Grab the lock and copy the callbacks.
Jeff Brownbd6e1502012-08-28 03:27:37 -07001478 final int count;
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001479 synchronized (mSyncRoot) {
Jeff Brownbd6e1502012-08-28 03:27:37 -07001480 count = mCallbacks.size();
1481 mTempCallbacks.clear();
1482 for (int i = 0; i < count; i++) {
1483 mTempCallbacks.add(mCallbacks.valueAt(i));
Craig Mautner4f67ba62012-08-02 11:23:00 -07001484 }
Jeff Brownbd6e1502012-08-28 03:27:37 -07001485 }
Craig Mautner4f67ba62012-08-02 11:23:00 -07001486
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001487 // After releasing the lock, send the notifications out.
Jeff Brownbd6e1502012-08-28 03:27:37 -07001488 for (int i = 0; i < count; i++) {
1489 mTempCallbacks.get(i).notifyDisplayEventAsync(displayId, event);
1490 }
1491 mTempCallbacks.clear();
Craig Mautner4f67ba62012-08-02 11:23:00 -07001492 }
1493
Michael Wrightc39d47a2014-07-08 18:07:36 -07001494 private IMediaProjectionManager getProjectionService() {
1495 if (mProjectionService == null) {
1496 IBinder b = ServiceManager.getService(Context.MEDIA_PROJECTION_SERVICE);
1497 mProjectionService = IMediaProjectionManager.Stub.asInterface(b);
1498 }
1499 return mProjectionService;
1500 }
1501
Michael Wrighteef0e132017-11-21 17:57:52 +00001502 private UserManager getUserManager() {
1503 return mContext.getSystemService(UserManager.class);
1504 }
1505
Jeff Brown4ccb8232014-01-16 22:16:42 -08001506 private void dumpInternal(PrintWriter pw) {
Jeff Brownbd6e1502012-08-28 03:27:37 -07001507 pw.println("DISPLAY MANAGER (dumpsys display)");
Jeff Brownfa25bf52012-07-23 19:26:30 -07001508
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001509 synchronized (mSyncRoot) {
Jeff Brown9e316a12012-10-08 19:17:06 -07001510 pw.println(" mOnlyCode=" + mOnlyCore);
1511 pw.println(" mSafeMode=" + mSafeMode);
1512 pw.println(" mPendingTraversal=" + mPendingTraversal);
Jeff Brown037c33e2014-04-09 00:31:55 -07001513 pw.println(" mGlobalDisplayState=" + Display.stateToString(mGlobalDisplayState));
Jeff Brown9e316a12012-10-08 19:17:06 -07001514 pw.println(" mNextNonDefaultDisplayId=" + mNextNonDefaultDisplayId);
Siarhei Vishniakou2eb0f8f2018-07-06 23:30:12 +01001515 pw.println(" mViewports=" + mViewports);
Damien Bargiacchi4364bbf2016-11-01 21:44:20 -07001516 pw.println(" mDefaultDisplayDefaultColorMode=" + mDefaultDisplayDefaultColorMode);
Jeff Brown27f1d672012-10-17 18:32:34 -07001517 pw.println(" mSingleDisplayDemoMode=" + mSingleDisplayDemoMode);
Jeff Brownce468a32013-11-21 16:42:03 -08001518 pw.println(" mWifiDisplayScanRequestCount=" + mWifiDisplayScanRequestCount);
Michael Wrighteedcbf12017-08-16 23:14:54 +01001519 pw.println(" mStableDisplaySize=" + mStableDisplaySize);
Kenny Guy2047db92019-02-21 13:04:05 +00001520 pw.println(" mMinimumBrightnessCurve=" + mMinimumBrightnessCurve);
Jeff Brown9e316a12012-10-08 19:17:06 -07001521
Jeff Brownbd6e1502012-08-28 03:27:37 -07001522 IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001523 ipw.increaseIndent();
Jeff Brownbd6e1502012-08-28 03:27:37 -07001524
1525 pw.println();
1526 pw.println("Display Adapters: size=" + mDisplayAdapters.size());
Jeff Brown848c2dc2012-08-19 20:18:08 -07001527 for (DisplayAdapter adapter : mDisplayAdapters) {
Jeff Brownbd6e1502012-08-28 03:27:37 -07001528 pw.println(" " + adapter.getName());
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001529 adapter.dumpLocked(ipw);
Jeff Brown848c2dc2012-08-19 20:18:08 -07001530 }
Craig Mautner9de49362012-08-02 14:30:30 -07001531
Jeff Brownbd6e1502012-08-28 03:27:37 -07001532 pw.println();
1533 pw.println("Display Devices: size=" + mDisplayDevices.size());
1534 for (DisplayDevice device : mDisplayDevices) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001535 pw.println(" " + device.getDisplayDeviceInfoLocked());
1536 device.dumpLocked(ipw);
Jeff Brownbd6e1502012-08-28 03:27:37 -07001537 }
1538
1539 final int logicalDisplayCount = mLogicalDisplays.size();
1540 pw.println();
1541 pw.println("Logical Displays: size=" + logicalDisplayCount);
1542 for (int i = 0; i < logicalDisplayCount; i++) {
1543 int displayId = mLogicalDisplays.keyAt(i);
1544 LogicalDisplay display = mLogicalDisplays.valueAt(i);
1545 pw.println(" Display " + displayId + ":");
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001546 display.dumpLocked(ipw);
Jeff Brownbd6e1502012-08-28 03:27:37 -07001547 }
Jeff Brownce468a32013-11-21 16:42:03 -08001548
Michael Wrighta3dab232019-02-22 16:54:21 +00001549 pw.println();
1550 mDisplayModeDirector.dump(pw);
1551
Jeff Brownce468a32013-11-21 16:42:03 -08001552 final int callbackCount = mCallbacks.size();
1553 pw.println();
1554 pw.println("Callbacks: size=" + callbackCount);
1555 for (int i = 0; i < callbackCount; i++) {
1556 CallbackRecord callback = mCallbacks.valueAt(i);
1557 pw.println(" " + i + ": mPid=" + callback.mPid
1558 + ", mWifiDisplayScanRequested=" + callback.mWifiDisplayScanRequested);
1559 }
Jeff Brownad9ef192014-04-08 17:26:30 -07001560
1561 if (mDisplayPowerController != null) {
1562 mDisplayPowerController.dump(pw);
1563 }
Michael Wright1c9977b2016-07-12 13:30:10 -07001564
1565 pw.println();
1566 mPersistentDataStore.dump(pw);
Jeff Brownbd6e1502012-08-28 03:27:37 -07001567 }
1568 }
1569
Dan Gittik122df862018-03-28 16:59:22 +01001570 private static float[] getFloatArray(TypedArray array) {
1571 int length = array.length();
1572 float[] floatArray = new float[length];
1573 for (int i = 0; i < length; i++) {
1574 floatArray[i] = array.getFloat(i, Float.NaN);
1575 }
1576 array.recycle();
1577 return floatArray;
1578 }
1579
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001580 /**
1581 * This is the object that everything in the display manager locks on.
1582 * We make it an inner class within the {@link DisplayManagerService} to so that it is
1583 * clear that the object belongs to the display manager service and that it is
1584 * a unique object with a special purpose.
1585 */
1586 public static final class SyncRoot {
1587 }
1588
Santos Cordonee8931e2017-04-05 10:31:15 -07001589 @VisibleForTesting
1590 static class Injector {
1591 VirtualDisplayAdapter getVirtualDisplayAdapter(SyncRoot syncRoot, Context context,
1592 Handler handler, DisplayAdapter.Listener displayAdapterListener) {
1593 return new VirtualDisplayAdapter(syncRoot, context, handler, displayAdapterListener);
1594 }
Santos Cordonc22c5632017-06-21 16:03:49 -07001595
1596 long getDefaultDisplayDelayTimeout() {
1597 return WAIT_FOR_DEFAULT_DISPLAY_TIMEOUT;
1598 }
Santos Cordonee8931e2017-04-05 10:31:15 -07001599 }
1600
Alex Sakhartchouk879d24f2017-06-20 22:01:19 -04001601 @VisibleForTesting
1602 DisplayDeviceInfo getDisplayDeviceInfoInternal(int displayId) {
1603 synchronized (mSyncRoot) {
1604 LogicalDisplay display = mLogicalDisplays.get(displayId);
1605 if (display != null) {
1606 DisplayDevice displayDevice = display.getPrimaryDisplayDeviceLocked();
1607 return displayDevice.getDisplayDeviceInfoLocked();
1608 }
1609 return null;
1610 }
1611 }
1612
Jeff Brownbd6e1502012-08-28 03:27:37 -07001613 private final class DisplayManagerHandler extends Handler {
1614 public DisplayManagerHandler(Looper looper) {
1615 super(looper, null, true /*async*/);
Jeff Brown848c2dc2012-08-19 20:18:08 -07001616 }
Jeff Brownbf5740e2012-08-19 23:20:02 -07001617
Jeff Brownbd6e1502012-08-28 03:27:37 -07001618 @Override
1619 public void handleMessage(Message msg) {
1620 switch (msg.what) {
Santos Cordonc22c5632017-06-21 16:03:49 -07001621 case MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS:
1622 registerDefaultDisplayAdapters();
Jeff Brownbd6e1502012-08-28 03:27:37 -07001623 break;
1624
1625 case MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS:
1626 registerAdditionalDisplayAdapters();
1627 break;
1628
1629 case MSG_DELIVER_DISPLAY_EVENT:
1630 deliverDisplayEvent(msg.arg1, msg.arg2);
1631 break;
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001632
1633 case MSG_REQUEST_TRAVERSAL:
Jeff Brown4ccb8232014-01-16 22:16:42 -08001634 mWindowManagerInternal.requestTraversalFromDisplayManager();
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001635 break;
Jeff Brownd728bf52012-09-08 18:05:28 -07001636
1637 case MSG_UPDATE_VIEWPORT: {
Siarhei Vishniakou2eb0f8f2018-07-06 23:30:12 +01001638 final boolean changed;
Jeff Brownd728bf52012-09-08 18:05:28 -07001639 synchronized (mSyncRoot) {
Siarhei Vishniakou2eb0f8f2018-07-06 23:30:12 +01001640 changed = !mTempViewports.equals(mViewports);
1641 if (changed) {
1642 mTempViewports.clear();
1643 for (DisplayViewport d : mViewports) {
1644 mTempViewports.add(d.makeCopy());
1645 }
Santos Cordonee8931e2017-04-05 10:31:15 -07001646 }
Jeff Brownd728bf52012-09-08 18:05:28 -07001647 }
Siarhei Vishniakou2eb0f8f2018-07-06 23:30:12 +01001648 if (changed) {
1649 mInputManagerInternal.setDisplayViewports(mTempViewports);
1650 }
Jeff Brownd728bf52012-09-08 18:05:28 -07001651 break;
1652 }
Kenny Guy22bd0442017-10-26 00:15:54 +01001653
Michael Wrighteef0e132017-11-21 17:57:52 +00001654 case MSG_LOAD_BRIGHTNESS_CONFIGURATION:
1655 loadBrightnessConfiguration();
1656 break;
Jeff Brownbd6e1502012-08-28 03:27:37 -07001657 }
1658 }
1659 }
1660
1661 private final class DisplayAdapterListener implements DisplayAdapter.Listener {
1662 @Override
1663 public void onDisplayDeviceEvent(DisplayDevice device, int event) {
1664 switch (event) {
1665 case DisplayAdapter.DISPLAY_DEVICE_EVENT_ADDED:
1666 handleDisplayDeviceAdded(device);
1667 break;
1668
1669 case DisplayAdapter.DISPLAY_DEVICE_EVENT_CHANGED:
1670 handleDisplayDeviceChanged(device);
1671 break;
1672
1673 case DisplayAdapter.DISPLAY_DEVICE_EVENT_REMOVED:
1674 handleDisplayDeviceRemoved(device);
1675 break;
1676 }
1677 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001678
1679 @Override
1680 public void onTraversalRequested() {
1681 synchronized (mSyncRoot) {
Craig Mautner65d11b32012-10-01 13:59:52 -07001682 scheduleTraversalLocked(false);
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001683 }
1684 }
Jeff Brownbd6e1502012-08-28 03:27:37 -07001685 }
1686
1687 private final class CallbackRecord implements DeathRecipient {
Jeff Brownce468a32013-11-21 16:42:03 -08001688 public final int mPid;
Jeff Brownbd6e1502012-08-28 03:27:37 -07001689 private final IDisplayManagerCallback mCallback;
1690
Jeff Brownce468a32013-11-21 16:42:03 -08001691 public boolean mWifiDisplayScanRequested;
1692
Jeff Brownbd6e1502012-08-28 03:27:37 -07001693 public CallbackRecord(int pid, IDisplayManagerCallback callback) {
1694 mPid = pid;
1695 mCallback = callback;
1696 }
1697
1698 @Override
1699 public void binderDied() {
1700 if (DEBUG) {
1701 Slog.d(TAG, "Display listener for pid " + mPid + " died.");
1702 }
Jeff Brownce468a32013-11-21 16:42:03 -08001703 onCallbackDied(this);
Jeff Brownbd6e1502012-08-28 03:27:37 -07001704 }
1705
1706 public void notifyDisplayEventAsync(int displayId, int event) {
1707 try {
1708 mCallback.onDisplayEvent(displayId, event);
1709 } catch (RemoteException ex) {
1710 Slog.w(TAG, "Failed to notify process "
1711 + mPid + " that displays changed, assuming it died.", ex);
1712 binderDied();
1713 }
1714 }
1715 }
Jeff Brown4ccb8232014-01-16 22:16:42 -08001716
Santos Cordonee8931e2017-04-05 10:31:15 -07001717 @VisibleForTesting
1718 final class BinderService extends IDisplayManager.Stub {
Jeff Brown4ccb8232014-01-16 22:16:42 -08001719 /**
1720 * Returns information about the specified logical display.
1721 *
1722 * @param displayId The logical display id.
lumarkec75b422019-01-07 15:58:38 +08001723 * @return The logical display info, return {@code null} if the display does not exist or
1724 * the calling UID isn't present on the display. The returned object must be treated as
1725 * immutable.
Jeff Brown4ccb8232014-01-16 22:16:42 -08001726 */
1727 @Override // Binder call
1728 public DisplayInfo getDisplayInfo(int displayId) {
1729 final int callingUid = Binder.getCallingUid();
1730 final long token = Binder.clearCallingIdentity();
1731 try {
1732 return getDisplayInfoInternal(displayId, callingUid);
1733 } finally {
1734 Binder.restoreCallingIdentity(token);
1735 }
1736 }
1737
1738 /**
1739 * Returns the list of all display ids.
1740 */
1741 @Override // Binder call
1742 public int[] getDisplayIds() {
1743 final int callingUid = Binder.getCallingUid();
1744 final long token = Binder.clearCallingIdentity();
1745 try {
1746 return getDisplayIdsInternal(callingUid);
1747 } finally {
1748 Binder.restoreCallingIdentity(token);
1749 }
1750 }
1751
lumarkec75b422019-01-07 15:58:38 +08001752 @Override // Binder call
1753 public boolean isUidPresentOnDisplay(int uid, int displayId) {
1754 final long token = Binder.clearCallingIdentity();
1755 try {
1756 return isUidPresentOnDisplayInternal(uid, displayId);
1757 } finally {
1758 Binder.restoreCallingIdentity(token);
1759 }
1760 }
1761
Michael Wrighteedcbf12017-08-16 23:14:54 +01001762 /**
1763 * Returns the stable device display size, in pixels.
1764 */
1765 @Override // Binder call
1766 public Point getStableDisplaySize() {
1767 final long token = Binder.clearCallingIdentity();
1768 try {
1769 return getStableDisplaySizeInternal();
1770 } finally {
1771 Binder.restoreCallingIdentity(token);
1772 }
1773 }
1774
Jeff Brown4ccb8232014-01-16 22:16:42 -08001775 @Override // Binder call
1776 public void registerCallback(IDisplayManagerCallback callback) {
1777 if (callback == null) {
1778 throw new IllegalArgumentException("listener must not be null");
1779 }
1780
1781 final int callingPid = Binder.getCallingPid();
1782 final long token = Binder.clearCallingIdentity();
1783 try {
1784 registerCallbackInternal(callback, callingPid);
1785 } finally {
1786 Binder.restoreCallingIdentity(token);
1787 }
1788 }
1789
1790 @Override // Binder call
1791 public void startWifiDisplayScan() {
1792 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
1793 "Permission required to start wifi display scans");
1794
1795 final int callingPid = Binder.getCallingPid();
1796 final long token = Binder.clearCallingIdentity();
1797 try {
1798 startWifiDisplayScanInternal(callingPid);
1799 } finally {
1800 Binder.restoreCallingIdentity(token);
1801 }
1802 }
1803
1804 @Override // Binder call
1805 public void stopWifiDisplayScan() {
1806 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
1807 "Permission required to stop wifi display scans");
1808
1809 final int callingPid = Binder.getCallingPid();
1810 final long token = Binder.clearCallingIdentity();
1811 try {
1812 stopWifiDisplayScanInternal(callingPid);
1813 } finally {
1814 Binder.restoreCallingIdentity(token);
1815 }
1816 }
1817
1818 @Override // Binder call
1819 public void connectWifiDisplay(String address) {
1820 if (address == null) {
1821 throw new IllegalArgumentException("address must not be null");
1822 }
1823 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
1824 "Permission required to connect to a wifi display");
1825
1826 final long token = Binder.clearCallingIdentity();
1827 try {
1828 connectWifiDisplayInternal(address);
1829 } finally {
1830 Binder.restoreCallingIdentity(token);
1831 }
1832 }
1833
1834 @Override // Binder call
1835 public void disconnectWifiDisplay() {
1836 // This request does not require special permissions.
1837 // Any app can request disconnection from the currently active wifi display.
1838 // This exception should no longer be needed once wifi display control moves
1839 // to the media router service.
1840
1841 final long token = Binder.clearCallingIdentity();
1842 try {
1843 disconnectWifiDisplayInternal();
1844 } finally {
1845 Binder.restoreCallingIdentity(token);
1846 }
1847 }
1848
1849 @Override // Binder call
1850 public void renameWifiDisplay(String address, String alias) {
1851 if (address == null) {
1852 throw new IllegalArgumentException("address must not be null");
1853 }
1854 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
1855 "Permission required to rename to a wifi display");
1856
1857 final long token = Binder.clearCallingIdentity();
1858 try {
1859 renameWifiDisplayInternal(address, alias);
1860 } finally {
1861 Binder.restoreCallingIdentity(token);
1862 }
1863 }
1864
1865 @Override // Binder call
1866 public void forgetWifiDisplay(String address) {
1867 if (address == null) {
1868 throw new IllegalArgumentException("address must not be null");
1869 }
1870 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
1871 "Permission required to forget to a wifi display");
1872
1873 final long token = Binder.clearCallingIdentity();
1874 try {
1875 forgetWifiDisplayInternal(address);
1876 } finally {
1877 Binder.restoreCallingIdentity(token);
1878 }
1879 }
1880
1881 @Override // Binder call
1882 public void pauseWifiDisplay() {
1883 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
1884 "Permission required to pause a wifi display session");
1885
1886 final long token = Binder.clearCallingIdentity();
1887 try {
1888 pauseWifiDisplayInternal();
1889 } finally {
1890 Binder.restoreCallingIdentity(token);
1891 }
1892 }
1893
1894 @Override // Binder call
1895 public void resumeWifiDisplay() {
1896 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
1897 "Permission required to resume a wifi display session");
1898
1899 final long token = Binder.clearCallingIdentity();
1900 try {
1901 resumeWifiDisplayInternal();
1902 } finally {
1903 Binder.restoreCallingIdentity(token);
1904 }
1905 }
1906
1907 @Override // Binder call
1908 public WifiDisplayStatus getWifiDisplayStatus() {
1909 // This request does not require special permissions.
1910 // Any app can get information about available wifi displays.
1911
1912 final long token = Binder.clearCallingIdentity();
1913 try {
1914 return getWifiDisplayStatusInternal();
1915 } finally {
1916 Binder.restoreCallingIdentity(token);
1917 }
1918 }
1919
1920 @Override // Binder call
Michael Wright1c9977b2016-07-12 13:30:10 -07001921 public void requestColorMode(int displayId, int colorMode) {
Michael Wright58e829f2015-09-15 00:13:26 +01001922 mContext.enforceCallingOrSelfPermission(
Michael Wright1c9977b2016-07-12 13:30:10 -07001923 Manifest.permission.CONFIGURE_DISPLAY_COLOR_MODE,
1924 "Permission required to change the display color mode");
Michael Wright58e829f2015-09-15 00:13:26 +01001925 final long token = Binder.clearCallingIdentity();
1926 try {
Michael Wright1c9977b2016-07-12 13:30:10 -07001927 requestColorModeInternal(displayId, colorMode);
Michael Wright58e829f2015-09-15 00:13:26 +01001928 } finally {
1929 Binder.restoreCallingIdentity(token);
1930 }
1931 }
1932
1933 @Override // Binder call
Michael Wright75ee9fc2014-09-01 19:55:22 -07001934 public int createVirtualDisplay(IVirtualDisplayCallback callback,
Michael Wrightc39d47a2014-07-08 18:07:36 -07001935 IMediaProjection projection, String packageName, String name,
Santos Cordonee8931e2017-04-05 10:31:15 -07001936 int width, int height, int densityDpi, Surface surface, int flags,
1937 String uniqueId) {
Jeff Brown4ccb8232014-01-16 22:16:42 -08001938 final int callingUid = Binder.getCallingUid();
1939 if (!validatePackageName(callingUid, packageName)) {
1940 throw new SecurityException("packageName must match the calling uid");
1941 }
Michael Wright75ee9fc2014-09-01 19:55:22 -07001942 if (callback == null) {
Jeff Brown4ccb8232014-01-16 22:16:42 -08001943 throw new IllegalArgumentException("appToken must not be null");
1944 }
1945 if (TextUtils.isEmpty(name)) {
1946 throw new IllegalArgumentException("name must be non-null and non-empty");
1947 }
1948 if (width <= 0 || height <= 0 || densityDpi <= 0) {
1949 throw new IllegalArgumentException("width, height, and densityDpi must be "
1950 + "greater than 0");
1951 }
Pablo Ceballoseb3370d2016-08-31 15:00:17 -07001952 if (surface != null && surface.isSingleBuffered()) {
Pablo Ceballosaff2f942016-07-29 14:49:55 -07001953 throw new IllegalArgumentException("Surface can't be single-buffered");
1954 }
Michael Wrightc39d47a2014-07-08 18:07:36 -07001955
Andrii Kulianfc8f82b2017-01-26 13:17:27 -08001956 if ((flags & VIRTUAL_DISPLAY_FLAG_PUBLIC) != 0) {
1957 flags |= VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR;
1958
1959 // Public displays can't be allowed to show content when locked.
Andrii Kulian7211d2e2017-01-27 15:58:05 -08001960 if ((flags & VIRTUAL_DISPLAY_FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD) != 0) {
Andrii Kulianfc8f82b2017-01-26 13:17:27 -08001961 throw new IllegalArgumentException(
1962 "Public display must not be marked as SHOW_WHEN_LOCKED_INSECURE");
1963 }
Michael Wright6720be42014-07-29 19:14:16 -07001964 }
Andrii Kulianfc8f82b2017-01-26 13:17:27 -08001965 if ((flags & VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY) != 0) {
1966 flags &= ~VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR;
Michael Wright6720be42014-07-29 19:14:16 -07001967 }
1968
Michael Wrightc39d47a2014-07-08 18:07:36 -07001969 if (projection != null) {
1970 try {
1971 if (!getProjectionService().isValidMediaProjection(projection)) {
1972 throw new SecurityException("Invalid media projection");
1973 }
Michael Wright6720be42014-07-29 19:14:16 -07001974 flags = projection.applyVirtualDisplayFlags(flags);
Michael Wrightc39d47a2014-07-08 18:07:36 -07001975 } catch (RemoteException e) {
Michael Wright6720be42014-07-29 19:14:16 -07001976 throw new SecurityException("unable to validate media projection or flags");
Michael Wrightc39d47a2014-07-08 18:07:36 -07001977 }
1978 }
1979
Michael Wright6720be42014-07-29 19:14:16 -07001980 if (callingUid != Process.SYSTEM_UID &&
Andrii Kulianfc8f82b2017-01-26 13:17:27 -08001981 (flags & VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR) != 0) {
Michael Wrightc39d47a2014-07-08 18:07:36 -07001982 if (!canProjectVideo(projection)) {
1983 throw new SecurityException("Requires CAPTURE_VIDEO_OUTPUT or "
1984 + "CAPTURE_SECURE_VIDEO_OUTPUT permission, or an appropriate "
1985 + "MediaProjection token in order to create a screen sharing virtual "
1986 + "display.");
1987 }
1988 }
Santos Cordonb6992f22018-01-30 14:51:20 -08001989 if (callingUid != Process.SYSTEM_UID && (flags & VIRTUAL_DISPLAY_FLAG_SECURE) != 0) {
Michael Wrightc39d47a2014-07-08 18:07:36 -07001990 if (!canProjectSecureVideo(projection)) {
Jeff Brown4ccb8232014-01-16 22:16:42 -08001991 throw new SecurityException("Requires CAPTURE_SECURE_VIDEO_OUTPUT "
Michael Wrightc39d47a2014-07-08 18:07:36 -07001992 + "or an appropriate MediaProjection token to create a "
1993 + "secure virtual display.");
Jeff Brown4ccb8232014-01-16 22:16:42 -08001994 }
1995 }
1996
Chilun67a379b2019-04-11 19:49:42 +08001997 // Sometimes users can have sensitive information in system decoration windows. An app
1998 // could create a virtual display with system decorations support and read the user info
1999 // from the surface.
2000 // We should only allow adding flag VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS
2001 // to virtual displays that are owned by the system.
2002 if (callingUid != Process.SYSTEM_UID
2003 && (flags & VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS) != 0) {
2004 if (!checkCallingPermission(INTERNAL_SYSTEM_WINDOW, "createVirtualDisplay()")) {
2005 throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission");
2006 }
2007 }
2008
Jeff Brown4ccb8232014-01-16 22:16:42 -08002009 final long token = Binder.clearCallingIdentity();
2010 try {
Santos Cordonee8931e2017-04-05 10:31:15 -07002011 return createVirtualDisplayInternal(callback, projection, callingUid, packageName,
2012 name, width, height, densityDpi, surface, flags, uniqueId);
Jeff Brown4ccb8232014-01-16 22:16:42 -08002013 } finally {
2014 Binder.restoreCallingIdentity(token);
2015 }
2016 }
2017
2018 @Override // Binder call
Michael Wright75ee9fc2014-09-01 19:55:22 -07002019 public void resizeVirtualDisplay(IVirtualDisplayCallback callback,
Michael Wright01e840f2014-06-26 16:03:25 -07002020 int width, int height, int densityDpi) {
2021 final long token = Binder.clearCallingIdentity();
2022 try {
Michael Wright75ee9fc2014-09-01 19:55:22 -07002023 resizeVirtualDisplayInternal(callback.asBinder(), width, height, densityDpi);
Michael Wright01e840f2014-06-26 16:03:25 -07002024 } finally {
2025 Binder.restoreCallingIdentity(token);
2026 }
2027 }
2028
2029 @Override // Binder call
Michael Wright75ee9fc2014-09-01 19:55:22 -07002030 public void setVirtualDisplaySurface(IVirtualDisplayCallback callback, Surface surface) {
Pablo Ceballoseb3370d2016-08-31 15:00:17 -07002031 if (surface != null && surface.isSingleBuffered()) {
2032 throw new IllegalArgumentException("Surface can't be single-buffered");
2033 }
Jeff Brown92207df2014-04-16 13:16:07 -07002034 final long token = Binder.clearCallingIdentity();
2035 try {
Michael Wright75ee9fc2014-09-01 19:55:22 -07002036 setVirtualDisplaySurfaceInternal(callback.asBinder(), surface);
Jeff Brown92207df2014-04-16 13:16:07 -07002037 } finally {
2038 Binder.restoreCallingIdentity(token);
2039 }
2040 }
2041
2042 @Override // Binder call
Michael Wright75ee9fc2014-09-01 19:55:22 -07002043 public void releaseVirtualDisplay(IVirtualDisplayCallback callback) {
Jeff Brown4ccb8232014-01-16 22:16:42 -08002044 final long token = Binder.clearCallingIdentity();
2045 try {
Michael Wright75ee9fc2014-09-01 19:55:22 -07002046 releaseVirtualDisplayInternal(callback.asBinder());
Jeff Brown4ccb8232014-01-16 22:16:42 -08002047 } finally {
2048 Binder.restoreCallingIdentity(token);
2049 }
2050 }
2051
2052 @Override // Binder call
chaviwda4c6942018-11-07 15:52:56 -08002053 public void setVirtualDisplayState(IVirtualDisplayCallback callback, boolean isOn) {
2054 final long token = Binder.clearCallingIdentity();
2055 try {
2056 setVirtualDisplayStateInternal(callback.asBinder(), isOn);
2057 } finally {
2058 Binder.restoreCallingIdentity(token);
2059 }
2060 }
2061
2062 @Override // Binder call
Jeff Brown4ccb8232014-01-16 22:16:42 -08002063 public void dump(FileDescriptor fd, final PrintWriter pw, String[] args) {
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -06002064 if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
Jeff Brown4ccb8232014-01-16 22:16:42 -08002065
2066 final long token = Binder.clearCallingIdentity();
2067 try {
2068 dumpInternal(pw);
2069 } finally {
2070 Binder.restoreCallingIdentity(token);
2071 }
2072 }
2073
Kenny Guy22bd0442017-10-26 00:15:54 +01002074 @Override // Binder call
Kenny Guy29aa30e2017-11-30 13:43:46 +00002075 public ParceledListSlice<BrightnessChangeEvent> getBrightnessEvents(String callingPackage) {
Kenny Guy22bd0442017-10-26 00:15:54 +01002076 mContext.enforceCallingOrSelfPermission(
2077 Manifest.permission.BRIGHTNESS_SLIDER_USAGE,
2078 "Permission to read brightness events.");
Kenny Guy29aa30e2017-11-30 13:43:46 +00002079
2080 final int callingUid = Binder.getCallingUid();
2081 AppOpsManager appOpsManager = mContext.getSystemService(AppOpsManager.class);
Jeff Sharkeyd9311192018-04-16 16:50:34 +00002082 final int mode = appOpsManager.noteOp(AppOpsManager.OP_GET_USAGE_STATS,
Kenny Guy29aa30e2017-11-30 13:43:46 +00002083 callingUid, callingPackage);
2084 final boolean hasUsageStats;
2085 if (mode == AppOpsManager.MODE_DEFAULT) {
2086 // The default behavior here is to check if PackageManager has given the app
2087 // permission.
2088 hasUsageStats = mContext.checkCallingPermission(
2089 Manifest.permission.PACKAGE_USAGE_STATS)
2090 == PackageManager.PERMISSION_GRANTED;
2091 } else {
2092 hasUsageStats = mode == AppOpsManager.MODE_ALLOWED;
2093 }
2094
2095 final int userId = UserHandle.getUserId(callingUid);
Kenny Guy22bd0442017-10-26 00:15:54 +01002096 final long token = Binder.clearCallingIdentity();
2097 try {
Michael Wright144aac92017-12-21 18:37:41 +00002098 synchronized (mSyncRoot) {
2099 return mDisplayPowerController.getBrightnessEvents(userId, hasUsageStats);
2100 }
Kenny Guy22bd0442017-10-26 00:15:54 +01002101 } finally {
2102 Binder.restoreCallingIdentity(token);
2103 }
2104 }
2105
Michael Wrighteef0e132017-11-21 17:57:52 +00002106 @Override // Binder call
Peeyush Agarwalcc155dd2018-01-10 11:51:33 +00002107 public ParceledListSlice<AmbientBrightnessDayStats> getAmbientBrightnessStats() {
2108 mContext.enforceCallingOrSelfPermission(
2109 Manifest.permission.ACCESS_AMBIENT_LIGHT_STATS,
2110 "Permission required to to access ambient light stats.");
2111 final int callingUid = Binder.getCallingUid();
2112 final int userId = UserHandle.getUserId(callingUid);
2113 final long token = Binder.clearCallingIdentity();
2114 try {
2115 synchronized (mSyncRoot) {
2116 return mDisplayPowerController.getAmbientBrightnessStats(userId);
2117 }
2118 } finally {
2119 Binder.restoreCallingIdentity(token);
2120 }
2121 }
2122
2123 @Override // Binder call
Michael Wrighteef0e132017-11-21 17:57:52 +00002124 public void setBrightnessConfigurationForUser(
Kenny Guy05ce8092018-01-17 13:44:20 +00002125 BrightnessConfiguration c, @UserIdInt int userId, String packageName) {
Michael Wrighteef0e132017-11-21 17:57:52 +00002126 mContext.enforceCallingOrSelfPermission(
2127 Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS,
2128 "Permission required to change the display's brightness configuration");
2129 if (userId != UserHandle.getCallingUserId()) {
2130 mContext.enforceCallingOrSelfPermission(
2131 Manifest.permission.INTERACT_ACROSS_USERS,
2132 "Permission required to change the display brightness"
2133 + " configuration of another user");
2134 }
Kenny Guy05ce8092018-01-17 13:44:20 +00002135 if (packageName != null && !validatePackageName(getCallingUid(), packageName)) {
2136 packageName = null;
2137 }
Michael Wrighteef0e132017-11-21 17:57:52 +00002138 final long token = Binder.clearCallingIdentity();
2139 try {
Kenny Guy05ce8092018-01-17 13:44:20 +00002140 setBrightnessConfigurationForUserInternal(c, userId, packageName);
Michael Wrighteef0e132017-11-21 17:57:52 +00002141 } finally {
2142 Binder.restoreCallingIdentity(token);
2143 }
2144 }
2145
Michael Wrightd8460232018-01-16 18:04:59 +00002146 @Override // Binder call
Kenny Guy6d1009f2018-03-14 14:28:23 +00002147 public BrightnessConfiguration getBrightnessConfigurationForUser(int userId) {
2148 mContext.enforceCallingOrSelfPermission(
2149 Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS,
2150 "Permission required to read the display's brightness configuration");
2151 if (userId != UserHandle.getCallingUserId()) {
2152 mContext.enforceCallingOrSelfPermission(
2153 Manifest.permission.INTERACT_ACROSS_USERS,
2154 "Permission required to read the display brightness"
2155 + " configuration of another user");
2156 }
2157 final long token = Binder.clearCallingIdentity();
2158 try {
2159 final int userSerial = getUserManager().getUserSerialNumber(userId);
2160 synchronized (mSyncRoot) {
2161 BrightnessConfiguration config =
2162 mPersistentDataStore.getBrightnessConfiguration(userSerial);
2163 if (config == null) {
2164 config = mDisplayPowerController.getDefaultBrightnessConfiguration();
2165 }
2166 return config;
2167 }
2168 } finally {
2169 Binder.restoreCallingIdentity(token);
2170 }
2171 }
2172
2173 @Override // Binder call
2174 public BrightnessConfiguration getDefaultBrightnessConfiguration() {
2175 mContext.enforceCallingOrSelfPermission(
2176 Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS,
2177 "Permission required to read the display's default brightness configuration");
2178 final long token = Binder.clearCallingIdentity();
2179 try {
2180 synchronized (mSyncRoot) {
2181 return mDisplayPowerController.getDefaultBrightnessConfiguration();
2182 }
2183 } finally {
2184 Binder.restoreCallingIdentity(token);
2185 }
2186 }
2187
2188 @Override // Binder call
Michael Wrightd8460232018-01-16 18:04:59 +00002189 public void setTemporaryBrightness(int brightness) {
2190 mContext.enforceCallingOrSelfPermission(
2191 Manifest.permission.CONTROL_DISPLAY_BRIGHTNESS,
2192 "Permission required to set the display's brightness");
2193 final long token = Binder.clearCallingIdentity();
2194 try {
2195 synchronized (mSyncRoot) {
2196 mDisplayPowerController.setTemporaryBrightness(brightness);
2197 }
2198 } finally {
2199 Binder.restoreCallingIdentity(token);
2200 }
2201 }
2202
2203 @Override // Binder call
2204 public void setTemporaryAutoBrightnessAdjustment(float adjustment) {
2205 mContext.enforceCallingOrSelfPermission(
2206 Manifest.permission.CONTROL_DISPLAY_BRIGHTNESS,
2207 "Permission required to set the display's auto brightness adjustment");
2208 final long token = Binder.clearCallingIdentity();
2209 try {
2210 synchronized (mSyncRoot) {
2211 mDisplayPowerController.setTemporaryAutoBrightnessAdjustment(adjustment);
2212 }
2213 } finally {
2214 Binder.restoreCallingIdentity(token);
2215 }
2216 }
2217
Dan Gittik7a32fba2018-03-28 12:19:38 +01002218 @Override // Binder call
2219 public void onShellCommand(FileDescriptor in, FileDescriptor out,
2220 FileDescriptor err, String[] args, ShellCallback callback,
2221 ResultReceiver resultReceiver) {
2222 final long token = Binder.clearCallingIdentity();
2223 try {
2224 DisplayManagerShellCommand command = new DisplayManagerShellCommand(this);
2225 command.exec(this, in, out, err, args, callback, resultReceiver);
2226 } finally {
2227 Binder.restoreCallingIdentity(token);
2228 }
2229 }
2230
Dan Gittik122df862018-03-28 16:59:22 +01002231 @Override // Binder call
2232 public Curve getMinimumBrightnessCurve() {
2233 final long token = Binder.clearCallingIdentity();
2234 try {
2235 return getMinimumBrightnessCurveInternal();
2236 } finally {
2237 Binder.restoreCallingIdentity(token);
2238 }
2239 }
2240
Peiyong Lin277eaff2019-01-16 16:18:22 -08002241 @Override // Binder call
2242 public int getPreferredWideGamutColorSpaceId() {
2243 final long token = Binder.clearCallingIdentity();
2244 try {
2245 return getPreferredWideGamutColorSpaceIdInternal();
2246 } finally {
2247 Binder.restoreCallingIdentity(token);
2248 }
2249 }
2250
Dan Gittik7a32fba2018-03-28 12:19:38 +01002251 void setBrightness(int brightness) {
2252 Settings.System.putIntForUser(mContext.getContentResolver(),
2253 Settings.System.SCREEN_BRIGHTNESS, brightness, UserHandle.USER_CURRENT);
2254 }
2255
2256 void resetBrightnessConfiguration() {
2257 setBrightnessConfigurationForUserInternal(null, mContext.getUserId(),
2258 mContext.getPackageName());
2259 }
2260
Dan Gittika5a2d632019-01-09 14:25:29 +00002261 void setAutoBrightnessLoggingEnabled(boolean enabled) {
2262 if (mDisplayPowerController != null) {
2263 synchronized (mSyncRoot) {
2264 mDisplayPowerController.setAutoBrightnessLoggingEnabled(enabled);
2265 }
2266 }
2267 }
2268
Dan Gittik8dbd7e92018-12-03 15:35:53 +00002269 void setDisplayWhiteBalanceLoggingEnabled(boolean enabled) {
2270 if (mDisplayPowerController != null) {
2271 synchronized (mSyncRoot) {
2272 mDisplayPowerController.setDisplayWhiteBalanceLoggingEnabled(enabled);
2273 }
2274 }
2275 }
2276
2277 void setAmbientColorTemperatureOverride(float cct) {
2278 if (mDisplayPowerController != null) {
2279 synchronized (mSyncRoot) {
2280 mDisplayPowerController.setAmbientColorTemperatureOverride(cct);
2281 }
2282 }
2283 }
2284
Jeff Brown4ccb8232014-01-16 22:16:42 -08002285 private boolean validatePackageName(int uid, String packageName) {
2286 if (packageName != null) {
2287 String[] packageNames = mContext.getPackageManager().getPackagesForUid(uid);
2288 if (packageNames != null) {
2289 for (String n : packageNames) {
2290 if (n.equals(packageName)) {
2291 return true;
2292 }
2293 }
2294 }
2295 }
2296 return false;
2297 }
Michael Wrightc39d47a2014-07-08 18:07:36 -07002298
2299 private boolean canProjectVideo(IMediaProjection projection) {
2300 if (projection != null) {
2301 try {
2302 if (projection.canProjectVideo()) {
2303 return true;
2304 }
2305 } catch (RemoteException e) {
2306 Slog.e(TAG, "Unable to query projection service for permissions", e);
2307 }
2308 }
Chilun67a379b2019-04-11 19:49:42 +08002309 if (checkCallingPermission(CAPTURE_VIDEO_OUTPUT, "canProjectVideo()")) {
Michael Wrightc39d47a2014-07-08 18:07:36 -07002310 return true;
2311 }
2312 return canProjectSecureVideo(projection);
2313 }
2314
2315 private boolean canProjectSecureVideo(IMediaProjection projection) {
2316 if (projection != null) {
2317 try {
2318 if (projection.canProjectSecureVideo()){
2319 return true;
2320 }
2321 } catch (RemoteException e) {
2322 Slog.e(TAG, "Unable to query projection service for permissions", e);
2323 }
2324 }
Chilun67a379b2019-04-11 19:49:42 +08002325 return checkCallingPermission(CAPTURE_SECURE_VIDEO_OUTPUT, "canProjectSecureVideo()");
2326 }
2327
2328 private boolean checkCallingPermission(String permission, String func) {
2329 if (mContext.checkCallingPermission(permission) == PackageManager.PERMISSION_GRANTED) {
2330 return true;
2331 }
2332 final String msg = "Permission Denial: " + func + " from pid=" + Binder.getCallingPid()
2333 + ", uid=" + Binder.getCallingUid() + " requires " + permission;
2334 Slog.w(TAG, msg);
2335 return false;
Michael Wrightc39d47a2014-07-08 18:07:36 -07002336 }
Jeff Brown4ccb8232014-01-16 22:16:42 -08002337 }
2338
2339 private final class LocalService extends DisplayManagerInternal {
2340 @Override
Jeff Brown037c33e2014-04-09 00:31:55 -07002341 public void initPowerManagement(final DisplayPowerCallbacks callbacks, Handler handler,
Jeff Brownad9ef192014-04-08 17:26:30 -07002342 SensorManager sensorManager) {
2343 synchronized (mSyncRoot) {
Jeff Brown037c33e2014-04-09 00:31:55 -07002344 DisplayBlanker blanker = new DisplayBlanker() {
2345 @Override
Jeff Brown5d6443b2015-04-10 20:15:01 -07002346 public void requestDisplayState(int state, int brightness) {
Jeff Brown037c33e2014-04-09 00:31:55 -07002347 // The order of operations is important for legacy reasons.
2348 if (state == Display.STATE_OFF) {
Jeff Brown5d6443b2015-04-10 20:15:01 -07002349 requestGlobalDisplayStateInternal(state, brightness);
Jeff Brown037c33e2014-04-09 00:31:55 -07002350 }
2351
2352 callbacks.onDisplayStateChange(state);
2353
2354 if (state != Display.STATE_OFF) {
Jeff Brown5d6443b2015-04-10 20:15:01 -07002355 requestGlobalDisplayStateInternal(state, brightness);
Jeff Brown037c33e2014-04-09 00:31:55 -07002356 }
2357 }
2358 };
Jeff Brownad9ef192014-04-08 17:26:30 -07002359 mDisplayPowerController = new DisplayPowerController(
Jeff Brown037c33e2014-04-09 00:31:55 -07002360 mContext, callbacks, handler, sensorManager, blanker);
Jeff Brownad9ef192014-04-08 17:26:30 -07002361 }
Michael Wrighteef0e132017-11-21 17:57:52 +00002362
2363 mHandler.sendEmptyMessage(MSG_LOAD_BRIGHTNESS_CONFIGURATION);
Jeff Brownad9ef192014-04-08 17:26:30 -07002364 }
2365
2366 @Override
2367 public boolean requestPowerState(DisplayPowerRequest request,
2368 boolean waitForNegativeProximity) {
Michael Wrighteef0e132017-11-21 17:57:52 +00002369 synchronized (mSyncRoot) {
2370 return mDisplayPowerController.requestPowerState(request,
2371 waitForNegativeProximity);
2372 }
Jeff Brownad9ef192014-04-08 17:26:30 -07002373 }
2374
2375 @Override
2376 public boolean isProximitySensorAvailable() {
Michael Wrighteef0e132017-11-21 17:57:52 +00002377 synchronized (mSyncRoot) {
2378 return mDisplayPowerController.isProximitySensorAvailable();
2379 }
Jeff Brownad9ef192014-04-08 17:26:30 -07002380 }
2381
2382 @Override
Robert Carr66b5664f2019-04-02 14:18:56 -07002383 public SurfaceControl.ScreenshotGraphicBuffer screenshot(int displayId) {
2384 return screenshotInternal(displayId);
Riddle Hsu654a6f92018-07-13 22:59:36 +08002385 }
2386
2387 @Override
Jeff Brown4ccb8232014-01-16 22:16:42 -08002388 public DisplayInfo getDisplayInfo(int displayId) {
2389 return getDisplayInfoInternal(displayId, Process.myUid());
2390 }
2391
2392 @Override
2393 public void registerDisplayTransactionListener(DisplayTransactionListener listener) {
2394 if (listener == null) {
2395 throw new IllegalArgumentException("listener must not be null");
2396 }
2397
2398 registerDisplayTransactionListenerInternal(listener);
2399 }
2400
2401 @Override
2402 public void unregisterDisplayTransactionListener(DisplayTransactionListener listener) {
2403 if (listener == null) {
2404 throw new IllegalArgumentException("listener must not be null");
2405 }
2406
2407 unregisterDisplayTransactionListenerInternal(listener);
2408 }
2409
2410 @Override
2411 public void setDisplayInfoOverrideFromWindowManager(int displayId, DisplayInfo info) {
2412 setDisplayInfoOverrideFromWindowManagerInternal(displayId, info);
2413 }
2414
2415 @Override
Andrii Kuliancd097992017-03-23 18:31:59 -07002416 public void getNonOverrideDisplayInfo(int displayId, DisplayInfo outInfo) {
2417 getNonOverrideDisplayInfoInternal(displayId, outInfo);
2418 }
2419
2420 @Override
Robert Carrae606b42018-02-15 15:36:23 -08002421 public void performTraversal(SurfaceControl.Transaction t) {
2422 performTraversalInternal(t);
Jeff Brown4ccb8232014-01-16 22:16:42 -08002423 }
2424
2425 @Override
Michael Wright3f145a22014-07-22 19:46:03 -07002426 public void setDisplayProperties(int displayId, boolean hasContent,
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -07002427 float requestedRefreshRate, int requestedMode, boolean inTraversal) {
2428 setDisplayPropertiesInternal(displayId, hasContent, requestedRefreshRate,
2429 requestedMode, inTraversal);
Jeff Brown4ccb8232014-01-16 22:16:42 -08002430 }
Filip Gruszczynskid2e86402015-02-19 13:05:03 -08002431
2432 @Override
2433 public void setDisplayOffsets(int displayId, int x, int y) {
2434 setDisplayOffsetsInternal(displayId, x, y);
2435 }
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002436
2437 @Override
Sam Lin4c3ac2b2019-02-18 04:50:26 -08002438 public void setDisplayScalingDisabled(int displayId, boolean disableScaling) {
2439 setDisplayScalingDisabledInternal(displayId, disableScaling);
2440 }
2441
2442 @Override
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002443 public void setDisplayAccessUIDs(SparseArray<IntArray> newDisplayAccessUIDs) {
2444 setDisplayAccessUIDsInternal(newDisplayAccessUIDs);
2445 }
2446
2447 @Override
Peeyush Agarwalcc155dd2018-01-10 11:51:33 +00002448 public void persistBrightnessTrackerState() {
Michael Wright144aac92017-12-21 18:37:41 +00002449 synchronized (mSyncRoot) {
Peeyush Agarwalcc155dd2018-01-10 11:51:33 +00002450 mDisplayPowerController.persistBrightnessTrackerState();
Michael Wright144aac92017-12-21 18:37:41 +00002451 }
Kenny Guycfe7b702017-11-14 21:04:58 +00002452 }
Adrian Roose1d68cd2018-01-17 12:54:50 +01002453
2454 @Override
2455 public void onOverlayChanged() {
2456 synchronized (mSyncRoot) {
Adrian Roos898ec382018-01-17 12:54:50 +01002457 for (int i = 0; i < mDisplayDevices.size(); i++) {
2458 mDisplayDevices.get(i).onOverlayChangedLocked();
Adrian Roose1d68cd2018-01-17 12:54:50 +01002459 }
2460 }
2461 }
Kevin DuBoisbf76b11b2018-09-04 09:14:15 -07002462
2463 @Override
2464 public DisplayedContentSamplingAttributes getDisplayedContentSamplingAttributes(
2465 int displayId) {
2466 return getDisplayedContentSamplingAttributesInternal(displayId);
2467 }
2468
2469 @Override
2470 public boolean setDisplayedContentSamplingEnabled(
2471 int displayId, boolean enable, int componentMask, int maxFrames) {
2472 return setDisplayedContentSamplingEnabledInternal(
2473 displayId, enable, componentMask, maxFrames);
2474 }
2475
2476 @Override
2477 public DisplayedContentSample getDisplayedContentSample(int displayId,
2478 long maxFrames, long timestamp) {
2479 return getDisplayedContentSampleInternal(displayId, maxFrames, timestamp);
2480 }
2481
Jeff Brown4ccb8232014-01-16 22:16:42 -08002482 }
Michael Wrighta3dab232019-02-22 16:54:21 +00002483
2484 class AllowedDisplayModeObserver implements DisplayModeDirector.Listener {
2485 public void onAllowedDisplayModesChanged() {
2486 onAllowedDisplayModesChangedInternal();
2487 }
2488 }
Jeff Brownfa25bf52012-07-23 19:26:30 -07002489}