1 /*
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 
17 package com.android.server.display;
18 
19 import static android.Manifest.permission.ADD_TRUSTED_DISPLAY;
20 import static android.Manifest.permission.CAPTURE_SECURE_VIDEO_OUTPUT;
21 import static android.Manifest.permission.CAPTURE_VIDEO_OUTPUT;
22 import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
23 import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR;
24 import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD;
25 import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY;
26 import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC;
27 import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE;
28 import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS;
29 import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_TRUSTED;
30 import static android.hardware.display.DisplayViewport.VIEWPORT_EXTERNAL;
31 import static android.hardware.display.DisplayViewport.VIEWPORT_INTERNAL;
32 import static android.hardware.display.DisplayViewport.VIEWPORT_VIRTUAL;
33 import static android.view.Surface.ROTATION_270;
34 import static android.view.Surface.ROTATION_90;
35 
36 import android.Manifest;
37 import android.annotation.NonNull;
38 import android.annotation.Nullable;
39 import android.annotation.UserIdInt;
40 import android.app.AppOpsManager;
41 import android.content.Context;
42 import android.content.pm.PackageManager;
43 import android.content.pm.ParceledListSlice;
44 import android.content.res.Resources;
45 import android.content.res.TypedArray;
46 import android.database.ContentObserver;
47 import android.graphics.ColorSpace;
48 import android.graphics.Point;
49 import android.graphics.Rect;
50 import android.hardware.SensorManager;
51 import android.hardware.display.AmbientBrightnessDayStats;
52 import android.hardware.display.BrightnessChangeEvent;
53 import android.hardware.display.BrightnessConfiguration;
54 import android.hardware.display.Curve;
55 import android.hardware.display.DisplayManagerGlobal;
56 import android.hardware.display.DisplayManagerInternal;
57 import android.hardware.display.DisplayManagerInternal.DisplayTransactionListener;
58 import android.hardware.display.DisplayViewport;
59 import android.hardware.display.DisplayedContentSample;
60 import android.hardware.display.DisplayedContentSamplingAttributes;
61 import android.hardware.display.IDisplayManager;
62 import android.hardware.display.IDisplayManagerCallback;
63 import android.hardware.display.IVirtualDisplayCallback;
64 import android.hardware.display.VirtualDisplayConfig;
65 import android.hardware.display.WifiDisplayStatus;
66 import android.hardware.input.InputManagerInternal;
67 import android.media.projection.IMediaProjection;
68 import android.media.projection.IMediaProjectionManager;
69 import android.net.Uri;
70 import android.os.Binder;
71 import android.os.Handler;
72 import android.os.IBinder;
73 import android.os.IBinder.DeathRecipient;
74 import android.os.Looper;
75 import android.os.Message;
76 import android.os.PowerManager;
77 import android.os.Process;
78 import android.os.RemoteException;
79 import android.os.ResultReceiver;
80 import android.os.ServiceManager;
81 import android.os.ShellCallback;
82 import android.os.SystemClock;
83 import android.os.SystemProperties;
84 import android.os.Trace;
85 import android.os.UserHandle;
86 import android.os.UserManager;
87 import android.provider.Settings;
88 import android.text.TextUtils;
89 import android.util.IntArray;
90 import android.util.Pair;
91 import android.util.Slog;
92 import android.util.SparseArray;
93 import android.util.Spline;
94 import android.view.Display;
95 import android.view.DisplayInfo;
96 import android.view.Surface;
97 import android.view.SurfaceControl;
98 
99 import com.android.internal.annotations.GuardedBy;
100 import com.android.internal.annotations.VisibleForTesting;
101 import com.android.internal.util.DumpUtils;
102 import com.android.internal.util.IndentingPrintWriter;
103 import com.android.server.AnimationThread;
104 import com.android.server.DisplayThread;
105 import com.android.server.LocalServices;
106 import com.android.server.SystemService;
107 import com.android.server.UiThread;
108 import com.android.server.wm.SurfaceAnimationThread;
109 import com.android.server.wm.WindowManagerInternal;
110 
111 import java.io.FileDescriptor;
112 import java.io.PrintWriter;
113 import java.util.ArrayList;
114 import java.util.Arrays;
115 import java.util.List;
116 import java.util.Optional;
117 import java.util.concurrent.CopyOnWriteArrayList;
118 
119 /**
120  * Manages attached displays.
121  * <p>
122  * The {@link DisplayManagerService} manages the global lifecycle of displays,
123  * decides how to configure logical displays based on the physical display devices currently
124  * attached, sends notifications to the system and to applications when the state
125  * changes, and so on.
126  * </p><p>
127  * The display manager service relies on a collection of {@link DisplayAdapter} components,
128  * for discovering and configuring physical display devices attached to the system.
129  * There are separate display adapters for each manner that devices are attached:
130  * one display adapter for physical displays, one for simulated non-functional
131  * displays when the system is headless, one for simulated overlay displays used for
132  * development, one for wifi displays, etc.
133  * </p><p>
134  * Display adapters are only weakly coupled to the display manager service.
135  * Display adapters communicate changes in display device state to the display manager
136  * service asynchronously via a {@link DisplayAdapter.Listener} registered
137  * by the display manager service.  This separation of concerns is important for
138  * two main reasons.  First, it neatly encapsulates the responsibilities of these
139  * two classes: display adapters handle individual display devices whereas
140  * the display manager service handles the global state.  Second, it eliminates
141  * the potential for deadlocks resulting from asynchronous display device discovery.
142  * </p>
143  *
144  * <h3>Synchronization</h3>
145  * <p>
146  * Because the display manager may be accessed by multiple threads, the synchronization
147  * story gets a little complicated.  In particular, the window manager may call into
148  * the display manager while holding a surface transaction with the expectation that
149  * it can apply changes immediately.  Unfortunately, that means we can't just do
150  * everything asynchronously (*grump*).
151  * </p><p>
152  * To make this work, all of the objects that belong to the display manager must
153  * use the same lock.  We call this lock the synchronization root and it has a unique
154  * type {@link DisplayManagerService.SyncRoot}.  Methods that require this lock are
155  * named with the "Locked" suffix.
156  * </p><p>
157  * Where things get tricky is that the display manager is not allowed to make
158  * any potentially reentrant calls, especially into the window manager.  We generally
159  * avoid this by making all potentially reentrant out-calls asynchronous.
160  * </p>
161  */
162 public final class DisplayManagerService extends SystemService {
163     private static final String TAG = "DisplayManagerService";
164     private static final boolean DEBUG = false;
165 
166     // When this system property is set to 0, WFD is forcibly disabled on boot.
167     // When this system property is set to 1, WFD is forcibly enabled on boot.
168     // Otherwise WFD is enabled according to the value of config_enableWifiDisplay.
169     private static final String FORCE_WIFI_DISPLAY_ENABLE = "persist.debug.wfd.enable";
170 
171     private static final String PROP_DEFAULT_DISPLAY_TOP_INSET = "persist.sys.displayinset.top";
172 
173     private static final long WAIT_FOR_DEFAULT_DISPLAY_TIMEOUT = 10000;
174 
175     private static final int MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS = 1;
176     private static final int MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS = 2;
177     private static final int MSG_DELIVER_DISPLAY_EVENT = 3;
178     private static final int MSG_REQUEST_TRAVERSAL = 4;
179     private static final int MSG_UPDATE_VIEWPORT = 5;
180     private static final int MSG_LOAD_BRIGHTNESS_CONFIGURATION = 6;
181 
182     private final Context mContext;
183     private final DisplayManagerHandler mHandler;
184     private final Handler mUiHandler;
185     private final DisplayAdapterListener mDisplayAdapterListener;
186     private final DisplayModeDirector mDisplayModeDirector;
187     private WindowManagerInternal mWindowManagerInternal;
188     private InputManagerInternal mInputManagerInternal;
189     private IMediaProjectionManager mProjectionService;
190 
191     // The synchronization root for the display manager.
192     // This lock guards most of the display manager's state.
193     // NOTE: This is synchronized on while holding WindowManagerService.mWindowMap so never call
194     // into WindowManagerService methods that require mWindowMap while holding this unless you are
195     // very very sure that no deadlock can occur.
196     private final SyncRoot mSyncRoot = new SyncRoot();
197 
198     // True if in safe mode.
199     // This option may disable certain display adapters.
200     public boolean mSafeMode;
201 
202     // True if we are in a special boot mode where only core applications and
203     // services should be started.  This option may disable certain display adapters.
204     public boolean mOnlyCore;
205 
206     // True if the display manager service should pretend there is only one display
207     // and only tell applications about the existence of the default logical display.
208     // The display manager can still mirror content to secondary displays but applications
209     // cannot present unique content on those displays.
210     // Used for demonstration purposes only.
211     private final boolean mSingleDisplayDemoMode;
212 
213     // All callback records indexed by calling process id.
214     public final SparseArray<CallbackRecord> mCallbacks =
215             new SparseArray<CallbackRecord>();
216 
217     // List of all currently registered display adapters.
218     private final ArrayList<DisplayAdapter> mDisplayAdapters = new ArrayList<DisplayAdapter>();
219 
220     // List of all currently connected display devices.
221     private final ArrayList<DisplayDevice> mDisplayDevices = new ArrayList<DisplayDevice>();
222 
223     // List of all logical displays indexed by logical display id.
224     // Any modification to mLogicalDisplays must invalidate the DisplayManagerGlobal cache.
225     private final SparseArray<LogicalDisplay> mLogicalDisplays =
226             new SparseArray<LogicalDisplay>();
227     private int mNextNonDefaultDisplayId = Display.DEFAULT_DISPLAY + 1;
228 
229     // List of all display transaction listeners.
230     private final CopyOnWriteArrayList<DisplayTransactionListener> mDisplayTransactionListeners =
231             new CopyOnWriteArrayList<DisplayTransactionListener>();
232 
233     // Display power controller.
234     private DisplayPowerController mDisplayPowerController;
235 
236     // The overall display state, independent of changes that might influence one
237     // display or another in particular.
238     private int mGlobalDisplayState = Display.STATE_ON;
239 
240     // The overall display brightness.
241     // For now, this only applies to the default display but we may split it up eventually.
242     private float mGlobalDisplayBrightness;
243 
244     // Set to true when there are pending display changes that have yet to be applied
245     // to the surface flinger state.
246     private boolean mPendingTraversal;
247 
248     // The Wifi display adapter, or null if not registered.
249     private WifiDisplayAdapter mWifiDisplayAdapter;
250 
251     // The number of active wifi display scan requests.
252     private int mWifiDisplayScanRequestCount;
253 
254     // The virtual display adapter, or null if not registered.
255     private VirtualDisplayAdapter mVirtualDisplayAdapter;
256 
257     // The User ID of the current user
258     private @UserIdInt int mCurrentUserId;
259 
260     // The stable device screen height and width. These are not tied to a specific display, even
261     // the default display, because they need to be stable over the course of the device's entire
262     // life, even if the default display changes (e.g. a new monitor is plugged into a PC-like
263     // device).
264     private Point mStableDisplaySize = new Point();
265 
266     // Whether the system has finished booting or not.
267     private boolean mSystemReady;
268 
269     // The top inset of the default display.
270     // This gets persisted so that the boot animation knows how to transition from the display's
271     // full size to the size configured by the user. Right now we only persist and animate the top
272     // inset, but theoretically we could do it for all of them.
273     private int mDefaultDisplayTopInset;
274 
275     // Viewports of the default display and the display that should receive touch
276     // input from an external source.  Used by the input system.
277     @GuardedBy("mSyncRoot")
278     private final ArrayList<DisplayViewport> mViewports = new ArrayList<>();
279 
280     // Persistent data store for all internal settings maintained by the display manager service.
281     private final PersistentDataStore mPersistentDataStore = new PersistentDataStore();
282 
283     // Temporary callback list, used when sending display events to applications.
284     // May be used outside of the lock but only on the handler thread.
285     private final ArrayList<CallbackRecord> mTempCallbacks = new ArrayList<CallbackRecord>();
286 
287     // Temporary display info, used for comparing display configurations.
288     private final DisplayInfo mTempDisplayInfo = new DisplayInfo();
289 
290     // Temporary viewports, used when sending new viewport information to the
291     // input system.  May be used outside of the lock but only on the handler thread.
292     private final ArrayList<DisplayViewport> mTempViewports = new ArrayList<>();
293 
294     // The default color mode for default displays. Overrides the usual
295     // Display.Display.COLOR_MODE_DEFAULT for displays with the
296     // DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY flag set.
297     private final int mDefaultDisplayDefaultColorMode;
298 
299     // Temporary list of deferred work to perform when setting the display state.
300     // Only used by requestDisplayState.  The field is self-synchronized and only
301     // intended for use inside of the requestGlobalDisplayStateInternal function.
302     private final ArrayList<Runnable> mTempDisplayStateWorkQueue = new ArrayList<Runnable>();
303 
304     // Lists of UIDs that are present on the displays. Maps displayId -> array of UIDs.
305     private final SparseArray<IntArray> mDisplayAccessUIDs = new SparseArray<>();
306 
307     private final Injector mInjector;
308 
309     // The minimum brightness curve, which guarantess that any brightness curve that dips below it
310     // is rejected by the system.
311     private final Curve mMinimumBrightnessCurve;
312     private final Spline mMinimumBrightnessSpline;
313     private final ColorSpace mWideColorSpace;
314 
315     private SensorManager mSensorManager;
316 
317     // Whether minimal post processing is allowed by the user.
318     @GuardedBy("mSyncRoot")
319     private boolean mMinimalPostProcessingAllowed;
320 
321     // Receives notifications about changes to Settings.
322     private SettingsObserver mSettingsObserver;
323 
DisplayManagerService(Context context)324     public DisplayManagerService(Context context) {
325         this(context, new Injector());
326     }
327 
328     @VisibleForTesting
DisplayManagerService(Context context, Injector injector)329     DisplayManagerService(Context context, Injector injector) {
330         super(context);
331         mInjector = injector;
332         mContext = context;
333         mHandler = new DisplayManagerHandler(DisplayThread.get().getLooper());
334         mUiHandler = UiThread.getHandler();
335         mDisplayAdapterListener = new DisplayAdapterListener();
336         mDisplayModeDirector = new DisplayModeDirector(context, mHandler);
337         mSingleDisplayDemoMode = SystemProperties.getBoolean("persist.demo.singledisplay", false);
338         Resources resources = mContext.getResources();
339         mDefaultDisplayDefaultColorMode = mContext.getResources().getInteger(
340                 com.android.internal.R.integer.config_defaultDisplayDefaultColorMode);
341         mDefaultDisplayTopInset = SystemProperties.getInt(PROP_DEFAULT_DISPLAY_TOP_INSET, -1);
342         float[] lux = getFloatArray(resources.obtainTypedArray(
343                 com.android.internal.R.array.config_minimumBrightnessCurveLux));
344         float[] nits = getFloatArray(resources.obtainTypedArray(
345                 com.android.internal.R.array.config_minimumBrightnessCurveNits));
346         mMinimumBrightnessCurve = new Curve(lux, nits);
347         mMinimumBrightnessSpline = Spline.createSpline(lux, nits);
348 
349         PowerManager pm = mContext.getSystemService(PowerManager.class);
350         mGlobalDisplayBrightness = pm.getBrightnessConstraint(
351                 PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_DEFAULT);
352         mCurrentUserId = UserHandle.USER_SYSTEM;
353         ColorSpace[] colorSpaces = SurfaceControl.getCompositionColorSpaces();
354         mWideColorSpace = colorSpaces[1];
355 
356         mSystemReady = false;
357     }
358 
setupSchedulerPolicies()359     public void setupSchedulerPolicies() {
360         // android.display and android.anim is critical to user experience and we should make sure
361         // it is not in the default foregroup groups, add it to top-app to make sure it uses all
362         // the cores and scheduling settings for top-app when it runs.
363         Process.setThreadGroupAndCpuset(DisplayThread.get().getThreadId(),
364                 Process.THREAD_GROUP_TOP_APP);
365         Process.setThreadGroupAndCpuset(AnimationThread.get().getThreadId(),
366                 Process.THREAD_GROUP_TOP_APP);
367         Process.setThreadGroupAndCpuset(SurfaceAnimationThread.get().getThreadId(),
368                 Process.THREAD_GROUP_TOP_APP);
369     }
370 
371     @Override
onStart()372     public void onStart() {
373         // We need to pre-load the persistent data store so it's ready before the default display
374         // adapter is up so that we have it's configuration. We could load it lazily, but since
375         // we're going to have to read it in eventually we may as well do it here rather than after
376         // we've waited for the display to register itself with us.
377         synchronized (mSyncRoot) {
378             mPersistentDataStore.loadIfNeeded();
379             loadStableDisplayValuesLocked();
380         }
381         mHandler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS);
382 
383         // If there was a runtime restart then we may have stale caches left around, so we need to
384         // make sure to invalidate them upon every start.
385         DisplayManagerGlobal.invalidateLocalDisplayInfoCaches();
386 
387         publishBinderService(Context.DISPLAY_SERVICE, new BinderService(),
388                 true /*allowIsolated*/);
389         publishLocalService(DisplayManagerInternal.class, new LocalService());
390     }
391 
392     @Override
onBootPhase(int phase)393     public void onBootPhase(int phase) {
394         if (phase == PHASE_WAIT_FOR_DEFAULT_DISPLAY) {
395             synchronized (mSyncRoot) {
396                 long timeout = SystemClock.uptimeMillis()
397                         + mInjector.getDefaultDisplayDelayTimeout();
398                 while (mLogicalDisplays.get(Display.DEFAULT_DISPLAY) == null ||
399                         mVirtualDisplayAdapter == null) {
400                     long delay = timeout - SystemClock.uptimeMillis();
401                     if (delay <= 0) {
402                         throw new RuntimeException("Timeout waiting for default display "
403                                 + "to be initialized. DefaultDisplay="
404                                 + mLogicalDisplays.get(Display.DEFAULT_DISPLAY)
405                                 + ", mVirtualDisplayAdapter=" + mVirtualDisplayAdapter);
406                     }
407                     if (DEBUG) {
408                         Slog.d(TAG, "waitForDefaultDisplay: waiting, timeout=" + delay);
409                     }
410                     try {
411                         mSyncRoot.wait(delay);
412                     } catch (InterruptedException ex) {
413                     }
414                 }
415             }
416         }
417     }
418 
419     @Override
onSwitchUser(@serIdInt int newUserId)420     public void onSwitchUser(@UserIdInt int newUserId) {
421         final int userSerial = getUserManager().getUserSerialNumber(newUserId);
422         synchronized (mSyncRoot) {
423             if (mCurrentUserId != newUserId) {
424                 mCurrentUserId = newUserId;
425                 BrightnessConfiguration config =
426                         mPersistentDataStore.getBrightnessConfiguration(userSerial);
427                 mDisplayPowerController.setBrightnessConfiguration(config);
428                 handleSettingsChange();
429             }
430             mDisplayPowerController.onSwitchUser(newUserId);
431         }
432     }
433 
434     // TODO: Use dependencies or a boot phase
windowManagerAndInputReady()435     public void windowManagerAndInputReady() {
436         synchronized (mSyncRoot) {
437             mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
438             mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);
439             scheduleTraversalLocked(false);
440         }
441     }
442 
443     /**
444      * Called when the system is ready to go.
445      */
systemReady(boolean safeMode, boolean onlyCore)446     public void systemReady(boolean safeMode, boolean onlyCore) {
447         synchronized (mSyncRoot) {
448             mSafeMode = safeMode;
449             mOnlyCore = onlyCore;
450             mSystemReady = true;
451             // Just in case the top inset changed before the system was ready. At this point, any
452             // relevant configuration should be in place.
453             recordTopInsetLocked(mLogicalDisplays.get(Display.DEFAULT_DISPLAY));
454 
455             updateSettingsLocked();
456         }
457 
458         mDisplayModeDirector.setDesiredDisplayModeSpecsListener(
459                 new DesiredDisplayModeSpecsObserver());
460         mDisplayModeDirector.start(mSensorManager);
461 
462         mHandler.sendEmptyMessage(MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS);
463 
464         mSettingsObserver = new SettingsObserver();
465     }
466 
467     @VisibleForTesting
getDisplayHandler()468     Handler getDisplayHandler() {
469         return mHandler;
470     }
471 
loadStableDisplayValuesLocked()472     private void loadStableDisplayValuesLocked() {
473         final Point size = mPersistentDataStore.getStableDisplaySize();
474         if (size.x > 0 && size.y > 0) {
475             // Just set these values directly so we don't write the display persistent data again
476             // unnecessarily
477             mStableDisplaySize.set(size.x, size.y);
478         } else {
479             final Resources res = mContext.getResources();
480             final int width = res.getInteger(
481                     com.android.internal.R.integer.config_stableDeviceDisplayWidth);
482             final int height = res.getInteger(
483                     com.android.internal.R.integer.config_stableDeviceDisplayHeight);
484             if (width > 0 && height > 0) {
485                 setStableDisplaySizeLocked(width, height);
486             }
487         }
488     }
489 
getStableDisplaySizeInternal()490     private Point getStableDisplaySizeInternal() {
491         Point r = new Point();
492         synchronized (mSyncRoot) {
493             if (mStableDisplaySize.x > 0 && mStableDisplaySize.y > 0) {
494                 r.set(mStableDisplaySize.x, mStableDisplaySize.y);
495             }
496         }
497         return r;
498     }
499 
registerDisplayTransactionListenerInternal( DisplayTransactionListener listener)500     private void registerDisplayTransactionListenerInternal(
501             DisplayTransactionListener listener) {
502         // List is self-synchronized copy-on-write.
503         mDisplayTransactionListeners.add(listener);
504     }
505 
unregisterDisplayTransactionListenerInternal( DisplayTransactionListener listener)506     private void unregisterDisplayTransactionListenerInternal(
507             DisplayTransactionListener listener) {
508         // List is self-synchronized copy-on-write.
509         mDisplayTransactionListeners.remove(listener);
510     }
511 
setDisplayInfoOverrideFromWindowManagerInternal( int displayId, DisplayInfo info)512     private void setDisplayInfoOverrideFromWindowManagerInternal(
513             int displayId, DisplayInfo info) {
514         synchronized (mSyncRoot) {
515             LogicalDisplay display = mLogicalDisplays.get(displayId);
516             if (display != null) {
517                 if (display.setDisplayInfoOverrideFromWindowManagerLocked(info)) {
518                     handleLogicalDisplayChanged(displayId, display);
519                     scheduleTraversalLocked(false);
520                 }
521             }
522         }
523     }
524 
525     /**
526      * @see DisplayManagerInternal#getNonOverrideDisplayInfo(int, DisplayInfo)
527      */
getNonOverrideDisplayInfoInternal(int displayId, DisplayInfo outInfo)528     private void getNonOverrideDisplayInfoInternal(int displayId, DisplayInfo outInfo) {
529         synchronized (mSyncRoot) {
530             final LogicalDisplay display = mLogicalDisplays.get(displayId);
531             if (display != null) {
532                 display.getNonOverrideDisplayInfoLocked(outInfo);
533             }
534         }
535     }
536 
537     @VisibleForTesting
performTraversalInternal(SurfaceControl.Transaction t)538     void performTraversalInternal(SurfaceControl.Transaction t) {
539         synchronized (mSyncRoot) {
540             if (!mPendingTraversal) {
541                 return;
542             }
543             mPendingTraversal = false;
544 
545             performTraversalLocked(t);
546         }
547 
548         // List is self-synchronized copy-on-write.
549         for (DisplayTransactionListener listener : mDisplayTransactionListeners) {
550             listener.onDisplayTransaction(t);
551         }
552     }
553 
requestGlobalDisplayStateInternal(int state, float brightnessState)554     private void requestGlobalDisplayStateInternal(int state, float brightnessState) {
555         if (state == Display.STATE_UNKNOWN) {
556             state = Display.STATE_ON;
557         }
558         if (state == Display.STATE_OFF) {
559             brightnessState = PowerManager.BRIGHTNESS_OFF_FLOAT;
560         } else if (brightnessState != PowerManager.BRIGHTNESS_OFF_FLOAT
561                 && brightnessState < PowerManager.BRIGHTNESS_MIN) {
562             brightnessState = PowerManager.BRIGHTNESS_INVALID_FLOAT;
563         } else if (brightnessState > PowerManager.BRIGHTNESS_MAX) {
564             brightnessState = PowerManager.BRIGHTNESS_MAX;
565         }
566 
567         synchronized (mTempDisplayStateWorkQueue) {
568             try {
569                 // Update the display state within the lock.
570                 // Note that we do not need to schedule traversals here although it
571                 // may happen as a side-effect of displays changing state.
572                 synchronized (mSyncRoot) {
573                     if (mGlobalDisplayState == state
574                             && mGlobalDisplayBrightness == brightnessState) {
575                         return; // no change
576                     }
577 
578                     Trace.traceBegin(Trace.TRACE_TAG_POWER, "requestGlobalDisplayState("
579                             + Display.stateToString(state)
580                             + ", brightness=" + brightnessState + ")");
581                     mGlobalDisplayState = state;
582                     mGlobalDisplayBrightness = brightnessState;
583                     applyGlobalDisplayStateLocked(mTempDisplayStateWorkQueue);
584                 }
585 
586                 // Setting the display power state can take hundreds of milliseconds
587                 // to complete so we defer the most expensive part of the work until
588                 // after we have exited the critical section to avoid blocking other
589                 // threads for a long time.
590                 for (int i = 0; i < mTempDisplayStateWorkQueue.size(); i++) {
591                     mTempDisplayStateWorkQueue.get(i).run();
592                 }
593                 Trace.traceEnd(Trace.TRACE_TAG_POWER);
594             } finally {
595                 mTempDisplayStateWorkQueue.clear();
596             }
597         }
598     }
599 
600     private class SettingsObserver extends ContentObserver {
SettingsObserver()601         SettingsObserver() {
602             super(mHandler);
603 
604             mContext.getContentResolver().registerContentObserver(
605                     Settings.Secure.getUriFor(
606                         Settings.Secure.MINIMAL_POST_PROCESSING_ALLOWED), false, this);
607         }
608 
609         @Override
onChange(boolean selfChange, Uri uri)610         public void onChange(boolean selfChange, Uri uri) {
611             handleSettingsChange();
612         }
613     }
614 
handleSettingsChange()615     private void handleSettingsChange() {
616         synchronized (mSyncRoot) {
617             updateSettingsLocked();
618             scheduleTraversalLocked(false);
619         }
620     }
621 
updateSettingsLocked()622     private void updateSettingsLocked() {
623         mMinimalPostProcessingAllowed = Settings.Secure.getIntForUser(mContext.getContentResolver(),
624                 Settings.Secure.MINIMAL_POST_PROCESSING_ALLOWED, 1, UserHandle.USER_CURRENT) != 0;
625     }
626 
getDisplayInfoInternal(int displayId, int callingUid)627     private DisplayInfo getDisplayInfoInternal(int displayId, int callingUid) {
628         synchronized (mSyncRoot) {
629             LogicalDisplay display = mLogicalDisplays.get(displayId);
630             if (display != null) {
631                 DisplayInfo info = display.getDisplayInfoLocked();
632                 if (info.hasAccess(callingUid)
633                         || isUidPresentOnDisplayInternal(callingUid, displayId)) {
634                     return info;
635                 }
636             }
637             return null;
638         }
639     }
640 
getDisplayIdsInternal(int callingUid)641     private int[] getDisplayIdsInternal(int callingUid) {
642         synchronized (mSyncRoot) {
643             final int count = mLogicalDisplays.size();
644             int[] displayIds = new int[count];
645             int n = 0;
646             for (int i = 0; i < count; i++) {
647                 LogicalDisplay display = mLogicalDisplays.valueAt(i);
648                 DisplayInfo info = display.getDisplayInfoLocked();
649                 if (info.hasAccess(callingUid)) {
650                     displayIds[n++] = mLogicalDisplays.keyAt(i);
651                 }
652             }
653             if (n != count) {
654                 displayIds = Arrays.copyOfRange(displayIds, 0, n);
655             }
656             return displayIds;
657         }
658     }
659 
registerCallbackInternal(IDisplayManagerCallback callback, int callingPid)660     private void registerCallbackInternal(IDisplayManagerCallback callback, int callingPid) {
661         synchronized (mSyncRoot) {
662             if (mCallbacks.get(callingPid) != null) {
663                 throw new SecurityException("The calling process has already "
664                         + "registered an IDisplayManagerCallback.");
665             }
666 
667             CallbackRecord record = new CallbackRecord(callingPid, callback);
668             try {
669                 IBinder binder = callback.asBinder();
670                 binder.linkToDeath(record, 0);
671             } catch (RemoteException ex) {
672                 // give up
673                 throw new RuntimeException(ex);
674             }
675 
676             mCallbacks.put(callingPid, record);
677         }
678     }
679 
onCallbackDied(CallbackRecord record)680     private void onCallbackDied(CallbackRecord record) {
681         synchronized (mSyncRoot) {
682             mCallbacks.remove(record.mPid);
683             stopWifiDisplayScanLocked(record);
684         }
685     }
686 
startWifiDisplayScanInternal(int callingPid)687     private void startWifiDisplayScanInternal(int callingPid) {
688         synchronized (mSyncRoot) {
689             CallbackRecord record = mCallbacks.get(callingPid);
690             if (record == null) {
691                 throw new IllegalStateException("The calling process has not "
692                         + "registered an IDisplayManagerCallback.");
693             }
694             startWifiDisplayScanLocked(record);
695         }
696     }
697 
startWifiDisplayScanLocked(CallbackRecord record)698     private void startWifiDisplayScanLocked(CallbackRecord record) {
699         if (!record.mWifiDisplayScanRequested) {
700             record.mWifiDisplayScanRequested = true;
701             if (mWifiDisplayScanRequestCount++ == 0) {
702                 if (mWifiDisplayAdapter != null) {
703                     mWifiDisplayAdapter.requestStartScanLocked();
704                 }
705             }
706         }
707     }
708 
stopWifiDisplayScanInternal(int callingPid)709     private void stopWifiDisplayScanInternal(int callingPid) {
710         synchronized (mSyncRoot) {
711             CallbackRecord record = mCallbacks.get(callingPid);
712             if (record == null) {
713                 throw new IllegalStateException("The calling process has not "
714                         + "registered an IDisplayManagerCallback.");
715             }
716             stopWifiDisplayScanLocked(record);
717         }
718     }
719 
stopWifiDisplayScanLocked(CallbackRecord record)720     private void stopWifiDisplayScanLocked(CallbackRecord record) {
721         if (record.mWifiDisplayScanRequested) {
722             record.mWifiDisplayScanRequested = false;
723             if (--mWifiDisplayScanRequestCount == 0) {
724                 if (mWifiDisplayAdapter != null) {
725                     mWifiDisplayAdapter.requestStopScanLocked();
726                 }
727             } else if (mWifiDisplayScanRequestCount < 0) {
728                 Slog.wtf(TAG, "mWifiDisplayScanRequestCount became negative: "
729                         + mWifiDisplayScanRequestCount);
730                 mWifiDisplayScanRequestCount = 0;
731             }
732         }
733     }
734 
connectWifiDisplayInternal(String address)735     private void connectWifiDisplayInternal(String address) {
736         synchronized (mSyncRoot) {
737             if (mWifiDisplayAdapter != null) {
738                 mWifiDisplayAdapter.requestConnectLocked(address);
739             }
740         }
741     }
742 
pauseWifiDisplayInternal()743     private void pauseWifiDisplayInternal() {
744         synchronized (mSyncRoot) {
745             if (mWifiDisplayAdapter != null) {
746                 mWifiDisplayAdapter.requestPauseLocked();
747             }
748         }
749     }
750 
resumeWifiDisplayInternal()751     private void resumeWifiDisplayInternal() {
752         synchronized (mSyncRoot) {
753             if (mWifiDisplayAdapter != null) {
754                 mWifiDisplayAdapter.requestResumeLocked();
755             }
756         }
757     }
758 
disconnectWifiDisplayInternal()759     private void disconnectWifiDisplayInternal() {
760         synchronized (mSyncRoot) {
761             if (mWifiDisplayAdapter != null) {
762                 mWifiDisplayAdapter.requestDisconnectLocked();
763             }
764         }
765     }
766 
renameWifiDisplayInternal(String address, String alias)767     private void renameWifiDisplayInternal(String address, String alias) {
768         synchronized (mSyncRoot) {
769             if (mWifiDisplayAdapter != null) {
770                 mWifiDisplayAdapter.requestRenameLocked(address, alias);
771             }
772         }
773     }
774 
forgetWifiDisplayInternal(String address)775     private void forgetWifiDisplayInternal(String address) {
776         synchronized (mSyncRoot) {
777             if (mWifiDisplayAdapter != null) {
778                 mWifiDisplayAdapter.requestForgetLocked(address);
779             }
780         }
781     }
782 
getWifiDisplayStatusInternal()783     private WifiDisplayStatus getWifiDisplayStatusInternal() {
784         synchronized (mSyncRoot) {
785             if (mWifiDisplayAdapter != null) {
786                 return mWifiDisplayAdapter.getWifiDisplayStatusLocked();
787             }
788             return new WifiDisplayStatus();
789         }
790     }
791 
requestColorModeInternal(int displayId, int colorMode)792     private void requestColorModeInternal(int displayId, int colorMode) {
793         synchronized (mSyncRoot) {
794             LogicalDisplay display = mLogicalDisplays.get(displayId);
795             if (display != null &&
796                     display.getRequestedColorModeLocked() != colorMode) {
797                 display.setRequestedColorModeLocked(colorMode);
798                 scheduleTraversalLocked(false);
799             }
800         }
801     }
802 
createVirtualDisplayInternal(IVirtualDisplayCallback callback, IMediaProjection projection, int callingUid, String packageName, Surface surface, int flags, VirtualDisplayConfig virtualDisplayConfig)803     private int createVirtualDisplayInternal(IVirtualDisplayCallback callback,
804             IMediaProjection projection, int callingUid, String packageName, Surface surface,
805             int flags, VirtualDisplayConfig virtualDisplayConfig) {
806         synchronized (mSyncRoot) {
807             if (mVirtualDisplayAdapter == null) {
808                 Slog.w(TAG, "Rejecting request to create private virtual display "
809                         + "because the virtual display adapter is not available.");
810                 return -1;
811             }
812 
813             DisplayDevice device = mVirtualDisplayAdapter.createVirtualDisplayLocked(
814                     callback, projection, callingUid, packageName, surface, flags,
815                     virtualDisplayConfig);
816             if (device == null) {
817                 return -1;
818             }
819 
820             handleDisplayDeviceAddedLocked(device);
821             LogicalDisplay display = findLogicalDisplayForDeviceLocked(device);
822             if (display != null) {
823                 return display.getDisplayIdLocked();
824             }
825 
826             // Something weird happened and the logical display was not created.
827             Slog.w(TAG, "Rejecting request to create virtual display "
828                     + "because the logical display was not created.");
829             mVirtualDisplayAdapter.releaseVirtualDisplayLocked(callback.asBinder());
830             handleDisplayDeviceRemovedLocked(device);
831         }
832         return -1;
833     }
834 
resizeVirtualDisplayInternal(IBinder appToken, int width, int height, int densityDpi)835     private void resizeVirtualDisplayInternal(IBinder appToken,
836             int width, int height, int densityDpi) {
837         synchronized (mSyncRoot) {
838             if (mVirtualDisplayAdapter == null) {
839                 return;
840             }
841 
842             mVirtualDisplayAdapter.resizeVirtualDisplayLocked(appToken, width, height, densityDpi);
843         }
844     }
845 
setVirtualDisplaySurfaceInternal(IBinder appToken, Surface surface)846     private void setVirtualDisplaySurfaceInternal(IBinder appToken, Surface surface) {
847         synchronized (mSyncRoot) {
848             if (mVirtualDisplayAdapter == null) {
849                 return;
850             }
851 
852             mVirtualDisplayAdapter.setVirtualDisplaySurfaceLocked(appToken, surface);
853         }
854     }
855 
releaseVirtualDisplayInternal(IBinder appToken)856     private void releaseVirtualDisplayInternal(IBinder appToken) {
857         synchronized (mSyncRoot) {
858             if (mVirtualDisplayAdapter == null) {
859                 return;
860             }
861 
862             DisplayDevice device =
863                     mVirtualDisplayAdapter.releaseVirtualDisplayLocked(appToken);
864             if (device != null) {
865                 handleDisplayDeviceRemovedLocked(device);
866             }
867         }
868     }
869 
setVirtualDisplayStateInternal(IBinder appToken, boolean isOn)870     private void setVirtualDisplayStateInternal(IBinder appToken, boolean isOn) {
871         synchronized (mSyncRoot) {
872             if (mVirtualDisplayAdapter == null) {
873                 return;
874             }
875 
876             mVirtualDisplayAdapter.setVirtualDisplayStateLocked(appToken, isOn);
877         }
878     }
879 
registerDefaultDisplayAdapters()880     private void registerDefaultDisplayAdapters() {
881         // Register default display adapters.
882         synchronized (mSyncRoot) {
883             // main display adapter
884             registerDisplayAdapterLocked(new LocalDisplayAdapter(
885                     mSyncRoot, mContext, mHandler, mDisplayAdapterListener));
886 
887             // Standalone VR devices rely on a virtual display as their primary display for
888             // 2D UI. We register virtual display adapter along side the main display adapter
889             // here so that it is ready by the time the system sends the home Intent for
890             // early apps like SetupWizard/Launcher. In particular, SUW is displayed using
891             // the virtual display inside VR before any VR-specific apps even run.
892             mVirtualDisplayAdapter = mInjector.getVirtualDisplayAdapter(mSyncRoot, mContext,
893                     mHandler, mDisplayAdapterListener);
894             if (mVirtualDisplayAdapter != null) {
895                 registerDisplayAdapterLocked(mVirtualDisplayAdapter);
896             }
897         }
898     }
899 
registerAdditionalDisplayAdapters()900     private void registerAdditionalDisplayAdapters() {
901         synchronized (mSyncRoot) {
902             if (shouldRegisterNonEssentialDisplayAdaptersLocked()) {
903                 registerOverlayDisplayAdapterLocked();
904                 registerWifiDisplayAdapterLocked();
905             }
906         }
907     }
908 
registerOverlayDisplayAdapterLocked()909     private void registerOverlayDisplayAdapterLocked() {
910         registerDisplayAdapterLocked(new OverlayDisplayAdapter(
911                 mSyncRoot, mContext, mHandler, mDisplayAdapterListener, mUiHandler));
912     }
913 
registerWifiDisplayAdapterLocked()914     private void registerWifiDisplayAdapterLocked() {
915         if (mContext.getResources().getBoolean(
916                 com.android.internal.R.bool.config_enableWifiDisplay)
917                 || SystemProperties.getInt(FORCE_WIFI_DISPLAY_ENABLE, -1) == 1) {
918             mWifiDisplayAdapter = new WifiDisplayAdapter(
919                     mSyncRoot, mContext, mHandler, mDisplayAdapterListener,
920                     mPersistentDataStore);
921             registerDisplayAdapterLocked(mWifiDisplayAdapter);
922         }
923     }
924 
shouldRegisterNonEssentialDisplayAdaptersLocked()925     private boolean shouldRegisterNonEssentialDisplayAdaptersLocked() {
926         // In safe mode, we disable non-essential display adapters to give the user
927         // an opportunity to fix broken settings or other problems that might affect
928         // system stability.
929         // In only-core mode, we disable non-essential display adapters to minimize
930         // the number of dependencies that are started while in this mode and to
931         // prevent problems that might occur due to the device being encrypted.
932         return !mSafeMode && !mOnlyCore;
933     }
934 
registerDisplayAdapterLocked(DisplayAdapter adapter)935     private void registerDisplayAdapterLocked(DisplayAdapter adapter) {
936         mDisplayAdapters.add(adapter);
937         adapter.registerLocked();
938     }
939 
handleDisplayDeviceAdded(DisplayDevice device)940     private void handleDisplayDeviceAdded(DisplayDevice device) {
941         synchronized (mSyncRoot) {
942             handleDisplayDeviceAddedLocked(device);
943         }
944     }
945 
handleDisplayDeviceAddedLocked(DisplayDevice device)946     private void handleDisplayDeviceAddedLocked(DisplayDevice device) {
947         DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
948         if (mDisplayDevices.contains(device)) {
949             Slog.w(TAG, "Attempted to add already added display device: " + info);
950             return;
951         }
952 
953         Slog.i(TAG, "Display device added: " + info);
954         device.mDebugLastLoggedDeviceInfo = info;
955 
956         mDisplayDevices.add(device);
957         LogicalDisplay display = addLogicalDisplayLocked(device);
958         Runnable work = updateDisplayStateLocked(device);
959         if (work != null) {
960             work.run();
961         }
962         scheduleTraversalLocked(false);
963     }
964 
handleDisplayDeviceChanged(DisplayDevice device)965     private void handleDisplayDeviceChanged(DisplayDevice device) {
966         synchronized (mSyncRoot) {
967             DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
968             if (!mDisplayDevices.contains(device)) {
969                 Slog.w(TAG, "Attempted to change non-existent display device: " + info);
970                 return;
971             }
972 
973             int diff = device.mDebugLastLoggedDeviceInfo.diff(info);
974             if (diff == DisplayDeviceInfo.DIFF_STATE) {
975                 Slog.i(TAG, "Display device changed state: \"" + info.name
976                         + "\", " + Display.stateToString(info.state));
977                 final Optional<Integer> viewportType = getViewportType(info);
978                 if (viewportType.isPresent()) {
979                     for (DisplayViewport d : mViewports) {
980                         if (d.type == viewportType.get() && info.uniqueId.equals(d.uniqueId)) {
981                             // Update display view port power state
982                             d.isActive = Display.isActiveState(info.state);
983                         }
984                     }
985                     if (mInputManagerInternal != null) {
986                         mHandler.sendEmptyMessage(MSG_UPDATE_VIEWPORT);
987                     }
988                 }
989             } else if (diff != 0) {
990                 Slog.i(TAG, "Display device changed: " + info);
991             }
992             if ((diff & DisplayDeviceInfo.DIFF_COLOR_MODE) != 0) {
993                 try {
994                     mPersistentDataStore.setColorMode(device, info.colorMode);
995                 } finally {
996                     mPersistentDataStore.saveIfNeeded();
997                 }
998             }
999             device.mDebugLastLoggedDeviceInfo = info;
1000 
1001             device.applyPendingDisplayDeviceInfoChangesLocked();
1002             if (updateLogicalDisplaysLocked()) {
1003                 scheduleTraversalLocked(false);
1004             }
1005         }
1006     }
1007 
handleDisplayDeviceRemoved(DisplayDevice device)1008     private void handleDisplayDeviceRemoved(DisplayDevice device) {
1009         synchronized (mSyncRoot) {
1010             handleDisplayDeviceRemovedLocked(device);
1011         }
1012     }
1013 
handleDisplayDeviceRemovedLocked(DisplayDevice device)1014     private void handleDisplayDeviceRemovedLocked(DisplayDevice device) {
1015         DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
1016         if (!mDisplayDevices.remove(device)) {
1017             Slog.w(TAG, "Attempted to remove non-existent display device: " + info);
1018             return;
1019         }
1020 
1021         Slog.i(TAG, "Display device removed: " + info);
1022         device.mDebugLastLoggedDeviceInfo = info;
1023 
1024         updateLogicalDisplaysLocked();
1025         scheduleTraversalLocked(false);
1026     }
1027 
handleLogicalDisplayChanged(int displayId, @NonNull LogicalDisplay display)1028     private void handleLogicalDisplayChanged(int displayId, @NonNull LogicalDisplay display) {
1029         if (displayId == Display.DEFAULT_DISPLAY) {
1030             recordTopInsetLocked(display);
1031         }
1032         // We don't bother invalidating the display info caches here because any changes to the
1033         // display info will trigger a cache invalidation inside of LogicalDisplay before we hit
1034         // this point.
1035         sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_CHANGED);
1036     }
1037 
handleLogicalDisplayRemoved(int displayId)1038     private void handleLogicalDisplayRemoved(int displayId) {
1039         DisplayManagerGlobal.invalidateLocalDisplayInfoCaches();
1040         sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_REMOVED);
1041     }
1042 
applyGlobalDisplayStateLocked(List<Runnable> workQueue)1043     private void applyGlobalDisplayStateLocked(List<Runnable> workQueue) {
1044         final int count = mDisplayDevices.size();
1045         for (int i = 0; i < count; i++) {
1046             DisplayDevice device = mDisplayDevices.get(i);
1047             Runnable runnable = updateDisplayStateLocked(device);
1048             if (runnable != null) {
1049                 workQueue.add(runnable);
1050             }
1051         }
1052     }
1053 
updateDisplayStateLocked(DisplayDevice device)1054     private Runnable updateDisplayStateLocked(DisplayDevice device) {
1055         // Blank or unblank the display immediately to match the state requested
1056         // by the display power controller (if known).
1057         DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
1058         if ((info.flags & DisplayDeviceInfo.FLAG_NEVER_BLANK) == 0) {
1059             return device.requestDisplayStateLocked(
1060                     mGlobalDisplayState, mGlobalDisplayBrightness);
1061         }
1062         return null;
1063     }
1064 
1065     // Adds a new logical display based on the given display device.
1066     // Sends notifications if needed.
addLogicalDisplayLocked(DisplayDevice device)1067     private LogicalDisplay addLogicalDisplayLocked(DisplayDevice device) {
1068         DisplayDeviceInfo deviceInfo = device.getDisplayDeviceInfoLocked();
1069         boolean isDefault = (deviceInfo.flags
1070                 & DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY) != 0;
1071         if (isDefault && mLogicalDisplays.get(Display.DEFAULT_DISPLAY) != null) {
1072             Slog.w(TAG, "Ignoring attempt to add a second default display: " + deviceInfo);
1073             isDefault = false;
1074         }
1075 
1076         if (!isDefault && mSingleDisplayDemoMode) {
1077             Slog.i(TAG, "Not creating a logical display for a secondary display "
1078                     + " because single display demo mode is enabled: " + deviceInfo);
1079             return null;
1080         }
1081 
1082         final int displayId = assignDisplayIdLocked(isDefault);
1083         final int layerStack = assignLayerStackLocked(displayId);
1084 
1085         LogicalDisplay display = new LogicalDisplay(displayId, layerStack, device);
1086         display.updateLocked(mDisplayDevices);
1087         if (!display.isValidLocked()) {
1088             // This should never happen currently.
1089             Slog.w(TAG, "Ignoring display device because the logical display "
1090                     + "created from it was not considered valid: " + deviceInfo);
1091             return null;
1092         }
1093 
1094         configureColorModeLocked(display, device);
1095         if (isDefault) {
1096             recordStableDisplayStatsIfNeededLocked(display);
1097             recordTopInsetLocked(display);
1098         }
1099 
1100         mLogicalDisplays.put(displayId, display);
1101         DisplayManagerGlobal.invalidateLocalDisplayInfoCaches();
1102 
1103         // Wake up waitForDefaultDisplay.
1104         if (isDefault) {
1105             mSyncRoot.notifyAll();
1106         }
1107 
1108         sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_ADDED);
1109         return display;
1110     }
1111 
assignDisplayIdLocked(boolean isDefault)1112     private int assignDisplayIdLocked(boolean isDefault) {
1113         return isDefault ? Display.DEFAULT_DISPLAY : mNextNonDefaultDisplayId++;
1114     }
1115 
assignLayerStackLocked(int displayId)1116     private int assignLayerStackLocked(int displayId) {
1117         // Currently layer stacks and display ids are the same.
1118         // This need not be the case.
1119         return displayId;
1120     }
1121 
configureColorModeLocked(LogicalDisplay display, DisplayDevice device)1122     private void configureColorModeLocked(LogicalDisplay display, DisplayDevice device) {
1123         if (display.getPrimaryDisplayDeviceLocked() == device) {
1124             int colorMode = mPersistentDataStore.getColorMode(device);
1125             if (colorMode == Display.COLOR_MODE_INVALID) {
1126                 if ((device.getDisplayDeviceInfoLocked().flags
1127                      & DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY) != 0) {
1128                     colorMode = mDefaultDisplayDefaultColorMode;
1129                 } else {
1130                     colorMode = Display.COLOR_MODE_DEFAULT;
1131                 }
1132             }
1133             display.setRequestedColorModeLocked(colorMode);
1134         }
1135     }
1136 
1137     // If we've never recorded stable device stats for this device before and they aren't
1138     // explicitly configured, go ahead and record the stable device stats now based on the status
1139     // of the default display at first boot.
recordStableDisplayStatsIfNeededLocked(LogicalDisplay d)1140     private void recordStableDisplayStatsIfNeededLocked(LogicalDisplay d) {
1141         if (mStableDisplaySize.x <= 0 && mStableDisplaySize.y <= 0) {
1142             DisplayInfo info = d.getDisplayInfoLocked();
1143             setStableDisplaySizeLocked(info.getNaturalWidth(), info.getNaturalHeight());
1144         }
1145     }
1146 
recordTopInsetLocked(@ullable LogicalDisplay d)1147     private void recordTopInsetLocked(@Nullable LogicalDisplay d) {
1148         // We must only persist the inset after boot has completed, otherwise we will end up
1149         // overwriting the persisted value before the masking flag has been loaded from the
1150         // resource overlay.
1151         if (!mSystemReady || d == null) {
1152             return;
1153         }
1154         int topInset = d.getInsets().top;
1155         if (topInset == mDefaultDisplayTopInset) {
1156             return;
1157         }
1158         mDefaultDisplayTopInset = topInset;
1159         SystemProperties.set(PROP_DEFAULT_DISPLAY_TOP_INSET, Integer.toString(topInset));
1160     }
1161 
setStableDisplaySizeLocked(int width, int height)1162     private void setStableDisplaySizeLocked(int width, int height) {
1163         mStableDisplaySize = new Point(width, height);
1164         try {
1165             mPersistentDataStore.setStableDisplaySize(mStableDisplaySize);
1166         } finally {
1167             mPersistentDataStore.saveIfNeeded();
1168         }
1169     }
1170 
1171     @VisibleForTesting
getMinimumBrightnessCurveInternal()1172     Curve getMinimumBrightnessCurveInternal() {
1173         return mMinimumBrightnessCurve;
1174     }
1175 
getPreferredWideGamutColorSpaceIdInternal()1176     int getPreferredWideGamutColorSpaceIdInternal() {
1177         return mWideColorSpace.getId();
1178     }
1179 
setBrightnessConfigurationForUserInternal( @ullable BrightnessConfiguration c, @UserIdInt int userId, @Nullable String packageName)1180     private void setBrightnessConfigurationForUserInternal(
1181             @Nullable BrightnessConfiguration c, @UserIdInt int userId,
1182             @Nullable String packageName) {
1183         validateBrightnessConfiguration(c);
1184         final int userSerial = getUserManager().getUserSerialNumber(userId);
1185         synchronized (mSyncRoot) {
1186             try {
1187                 mPersistentDataStore.setBrightnessConfigurationForUser(c, userSerial,
1188                         packageName);
1189             } finally {
1190                 mPersistentDataStore.saveIfNeeded();
1191             }
1192             if (userId == mCurrentUserId) {
1193                 mDisplayPowerController.setBrightnessConfiguration(c);
1194             }
1195         }
1196     }
1197 
1198     @VisibleForTesting
validateBrightnessConfiguration(BrightnessConfiguration config)1199     void validateBrightnessConfiguration(BrightnessConfiguration config) {
1200         if (config == null) {
1201             return;
1202         }
1203         if (isBrightnessConfigurationTooDark(config)) {
1204             throw new IllegalArgumentException("brightness curve is too dark");
1205         }
1206     }
1207 
isBrightnessConfigurationTooDark(BrightnessConfiguration config)1208     private boolean isBrightnessConfigurationTooDark(BrightnessConfiguration config) {
1209         Pair<float[], float[]> curve = config.getCurve();
1210         float[] lux = curve.first;
1211         float[] nits = curve.second;
1212         for (int i = 0; i < lux.length; i++) {
1213             if (nits[i] < mMinimumBrightnessSpline.interpolate(lux[i])) {
1214                 return true;
1215             }
1216         }
1217         return false;
1218     }
1219 
loadBrightnessConfiguration()1220     private void loadBrightnessConfiguration() {
1221         synchronized (mSyncRoot) {
1222             final int userSerial = getUserManager().getUserSerialNumber(mCurrentUserId);
1223             BrightnessConfiguration config =
1224                     mPersistentDataStore.getBrightnessConfiguration(userSerial);
1225             mDisplayPowerController.setBrightnessConfiguration(config);
1226         }
1227     }
1228 
1229     // Updates all existing logical displays given the current set of display devices.
1230     // Removes invalid logical displays.
1231     // Sends notifications if needed.
updateLogicalDisplaysLocked()1232     private boolean updateLogicalDisplaysLocked() {
1233         boolean changed = false;
1234         for (int i = mLogicalDisplays.size(); i-- > 0; ) {
1235             final int displayId = mLogicalDisplays.keyAt(i);
1236             LogicalDisplay display = mLogicalDisplays.valueAt(i);
1237 
1238             mTempDisplayInfo.copyFrom(display.getDisplayInfoLocked());
1239             display.updateLocked(mDisplayDevices);
1240             if (!display.isValidLocked()) {
1241                 mLogicalDisplays.removeAt(i);
1242                 handleLogicalDisplayRemoved(displayId);
1243                 changed = true;
1244             } else if (!mTempDisplayInfo.equals(display.getDisplayInfoLocked())) {
1245                 handleLogicalDisplayChanged(displayId, display);
1246                 changed = true;
1247             }
1248         }
1249         return changed;
1250     }
1251 
performTraversalLocked(SurfaceControl.Transaction t)1252     private void performTraversalLocked(SurfaceControl.Transaction t) {
1253         // Clear all viewports before configuring displays so that we can keep
1254         // track of which ones we have configured.
1255         clearViewportsLocked();
1256 
1257         // Configure each display device.
1258         final int count = mDisplayDevices.size();
1259         for (int i = 0; i < count; i++) {
1260             DisplayDevice device = mDisplayDevices.get(i);
1261             configureDisplayLocked(t, device);
1262             device.performTraversalLocked(t);
1263         }
1264 
1265         // Tell the input system about these new viewports.
1266         if (mInputManagerInternal != null) {
1267             mHandler.sendEmptyMessage(MSG_UPDATE_VIEWPORT);
1268         }
1269     }
1270 
setDisplayPropertiesInternal(int displayId, boolean hasContent, float requestedRefreshRate, int requestedModeId, boolean preferMinimalPostProcessing, boolean inTraversal)1271     private void setDisplayPropertiesInternal(int displayId, boolean hasContent,
1272             float requestedRefreshRate, int requestedModeId, boolean preferMinimalPostProcessing,
1273             boolean inTraversal) {
1274         synchronized (mSyncRoot) {
1275             LogicalDisplay display = mLogicalDisplays.get(displayId);
1276             if (display == null) {
1277                 return;
1278             }
1279 
1280             boolean shouldScheduleTraversal = false;
1281 
1282             if (display.hasContentLocked() != hasContent) {
1283                 if (DEBUG) {
1284                     Slog.d(TAG, "Display " + displayId + " hasContent flag changed: "
1285                             + "hasContent=" + hasContent + ", inTraversal=" + inTraversal);
1286                 }
1287 
1288                 display.setHasContentLocked(hasContent);
1289                 shouldScheduleTraversal = true;
1290             }
1291             if (requestedModeId == 0 && requestedRefreshRate != 0) {
1292                 // Scan supported modes returned by display.getInfo() to find a mode with the same
1293                 // size as the default display mode but with the specified refresh rate instead.
1294                 requestedModeId = display.getDisplayInfoLocked().findDefaultModeByRefreshRate(
1295                         requestedRefreshRate);
1296             }
1297             mDisplayModeDirector.getAppRequestObserver().setAppRequestedMode(
1298                     displayId, requestedModeId);
1299 
1300             if (display.getDisplayInfoLocked().minimalPostProcessingSupported) {
1301                 boolean mppRequest = mMinimalPostProcessingAllowed && preferMinimalPostProcessing;
1302 
1303                 if (display.getRequestedMinimalPostProcessingLocked() != mppRequest) {
1304                     display.setRequestedMinimalPostProcessingLocked(mppRequest);
1305                     shouldScheduleTraversal = true;
1306                 }
1307             }
1308 
1309             if (shouldScheduleTraversal) {
1310                 scheduleTraversalLocked(inTraversal);
1311             }
1312         }
1313     }
1314 
setDisplayOffsetsInternal(int displayId, int x, int y)1315     private void setDisplayOffsetsInternal(int displayId, int x, int y) {
1316         synchronized (mSyncRoot) {
1317             LogicalDisplay display = mLogicalDisplays.get(displayId);
1318             if (display == null) {
1319                 return;
1320             }
1321             if (display.getDisplayOffsetXLocked() != x
1322                     || display.getDisplayOffsetYLocked() != y) {
1323                 if (DEBUG) {
1324                     Slog.d(TAG, "Display " + displayId + " burn-in offset set to ("
1325                             + x + ", " + y + ")");
1326                 }
1327                 display.setDisplayOffsetsLocked(x, y);
1328                 scheduleTraversalLocked(false);
1329             }
1330         }
1331     }
1332 
setDisplayScalingDisabledInternal(int displayId, boolean disable)1333     private void setDisplayScalingDisabledInternal(int displayId, boolean disable) {
1334         synchronized (mSyncRoot) {
1335             final LogicalDisplay display = mLogicalDisplays.get(displayId);
1336             if (display == null) {
1337                 return;
1338             }
1339             if (display.isDisplayScalingDisabled() != disable) {
1340                 if (DEBUG) {
1341                     Slog.d(TAG, "Display " + displayId + " content scaling disabled = " + disable);
1342                 }
1343                 display.setDisplayScalingDisabledLocked(disable);
1344                 scheduleTraversalLocked(false);
1345             }
1346         }
1347     }
1348 
1349     // Updates the lists of UIDs that are present on displays.
setDisplayAccessUIDsInternal(SparseArray<IntArray> newDisplayAccessUIDs)1350     private void setDisplayAccessUIDsInternal(SparseArray<IntArray> newDisplayAccessUIDs) {
1351         synchronized (mSyncRoot) {
1352             mDisplayAccessUIDs.clear();
1353             for (int i = newDisplayAccessUIDs.size() - 1; i >= 0; i--) {
1354                 mDisplayAccessUIDs.append(newDisplayAccessUIDs.keyAt(i),
1355                         newDisplayAccessUIDs.valueAt(i));
1356             }
1357         }
1358     }
1359 
1360     // Checks if provided UID's content is present on the display and UID has access to it.
isUidPresentOnDisplayInternal(int uid, int displayId)1361     private boolean isUidPresentOnDisplayInternal(int uid, int displayId) {
1362         synchronized (mSyncRoot) {
1363             final IntArray displayUIDs = mDisplayAccessUIDs.get(displayId);
1364             return displayUIDs != null && displayUIDs.indexOf(uid) != -1;
1365         }
1366     }
1367 
1368     @Nullable
getDisplayToken(int displayId)1369     private IBinder getDisplayToken(int displayId) {
1370         synchronized (mSyncRoot) {
1371             final LogicalDisplay display = mLogicalDisplays.get(displayId);
1372             if (display != null) {
1373                 final DisplayDevice device = display.getPrimaryDisplayDeviceLocked();
1374                 if (device != null) {
1375                     return device.getDisplayTokenLocked();
1376                 }
1377             }
1378         }
1379 
1380         return null;
1381     }
1382 
systemScreenshotInternal(int displayId)1383     private SurfaceControl.ScreenshotGraphicBuffer systemScreenshotInternal(int displayId) {
1384         synchronized (mSyncRoot) {
1385             final IBinder token = getDisplayToken(displayId);
1386             if (token == null) {
1387                 return null;
1388             }
1389             final LogicalDisplay logicalDisplay = mLogicalDisplays.get(displayId);
1390             if (logicalDisplay == null) {
1391                 return null;
1392             }
1393 
1394             final DisplayInfo displayInfo = logicalDisplay.getDisplayInfoLocked();
1395             return SurfaceControl.screenshotToBufferWithSecureLayersUnsafe(token, new Rect(),
1396                     displayInfo.getNaturalWidth(), displayInfo.getNaturalHeight(),
1397                     false /* useIdentityTransform */, 0 /* rotation */);
1398         }
1399     }
1400 
userScreenshotInternal(int displayId)1401     private SurfaceControl.ScreenshotGraphicBuffer userScreenshotInternal(int displayId) {
1402         synchronized (mSyncRoot) {
1403             final IBinder token = getDisplayToken(displayId);
1404             if (token == null) {
1405                 return null;
1406             }
1407             final LogicalDisplay logicalDisplay = mLogicalDisplays.get(displayId);
1408             if (logicalDisplay == null) {
1409                 return null;
1410             }
1411 
1412             final DisplayInfo displayInfo = logicalDisplay.getDisplayInfoLocked();
1413             // Takes screenshot based on current device orientation.
1414             final Display display = DisplayManagerGlobal.getInstance()
1415                     .getRealDisplay(displayId);
1416             if (display == null) {
1417                 return null;
1418             }
1419             final Point displaySize = new Point();
1420             display.getRealSize(displaySize);
1421 
1422             int rotation = displayInfo.rotation;
1423             // TODO (b/153382624) : This workaround solution would be removed after
1424             // SurfaceFlinger fixes the inconsistency with rotation direction issue.
1425             if (rotation == ROTATION_90 || rotation == ROTATION_270) {
1426                 rotation = (rotation == ROTATION_90) ? ROTATION_270 : ROTATION_90;
1427             }
1428 
1429             return SurfaceControl.screenshotToBuffer(token, new Rect(), displaySize.x,
1430                     displaySize.y, false /* useIdentityTransform */, rotation /* rotation */);
1431         }
1432     }
1433 
1434     @VisibleForTesting
getDisplayedContentSamplingAttributesInternal( int displayId)1435     DisplayedContentSamplingAttributes getDisplayedContentSamplingAttributesInternal(
1436             int displayId) {
1437         final IBinder token = getDisplayToken(displayId);
1438         if (token == null) {
1439             return null;
1440         }
1441         return SurfaceControl.getDisplayedContentSamplingAttributes(token);
1442     }
1443 
1444     @VisibleForTesting
setDisplayedContentSamplingEnabledInternal( int displayId, boolean enable, int componentMask, int maxFrames)1445     boolean setDisplayedContentSamplingEnabledInternal(
1446             int displayId, boolean enable, int componentMask, int maxFrames) {
1447         final IBinder token = getDisplayToken(displayId);
1448         if (token == null) {
1449             return false;
1450         }
1451         return SurfaceControl.setDisplayedContentSamplingEnabled(
1452                 token, enable, componentMask, maxFrames);
1453     }
1454 
1455     @VisibleForTesting
getDisplayedContentSampleInternal(int displayId, long maxFrames, long timestamp)1456     DisplayedContentSample getDisplayedContentSampleInternal(int displayId,
1457             long maxFrames, long timestamp) {
1458         final IBinder token = getDisplayToken(displayId);
1459         if (token == null) {
1460             return null;
1461         }
1462         return SurfaceControl.getDisplayedContentSample(token, maxFrames, timestamp);
1463     }
1464 
resetBrightnessConfiguration()1465     void resetBrightnessConfiguration() {
1466         setBrightnessConfigurationForUserInternal(null, mContext.getUserId(),
1467                 mContext.getPackageName());
1468     }
1469 
setAutoBrightnessLoggingEnabled(boolean enabled)1470     void setAutoBrightnessLoggingEnabled(boolean enabled) {
1471         if (mDisplayPowerController != null) {
1472             synchronized (mSyncRoot) {
1473                 mDisplayPowerController.setAutoBrightnessLoggingEnabled(enabled);
1474             }
1475         }
1476     }
1477 
setDisplayWhiteBalanceLoggingEnabled(boolean enabled)1478     void setDisplayWhiteBalanceLoggingEnabled(boolean enabled) {
1479         if (mDisplayPowerController != null) {
1480             synchronized (mSyncRoot) {
1481                 mDisplayPowerController.setDisplayWhiteBalanceLoggingEnabled(enabled);
1482             }
1483         }
1484     }
1485 
setAmbientColorTemperatureOverride(float cct)1486     void setAmbientColorTemperatureOverride(float cct) {
1487         if (mDisplayPowerController != null) {
1488             synchronized (mSyncRoot) {
1489                 mDisplayPowerController.setAmbientColorTemperatureOverride(cct);
1490             }
1491         }
1492     }
1493 
onDesiredDisplayModeSpecsChangedInternal()1494     private void onDesiredDisplayModeSpecsChangedInternal() {
1495         boolean changed = false;
1496         synchronized (mSyncRoot) {
1497             final int count = mLogicalDisplays.size();
1498             for (int i = 0; i < count; i++) {
1499                 LogicalDisplay display = mLogicalDisplays.valueAt(i);
1500                 int displayId = mLogicalDisplays.keyAt(i);
1501                 DisplayModeDirector.DesiredDisplayModeSpecs desiredDisplayModeSpecs =
1502                         mDisplayModeDirector.getDesiredDisplayModeSpecs(displayId);
1503                 DisplayModeDirector.DesiredDisplayModeSpecs existingDesiredDisplayModeSpecs =
1504                         display.getDesiredDisplayModeSpecsLocked();
1505                 if (DEBUG) {
1506                     Slog.i(TAG,
1507                             "Comparing display specs: " + desiredDisplayModeSpecs
1508                                     + ", existing: " + existingDesiredDisplayModeSpecs);
1509                 }
1510                 if (!desiredDisplayModeSpecs.equals(existingDesiredDisplayModeSpecs)) {
1511                     display.setDesiredDisplayModeSpecsLocked(desiredDisplayModeSpecs);
1512                     changed = true;
1513                 }
1514             }
1515             if (changed) {
1516                 scheduleTraversalLocked(false);
1517             }
1518         }
1519     }
1520 
clearViewportsLocked()1521     private void clearViewportsLocked() {
1522         mViewports.clear();
1523     }
1524 
getViewportType(DisplayDeviceInfo info)1525     private Optional<Integer> getViewportType(DisplayDeviceInfo info) {
1526         // Get the corresponding viewport type.
1527         if ((info.flags & DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY) != 0) {
1528             return Optional.of(VIEWPORT_INTERNAL);
1529         } else if (info.touch == DisplayDeviceInfo.TOUCH_EXTERNAL) {
1530             return Optional.of(VIEWPORT_EXTERNAL);
1531         } else if (info.touch == DisplayDeviceInfo.TOUCH_VIRTUAL
1532                 && !TextUtils.isEmpty(info.uniqueId)) {
1533             return Optional.of(VIEWPORT_VIRTUAL);
1534         } else {
1535             if (DEBUG) {
1536                 Slog.i(TAG, "Display " + info + " does not support input device matching.");
1537             }
1538         }
1539         return Optional.empty();
1540     }
1541 
configureDisplayLocked(SurfaceControl.Transaction t, DisplayDevice device)1542     private void configureDisplayLocked(SurfaceControl.Transaction t, DisplayDevice device) {
1543         final DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
1544         final boolean ownContent = (info.flags & DisplayDeviceInfo.FLAG_OWN_CONTENT_ONLY) != 0;
1545 
1546         // Find the logical display that the display device is showing.
1547         // Certain displays only ever show their own content.
1548         LogicalDisplay display = findLogicalDisplayForDeviceLocked(device);
1549         if (!ownContent) {
1550             if (display != null && !display.hasContentLocked()) {
1551                 // If the display does not have any content of its own, then
1552                 // automatically mirror the requested logical display contents if possible.
1553                 display = mLogicalDisplays.get(device.getDisplayIdToMirrorLocked());
1554             }
1555             if (display == null) {
1556                 display = mLogicalDisplays.get(Display.DEFAULT_DISPLAY);
1557             }
1558         }
1559 
1560         // Apply the logical display configuration to the display device.
1561         if (display == null) {
1562             // TODO: no logical display for the device, blank it
1563             Slog.w(TAG, "Missing logical display to use for physical display device: "
1564                     + device.getDisplayDeviceInfoLocked());
1565             return;
1566         }
1567         display.configureDisplayLocked(t, device, info.state == Display.STATE_OFF);
1568         final Optional<Integer> viewportType = getViewportType(info);
1569         if (viewportType.isPresent()) {
1570             populateViewportLocked(viewportType.get(), display.getDisplayIdLocked(), device, info);
1571         }
1572     }
1573 
1574     /**
1575      * Get internal or external viewport. Create it if does not currently exist.
1576      * @param viewportType - either INTERNAL or EXTERNAL
1577      * @return the viewport with the requested type
1578      */
getViewportLocked(int viewportType, String uniqueId)1579     private DisplayViewport getViewportLocked(int viewportType, String uniqueId) {
1580         if (viewportType != VIEWPORT_INTERNAL && viewportType != VIEWPORT_EXTERNAL
1581                 && viewportType != VIEWPORT_VIRTUAL) {
1582             Slog.wtf(TAG, "Cannot call getViewportByTypeLocked for type "
1583                     + DisplayViewport.typeToString(viewportType));
1584             return null;
1585         }
1586 
1587         // Only allow a single INTERNAL or EXTERNAL viewport by forcing their uniqueIds
1588         // to be identical (in particular, empty).
1589         // TODO (b/116824030) allow multiple EXTERNAL viewports and remove this function.
1590         if (viewportType != VIEWPORT_VIRTUAL) {
1591             uniqueId = "";
1592         }
1593 
1594         DisplayViewport viewport;
1595         final int count = mViewports.size();
1596         for (int i = 0; i < count; i++) {
1597             viewport = mViewports.get(i);
1598             if (viewport.type == viewportType && uniqueId.equals(viewport.uniqueId)) {
1599                 return viewport;
1600             }
1601         }
1602 
1603         // Creates the viewport if none exists.
1604         viewport = new DisplayViewport();
1605         viewport.type = viewportType;
1606         viewport.uniqueId = uniqueId;
1607         mViewports.add(viewport);
1608         return viewport;
1609     }
1610 
populateViewportLocked(int viewportType, int displayId, DisplayDevice device, DisplayDeviceInfo info)1611     private void populateViewportLocked(int viewportType, int displayId, DisplayDevice device,
1612             DisplayDeviceInfo info) {
1613         final DisplayViewport viewport = getViewportLocked(viewportType, info.uniqueId);
1614         device.populateViewportLocked(viewport);
1615         viewport.valid = true;
1616         viewport.displayId = displayId;
1617         viewport.isActive = Display.isActiveState(info.state);
1618     }
1619 
findLogicalDisplayForDeviceLocked(DisplayDevice device)1620     private LogicalDisplay findLogicalDisplayForDeviceLocked(DisplayDevice device) {
1621         final int count = mLogicalDisplays.size();
1622         for (int i = 0; i < count; i++) {
1623             LogicalDisplay display = mLogicalDisplays.valueAt(i);
1624             if (display.getPrimaryDisplayDeviceLocked() == device) {
1625                 return display;
1626             }
1627         }
1628         return null;
1629     }
1630 
sendDisplayEventLocked(int displayId, int event)1631     private void sendDisplayEventLocked(int displayId, int event) {
1632         Message msg = mHandler.obtainMessage(MSG_DELIVER_DISPLAY_EVENT, displayId, event);
1633         mHandler.sendMessage(msg);
1634     }
1635 
1636     // Requests that performTraversals be called at a
1637     // later time to apply changes to surfaces and displays.
scheduleTraversalLocked(boolean inTraversal)1638     private void scheduleTraversalLocked(boolean inTraversal) {
1639         if (!mPendingTraversal && mWindowManagerInternal != null) {
1640             mPendingTraversal = true;
1641             if (!inTraversal) {
1642                 mHandler.sendEmptyMessage(MSG_REQUEST_TRAVERSAL);
1643             }
1644         }
1645     }
1646 
1647     // Runs on Handler thread.
1648     // Delivers display event notifications to callbacks.
deliverDisplayEvent(int displayId, int event)1649     private void deliverDisplayEvent(int displayId, int event) {
1650         if (DEBUG) {
1651             Slog.d(TAG, "Delivering display event: displayId="
1652                     + displayId + ", event=" + event);
1653         }
1654 
1655         // Grab the lock and copy the callbacks.
1656         final int count;
1657         synchronized (mSyncRoot) {
1658             count = mCallbacks.size();
1659             mTempCallbacks.clear();
1660             for (int i = 0; i < count; i++) {
1661                 mTempCallbacks.add(mCallbacks.valueAt(i));
1662             }
1663         }
1664 
1665         // After releasing the lock, send the notifications out.
1666         for (int i = 0; i < count; i++) {
1667             mTempCallbacks.get(i).notifyDisplayEventAsync(displayId, event);
1668         }
1669         mTempCallbacks.clear();
1670     }
1671 
getProjectionService()1672     private IMediaProjectionManager getProjectionService() {
1673         if (mProjectionService == null) {
1674             IBinder b = ServiceManager.getService(Context.MEDIA_PROJECTION_SERVICE);
1675             mProjectionService = IMediaProjectionManager.Stub.asInterface(b);
1676         }
1677         return mProjectionService;
1678     }
1679 
getUserManager()1680     private UserManager getUserManager() {
1681         return mContext.getSystemService(UserManager.class);
1682     }
1683 
dumpInternal(PrintWriter pw)1684     private void dumpInternal(PrintWriter pw) {
1685         pw.println("DISPLAY MANAGER (dumpsys display)");
1686 
1687         synchronized (mSyncRoot) {
1688             pw.println("  mOnlyCode=" + mOnlyCore);
1689             pw.println("  mSafeMode=" + mSafeMode);
1690             pw.println("  mPendingTraversal=" + mPendingTraversal);
1691             pw.println("  mGlobalDisplayState=" + Display.stateToString(mGlobalDisplayState));
1692             pw.println("  mNextNonDefaultDisplayId=" + mNextNonDefaultDisplayId);
1693             pw.println("  mViewports=" + mViewports);
1694             pw.println("  mDefaultDisplayDefaultColorMode=" + mDefaultDisplayDefaultColorMode);
1695             pw.println("  mSingleDisplayDemoMode=" + mSingleDisplayDemoMode);
1696             pw.println("  mWifiDisplayScanRequestCount=" + mWifiDisplayScanRequestCount);
1697             pw.println("  mStableDisplaySize=" + mStableDisplaySize);
1698             pw.println("  mMinimumBrightnessCurve=" + mMinimumBrightnessCurve);
1699 
1700             IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "    ");
1701             ipw.increaseIndent();
1702 
1703             pw.println();
1704             pw.println("Display Adapters: size=" + mDisplayAdapters.size());
1705             for (DisplayAdapter adapter : mDisplayAdapters) {
1706                 pw.println("  " + adapter.getName());
1707                 adapter.dumpLocked(ipw);
1708             }
1709 
1710             pw.println();
1711             pw.println("Display Devices: size=" + mDisplayDevices.size());
1712             for (DisplayDevice device : mDisplayDevices) {
1713                 pw.println("  " + device.getDisplayDeviceInfoLocked());
1714                 device.dumpLocked(ipw);
1715             }
1716 
1717             final int logicalDisplayCount = mLogicalDisplays.size();
1718             pw.println();
1719             pw.println("Logical Displays: size=" + logicalDisplayCount);
1720             for (int i = 0; i < logicalDisplayCount; i++) {
1721                 int displayId = mLogicalDisplays.keyAt(i);
1722                 LogicalDisplay display = mLogicalDisplays.valueAt(i);
1723                 pw.println("  Display " + displayId + ":");
1724                 display.dumpLocked(ipw);
1725             }
1726 
1727             pw.println();
1728             mDisplayModeDirector.dump(pw);
1729 
1730             final int callbackCount = mCallbacks.size();
1731             pw.println();
1732             pw.println("Callbacks: size=" + callbackCount);
1733             for (int i = 0; i < callbackCount; i++) {
1734                 CallbackRecord callback = mCallbacks.valueAt(i);
1735                 pw.println("  " + i + ": mPid=" + callback.mPid
1736                         + ", mWifiDisplayScanRequested=" + callback.mWifiDisplayScanRequested);
1737             }
1738 
1739             if (mDisplayPowerController != null) {
1740                 mDisplayPowerController.dump(pw);
1741             }
1742 
1743             pw.println();
1744             mPersistentDataStore.dump(pw);
1745         }
1746     }
1747 
getFloatArray(TypedArray array)1748     private static float[] getFloatArray(TypedArray array) {
1749         int length = array.length();
1750         float[] floatArray = new float[length];
1751         for (int i = 0; i < length; i++) {
1752             floatArray[i] = array.getFloat(i, Float.NaN);
1753         }
1754         array.recycle();
1755         return floatArray;
1756     }
1757 
1758     /**
1759      * This is the object that everything in the display manager locks on.
1760      * We make it an inner class within the {@link DisplayManagerService} to so that it is
1761      * clear that the object belongs to the display manager service and that it is
1762      * a unique object with a special purpose.
1763      */
1764     public static final class SyncRoot {
1765     }
1766 
1767     @VisibleForTesting
1768     static class Injector {
getVirtualDisplayAdapter(SyncRoot syncRoot, Context context, Handler handler, DisplayAdapter.Listener displayAdapterListener)1769         VirtualDisplayAdapter getVirtualDisplayAdapter(SyncRoot syncRoot, Context context,
1770                 Handler handler, DisplayAdapter.Listener displayAdapterListener) {
1771             return new VirtualDisplayAdapter(syncRoot, context, handler, displayAdapterListener);
1772         }
1773 
getDefaultDisplayDelayTimeout()1774         long getDefaultDisplayDelayTimeout() {
1775             return WAIT_FOR_DEFAULT_DISPLAY_TIMEOUT;
1776         }
1777     }
1778 
1779     @VisibleForTesting
getDisplayDeviceInfoInternal(int displayId)1780     DisplayDeviceInfo getDisplayDeviceInfoInternal(int displayId) {
1781         synchronized (mSyncRoot) {
1782             LogicalDisplay display = mLogicalDisplays.get(displayId);
1783             if (display != null) {
1784                 DisplayDevice displayDevice = display.getPrimaryDisplayDeviceLocked();
1785                 return displayDevice.getDisplayDeviceInfoLocked();
1786             }
1787             return null;
1788         }
1789     }
1790 
1791     @VisibleForTesting
getDisplayIdToMirrorInternal(int displayId)1792     int getDisplayIdToMirrorInternal(int displayId) {
1793         synchronized (mSyncRoot) {
1794             LogicalDisplay display = mLogicalDisplays.get(displayId);
1795             if (display != null) {
1796                 DisplayDevice displayDevice = display.getPrimaryDisplayDeviceLocked();
1797                 return displayDevice.getDisplayIdToMirrorLocked();
1798             }
1799             return Display.INVALID_DISPLAY;
1800         }
1801     }
1802 
1803     @VisibleForTesting
getVirtualDisplaySurfaceInternal(IBinder appToken)1804     Surface getVirtualDisplaySurfaceInternal(IBinder appToken) {
1805         synchronized (mSyncRoot) {
1806             if (mVirtualDisplayAdapter == null) {
1807                 return null;
1808             }
1809             return mVirtualDisplayAdapter.getVirtualDisplaySurfaceLocked(appToken);
1810         }
1811     }
1812 
1813     private final class DisplayManagerHandler extends Handler {
DisplayManagerHandler(Looper looper)1814         public DisplayManagerHandler(Looper looper) {
1815             super(looper, null, true /*async*/);
1816         }
1817 
1818         @Override
handleMessage(Message msg)1819         public void handleMessage(Message msg) {
1820             switch (msg.what) {
1821                 case MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS:
1822                     registerDefaultDisplayAdapters();
1823                     break;
1824 
1825                 case MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS:
1826                     registerAdditionalDisplayAdapters();
1827                     break;
1828 
1829                 case MSG_DELIVER_DISPLAY_EVENT:
1830                     deliverDisplayEvent(msg.arg1, msg.arg2);
1831                     break;
1832 
1833                 case MSG_REQUEST_TRAVERSAL:
1834                     mWindowManagerInternal.requestTraversalFromDisplayManager();
1835                     break;
1836 
1837                 case MSG_UPDATE_VIEWPORT: {
1838                     final boolean changed;
1839                     synchronized (mSyncRoot) {
1840                         changed = !mTempViewports.equals(mViewports);
1841                         if (changed) {
1842                             mTempViewports.clear();
1843                             for (DisplayViewport d : mViewports) {
1844                                 mTempViewports.add(d.makeCopy());
1845                             }
1846                         }
1847                     }
1848                     if (changed) {
1849                         mInputManagerInternal.setDisplayViewports(mTempViewports);
1850                     }
1851                     break;
1852                 }
1853 
1854                 case MSG_LOAD_BRIGHTNESS_CONFIGURATION:
1855                     loadBrightnessConfiguration();
1856                     break;
1857             }
1858         }
1859     }
1860 
1861     private final class DisplayAdapterListener implements DisplayAdapter.Listener {
1862         @Override
onDisplayDeviceEvent(DisplayDevice device, int event)1863         public void onDisplayDeviceEvent(DisplayDevice device, int event) {
1864             switch (event) {
1865                 case DisplayAdapter.DISPLAY_DEVICE_EVENT_ADDED:
1866                     handleDisplayDeviceAdded(device);
1867                     break;
1868 
1869                 case DisplayAdapter.DISPLAY_DEVICE_EVENT_CHANGED:
1870                     handleDisplayDeviceChanged(device);
1871                     break;
1872 
1873                 case DisplayAdapter.DISPLAY_DEVICE_EVENT_REMOVED:
1874                     handleDisplayDeviceRemoved(device);
1875                     break;
1876             }
1877         }
1878 
1879         @Override
onTraversalRequested()1880         public void onTraversalRequested() {
1881             synchronized (mSyncRoot) {
1882                 scheduleTraversalLocked(false);
1883             }
1884         }
1885     }
1886 
1887     private final class CallbackRecord implements DeathRecipient {
1888         public final int mPid;
1889         private final IDisplayManagerCallback mCallback;
1890 
1891         public boolean mWifiDisplayScanRequested;
1892 
CallbackRecord(int pid, IDisplayManagerCallback callback)1893         public CallbackRecord(int pid, IDisplayManagerCallback callback) {
1894             mPid = pid;
1895             mCallback = callback;
1896         }
1897 
1898         @Override
binderDied()1899         public void binderDied() {
1900             if (DEBUG) {
1901                 Slog.d(TAG, "Display listener for pid " + mPid + " died.");
1902             }
1903             onCallbackDied(this);
1904         }
1905 
notifyDisplayEventAsync(int displayId, int event)1906         public void notifyDisplayEventAsync(int displayId, int event) {
1907             try {
1908                 mCallback.onDisplayEvent(displayId, event);
1909             } catch (RemoteException ex) {
1910                 Slog.w(TAG, "Failed to notify process "
1911                         + mPid + " that displays changed, assuming it died.", ex);
1912                 binderDied();
1913             }
1914         }
1915     }
1916 
1917     @VisibleForTesting
1918     final class BinderService extends IDisplayManager.Stub {
1919         /**
1920          * Returns information about the specified logical display.
1921          *
1922          * @param displayId The logical display id.
1923          * @return The logical display info, return {@code null} if the display does not exist or
1924          * the calling UID isn't present on the display.  The returned object must be treated as
1925          * immutable.
1926          */
1927         @Override // Binder call
getDisplayInfo(int displayId)1928         public DisplayInfo getDisplayInfo(int displayId) {
1929             final int callingUid = Binder.getCallingUid();
1930             final long token = Binder.clearCallingIdentity();
1931             try {
1932                 return getDisplayInfoInternal(displayId, callingUid);
1933             } finally {
1934                 Binder.restoreCallingIdentity(token);
1935             }
1936         }
1937 
1938         /**
1939          * Returns the list of all display ids.
1940          */
1941         @Override // Binder call
getDisplayIds()1942         public int[] getDisplayIds() {
1943             final int callingUid = Binder.getCallingUid();
1944             final long token = Binder.clearCallingIdentity();
1945             try {
1946                 return getDisplayIdsInternal(callingUid);
1947             } finally {
1948                 Binder.restoreCallingIdentity(token);
1949             }
1950         }
1951 
1952         @Override // Binder call
isUidPresentOnDisplay(int uid, int displayId)1953         public boolean isUidPresentOnDisplay(int uid, int displayId) {
1954             final long token = Binder.clearCallingIdentity();
1955             try {
1956                 return isUidPresentOnDisplayInternal(uid, displayId);
1957             } finally {
1958                 Binder.restoreCallingIdentity(token);
1959             }
1960         }
1961 
1962         /**
1963          * Returns the stable device display size, in pixels.
1964          */
1965         @Override // Binder call
getStableDisplaySize()1966         public Point getStableDisplaySize() {
1967             final long token = Binder.clearCallingIdentity();
1968             try {
1969                 return getStableDisplaySizeInternal();
1970             } finally {
1971                 Binder.restoreCallingIdentity(token);
1972             }
1973         }
1974 
1975         @Override // Binder call
registerCallback(IDisplayManagerCallback callback)1976         public void registerCallback(IDisplayManagerCallback callback) {
1977             if (callback == null) {
1978                 throw new IllegalArgumentException("listener must not be null");
1979             }
1980 
1981             final int callingPid = Binder.getCallingPid();
1982             final long token = Binder.clearCallingIdentity();
1983             try {
1984                 registerCallbackInternal(callback, callingPid);
1985             } finally {
1986                 Binder.restoreCallingIdentity(token);
1987             }
1988         }
1989 
1990         @Override // Binder call
startWifiDisplayScan()1991         public void startWifiDisplayScan() {
1992             mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
1993                     "Permission required to start wifi display scans");
1994 
1995             final int callingPid = Binder.getCallingPid();
1996             final long token = Binder.clearCallingIdentity();
1997             try {
1998                 startWifiDisplayScanInternal(callingPid);
1999             } finally {
2000                 Binder.restoreCallingIdentity(token);
2001             }
2002         }
2003 
2004         @Override // Binder call
stopWifiDisplayScan()2005         public void stopWifiDisplayScan() {
2006             mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
2007                     "Permission required to stop wifi display scans");
2008 
2009             final int callingPid = Binder.getCallingPid();
2010             final long token = Binder.clearCallingIdentity();
2011             try {
2012                 stopWifiDisplayScanInternal(callingPid);
2013             } finally {
2014                 Binder.restoreCallingIdentity(token);
2015             }
2016         }
2017 
2018         @Override // Binder call
connectWifiDisplay(String address)2019         public void connectWifiDisplay(String address) {
2020             if (address == null) {
2021                 throw new IllegalArgumentException("address must not be null");
2022             }
2023             mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
2024                     "Permission required to connect to a wifi display");
2025 
2026             final long token = Binder.clearCallingIdentity();
2027             try {
2028                 connectWifiDisplayInternal(address);
2029             } finally {
2030                 Binder.restoreCallingIdentity(token);
2031             }
2032         }
2033 
2034         @Override // Binder call
disconnectWifiDisplay()2035         public void disconnectWifiDisplay() {
2036             // This request does not require special permissions.
2037             // Any app can request disconnection from the currently active wifi display.
2038             // This exception should no longer be needed once wifi display control moves
2039             // to the media router service.
2040 
2041             final long token = Binder.clearCallingIdentity();
2042             try {
2043                 disconnectWifiDisplayInternal();
2044             } finally {
2045                 Binder.restoreCallingIdentity(token);
2046             }
2047         }
2048 
2049         @Override // Binder call
renameWifiDisplay(String address, String alias)2050         public void renameWifiDisplay(String address, String alias) {
2051             if (address == null) {
2052                 throw new IllegalArgumentException("address must not be null");
2053             }
2054             mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
2055                     "Permission required to rename to a wifi display");
2056 
2057             final long token = Binder.clearCallingIdentity();
2058             try {
2059                 renameWifiDisplayInternal(address, alias);
2060             } finally {
2061                 Binder.restoreCallingIdentity(token);
2062             }
2063         }
2064 
2065         @Override // Binder call
forgetWifiDisplay(String address)2066         public void forgetWifiDisplay(String address) {
2067             if (address == null) {
2068                 throw new IllegalArgumentException("address must not be null");
2069             }
2070             mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
2071                     "Permission required to forget to a wifi display");
2072 
2073             final long token = Binder.clearCallingIdentity();
2074             try {
2075                 forgetWifiDisplayInternal(address);
2076             } finally {
2077                 Binder.restoreCallingIdentity(token);
2078             }
2079         }
2080 
2081         @Override // Binder call
pauseWifiDisplay()2082         public void pauseWifiDisplay() {
2083             mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
2084                     "Permission required to pause a wifi display session");
2085 
2086             final long token = Binder.clearCallingIdentity();
2087             try {
2088                 pauseWifiDisplayInternal();
2089             } finally {
2090                 Binder.restoreCallingIdentity(token);
2091             }
2092         }
2093 
2094         @Override // Binder call
resumeWifiDisplay()2095         public void resumeWifiDisplay() {
2096             mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
2097                     "Permission required to resume a wifi display session");
2098 
2099             final long token = Binder.clearCallingIdentity();
2100             try {
2101                 resumeWifiDisplayInternal();
2102             } finally {
2103                 Binder.restoreCallingIdentity(token);
2104             }
2105         }
2106 
2107         @Override // Binder call
getWifiDisplayStatus()2108         public WifiDisplayStatus getWifiDisplayStatus() {
2109             // This request does not require special permissions.
2110             // Any app can get information about available wifi displays.
2111 
2112             final long token = Binder.clearCallingIdentity();
2113             try {
2114                 return getWifiDisplayStatusInternal();
2115             } finally {
2116                 Binder.restoreCallingIdentity(token);
2117             }
2118         }
2119 
2120         @Override // Binder call
requestColorMode(int displayId, int colorMode)2121         public void requestColorMode(int displayId, int colorMode) {
2122             mContext.enforceCallingOrSelfPermission(
2123                     Manifest.permission.CONFIGURE_DISPLAY_COLOR_MODE,
2124                     "Permission required to change the display color mode");
2125             final long token = Binder.clearCallingIdentity();
2126             try {
2127                 requestColorModeInternal(displayId, colorMode);
2128             } finally {
2129                 Binder.restoreCallingIdentity(token);
2130             }
2131         }
2132 
2133         @Override // Binder call
createVirtualDisplay(VirtualDisplayConfig virtualDisplayConfig, IVirtualDisplayCallback callback, IMediaProjection projection, String packageName)2134         public int createVirtualDisplay(VirtualDisplayConfig virtualDisplayConfig,
2135                 IVirtualDisplayCallback callback, IMediaProjection projection, String packageName) {
2136             final int callingUid = Binder.getCallingUid();
2137             if (!validatePackageName(callingUid, packageName)) {
2138                 throw new SecurityException("packageName must match the calling uid");
2139             }
2140             if (callback == null) {
2141                 throw new IllegalArgumentException("appToken must not be null");
2142             }
2143             if (virtualDisplayConfig == null) {
2144                 throw new IllegalArgumentException("virtualDisplayConfig must not be null");
2145             }
2146             final Surface surface = virtualDisplayConfig.getSurface();
2147             int flags = virtualDisplayConfig.getFlags();
2148 
2149             if (surface != null && surface.isSingleBuffered()) {
2150                 throw new IllegalArgumentException("Surface can't be single-buffered");
2151             }
2152 
2153             if ((flags & VIRTUAL_DISPLAY_FLAG_PUBLIC) != 0) {
2154                 flags |= VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR;
2155 
2156                 // Public displays can't be allowed to show content when locked.
2157                 if ((flags & VIRTUAL_DISPLAY_FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD) != 0) {
2158                     throw new IllegalArgumentException(
2159                             "Public display must not be marked as SHOW_WHEN_LOCKED_INSECURE");
2160                 }
2161             }
2162             if ((flags & VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY) != 0) {
2163                 flags &= ~VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR;
2164             }
2165 
2166             if (projection != null) {
2167                 try {
2168                     if (!getProjectionService().isValidMediaProjection(projection)) {
2169                         throw new SecurityException("Invalid media projection");
2170                     }
2171                     flags = projection.applyVirtualDisplayFlags(flags);
2172                 } catch (RemoteException e) {
2173                     throw new SecurityException("unable to validate media projection or flags");
2174                 }
2175             }
2176 
2177             if (callingUid != Process.SYSTEM_UID &&
2178                     (flags & VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR) != 0) {
2179                 if (!canProjectVideo(projection)) {
2180                     throw new SecurityException("Requires CAPTURE_VIDEO_OUTPUT or "
2181                             + "CAPTURE_SECURE_VIDEO_OUTPUT permission, or an appropriate "
2182                             + "MediaProjection token in order to create a screen sharing virtual "
2183                             + "display.");
2184                 }
2185             }
2186             if (callingUid != Process.SYSTEM_UID && (flags & VIRTUAL_DISPLAY_FLAG_SECURE) != 0) {
2187                 if (!canProjectSecureVideo(projection)) {
2188                     throw new SecurityException("Requires CAPTURE_SECURE_VIDEO_OUTPUT "
2189                             + "or an appropriate MediaProjection token to create a "
2190                             + "secure virtual display.");
2191                 }
2192             }
2193 
2194             if (callingUid == Process.SYSTEM_UID
2195                     || checkCallingPermission(ADD_TRUSTED_DISPLAY, "createVirtualDisplay()")) {
2196                 flags |= VIRTUAL_DISPLAY_FLAG_TRUSTED;
2197             } else {
2198                 flags &= ~VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS;
2199             }
2200 
2201             // Sometimes users can have sensitive information in system decoration windows. An app
2202             // could create a virtual display with system decorations support and read the user info
2203             // from the surface.
2204             // We should only allow adding flag VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS
2205             // to trusted virtual displays.
2206             final int trustedDisplayWithSysDecorFlag =
2207                     (VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS
2208                             | VIRTUAL_DISPLAY_FLAG_TRUSTED);
2209             if ((flags & trustedDisplayWithSysDecorFlag)
2210                     == VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS
2211                     && !checkCallingPermission(INTERNAL_SYSTEM_WINDOW, "createVirtualDisplay()")) {
2212                     throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission");
2213             }
2214 
2215             final long token = Binder.clearCallingIdentity();
2216             try {
2217                 return createVirtualDisplayInternal(callback, projection, callingUid, packageName,
2218                         surface, flags, virtualDisplayConfig);
2219             } finally {
2220                 Binder.restoreCallingIdentity(token);
2221             }
2222         }
2223 
2224         @Override // Binder call
resizeVirtualDisplay(IVirtualDisplayCallback callback, int width, int height, int densityDpi)2225         public void resizeVirtualDisplay(IVirtualDisplayCallback callback,
2226                 int width, int height, int densityDpi) {
2227             if (width <= 0 || height <= 0 || densityDpi <= 0) {
2228                 throw new IllegalArgumentException("width, height, and densityDpi must be "
2229                         + "greater than 0");
2230             }
2231             final long token = Binder.clearCallingIdentity();
2232             try {
2233                 resizeVirtualDisplayInternal(callback.asBinder(), width, height, densityDpi);
2234             } finally {
2235                 Binder.restoreCallingIdentity(token);
2236             }
2237         }
2238 
2239         @Override // Binder call
setVirtualDisplaySurface(IVirtualDisplayCallback callback, Surface surface)2240         public void setVirtualDisplaySurface(IVirtualDisplayCallback callback, Surface surface) {
2241             if (surface != null && surface.isSingleBuffered()) {
2242                 throw new IllegalArgumentException("Surface can't be single-buffered");
2243             }
2244             final long token = Binder.clearCallingIdentity();
2245             try {
2246                 setVirtualDisplaySurfaceInternal(callback.asBinder(), surface);
2247             } finally {
2248                 Binder.restoreCallingIdentity(token);
2249             }
2250         }
2251 
2252         @Override // Binder call
releaseVirtualDisplay(IVirtualDisplayCallback callback)2253         public void releaseVirtualDisplay(IVirtualDisplayCallback callback) {
2254             final long token = Binder.clearCallingIdentity();
2255             try {
2256                 releaseVirtualDisplayInternal(callback.asBinder());
2257             } finally {
2258                 Binder.restoreCallingIdentity(token);
2259             }
2260         }
2261 
2262         @Override // Binder call
setVirtualDisplayState(IVirtualDisplayCallback callback, boolean isOn)2263         public void setVirtualDisplayState(IVirtualDisplayCallback callback, boolean isOn) {
2264             final long token = Binder.clearCallingIdentity();
2265             try {
2266                 setVirtualDisplayStateInternal(callback.asBinder(), isOn);
2267             } finally {
2268                 Binder.restoreCallingIdentity(token);
2269             }
2270         }
2271 
2272         @Override // Binder call
dump(FileDescriptor fd, final PrintWriter pw, String[] args)2273         public void dump(FileDescriptor fd, final PrintWriter pw, String[] args) {
2274             if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
2275 
2276             final long token = Binder.clearCallingIdentity();
2277             try {
2278                 dumpInternal(pw);
2279             } finally {
2280                 Binder.restoreCallingIdentity(token);
2281             }
2282         }
2283 
2284         @Override // Binder call
getBrightnessEvents(String callingPackage)2285         public ParceledListSlice<BrightnessChangeEvent> getBrightnessEvents(String callingPackage) {
2286             mContext.enforceCallingOrSelfPermission(
2287                     Manifest.permission.BRIGHTNESS_SLIDER_USAGE,
2288                     "Permission to read brightness events.");
2289 
2290             final int callingUid = Binder.getCallingUid();
2291             AppOpsManager appOpsManager = mContext.getSystemService(AppOpsManager.class);
2292             final int mode = appOpsManager.noteOp(AppOpsManager.OP_GET_USAGE_STATS,
2293                     callingUid, callingPackage);
2294             final boolean hasUsageStats;
2295             if (mode == AppOpsManager.MODE_DEFAULT) {
2296                 // The default behavior here is to check if PackageManager has given the app
2297                 // permission.
2298                 hasUsageStats = mContext.checkCallingPermission(
2299                         Manifest.permission.PACKAGE_USAGE_STATS)
2300                         == PackageManager.PERMISSION_GRANTED;
2301             } else {
2302                 hasUsageStats = mode == AppOpsManager.MODE_ALLOWED;
2303             }
2304 
2305             final int userId = UserHandle.getUserId(callingUid);
2306             final long token = Binder.clearCallingIdentity();
2307             try {
2308                 synchronized (mSyncRoot) {
2309                     return mDisplayPowerController.getBrightnessEvents(userId, hasUsageStats);
2310                 }
2311             } finally {
2312                 Binder.restoreCallingIdentity(token);
2313             }
2314         }
2315 
2316         @Override // Binder call
getAmbientBrightnessStats()2317         public ParceledListSlice<AmbientBrightnessDayStats> getAmbientBrightnessStats() {
2318             mContext.enforceCallingOrSelfPermission(
2319                     Manifest.permission.ACCESS_AMBIENT_LIGHT_STATS,
2320                     "Permission required to to access ambient light stats.");
2321             final int callingUid = Binder.getCallingUid();
2322             final int userId = UserHandle.getUserId(callingUid);
2323             final long token = Binder.clearCallingIdentity();
2324             try {
2325                 synchronized (mSyncRoot) {
2326                     return mDisplayPowerController.getAmbientBrightnessStats(userId);
2327                 }
2328             } finally {
2329                 Binder.restoreCallingIdentity(token);
2330             }
2331         }
2332 
2333         @Override // Binder call
setBrightnessConfigurationForUser( BrightnessConfiguration c, @UserIdInt int userId, String packageName)2334         public void setBrightnessConfigurationForUser(
2335                 BrightnessConfiguration c, @UserIdInt int userId, String packageName) {
2336             mContext.enforceCallingOrSelfPermission(
2337                     Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS,
2338                     "Permission required to change the display's brightness configuration");
2339             if (userId != UserHandle.getCallingUserId()) {
2340                 mContext.enforceCallingOrSelfPermission(
2341                         Manifest.permission.INTERACT_ACROSS_USERS,
2342                         "Permission required to change the display brightness"
2343                         + " configuration of another user");
2344             }
2345             if (packageName != null && !validatePackageName(getCallingUid(), packageName)) {
2346                 packageName = null;
2347             }
2348             final long token = Binder.clearCallingIdentity();
2349             try {
2350                 setBrightnessConfigurationForUserInternal(c, userId, packageName);
2351             } finally {
2352                 Binder.restoreCallingIdentity(token);
2353             }
2354         }
2355 
2356         @Override // Binder call
getBrightnessConfigurationForUser(int userId)2357         public BrightnessConfiguration getBrightnessConfigurationForUser(int userId) {
2358             mContext.enforceCallingOrSelfPermission(
2359                     Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS,
2360                     "Permission required to read the display's brightness configuration");
2361             if (userId != UserHandle.getCallingUserId()) {
2362                 mContext.enforceCallingOrSelfPermission(
2363                         Manifest.permission.INTERACT_ACROSS_USERS,
2364                         "Permission required to read the display brightness"
2365                                 + " configuration of another user");
2366             }
2367             final long token = Binder.clearCallingIdentity();
2368             try {
2369                 final int userSerial = getUserManager().getUserSerialNumber(userId);
2370                 synchronized (mSyncRoot) {
2371                     BrightnessConfiguration config =
2372                             mPersistentDataStore.getBrightnessConfiguration(userSerial);
2373                     if (config == null) {
2374                         config = mDisplayPowerController.getDefaultBrightnessConfiguration();
2375                     }
2376                     return config;
2377                 }
2378             } finally {
2379                 Binder.restoreCallingIdentity(token);
2380             }
2381         }
2382 
2383         @Override // Binder call
getDefaultBrightnessConfiguration()2384         public BrightnessConfiguration getDefaultBrightnessConfiguration() {
2385             mContext.enforceCallingOrSelfPermission(
2386                     Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS,
2387                     "Permission required to read the display's default brightness configuration");
2388             final long token = Binder.clearCallingIdentity();
2389             try {
2390                 synchronized (mSyncRoot) {
2391                     return mDisplayPowerController.getDefaultBrightnessConfiguration();
2392                 }
2393             } finally {
2394                 Binder.restoreCallingIdentity(token);
2395             }
2396         }
2397 
2398         @Override // Binder call
isMinimalPostProcessingRequested(int displayId)2399         public boolean isMinimalPostProcessingRequested(int displayId) {
2400             synchronized (mSyncRoot) {
2401                 return mLogicalDisplays.get(displayId).getRequestedMinimalPostProcessingLocked();
2402             }
2403         }
2404 
2405         @Override // Binder call
setTemporaryBrightness(float brightness)2406         public void setTemporaryBrightness(float brightness) {
2407             mContext.enforceCallingOrSelfPermission(
2408                     Manifest.permission.CONTROL_DISPLAY_BRIGHTNESS,
2409                     "Permission required to set the display's brightness");
2410             final long token = Binder.clearCallingIdentity();
2411             try {
2412                 synchronized (mSyncRoot) {
2413                     mDisplayPowerController.setTemporaryBrightness(brightness);
2414                 }
2415             } finally {
2416                 Binder.restoreCallingIdentity(token);
2417             }
2418         }
2419 
2420         @Override // Binder call
setTemporaryAutoBrightnessAdjustment(float adjustment)2421         public void setTemporaryAutoBrightnessAdjustment(float adjustment) {
2422             mContext.enforceCallingOrSelfPermission(
2423                     Manifest.permission.CONTROL_DISPLAY_BRIGHTNESS,
2424                     "Permission required to set the display's auto brightness adjustment");
2425             final long token = Binder.clearCallingIdentity();
2426             try {
2427                 synchronized (mSyncRoot) {
2428                     mDisplayPowerController.setTemporaryAutoBrightnessAdjustment(adjustment);
2429                 }
2430             } finally {
2431                 Binder.restoreCallingIdentity(token);
2432             }
2433         }
2434 
2435         @Override // Binder call
onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, String[] args, ShellCallback callback, ResultReceiver resultReceiver)2436         public void onShellCommand(FileDescriptor in, FileDescriptor out,
2437                 FileDescriptor err, String[] args, ShellCallback callback,
2438                 ResultReceiver resultReceiver) {
2439             new DisplayManagerShellCommand(DisplayManagerService.this).exec(this, in, out, err,
2440                     args, callback, resultReceiver);
2441         }
2442 
2443         @Override // Binder call
getMinimumBrightnessCurve()2444         public Curve getMinimumBrightnessCurve() {
2445             final long token = Binder.clearCallingIdentity();
2446             try {
2447                 return getMinimumBrightnessCurveInternal();
2448             } finally {
2449                 Binder.restoreCallingIdentity(token);
2450             }
2451         }
2452 
2453         @Override // Binder call
getPreferredWideGamutColorSpaceId()2454         public int getPreferredWideGamutColorSpaceId() {
2455             final long token = Binder.clearCallingIdentity();
2456             try {
2457                 return getPreferredWideGamutColorSpaceIdInternal();
2458             } finally {
2459                 Binder.restoreCallingIdentity(token);
2460             }
2461         }
2462 
validatePackageName(int uid, String packageName)2463         private boolean validatePackageName(int uid, String packageName) {
2464             if (packageName != null) {
2465                 String[] packageNames = mContext.getPackageManager().getPackagesForUid(uid);
2466                 if (packageNames != null) {
2467                     for (String n : packageNames) {
2468                         if (n.equals(packageName)) {
2469                             return true;
2470                         }
2471                     }
2472                 }
2473             }
2474             return false;
2475         }
2476 
canProjectVideo(IMediaProjection projection)2477         private boolean canProjectVideo(IMediaProjection projection) {
2478             if (projection != null) {
2479                 try {
2480                     if (projection.canProjectVideo()) {
2481                         return true;
2482                     }
2483                 } catch (RemoteException e) {
2484                     Slog.e(TAG, "Unable to query projection service for permissions", e);
2485                 }
2486             }
2487             if (checkCallingPermission(CAPTURE_VIDEO_OUTPUT, "canProjectVideo()")) {
2488                 return true;
2489             }
2490             return canProjectSecureVideo(projection);
2491         }
2492 
canProjectSecureVideo(IMediaProjection projection)2493         private boolean canProjectSecureVideo(IMediaProjection projection) {
2494             if (projection != null) {
2495                 try {
2496                     if (projection.canProjectSecureVideo()){
2497                         return true;
2498                     }
2499                 } catch (RemoteException e) {
2500                     Slog.e(TAG, "Unable to query projection service for permissions", e);
2501                 }
2502             }
2503             return checkCallingPermission(CAPTURE_SECURE_VIDEO_OUTPUT, "canProjectSecureVideo()");
2504         }
2505 
checkCallingPermission(String permission, String func)2506         private boolean checkCallingPermission(String permission, String func) {
2507             if (mContext.checkCallingPermission(permission) == PackageManager.PERMISSION_GRANTED) {
2508                 return true;
2509             }
2510             final String msg = "Permission Denial: " + func + " from pid=" + Binder.getCallingPid()
2511                     + ", uid=" + Binder.getCallingUid() + " requires " + permission;
2512             Slog.w(TAG, msg);
2513             return false;
2514         }
2515     }
2516 
2517     private final class LocalService extends DisplayManagerInternal {
2518 
2519         @Override
initPowerManagement(final DisplayPowerCallbacks callbacks, Handler handler, SensorManager sensorManager)2520         public void initPowerManagement(final DisplayPowerCallbacks callbacks, Handler handler,
2521                 SensorManager sensorManager) {
2522             synchronized (mSyncRoot) {
2523                 DisplayBlanker blanker = new DisplayBlanker() {
2524                     @Override
2525                     public void requestDisplayState(int state, float brightness) {
2526                         // The order of operations is important for legacy reasons.
2527                         if (state == Display.STATE_OFF) {
2528                             requestGlobalDisplayStateInternal(state, brightness);
2529                         }
2530 
2531                         callbacks.onDisplayStateChange(state);
2532 
2533                         if (state != Display.STATE_OFF) {
2534                             requestGlobalDisplayStateInternal(state, brightness);
2535                         }
2536                     }
2537                 };
2538                 mDisplayPowerController = new DisplayPowerController(
2539                         mContext, callbacks, handler, sensorManager, blanker,
2540                         mDisplayDevices.get(Display.DEFAULT_DISPLAY));
2541                 mSensorManager = sensorManager;
2542             }
2543 
2544             mHandler.sendEmptyMessage(MSG_LOAD_BRIGHTNESS_CONFIGURATION);
2545         }
2546 
2547         @Override
requestPowerState(DisplayPowerRequest request, boolean waitForNegativeProximity)2548         public boolean requestPowerState(DisplayPowerRequest request,
2549                 boolean waitForNegativeProximity) {
2550             synchronized (mSyncRoot) {
2551                 return mDisplayPowerController.requestPowerState(request,
2552                         waitForNegativeProximity);
2553             }
2554         }
2555 
2556         @Override
isProximitySensorAvailable()2557         public boolean isProximitySensorAvailable() {
2558             synchronized (mSyncRoot) {
2559                 return mDisplayPowerController.isProximitySensorAvailable();
2560             }
2561         }
2562 
2563         @Override
systemScreenshot(int displayId)2564         public SurfaceControl.ScreenshotGraphicBuffer systemScreenshot(int displayId) {
2565             return systemScreenshotInternal(displayId);
2566         }
2567 
2568         @Override
userScreenshot(int displayId)2569         public SurfaceControl.ScreenshotGraphicBuffer userScreenshot(int displayId) {
2570             return userScreenshotInternal(displayId);
2571         }
2572 
2573         @Override
getDisplayInfo(int displayId)2574         public DisplayInfo getDisplayInfo(int displayId) {
2575             return getDisplayInfoInternal(displayId, Process.myUid());
2576         }
2577 
2578         @Override
getDisplayPosition(int displayId)2579         public Point getDisplayPosition(int displayId) {
2580             synchronized (mSyncRoot) {
2581                 LogicalDisplay display = mLogicalDisplays.get(displayId);
2582                 if (display != null) {
2583                     return display.getDisplayPosition();
2584                 }
2585                 return null;
2586             }
2587         }
2588 
2589         @Override
registerDisplayTransactionListener(DisplayTransactionListener listener)2590         public void registerDisplayTransactionListener(DisplayTransactionListener listener) {
2591             if (listener == null) {
2592                 throw new IllegalArgumentException("listener must not be null");
2593             }
2594 
2595             registerDisplayTransactionListenerInternal(listener);
2596         }
2597 
2598         @Override
unregisterDisplayTransactionListener(DisplayTransactionListener listener)2599         public void unregisterDisplayTransactionListener(DisplayTransactionListener listener) {
2600             if (listener == null) {
2601                 throw new IllegalArgumentException("listener must not be null");
2602             }
2603 
2604             unregisterDisplayTransactionListenerInternal(listener);
2605         }
2606 
2607         @Override
setDisplayInfoOverrideFromWindowManager(int displayId, DisplayInfo info)2608         public void setDisplayInfoOverrideFromWindowManager(int displayId, DisplayInfo info) {
2609             setDisplayInfoOverrideFromWindowManagerInternal(displayId, info);
2610         }
2611 
2612         @Override
getNonOverrideDisplayInfo(int displayId, DisplayInfo outInfo)2613         public void getNonOverrideDisplayInfo(int displayId, DisplayInfo outInfo) {
2614             getNonOverrideDisplayInfoInternal(displayId, outInfo);
2615         }
2616 
2617         @Override
performTraversal(SurfaceControl.Transaction t)2618         public void performTraversal(SurfaceControl.Transaction t) {
2619             performTraversalInternal(t);
2620         }
2621 
2622         @Override
setDisplayProperties(int displayId, boolean hasContent, float requestedRefreshRate, int requestedMode, boolean requestedMinimalPostProcessing, boolean inTraversal)2623         public void setDisplayProperties(int displayId, boolean hasContent,
2624                 float requestedRefreshRate, int requestedMode,
2625                 boolean requestedMinimalPostProcessing, boolean inTraversal) {
2626             setDisplayPropertiesInternal(displayId, hasContent, requestedRefreshRate,
2627                     requestedMode, requestedMinimalPostProcessing, inTraversal);
2628         }
2629 
2630         @Override
setDisplayOffsets(int displayId, int x, int y)2631         public void setDisplayOffsets(int displayId, int x, int y) {
2632             setDisplayOffsetsInternal(displayId, x, y);
2633         }
2634 
2635         @Override
setDisplayScalingDisabled(int displayId, boolean disableScaling)2636         public void setDisplayScalingDisabled(int displayId, boolean disableScaling) {
2637             setDisplayScalingDisabledInternal(displayId, disableScaling);
2638         }
2639 
2640         @Override
setDisplayAccessUIDs(SparseArray<IntArray> newDisplayAccessUIDs)2641         public void setDisplayAccessUIDs(SparseArray<IntArray> newDisplayAccessUIDs) {
2642             setDisplayAccessUIDsInternal(newDisplayAccessUIDs);
2643         }
2644 
2645         @Override
persistBrightnessTrackerState()2646         public void persistBrightnessTrackerState() {
2647             synchronized (mSyncRoot) {
2648                 mDisplayPowerController.persistBrightnessTrackerState();
2649             }
2650         }
2651 
2652         @Override
onOverlayChanged()2653         public void onOverlayChanged() {
2654             synchronized (mSyncRoot) {
2655                 for (int i = 0; i < mDisplayDevices.size(); i++) {
2656                     mDisplayDevices.get(i).onOverlayChangedLocked();
2657                 }
2658             }
2659         }
2660 
2661         @Override
getDisplayedContentSamplingAttributes( int displayId)2662         public DisplayedContentSamplingAttributes getDisplayedContentSamplingAttributes(
2663                 int displayId) {
2664             return getDisplayedContentSamplingAttributesInternal(displayId);
2665         }
2666 
2667         @Override
setDisplayedContentSamplingEnabled( int displayId, boolean enable, int componentMask, int maxFrames)2668         public boolean setDisplayedContentSamplingEnabled(
2669                 int displayId, boolean enable, int componentMask, int maxFrames) {
2670             return setDisplayedContentSamplingEnabledInternal(
2671                     displayId, enable, componentMask, maxFrames);
2672         }
2673 
2674         @Override
getDisplayedContentSample(int displayId, long maxFrames, long timestamp)2675         public DisplayedContentSample getDisplayedContentSample(int displayId,
2676                 long maxFrames, long timestamp) {
2677             return getDisplayedContentSampleInternal(displayId, maxFrames, timestamp);
2678         }
2679 
2680     }
2681 
2682     class DesiredDisplayModeSpecsObserver
2683             implements DisplayModeDirector.DesiredDisplayModeSpecsListener {
onDesiredDisplayModeSpecsChanged()2684         public void onDesiredDisplayModeSpecsChanged() {
2685             onDesiredDisplayModeSpecsChangedInternal();
2686         }
2687     }
2688 }
2689