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