blob: 75b3556f9206b87058e80f7d83095d0c3742c65b [file] [log] [blame]
Jeff Brownfa25bf52012-07-23 19:26:30 -07001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.display;
18
Andrii Kulianfc8f82b2017-01-26 13:17:27 -080019import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR;
20import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY;
21import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC;
22import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE;
23import static android.hardware.display.DisplayManager
Andrii Kulian7211d2e2017-01-27 15:58:05 -080024 .VIRTUAL_DISPLAY_FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD;
Andrii Kulianfc8f82b2017-01-26 13:17:27 -080025
Santos Cordonee8931e2017-04-05 10:31:15 -070026import com.android.internal.annotations.VisibleForTesting;
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -060027import com.android.internal.util.DumpUtils;
Jeff Brownbd6e1502012-08-28 03:27:37 -070028import com.android.internal.util.IndentingPrintWriter;
29
Jeff Brownfa25bf52012-07-23 19:26:30 -070030import android.Manifest;
Santos Cordonee8931e2017-04-05 10:31:15 -070031import android.annotation.NonNull;
Kenny Guy05ce8092018-01-17 13:44:20 +000032import android.annotation.Nullable;
Michael Wrighteef0e132017-11-21 17:57:52 +000033import android.annotation.UserIdInt;
Kenny Guy29aa30e2017-11-30 13:43:46 +000034import android.app.AppOpsManager;
Jeff Brownfa25bf52012-07-23 19:26:30 -070035import android.content.Context;
36import android.content.pm.PackageManager;
Kenny Guy22bd0442017-10-26 00:15:54 +010037import android.content.pm.ParceledListSlice;
Michael Wrighteedcbf12017-08-16 23:14:54 +010038import android.content.res.Resources;
Dan Gittik122df862018-03-28 16:59:22 +010039import android.content.res.TypedArray;
Michael Wrighteedcbf12017-08-16 23:14:54 +010040import android.graphics.Point;
Jeff Brownad9ef192014-04-08 17:26:30 -070041import android.hardware.SensorManager;
Peeyush Agarwalcc155dd2018-01-10 11:51:33 +000042import android.hardware.display.AmbientBrightnessDayStats;
Kenny Guy22bd0442017-10-26 00:15:54 +010043import android.hardware.display.BrightnessChangeEvent;
Michael Wrighteef0e132017-11-21 17:57:52 +000044import android.hardware.display.BrightnessConfiguration;
Dan Gittik122df862018-03-28 16:59:22 +010045import android.hardware.display.Curve;
Jeff Brownbd6e1502012-08-28 03:27:37 -070046import android.hardware.display.DisplayManagerGlobal;
Jeff Brown4ccb8232014-01-16 22:16:42 -080047import android.hardware.display.DisplayManagerInternal;
48import android.hardware.display.DisplayViewport;
49import android.hardware.display.DisplayManagerInternal.DisplayTransactionListener;
Jeff Brownfa25bf52012-07-23 19:26:30 -070050import android.hardware.display.IDisplayManager;
Jeff Brownbd6e1502012-08-28 03:27:37 -070051import android.hardware.display.IDisplayManagerCallback;
Michael Wright75ee9fc2014-09-01 19:55:22 -070052import android.hardware.display.IVirtualDisplayCallback;
Jeff Browne08ae382012-09-07 20:36:36 -070053import android.hardware.display.WifiDisplayStatus;
Jeff Brown4ccb8232014-01-16 22:16:42 -080054import android.hardware.input.InputManagerInternal;
Michael Wrightc39d47a2014-07-08 18:07:36 -070055import android.media.projection.IMediaProjection;
56import android.media.projection.IMediaProjectionManager;
Jeff Brownfa25bf52012-07-23 19:26:30 -070057import android.os.Binder;
Jeff Brownbd6e1502012-08-28 03:27:37 -070058import android.os.Handler;
Jeff Brown64a55af2012-08-26 02:47:39 -070059import android.os.IBinder;
Jeff Brown4ccb8232014-01-16 22:16:42 -080060import android.os.IBinder.DeathRecipient;
Jeff Brownbd6e1502012-08-28 03:27:37 -070061import android.os.Looper;
62import android.os.Message;
Jeff Brown5d6443b2015-04-10 20:15:01 -070063import android.os.PowerManager;
Craig Mautner4504de52013-12-20 09:06:56 -080064import android.os.Process;
Jeff Brownbd6e1502012-08-28 03:27:37 -070065import android.os.RemoteException;
Dan Gittik7a32fba2018-03-28 12:19:38 +010066import android.os.ResultReceiver;
Michael Wrightc39d47a2014-07-08 18:07:36 -070067import android.os.ServiceManager;
Dan Gittik7a32fba2018-03-28 12:19:38 +010068import android.os.ShellCallback;
Jeff Brownbd6e1502012-08-28 03:27:37 -070069import android.os.SystemClock;
Jeff Brownfa25bf52012-07-23 19:26:30 -070070import android.os.SystemProperties;
Jeff Brown5d6443b2015-04-10 20:15:01 -070071import android.os.Trace;
Kenny Guy22bd0442017-10-26 00:15:54 +010072import android.os.UserHandle;
Michael Wrighteef0e132017-11-21 17:57:52 +000073import android.os.UserManager;
Dan Gittik7a32fba2018-03-28 12:19:38 +010074import android.provider.Settings;
Jeff Browna506a6e2013-06-04 00:02:38 -070075import android.text.TextUtils;
Andrii Kulianfb1bf692017-01-17 11:17:34 -080076import android.util.IntArray;
Dan Gittik122df862018-03-28 16:59:22 +010077import android.util.Pair;
Jeff Brownbd6e1502012-08-28 03:27:37 -070078import android.util.Slog;
79import android.util.SparseArray;
Dan Gittik122df862018-03-28 16:59:22 +010080import android.util.Spline;
Jeff Brownfa25bf52012-07-23 19:26:30 -070081import android.view.Display;
82import android.view.DisplayInfo;
Jeff Browna506a6e2013-06-04 00:02:38 -070083import android.view.Surface;
Robert Carrae606b42018-02-15 15:36:23 -080084import android.view.SurfaceControl;
Jeff Browna506a6e2013-06-04 00:02:38 -070085
Michael Wrighteef0e132017-11-21 17:57:52 +000086import com.android.internal.util.Preconditions;
Jorim Jaggied7993b2017-03-28 18:50:01 +010087import com.android.server.AnimationThread;
Jeff Brown4ccb8232014-01-16 22:16:42 -080088import com.android.server.DisplayThread;
89import com.android.server.LocalServices;
90import com.android.server.SystemService;
Dianne Hackborn8d044e82013-04-30 17:24:15 -070091import com.android.server.UiThread;
Adrian Roose99bc052017-11-20 17:55:31 +010092import com.android.server.wm.WindowManagerInternal;
Jorim Jaggi21c39a72017-10-20 15:47:51 +020093import com.android.server.wm.SurfaceAnimationThread;
Jeff Brownfa25bf52012-07-23 19:26:30 -070094
95import java.io.FileDescriptor;
96import java.io.PrintWriter;
97import java.util.ArrayList;
Jeff Browna506a6e2013-06-04 00:02:38 -070098import java.util.Arrays;
Jeff Browne75926d2014-09-18 15:24:49 -070099import java.util.List;
Jeff Brown7f3994e2012-12-04 14:04:28 -0800100import java.util.concurrent.CopyOnWriteArrayList;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700101
102/**
Jeff Brownbd6e1502012-08-28 03:27:37 -0700103 * Manages attached displays.
Jeff Brownfa25bf52012-07-23 19:26:30 -0700104 * <p>
Jeff Brownbd6e1502012-08-28 03:27:37 -0700105 * The {@link DisplayManagerService} manages the global lifecycle of displays,
106 * decides how to configure logical displays based on the physical display devices currently
107 * attached, sends notifications to the system and to applications when the state
108 * changes, and so on.
109 * </p><p>
110 * The display manager service relies on a collection of {@link DisplayAdapter} components,
111 * for discovering and configuring physical display devices attached to the system.
112 * There are separate display adapters for each manner that devices are attached:
113 * one display adapter for built-in local displays, one for simulated non-functional
114 * displays when the system is headless, one for simulated overlay displays used for
115 * development, one for wifi displays, etc.
116 * </p><p>
117 * Display adapters are only weakly coupled to the display manager service.
118 * Display adapters communicate changes in display device state to the display manager
Craig Mautner722285e2012-09-07 13:55:58 -0700119 * service asynchronously via a {@link DisplayAdapter.Listener} registered
Jeff Brownbd6e1502012-08-28 03:27:37 -0700120 * by the display manager service. This separation of concerns is important for
121 * two main reasons. First, it neatly encapsulates the responsibilities of these
122 * two classes: display adapters handle individual display devices whereas
123 * the display manager service handles the global state. Second, it eliminates
124 * the potential for deadlocks resulting from asynchronous display device discovery.
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700125 * </p>
126 *
127 * <h3>Synchronization</h3>
128 * <p>
129 * Because the display manager may be accessed by multiple threads, the synchronization
130 * story gets a little complicated. In particular, the window manager may call into
131 * the display manager while holding a surface transaction with the expectation that
132 * it can apply changes immediately. Unfortunately, that means we can't just do
133 * everything asynchronously (*grump*).
Jeff Brownbd6e1502012-08-28 03:27:37 -0700134 * </p><p>
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700135 * To make this work, all of the objects that belong to the display manager must
136 * use the same lock. We call this lock the synchronization root and it has a unique
137 * type {@link DisplayManagerService.SyncRoot}. Methods that require this lock are
138 * named with the "Locked" suffix.
139 * </p><p>
140 * Where things get tricky is that the display manager is not allowed to make
141 * any potentially reentrant calls, especially into the window manager. We generally
142 * avoid this by making all potentially reentrant out-calls asynchronous.
Jeff Brownfa25bf52012-07-23 19:26:30 -0700143 * </p>
144 */
Jeff Brown4ccb8232014-01-16 22:16:42 -0800145public final class DisplayManagerService extends SystemService {
Jeff Brownfa25bf52012-07-23 19:26:30 -0700146 private static final String TAG = "DisplayManagerService";
Jeff Brownbd6e1502012-08-28 03:27:37 -0700147 private static final boolean DEBUG = false;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700148
Jeff Brownbbd28a22012-09-20 16:47:15 -0700149 // When this system property is set to 0, WFD is forcibly disabled on boot.
150 // When this system property is set to 1, WFD is forcibly enabled on boot.
151 // Otherwise WFD is enabled according to the value of config_enableWifiDisplay.
152 private static final String FORCE_WIFI_DISPLAY_ENABLE = "persist.debug.wfd.enable";
153
Jeff Brownbd6e1502012-08-28 03:27:37 -0700154 private static final long WAIT_FOR_DEFAULT_DISPLAY_TIMEOUT = 10000;
155
Santos Cordonc22c5632017-06-21 16:03:49 -0700156 private static final int MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS = 1;
Jeff Brownbd6e1502012-08-28 03:27:37 -0700157 private static final int MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS = 2;
158 private static final int MSG_DELIVER_DISPLAY_EVENT = 3;
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700159 private static final int MSG_REQUEST_TRAVERSAL = 4;
Jeff Brownd728bf52012-09-08 18:05:28 -0700160 private static final int MSG_UPDATE_VIEWPORT = 5;
Kenny Guy22bd0442017-10-26 00:15:54 +0100161 private static final int MSG_REGISTER_BRIGHTNESS_TRACKER = 6;
Michael Wrighteef0e132017-11-21 17:57:52 +0000162 private static final int MSG_LOAD_BRIGHTNESS_CONFIGURATION = 7;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700163
Jeff Brownb880d882014-02-10 19:47:07 -0800164 private final Context mContext;
Jeff Brownbd6e1502012-08-28 03:27:37 -0700165 private final DisplayManagerHandler mHandler;
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700166 private final Handler mUiHandler;
167 private final DisplayAdapterListener mDisplayAdapterListener;
Jeff Brown4ccb8232014-01-16 22:16:42 -0800168 private WindowManagerInternal mWindowManagerInternal;
169 private InputManagerInternal mInputManagerInternal;
Michael Wrightc39d47a2014-07-08 18:07:36 -0700170 private IMediaProjectionManager mProjectionService;
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700171
172 // The synchronization root for the display manager.
173 // This lock guards most of the display manager's state.
Craig Mautner0bf6ec92012-12-18 08:33:27 -0800174 // NOTE: This is synchronized on while holding WindowManagerService.mWindowMap so never call
175 // into WindowManagerService methods that require mWindowMap while holding this unless you are
176 // very very sure that no deadlock can occur.
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700177 private final SyncRoot mSyncRoot = new SyncRoot();
178
179 // True if in safe mode.
180 // This option may disable certain display adapters.
181 public boolean mSafeMode;
182
183 // True if we are in a special boot mode where only core applications and
184 // services should be started. This option may disable certain display adapters.
185 public boolean mOnlyCore;
186
Jeff Brown27f1d672012-10-17 18:32:34 -0700187 // True if the display manager service should pretend there is only one display
188 // and only tell applications about the existence of the default logical display.
189 // The display manager can still mirror content to secondary displays but applications
190 // cannot present unique content on those displays.
191 // Used for demonstration purposes only.
192 private final boolean mSingleDisplayDemoMode;
193
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700194 // All callback records indexed by calling process id.
195 public final SparseArray<CallbackRecord> mCallbacks =
Jeff Brownbd6e1502012-08-28 03:27:37 -0700196 new SparseArray<CallbackRecord>();
Jeff Brownfa25bf52012-07-23 19:26:30 -0700197
Jeff Brownbd6e1502012-08-28 03:27:37 -0700198 // List of all currently registered display adapters.
199 private final ArrayList<DisplayAdapter> mDisplayAdapters = new ArrayList<DisplayAdapter>();
200
201 // List of all currently connected display devices.
202 private final ArrayList<DisplayDevice> mDisplayDevices = new ArrayList<DisplayDevice>();
203
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700204 // List of all logical displays indexed by logical display id.
205 private final SparseArray<LogicalDisplay> mLogicalDisplays =
206 new SparseArray<LogicalDisplay>();
Jeff Brownbd6e1502012-08-28 03:27:37 -0700207 private int mNextNonDefaultDisplayId = Display.DEFAULT_DISPLAY + 1;
208
Jeff Brown7f3994e2012-12-04 14:04:28 -0800209 // List of all display transaction listeners.
210 private final CopyOnWriteArrayList<DisplayTransactionListener> mDisplayTransactionListeners =
211 new CopyOnWriteArrayList<DisplayTransactionListener>();
212
Jeff Brownad9ef192014-04-08 17:26:30 -0700213 // Display power controller.
214 private DisplayPowerController mDisplayPowerController;
215
Jeff Brown037c33e2014-04-09 00:31:55 -0700216 // The overall display state, independent of changes that might influence one
217 // display or another in particular.
Jeff Brown5d6443b2015-04-10 20:15:01 -0700218 private int mGlobalDisplayState = Display.STATE_ON;
219
220 // The overall display brightness.
221 // For now, this only applies to the built-in display but we may split it up eventually.
222 private int mGlobalDisplayBrightness = PowerManager.BRIGHTNESS_DEFAULT;
Jeff Brown9e316a12012-10-08 19:17:06 -0700223
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700224 // Set to true when there are pending display changes that have yet to be applied
225 // to the surface flinger state.
226 private boolean mPendingTraversal;
Jeff Brownbd6e1502012-08-28 03:27:37 -0700227
Jeff Browne08ae382012-09-07 20:36:36 -0700228 // The Wifi display adapter, or null if not registered.
229 private WifiDisplayAdapter mWifiDisplayAdapter;
230
Jeff Brownce468a32013-11-21 16:42:03 -0800231 // The number of active wifi display scan requests.
232 private int mWifiDisplayScanRequestCount;
233
Jeff Browna506a6e2013-06-04 00:02:38 -0700234 // The virtual display adapter, or null if not registered.
235 private VirtualDisplayAdapter mVirtualDisplayAdapter;
236
Michael Wrighteef0e132017-11-21 17:57:52 +0000237 // The User ID of the current user
238 private @UserIdInt int mCurrentUserId;
239
Michael Wrighteedcbf12017-08-16 23:14:54 +0100240 // The stable device screen height and width. These are not tied to a specific display, even
241 // the default display, because they need to be stable over the course of the device's entire
242 // life, even if the default display changes (e.g. a new monitor is plugged into a PC-like
243 // device).
244 private Point mStableDisplaySize = new Point();
245
Jeff Brownd728bf52012-09-08 18:05:28 -0700246 // Viewports of the default display and the display that should receive touch
247 // input from an external source. Used by the input system.
248 private final DisplayViewport mDefaultViewport = new DisplayViewport();
249 private final DisplayViewport mExternalTouchViewport = new DisplayViewport();
Santos Cordonee8931e2017-04-05 10:31:15 -0700250 private final ArrayList<DisplayViewport> mVirtualTouchViewports = new ArrayList<>();
Jeff Brownd728bf52012-09-08 18:05:28 -0700251
Jeff Brown89d55462012-09-19 11:33:42 -0700252 // Persistent data store for all internal settings maintained by the display manager service.
253 private final PersistentDataStore mPersistentDataStore = new PersistentDataStore();
254
Jeff Brownbd6e1502012-08-28 03:27:37 -0700255 // Temporary callback list, used when sending display events to applications.
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700256 // May be used outside of the lock but only on the handler thread.
257 private final ArrayList<CallbackRecord> mTempCallbacks = new ArrayList<CallbackRecord>();
Jeff Brownbd6e1502012-08-28 03:27:37 -0700258
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700259 // Temporary display info, used for comparing display configurations.
260 private final DisplayInfo mTempDisplayInfo = new DisplayInfo();
261
Jeff Brownd728bf52012-09-08 18:05:28 -0700262 // Temporary viewports, used when sending new viewport information to the
263 // input system. May be used outside of the lock but only on the handler thread.
264 private final DisplayViewport mTempDefaultViewport = new DisplayViewport();
265 private final DisplayViewport mTempExternalTouchViewport = new DisplayViewport();
Santos Cordonee8931e2017-04-05 10:31:15 -0700266 private final ArrayList<DisplayViewport> mTempVirtualTouchViewports = new ArrayList<>();
Jeff Brownd728bf52012-09-08 18:05:28 -0700267
Damien Bargiacchi4364bbf2016-11-01 21:44:20 -0700268 // The default color mode for default displays. Overrides the usual
269 // Display.Display.COLOR_MODE_DEFAULT for displays with the
270 // DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY flag set.
271 private final int mDefaultDisplayDefaultColorMode;
272
Jeff Browne75926d2014-09-18 15:24:49 -0700273 // Temporary list of deferred work to perform when setting the display state.
274 // Only used by requestDisplayState. The field is self-synchronized and only
275 // intended for use inside of the requestGlobalDisplayStateInternal function.
276 private final ArrayList<Runnable> mTempDisplayStateWorkQueue = new ArrayList<Runnable>();
277
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800278 // Lists of UIDs that are present on the displays. Maps displayId -> array of UIDs.
279 private final SparseArray<IntArray> mDisplayAccessUIDs = new SparseArray<>();
280
Santos Cordonee8931e2017-04-05 10:31:15 -0700281 private final Injector mInjector;
282
Dan Gittik122df862018-03-28 16:59:22 +0100283 // The minimum brightness curve, which guarantess that any brightness curve that dips below it
284 // is rejected by the system.
285 private final Curve mMinimumBrightnessCurve;
286 private final Spline mMinimumBrightnessSpline;
287
Jeff Brownb880d882014-02-10 19:47:07 -0800288 public DisplayManagerService(Context context) {
Santos Cordonee8931e2017-04-05 10:31:15 -0700289 this(context, new Injector());
290 }
291
292 @VisibleForTesting
293 DisplayManagerService(Context context, Injector injector) {
Jeff Brownb880d882014-02-10 19:47:07 -0800294 super(context);
Santos Cordonee8931e2017-04-05 10:31:15 -0700295 mInjector = injector;
Jeff Brownb880d882014-02-10 19:47:07 -0800296 mContext = context;
Jeff Brown4ccb8232014-01-16 22:16:42 -0800297 mHandler = new DisplayManagerHandler(DisplayThread.get().getLooper());
Dianne Hackborn8d044e82013-04-30 17:24:15 -0700298 mUiHandler = UiThread.getHandler();
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700299 mDisplayAdapterListener = new DisplayAdapterListener();
Jeff Brown27f1d672012-10-17 18:32:34 -0700300 mSingleDisplayDemoMode = SystemProperties.getBoolean("persist.demo.singledisplay", false);
Dan Gittik122df862018-03-28 16:59:22 +0100301 Resources resources = mContext.getResources();
Damien Bargiacchi4364bbf2016-11-01 21:44:20 -0700302 mDefaultDisplayDefaultColorMode = mContext.getResources().getInteger(
Michael Wrighteef0e132017-11-21 17:57:52 +0000303 com.android.internal.R.integer.config_defaultDisplayDefaultColorMode);
Dan Gittik122df862018-03-28 16:59:22 +0100304 float[] lux = getFloatArray(resources.obtainTypedArray(
305 com.android.internal.R.array.config_minimumBrightnessCurveLux));
306 float[] nits = getFloatArray(resources.obtainTypedArray(
307 com.android.internal.R.array.config_minimumBrightnessCurveNits));
308 mMinimumBrightnessCurve = new Curve(lux, nits);
309 mMinimumBrightnessSpline = Spline.createSpline(lux, nits);
Jeff Brown5d6443b2015-04-10 20:15:01 -0700310
311 PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
312 mGlobalDisplayBrightness = pm.getDefaultScreenBrightnessSetting();
Michael Wrighteef0e132017-11-21 17:57:52 +0000313 mCurrentUserId = UserHandle.USER_SYSTEM;
Joel Fernandes2d314e12017-04-04 16:32:15 -0700314 }
315
316 public void setupSchedulerPolicies() {
Jorim Jaggied7993b2017-03-28 18:50:01 +0100317 // android.display and android.anim is critical to user experience and we should make sure
Michael Wrighteef0e132017-11-21 17:57:52 +0000318 // it is not in the default foregroup groups, add it to top-app to make sure it uses all
319 // the cores and scheduling settings for top-app when it runs.
Jorim Jaggied7993b2017-03-28 18:50:01 +0100320 Process.setThreadGroupAndCpuset(DisplayThread.get().getThreadId(),
321 Process.THREAD_GROUP_TOP_APP);
322 Process.setThreadGroupAndCpuset(AnimationThread.get().getThreadId(),
323 Process.THREAD_GROUP_TOP_APP);
Jorim Jaggi21c39a72017-10-20 15:47:51 +0200324 Process.setThreadGroupAndCpuset(SurfaceAnimationThread.get().getThreadId(),
325 Process.THREAD_GROUP_TOP_APP);
Craig Mautner4f67ba62012-08-02 11:23:00 -0700326 }
327
Jeff Brown4ccb8232014-01-16 22:16:42 -0800328 @Override
Jeff Brown4ccb8232014-01-16 22:16:42 -0800329 public void onStart() {
Michael Wright1c9977b2016-07-12 13:30:10 -0700330 // We need to pre-load the persistent data store so it's ready before the default display
331 // adapter is up so that we have it's configuration. We could load it lazily, but since
332 // we're going to have to read it in eventually we may as well do it here rather than after
Santos Cordonc22c5632017-06-21 16:03:49 -0700333 // we've waited for the display to register itself with us.
Michael Wrighteedcbf12017-08-16 23:14:54 +0100334 synchronized(mSyncRoot) {
335 mPersistentDataStore.loadIfNeeded();
336 loadStableDisplayValuesLocked();
337 }
Santos Cordonc22c5632017-06-21 16:03:49 -0700338 mHandler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS);
Jeff Brown4ccb8232014-01-16 22:16:42 -0800339
340 publishBinderService(Context.DISPLAY_SERVICE, new BinderService(),
341 true /*allowIsolated*/);
342 publishLocalService(DisplayManagerInternal.class, new LocalService());
Justin Klaassen22eb1992016-07-11 20:52:23 -0700343 publishLocalService(DisplayTransformManager.class, new DisplayTransformManager());
Jeff Brown4ccb8232014-01-16 22:16:42 -0800344 }
345
346 @Override
347 public void onBootPhase(int phase) {
348 if (phase == PHASE_WAIT_FOR_DEFAULT_DISPLAY) {
349 synchronized (mSyncRoot) {
Santos Cordonc22c5632017-06-21 16:03:49 -0700350 long timeout = SystemClock.uptimeMillis()
351 + mInjector.getDefaultDisplayDelayTimeout();
352 while (mLogicalDisplays.get(Display.DEFAULT_DISPLAY) == null ||
353 mVirtualDisplayAdapter == null) {
Jeff Brown4ccb8232014-01-16 22:16:42 -0800354 long delay = timeout - SystemClock.uptimeMillis();
355 if (delay <= 0) {
356 throw new RuntimeException("Timeout waiting for default display "
Santos Cordonc22c5632017-06-21 16:03:49 -0700357 + "to be initialized. DefaultDisplay="
358 + mLogicalDisplays.get(Display.DEFAULT_DISPLAY)
359 + ", mVirtualDisplayAdapter=" + mVirtualDisplayAdapter);
Jeff Brown4ccb8232014-01-16 22:16:42 -0800360 }
361 if (DEBUG) {
362 Slog.d(TAG, "waitForDefaultDisplay: waiting, timeout=" + delay);
363 }
364 try {
365 mSyncRoot.wait(delay);
366 } catch (InterruptedException ex) {
367 }
Jeff Brownbd6e1502012-08-28 03:27:37 -0700368 }
369 }
370 }
Jeff Brownbd6e1502012-08-28 03:27:37 -0700371 }
372
Michael Wrighteef0e132017-11-21 17:57:52 +0000373 @Override
374 public void onSwitchUser(@UserIdInt int newUserId) {
375 final int userSerial = getUserManager().getUserSerialNumber(newUserId);
376 synchronized (mSyncRoot) {
377 if (mCurrentUserId != newUserId) {
378 mCurrentUserId = newUserId;
379 BrightnessConfiguration config =
380 mPersistentDataStore.getBrightnessConfiguration(userSerial);
381 mDisplayPowerController.setBrightnessConfiguration(config);
382 }
Peeyush Agarwalcc155dd2018-01-10 11:51:33 +0000383 mDisplayPowerController.onSwitchUser(newUserId);
Michael Wrighteef0e132017-11-21 17:57:52 +0000384 }
385 }
386
Jeff Brown4ccb8232014-01-16 22:16:42 -0800387 // TODO: Use dependencies or a boot phase
388 public void windowManagerAndInputReady() {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700389 synchronized (mSyncRoot) {
Jeff Brown4ccb8232014-01-16 22:16:42 -0800390 mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
391 mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);
Craig Mautner65d11b32012-10-01 13:59:52 -0700392 scheduleTraversalLocked(false);
Jeff Brownd728bf52012-09-08 18:05:28 -0700393 }
394 }
395
396 /**
Jeff Brownbd6e1502012-08-28 03:27:37 -0700397 * Called when the system is ready to go.
398 */
399 public void systemReady(boolean safeMode, boolean onlyCore) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700400 synchronized (mSyncRoot) {
Jeff Brownbd6e1502012-08-28 03:27:37 -0700401 mSafeMode = safeMode;
402 mOnlyCore = onlyCore;
403 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700404
Jeff Brownbd6e1502012-08-28 03:27:37 -0700405 mHandler.sendEmptyMessage(MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS);
Kenny Guy22bd0442017-10-26 00:15:54 +0100406 mHandler.sendEmptyMessage(MSG_REGISTER_BRIGHTNESS_TRACKER);
Jeff Brownbd6e1502012-08-28 03:27:37 -0700407 }
408
Santos Cordonee8931e2017-04-05 10:31:15 -0700409 @VisibleForTesting
410 Handler getDisplayHandler() {
411 return mHandler;
412 }
413
Michael Wrighteedcbf12017-08-16 23:14:54 +0100414 private void loadStableDisplayValuesLocked() {
415 final Point size = mPersistentDataStore.getStableDisplaySize();
416 if (size.x > 0 && size.y > 0) {
417 // Just set these values directly so we don't write the display persistent data again
418 // unnecessarily
419 mStableDisplaySize.set(size.x, size.y);
420 } else {
421 final Resources res = mContext.getResources();
422 final int width = res.getInteger(
423 com.android.internal.R.integer.config_stableDeviceDisplayWidth);
424 final int height = res.getInteger(
425 com.android.internal.R.integer.config_stableDeviceDisplayHeight);
426 if (width > 0 && height > 0) {
427 setStableDisplaySizeLocked(width, height);
428 }
429 }
430 }
431
432 private Point getStableDisplaySizeInternal() {
433 Point r = new Point();
434 synchronized (mSyncRoot) {
435 if (mStableDisplaySize.x > 0 && mStableDisplaySize.y > 0) {
436 r.set(mStableDisplaySize.x, mStableDisplaySize.y);
437 }
438 }
439 return r;
440 }
441
Jeff Brown4ccb8232014-01-16 22:16:42 -0800442 private void registerDisplayTransactionListenerInternal(
443 DisplayTransactionListener listener) {
Jeff Brown7f3994e2012-12-04 14:04:28 -0800444 // List is self-synchronized copy-on-write.
445 mDisplayTransactionListeners.add(listener);
446 }
447
Jeff Brown4ccb8232014-01-16 22:16:42 -0800448 private void unregisterDisplayTransactionListenerInternal(
449 DisplayTransactionListener listener) {
Jeff Brown7f3994e2012-12-04 14:04:28 -0800450 // List is self-synchronized copy-on-write.
451 mDisplayTransactionListeners.remove(listener);
452 }
453
Jeff Brown4ccb8232014-01-16 22:16:42 -0800454 private void setDisplayInfoOverrideFromWindowManagerInternal(
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700455 int displayId, DisplayInfo info) {
456 synchronized (mSyncRoot) {
Jeff Brownbd6e1502012-08-28 03:27:37 -0700457 LogicalDisplay display = mLogicalDisplays.get(displayId);
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700458 if (display != null) {
Jeff Brownef981a42013-08-07 14:13:37 -0700459 if (display.setDisplayInfoOverrideFromWindowManagerLocked(info)) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700460 sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_CHANGED);
Craig Mautner65d11b32012-10-01 13:59:52 -0700461 scheduleTraversalLocked(false);
Jeff Brownbd6e1502012-08-28 03:27:37 -0700462 }
Jeff Brownbd6e1502012-08-28 03:27:37 -0700463 }
464 }
465 }
466
Andrii Kuliancd097992017-03-23 18:31:59 -0700467 /**
468 * @see DisplayManagerInternal#getNonOverrideDisplayInfo(int, DisplayInfo)
469 */
470 private void getNonOverrideDisplayInfoInternal(int displayId, DisplayInfo outInfo) {
471 synchronized (mSyncRoot) {
472 final LogicalDisplay display = mLogicalDisplays.get(displayId);
473 if (display != null) {
474 display.getNonOverrideDisplayInfoLocked(outInfo);
475 }
476 }
477 }
478
Santos Cordonee8931e2017-04-05 10:31:15 -0700479 @VisibleForTesting
Robert Carrae606b42018-02-15 15:36:23 -0800480 void performTraversalInternal(SurfaceControl.Transaction t) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700481 synchronized (mSyncRoot) {
482 if (!mPendingTraversal) {
483 return;
Jeff Brownbd6e1502012-08-28 03:27:37 -0700484 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700485 mPendingTraversal = false;
486
Robert Carrae606b42018-02-15 15:36:23 -0800487 performTraversalLocked(t);
Jeff Brownbd6e1502012-08-28 03:27:37 -0700488 }
Jeff Brown7f3994e2012-12-04 14:04:28 -0800489
490 // List is self-synchronized copy-on-write.
491 for (DisplayTransactionListener listener : mDisplayTransactionListeners) {
492 listener.onDisplayTransaction();
493 }
Jeff Brownbd6e1502012-08-28 03:27:37 -0700494 }
495
Jeff Brown5d6443b2015-04-10 20:15:01 -0700496 private void requestGlobalDisplayStateInternal(int state, int brightness) {
497 if (state == Display.STATE_UNKNOWN) {
498 state = Display.STATE_ON;
499 }
500 if (state == Display.STATE_OFF) {
501 brightness = PowerManager.BRIGHTNESS_OFF;
502 } else if (brightness < 0) {
503 brightness = PowerManager.BRIGHTNESS_DEFAULT;
504 } else if (brightness > PowerManager.BRIGHTNESS_ON) {
505 brightness = PowerManager.BRIGHTNESS_ON;
506 }
507
Jeff Browne75926d2014-09-18 15:24:49 -0700508 synchronized (mTempDisplayStateWorkQueue) {
509 try {
510 // Update the display state within the lock.
Jeff Brown8e5d33e2015-06-10 13:05:50 -0700511 // Note that we do not need to schedule traversals here although it
512 // may happen as a side-effect of displays changing state.
Jeff Browne75926d2014-09-18 15:24:49 -0700513 synchronized (mSyncRoot) {
Jeff Brown5d6443b2015-04-10 20:15:01 -0700514 if (mGlobalDisplayState == state
515 && mGlobalDisplayBrightness == brightness) {
516 return; // no change
Jeff Browne75926d2014-09-18 15:24:49 -0700517 }
Jeff Brown5d6443b2015-04-10 20:15:01 -0700518
519 Trace.traceBegin(Trace.TRACE_TAG_POWER, "requestGlobalDisplayState("
520 + Display.stateToString(state)
521 + ", brightness=" + brightness + ")");
522 mGlobalDisplayState = state;
523 mGlobalDisplayBrightness = brightness;
Jeff Brown8e5d33e2015-06-10 13:05:50 -0700524 applyGlobalDisplayStateLocked(mTempDisplayStateWorkQueue);
Jeff Browne75926d2014-09-18 15:24:49 -0700525 }
526
527 // Setting the display power state can take hundreds of milliseconds
528 // to complete so we defer the most expensive part of the work until
529 // after we have exited the critical section to avoid blocking other
530 // threads for a long time.
531 for (int i = 0; i < mTempDisplayStateWorkQueue.size(); i++) {
532 mTempDisplayStateWorkQueue.get(i).run();
533 }
Jeff Brown5d6443b2015-04-10 20:15:01 -0700534 Trace.traceEnd(Trace.TRACE_TAG_POWER);
Jeff Browne75926d2014-09-18 15:24:49 -0700535 } finally {
536 mTempDisplayStateWorkQueue.clear();
Jeff Brown9e316a12012-10-08 19:17:06 -0700537 }
538 }
539 }
540
Jeff Brown4ccb8232014-01-16 22:16:42 -0800541 private DisplayInfo getDisplayInfoInternal(int displayId, int callingUid) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700542 synchronized (mSyncRoot) {
Jeff Brown4ccb8232014-01-16 22:16:42 -0800543 LogicalDisplay display = mLogicalDisplays.get(displayId);
544 if (display != null) {
545 DisplayInfo info = display.getDisplayInfoLocked();
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800546 if (info.hasAccess(callingUid)
547 || isUidPresentOnDisplayInternal(callingUid, displayId)) {
Jeff Brown4ccb8232014-01-16 22:16:42 -0800548 return info;
549 }
550 }
551 return null;
552 }
553 }
554
555 private int[] getDisplayIdsInternal(int callingUid) {
556 synchronized (mSyncRoot) {
557 final int count = mLogicalDisplays.size();
558 int[] displayIds = new int[count];
559 int n = 0;
560 for (int i = 0; i < count; i++) {
561 LogicalDisplay display = mLogicalDisplays.valueAt(i);
562 DisplayInfo info = display.getDisplayInfoLocked();
563 if (info.hasAccess(callingUid)) {
564 displayIds[n++] = mLogicalDisplays.keyAt(i);
565 }
566 }
567 if (n != count) {
568 displayIds = Arrays.copyOfRange(displayIds, 0, n);
569 }
570 return displayIds;
571 }
572 }
573
574 private void registerCallbackInternal(IDisplayManagerCallback callback, int callingPid) {
575 synchronized (mSyncRoot) {
Jeff Brownbd6e1502012-08-28 03:27:37 -0700576 if (mCallbacks.get(callingPid) != null) {
577 throw new SecurityException("The calling process has already "
578 + "registered an IDisplayManagerCallback.");
Jeff Brown64a55af2012-08-26 02:47:39 -0700579 }
580
Jeff Brownbd6e1502012-08-28 03:27:37 -0700581 CallbackRecord record = new CallbackRecord(callingPid, callback);
582 try {
583 IBinder binder = callback.asBinder();
584 binder.linkToDeath(record, 0);
585 } catch (RemoteException ex) {
586 // give up
587 throw new RuntimeException(ex);
588 }
589
590 mCallbacks.put(callingPid, record);
591 }
592 }
593
Jeff Brownce468a32013-11-21 16:42:03 -0800594 private void onCallbackDied(CallbackRecord record) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700595 synchronized (mSyncRoot) {
Jeff Brownce468a32013-11-21 16:42:03 -0800596 mCallbacks.remove(record.mPid);
597 stopWifiDisplayScanLocked(record);
Jeff Brownbd6e1502012-08-28 03:27:37 -0700598 }
599 }
600
Jeff Brown4ccb8232014-01-16 22:16:42 -0800601 private void startWifiDisplayScanInternal(int callingPid) {
602 synchronized (mSyncRoot) {
603 CallbackRecord record = mCallbacks.get(callingPid);
604 if (record == null) {
605 throw new IllegalStateException("The calling process has not "
606 + "registered an IDisplayManagerCallback.");
Jeff Browne08ae382012-09-07 20:36:36 -0700607 }
Jeff Brown4ccb8232014-01-16 22:16:42 -0800608 startWifiDisplayScanLocked(record);
Jeff Browne08ae382012-09-07 20:36:36 -0700609 }
610 }
611
Jeff Brownce468a32013-11-21 16:42:03 -0800612 private void startWifiDisplayScanLocked(CallbackRecord record) {
613 if (!record.mWifiDisplayScanRequested) {
614 record.mWifiDisplayScanRequested = true;
615 if (mWifiDisplayScanRequestCount++ == 0) {
616 if (mWifiDisplayAdapter != null) {
617 mWifiDisplayAdapter.requestStartScanLocked();
618 }
619 }
620 }
621 }
622
Jeff Brown4ccb8232014-01-16 22:16:42 -0800623 private void stopWifiDisplayScanInternal(int callingPid) {
624 synchronized (mSyncRoot) {
625 CallbackRecord record = mCallbacks.get(callingPid);
626 if (record == null) {
627 throw new IllegalStateException("The calling process has not "
628 + "registered an IDisplayManagerCallback.");
Jeff Brownce468a32013-11-21 16:42:03 -0800629 }
Jeff Brown4ccb8232014-01-16 22:16:42 -0800630 stopWifiDisplayScanLocked(record);
Jeff Brownce468a32013-11-21 16:42:03 -0800631 }
632 }
633
634 private void stopWifiDisplayScanLocked(CallbackRecord record) {
635 if (record.mWifiDisplayScanRequested) {
636 record.mWifiDisplayScanRequested = false;
637 if (--mWifiDisplayScanRequestCount == 0) {
638 if (mWifiDisplayAdapter != null) {
639 mWifiDisplayAdapter.requestStopScanLocked();
640 }
641 } else if (mWifiDisplayScanRequestCount < 0) {
Dianne Hackborn8d051722014-10-01 14:59:58 -0700642 Slog.wtf(TAG, "mWifiDisplayScanRequestCount became negative: "
Jeff Brownce468a32013-11-21 16:42:03 -0800643 + mWifiDisplayScanRequestCount);
644 mWifiDisplayScanRequestCount = 0;
645 }
646 }
647 }
648
Jeff Brown4ccb8232014-01-16 22:16:42 -0800649 private void connectWifiDisplayInternal(String address) {
650 synchronized (mSyncRoot) {
651 if (mWifiDisplayAdapter != null) {
652 mWifiDisplayAdapter.requestConnectLocked(address);
Jeff Browne08ae382012-09-07 20:36:36 -0700653 }
Jeff Browne08ae382012-09-07 20:36:36 -0700654 }
655 }
656
Jeff Brown4ccb8232014-01-16 22:16:42 -0800657 private void pauseWifiDisplayInternal() {
658 synchronized (mSyncRoot) {
659 if (mWifiDisplayAdapter != null) {
660 mWifiDisplayAdapter.requestPauseLocked();
Chong Zhang1f3ecaa2013-05-03 15:55:36 -0700661 }
Chong Zhang1f3ecaa2013-05-03 15:55:36 -0700662 }
663 }
664
Jeff Brown4ccb8232014-01-16 22:16:42 -0800665 private void resumeWifiDisplayInternal() {
666 synchronized (mSyncRoot) {
667 if (mWifiDisplayAdapter != null) {
668 mWifiDisplayAdapter.requestResumeLocked();
Chong Zhang1f3ecaa2013-05-03 15:55:36 -0700669 }
Chong Zhang1f3ecaa2013-05-03 15:55:36 -0700670 }
671 }
672
Jeff Brown4ccb8232014-01-16 22:16:42 -0800673 private void disconnectWifiDisplayInternal() {
674 synchronized (mSyncRoot) {
675 if (mWifiDisplayAdapter != null) {
676 mWifiDisplayAdapter.requestDisconnectLocked();
Jeff Browne08ae382012-09-07 20:36:36 -0700677 }
Jeff Browne08ae382012-09-07 20:36:36 -0700678 }
679 }
680
Jeff Brown4ccb8232014-01-16 22:16:42 -0800681 private void renameWifiDisplayInternal(String address, String alias) {
682 synchronized (mSyncRoot) {
683 if (mWifiDisplayAdapter != null) {
684 mWifiDisplayAdapter.requestRenameLocked(address, alias);
Jeff Brown89d55462012-09-19 11:33:42 -0700685 }
Jeff Brown89d55462012-09-19 11:33:42 -0700686 }
687 }
688
Jeff Brown4ccb8232014-01-16 22:16:42 -0800689 private void forgetWifiDisplayInternal(String address) {
690 synchronized (mSyncRoot) {
691 if (mWifiDisplayAdapter != null) {
692 mWifiDisplayAdapter.requestForgetLocked(address);
Jeff Brown89d55462012-09-19 11:33:42 -0700693 }
Jeff Brown89d55462012-09-19 11:33:42 -0700694 }
695 }
696
Jeff Brown4ccb8232014-01-16 22:16:42 -0800697 private WifiDisplayStatus getWifiDisplayStatusInternal() {
698 synchronized (mSyncRoot) {
699 if (mWifiDisplayAdapter != null) {
700 return mWifiDisplayAdapter.getWifiDisplayStatusLocked();
Jeff Browne08ae382012-09-07 20:36:36 -0700701 }
Jeff Brown4ccb8232014-01-16 22:16:42 -0800702 return new WifiDisplayStatus();
Jeff Browne08ae382012-09-07 20:36:36 -0700703 }
704 }
705
Michael Wright1c9977b2016-07-12 13:30:10 -0700706 private void requestColorModeInternal(int displayId, int colorMode) {
Michael Wright58e829f2015-09-15 00:13:26 +0100707 synchronized (mSyncRoot) {
708 LogicalDisplay display = mLogicalDisplays.get(displayId);
709 if (display != null &&
Michael Wright1c9977b2016-07-12 13:30:10 -0700710 display.getRequestedColorModeLocked() != colorMode) {
711 display.setRequestedColorModeLocked(colorMode);
Michael Wright58e829f2015-09-15 00:13:26 +0100712 scheduleTraversalLocked(false);
713 }
714 }
715 }
716
Bryan Mawhinney462e29d2018-03-22 15:52:41 +0000717 private void setSaturationLevelInternal(float level) {
718 if (level < 0 || level > 1) {
719 throw new IllegalArgumentException("Saturation level must be between 0 and 1");
720 }
721 float[] matrix = (level == 1.0f ? null : computeSaturationMatrix(level));
722 DisplayTransformManager dtm = LocalServices.getService(DisplayTransformManager.class);
723 dtm.setColorMatrix(DisplayTransformManager.LEVEL_COLOR_MATRIX_SATURATION, matrix);
724 }
725
726 private static float[] computeSaturationMatrix(float saturation) {
727 float desaturation = 1.0f - saturation;
728 float[] luminance = {0.231f * desaturation, 0.715f * desaturation, 0.072f * desaturation};
729 float[] matrix = {
730 luminance[0] + saturation, luminance[0], luminance[0], 0,
731 luminance[1], luminance[1] + saturation, luminance[1], 0,
732 luminance[2], luminance[2], luminance[2] + saturation, 0,
733 0, 0, 0, 1
734 };
735 return matrix;
736 }
737
Michael Wright75ee9fc2014-09-01 19:55:22 -0700738 private int createVirtualDisplayInternal(IVirtualDisplayCallback callback,
Santos Cordonee8931e2017-04-05 10:31:15 -0700739 IMediaProjection projection, int callingUid, String packageName, String name, int width,
740 int height, int densityDpi, Surface surface, int flags, String uniqueId) {
Jeff Brown4ccb8232014-01-16 22:16:42 -0800741 synchronized (mSyncRoot) {
742 if (mVirtualDisplayAdapter == null) {
743 Slog.w(TAG, "Rejecting request to create private virtual display "
744 + "because the virtual display adapter is not available.");
745 return -1;
Jeff Brown7d00aff2013-08-02 19:03:49 -0700746 }
Jeff Brown4ccb8232014-01-16 22:16:42 -0800747
748 DisplayDevice device = mVirtualDisplayAdapter.createVirtualDisplayLocked(
Santos Cordonee8931e2017-04-05 10:31:15 -0700749 callback, projection, callingUid, packageName, name, width, height, densityDpi,
750 surface, flags, uniqueId);
Jeff Brown4ccb8232014-01-16 22:16:42 -0800751 if (device == null) {
752 return -1;
Jeff Brown7d00aff2013-08-02 19:03:49 -0700753 }
Jeff Browna506a6e2013-06-04 00:02:38 -0700754
Jeff Brown4ccb8232014-01-16 22:16:42 -0800755 handleDisplayDeviceAddedLocked(device);
756 LogicalDisplay display = findLogicalDisplayForDeviceLocked(device);
757 if (display != null) {
758 return display.getDisplayIdLocked();
Jeff Browna506a6e2013-06-04 00:02:38 -0700759 }
Jeff Brown4ccb8232014-01-16 22:16:42 -0800760
761 // Something weird happened and the logical display was not created.
762 Slog.w(TAG, "Rejecting request to create virtual display "
763 + "because the logical display was not created.");
Michael Wright75ee9fc2014-09-01 19:55:22 -0700764 mVirtualDisplayAdapter.releaseVirtualDisplayLocked(callback.asBinder());
Jeff Brown4ccb8232014-01-16 22:16:42 -0800765 handleDisplayDeviceRemovedLocked(device);
Jeff Browna506a6e2013-06-04 00:02:38 -0700766 }
767 return -1;
768 }
769
Michael Wright01e840f2014-06-26 16:03:25 -0700770 private void resizeVirtualDisplayInternal(IBinder appToken,
771 int width, int height, int densityDpi) {
772 synchronized (mSyncRoot) {
773 if (mVirtualDisplayAdapter == null) {
774 return;
775 }
776
777 mVirtualDisplayAdapter.resizeVirtualDisplayLocked(appToken, width, height, densityDpi);
778 }
779 }
780
Jeff Brown92207df2014-04-16 13:16:07 -0700781 private void setVirtualDisplaySurfaceInternal(IBinder appToken, Surface surface) {
782 synchronized (mSyncRoot) {
783 if (mVirtualDisplayAdapter == null) {
784 return;
785 }
786
787 mVirtualDisplayAdapter.setVirtualDisplaySurfaceLocked(appToken, surface);
788 }
789 }
790
Jeff Brown4ccb8232014-01-16 22:16:42 -0800791 private void releaseVirtualDisplayInternal(IBinder appToken) {
792 synchronized (mSyncRoot) {
793 if (mVirtualDisplayAdapter == null) {
794 return;
Jeff Browna506a6e2013-06-04 00:02:38 -0700795 }
Jeff Browna506a6e2013-06-04 00:02:38 -0700796
Jeff Brown4ccb8232014-01-16 22:16:42 -0800797 DisplayDevice device =
798 mVirtualDisplayAdapter.releaseVirtualDisplayLocked(appToken);
799 if (device != null) {
800 handleDisplayDeviceRemovedLocked(device);
Jeff Browna506a6e2013-06-04 00:02:38 -0700801 }
802 }
Jeff Browna506a6e2013-06-04 00:02:38 -0700803 }
804
Santos Cordonc22c5632017-06-21 16:03:49 -0700805 private void registerDefaultDisplayAdapters() {
806 // Register default display adapters.
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700807 synchronized (mSyncRoot) {
Santos Cordonc22c5632017-06-21 16:03:49 -0700808 // main display adapter
Mike Lockwoode63f6f72013-11-15 11:01:47 -0800809 registerDisplayAdapterLocked(new LocalDisplayAdapter(
810 mSyncRoot, mContext, mHandler, mDisplayAdapterListener));
Santos Cordonc22c5632017-06-21 16:03:49 -0700811
812 // Standalone VR devices rely on a virtual display as their primary display for
813 // 2D UI. We register virtual display adapter along side the main display adapter
814 // here so that it is ready by the time the system sends the home Intent for
815 // early apps like SetupWizard/Launcher. In particular, SUW is displayed using
816 // the virtual display inside VR before any VR-specific apps even run.
817 mVirtualDisplayAdapter = mInjector.getVirtualDisplayAdapter(mSyncRoot, mContext,
818 mHandler, mDisplayAdapterListener);
819 if (mVirtualDisplayAdapter != null) {
820 registerDisplayAdapterLocked(mVirtualDisplayAdapter);
821 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700822 }
823 }
824
825 private void registerAdditionalDisplayAdapters() {
826 synchronized (mSyncRoot) {
827 if (shouldRegisterNonEssentialDisplayAdaptersLocked()) {
Jeff Brown89d55462012-09-19 11:33:42 -0700828 registerOverlayDisplayAdapterLocked();
829 registerWifiDisplayAdapterLocked();
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700830 }
831 }
832 }
833
Jeff Brown89d55462012-09-19 11:33:42 -0700834 private void registerOverlayDisplayAdapterLocked() {
835 registerDisplayAdapterLocked(new OverlayDisplayAdapter(
836 mSyncRoot, mContext, mHandler, mDisplayAdapterListener, mUiHandler));
837 }
838
839 private void registerWifiDisplayAdapterLocked() {
840 if (mContext.getResources().getBoolean(
Jeff Brownbbd28a22012-09-20 16:47:15 -0700841 com.android.internal.R.bool.config_enableWifiDisplay)
842 || SystemProperties.getInt(FORCE_WIFI_DISPLAY_ENABLE, -1) == 1) {
Jeff Brown89d55462012-09-19 11:33:42 -0700843 mWifiDisplayAdapter = new WifiDisplayAdapter(
844 mSyncRoot, mContext, mHandler, mDisplayAdapterListener,
845 mPersistentDataStore);
846 registerDisplayAdapterLocked(mWifiDisplayAdapter);
847 }
848 }
849
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700850 private boolean shouldRegisterNonEssentialDisplayAdaptersLocked() {
851 // In safe mode, we disable non-essential display adapters to give the user
852 // an opportunity to fix broken settings or other problems that might affect
853 // system stability.
854 // In only-core mode, we disable non-essential display adapters to minimize
855 // the number of dependencies that are started while in this mode and to
856 // prevent problems that might occur due to the device being encrypted.
857 return !mSafeMode && !mOnlyCore;
858 }
859
860 private void registerDisplayAdapterLocked(DisplayAdapter adapter) {
861 mDisplayAdapters.add(adapter);
862 adapter.registerLocked();
863 }
864
Jeff Brownbd6e1502012-08-28 03:27:37 -0700865 private void handleDisplayDeviceAdded(DisplayDevice device) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700866 synchronized (mSyncRoot) {
Jeff Browna506a6e2013-06-04 00:02:38 -0700867 handleDisplayDeviceAddedLocked(device);
Jeff Brownbd6e1502012-08-28 03:27:37 -0700868 }
869 }
870
Jeff Browna506a6e2013-06-04 00:02:38 -0700871 private void handleDisplayDeviceAddedLocked(DisplayDevice device) {
Jeff Brown10acf6d2015-04-14 14:20:47 -0700872 DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
Jeff Browna506a6e2013-06-04 00:02:38 -0700873 if (mDisplayDevices.contains(device)) {
Jeff Brown10acf6d2015-04-14 14:20:47 -0700874 Slog.w(TAG, "Attempted to add already added display device: " + info);
Jeff Browna506a6e2013-06-04 00:02:38 -0700875 return;
876 }
877
Jeff Brown10acf6d2015-04-14 14:20:47 -0700878 Slog.i(TAG, "Display device added: " + info);
879 device.mDebugLastLoggedDeviceInfo = info;
Jeff Browna506a6e2013-06-04 00:02:38 -0700880
881 mDisplayDevices.add(device);
Michael Wright1c9977b2016-07-12 13:30:10 -0700882 LogicalDisplay display = addLogicalDisplayLocked(device);
Jeff Brown0033a862014-10-08 12:06:39 -0700883 Runnable work = updateDisplayStateLocked(device);
884 if (work != null) {
885 work.run();
886 }
Jeff Browna506a6e2013-06-04 00:02:38 -0700887 scheduleTraversalLocked(false);
888 }
889
Jeff Brownbd6e1502012-08-28 03:27:37 -0700890 private void handleDisplayDeviceChanged(DisplayDevice device) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700891 synchronized (mSyncRoot) {
Jeff Brown10acf6d2015-04-14 14:20:47 -0700892 DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
Jeff Brownbd6e1502012-08-28 03:27:37 -0700893 if (!mDisplayDevices.contains(device)) {
Jeff Brown10acf6d2015-04-14 14:20:47 -0700894 Slog.w(TAG, "Attempted to change non-existent display device: " + info);
Jeff Brownbd6e1502012-08-28 03:27:37 -0700895 return;
896 }
897
Jeff Brown10acf6d2015-04-14 14:20:47 -0700898 int diff = device.mDebugLastLoggedDeviceInfo.diff(info);
899 if (diff == DisplayDeviceInfo.DIFF_STATE) {
900 Slog.i(TAG, "Display device changed state: \"" + info.name
901 + "\", " + Display.stateToString(info.state));
902 } else if (diff != 0) {
903 Slog.i(TAG, "Display device changed: " + info);
904 }
Michael Wright1c9977b2016-07-12 13:30:10 -0700905 if ((diff & DisplayDeviceInfo.DIFF_COLOR_MODE) != 0) {
906 try {
907 mPersistentDataStore.setColorMode(device, info.colorMode);
908 } finally {
909 mPersistentDataStore.saveIfNeeded();
910 }
911 }
Jeff Brown10acf6d2015-04-14 14:20:47 -0700912 device.mDebugLastLoggedDeviceInfo = info;
Jeff Browne87bf032012-09-20 18:30:13 -0700913
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700914 device.applyPendingDisplayDeviceInfoChangesLocked();
915 if (updateLogicalDisplaysLocked()) {
Craig Mautner65d11b32012-10-01 13:59:52 -0700916 scheduleTraversalLocked(false);
Jeff Brown64a55af2012-08-26 02:47:39 -0700917 }
918 }
919 }
920
Jeff Brownbd6e1502012-08-28 03:27:37 -0700921 private void handleDisplayDeviceRemoved(DisplayDevice device) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700922 synchronized (mSyncRoot) {
Jeff Browna506a6e2013-06-04 00:02:38 -0700923 handleDisplayDeviceRemovedLocked(device);
924 }
925 }
Jeff Brown8e5d33e2015-06-10 13:05:50 -0700926
Jeff Browna506a6e2013-06-04 00:02:38 -0700927 private void handleDisplayDeviceRemovedLocked(DisplayDevice device) {
Jeff Brown10acf6d2015-04-14 14:20:47 -0700928 DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
Jeff Browna506a6e2013-06-04 00:02:38 -0700929 if (!mDisplayDevices.remove(device)) {
Jeff Brown10acf6d2015-04-14 14:20:47 -0700930 Slog.w(TAG, "Attempted to remove non-existent display device: " + info);
Jeff Browna506a6e2013-06-04 00:02:38 -0700931 return;
932 }
933
Jeff Brown10acf6d2015-04-14 14:20:47 -0700934 Slog.i(TAG, "Display device removed: " + info);
935 device.mDebugLastLoggedDeviceInfo = info;
Jeff Browna506a6e2013-06-04 00:02:38 -0700936
Jeff Browna506a6e2013-06-04 00:02:38 -0700937 updateLogicalDisplaysLocked();
938 scheduleTraversalLocked(false);
939 }
940
Jeff Brown8e5d33e2015-06-10 13:05:50 -0700941 private void applyGlobalDisplayStateLocked(List<Runnable> workQueue) {
Jeff Browna506a6e2013-06-04 00:02:38 -0700942 final int count = mDisplayDevices.size();
943 for (int i = 0; i < count; i++) {
944 DisplayDevice device = mDisplayDevices.get(i);
Jeff Browne75926d2014-09-18 15:24:49 -0700945 Runnable runnable = updateDisplayStateLocked(device);
946 if (runnable != null) {
947 workQueue.add(runnable);
948 }
Jeff Browna506a6e2013-06-04 00:02:38 -0700949 }
950 }
951
Jeff Browne75926d2014-09-18 15:24:49 -0700952 private Runnable updateDisplayStateLocked(DisplayDevice device) {
Jeff Browna506a6e2013-06-04 00:02:38 -0700953 // Blank or unblank the display immediately to match the state requested
Jeff Brown037c33e2014-04-09 00:31:55 -0700954 // by the display power controller (if known).
Jeff Browna506a6e2013-06-04 00:02:38 -0700955 DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
956 if ((info.flags & DisplayDeviceInfo.FLAG_NEVER_BLANK) == 0) {
Jeff Brown5d6443b2015-04-10 20:15:01 -0700957 return device.requestDisplayStateLocked(mGlobalDisplayState, mGlobalDisplayBrightness);
Craig Mautner4f67ba62012-08-02 11:23:00 -0700958 }
Jeff Browne75926d2014-09-18 15:24:49 -0700959 return null;
Craig Mautner4f67ba62012-08-02 11:23:00 -0700960 }
961
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700962 // Adds a new logical display based on the given display device.
963 // Sends notifications if needed.
Michael Wright1c9977b2016-07-12 13:30:10 -0700964 private LogicalDisplay addLogicalDisplayLocked(DisplayDevice device) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700965 DisplayDeviceInfo deviceInfo = device.getDisplayDeviceInfoLocked();
966 boolean isDefault = (deviceInfo.flags
967 & DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY) != 0;
968 if (isDefault && mLogicalDisplays.get(Display.DEFAULT_DISPLAY) != null) {
969 Slog.w(TAG, "Ignoring attempt to add a second default display: " + deviceInfo);
970 isDefault = false;
971 }
972
Jeff Brown27f1d672012-10-17 18:32:34 -0700973 if (!isDefault && mSingleDisplayDemoMode) {
974 Slog.i(TAG, "Not creating a logical display for a secondary display "
975 + " because single display demo mode is enabled: " + deviceInfo);
Michael Wright1c9977b2016-07-12 13:30:10 -0700976 return null;
Jeff Brown27f1d672012-10-17 18:32:34 -0700977 }
978
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700979 final int displayId = assignDisplayIdLocked(isDefault);
980 final int layerStack = assignLayerStackLocked(displayId);
981
Jeff Brownd728bf52012-09-08 18:05:28 -0700982 LogicalDisplay display = new LogicalDisplay(displayId, layerStack, device);
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700983 display.updateLocked(mDisplayDevices);
984 if (!display.isValidLocked()) {
985 // This should never happen currently.
986 Slog.w(TAG, "Ignoring display device because the logical display "
987 + "created from it was not considered valid: " + deviceInfo);
Michael Wright1c9977b2016-07-12 13:30:10 -0700988 return null;
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700989 }
990
Michael Wrighteedcbf12017-08-16 23:14:54 +0100991 configureColorModeLocked(display, device);
992 if (isDefault) {
993 recordStableDisplayStatsIfNeededLocked(display);
994 }
995
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700996 mLogicalDisplays.put(displayId, display);
997
998 // Wake up waitForDefaultDisplay.
999 if (isDefault) {
1000 mSyncRoot.notifyAll();
1001 }
1002
1003 sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_ADDED);
Michael Wright1c9977b2016-07-12 13:30:10 -07001004 return display;
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001005 }
1006
1007 private int assignDisplayIdLocked(boolean isDefault) {
1008 return isDefault ? Display.DEFAULT_DISPLAY : mNextNonDefaultDisplayId++;
1009 }
1010
1011 private int assignLayerStackLocked(int displayId) {
1012 // Currently layer stacks and display ids are the same.
1013 // This need not be the case.
1014 return displayId;
1015 }
1016
Michael Wrighteedcbf12017-08-16 23:14:54 +01001017 private void configureColorModeLocked(LogicalDisplay display, DisplayDevice device) {
1018 if (display.getPrimaryDisplayDeviceLocked() == device) {
1019 int colorMode = mPersistentDataStore.getColorMode(device);
1020 if (colorMode == Display.COLOR_MODE_INVALID) {
1021 if ((device.getDisplayDeviceInfoLocked().flags
1022 & DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY) != 0) {
1023 colorMode = mDefaultDisplayDefaultColorMode;
1024 } else {
1025 colorMode = Display.COLOR_MODE_DEFAULT;
1026 }
1027 }
1028 display.setRequestedColorModeLocked(colorMode);
1029 }
1030 }
1031
1032 // If we've never recorded stable device stats for this device before and they aren't
1033 // explicitly configured, go ahead and record the stable device stats now based on the status
1034 // of the default display at first boot.
1035 private void recordStableDisplayStatsIfNeededLocked(LogicalDisplay d) {
1036 if (mStableDisplaySize.x <= 0 && mStableDisplaySize.y <= 0) {
1037 DisplayInfo info = d.getDisplayInfoLocked();
1038 setStableDisplaySizeLocked(info.getNaturalWidth(), info.getNaturalHeight());
1039 }
1040 }
1041
1042 private void setStableDisplaySizeLocked(int width, int height) {
1043 mStableDisplaySize = new Point(width, height);
1044 try {
1045 mPersistentDataStore.setStableDisplaySize(mStableDisplaySize);
1046 } finally {
1047 mPersistentDataStore.saveIfNeeded();
1048 }
1049 }
1050
Dan Gittik122df862018-03-28 16:59:22 +01001051 @VisibleForTesting
1052 Curve getMinimumBrightnessCurveInternal() {
1053 return mMinimumBrightnessCurve;
1054 }
1055
Michael Wrighteef0e132017-11-21 17:57:52 +00001056 private void setBrightnessConfigurationForUserInternal(
Dan Gittik7a32fba2018-03-28 12:19:38 +01001057 @Nullable BrightnessConfiguration c, @UserIdInt int userId,
Kenny Guy05ce8092018-01-17 13:44:20 +00001058 @Nullable String packageName) {
Dan Gittik122df862018-03-28 16:59:22 +01001059 validateBrightnessConfiguration(c);
Michael Wrighteef0e132017-11-21 17:57:52 +00001060 final int userSerial = getUserManager().getUserSerialNumber(userId);
1061 synchronized (mSyncRoot) {
1062 try {
Kenny Guy05ce8092018-01-17 13:44:20 +00001063 mPersistentDataStore.setBrightnessConfigurationForUser(c, userSerial,
1064 packageName);
Michael Wrighteef0e132017-11-21 17:57:52 +00001065 } finally {
1066 mPersistentDataStore.saveIfNeeded();
1067 }
1068 if (userId == mCurrentUserId) {
1069 mDisplayPowerController.setBrightnessConfiguration(c);
1070 }
1071 }
1072 }
1073
Dan Gittik122df862018-03-28 16:59:22 +01001074 @VisibleForTesting
1075 void validateBrightnessConfiguration(BrightnessConfiguration config) {
1076 if (config == null) {
1077 return;
1078 }
1079 if (isBrightnessConfigurationTooDark(config)) {
1080 throw new IllegalArgumentException("brightness curve is too dark");
1081 }
1082 }
1083
1084 private boolean isBrightnessConfigurationTooDark(BrightnessConfiguration config) {
1085 Pair<float[], float[]> curve = config.getCurve();
1086 float[] lux = curve.first;
1087 float[] nits = curve.second;
1088 for (int i = 0; i < lux.length; i++) {
1089 if (nits[i] < mMinimumBrightnessSpline.interpolate(lux[i])) {
1090 return true;
1091 }
1092 }
1093 return false;
1094 }
1095
Michael Wrighteef0e132017-11-21 17:57:52 +00001096 private void loadBrightnessConfiguration() {
1097 synchronized (mSyncRoot) {
1098 final int userSerial = getUserManager().getUserSerialNumber(mCurrentUserId);
1099 BrightnessConfiguration config =
1100 mPersistentDataStore.getBrightnessConfiguration(userSerial);
1101 mDisplayPowerController.setBrightnessConfiguration(config);
1102 }
1103 }
1104
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001105 // Updates all existing logical displays given the current set of display devices.
1106 // Removes invalid logical displays.
1107 // Sends notifications if needed.
1108 private boolean updateLogicalDisplaysLocked() {
1109 boolean changed = false;
1110 for (int i = mLogicalDisplays.size(); i-- > 0; ) {
1111 final int displayId = mLogicalDisplays.keyAt(i);
1112 LogicalDisplay display = mLogicalDisplays.valueAt(i);
1113
1114 mTempDisplayInfo.copyFrom(display.getDisplayInfoLocked());
1115 display.updateLocked(mDisplayDevices);
1116 if (!display.isValidLocked()) {
1117 mLogicalDisplays.removeAt(i);
1118 sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_REMOVED);
1119 changed = true;
1120 } else if (!mTempDisplayInfo.equals(display.getDisplayInfoLocked())) {
1121 sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_CHANGED);
1122 changed = true;
1123 }
1124 }
1125 return changed;
1126 }
1127
Robert Carrae606b42018-02-15 15:36:23 -08001128 private void performTraversalLocked(SurfaceControl.Transaction t) {
Jeff Brownd728bf52012-09-08 18:05:28 -07001129 // Clear all viewports before configuring displays so that we can keep
1130 // track of which ones we have configured.
1131 clearViewportsLocked();
1132
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001133 // Configure each display device.
1134 final int count = mDisplayDevices.size();
1135 for (int i = 0; i < count; i++) {
1136 DisplayDevice device = mDisplayDevices.get(i);
Robert Carrae606b42018-02-15 15:36:23 -08001137 configureDisplayLocked(t, device);
1138 device.performTraversalLocked(t);
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001139 }
Jeff Brownd728bf52012-09-08 18:05:28 -07001140
1141 // Tell the input system about these new viewports.
Jeff Brown4ccb8232014-01-16 22:16:42 -08001142 if (mInputManagerInternal != null) {
Jeff Brownd728bf52012-09-08 18:05:28 -07001143 mHandler.sendEmptyMessage(MSG_UPDATE_VIEWPORT);
1144 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001145 }
1146
Michael Wright3f145a22014-07-22 19:46:03 -07001147 private void setDisplayPropertiesInternal(int displayId, boolean hasContent,
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -07001148 float requestedRefreshRate, int requestedModeId, boolean inTraversal) {
Craig Mautner722285e2012-09-07 13:55:58 -07001149 synchronized (mSyncRoot) {
1150 LogicalDisplay display = mLogicalDisplays.get(displayId);
Michael Wright3f145a22014-07-22 19:46:03 -07001151 if (display == null) {
1152 return;
1153 }
1154 if (display.hasContentLocked() != hasContent) {
Jeff Brown33041bd2013-08-02 21:11:14 -07001155 if (DEBUG) {
1156 Slog.d(TAG, "Display " + displayId + " hasContent flag changed: "
1157 + "hasContent=" + hasContent + ", inTraversal=" + inTraversal);
1158 }
1159
Craig Mautner722285e2012-09-07 13:55:58 -07001160 display.setHasContentLocked(hasContent);
Craig Mautner65d11b32012-10-01 13:59:52 -07001161 scheduleTraversalLocked(inTraversal);
Craig Mautner722285e2012-09-07 13:55:58 -07001162 }
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -07001163 if (requestedModeId == 0 && requestedRefreshRate != 0) {
1164 // Scan supported modes returned by display.getInfo() to find a mode with the same
1165 // size as the default display mode but with the specified refresh rate instead.
1166 requestedModeId = display.getDisplayInfoLocked().findDefaultModeByRefreshRate(
1167 requestedRefreshRate);
1168 }
1169 if (display.getRequestedModeIdLocked() != requestedModeId) {
Michael Wright3f145a22014-07-22 19:46:03 -07001170 if (DEBUG) {
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -07001171 Slog.d(TAG, "Display " + displayId + " switching to mode " + requestedModeId);
Michael Wright3f145a22014-07-22 19:46:03 -07001172 }
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -07001173 display.setRequestedModeIdLocked(requestedModeId);
Michael Wright3f145a22014-07-22 19:46:03 -07001174 scheduleTraversalLocked(inTraversal);
1175 }
Craig Mautner722285e2012-09-07 13:55:58 -07001176 }
Jeff Brownd728bf52012-09-08 18:05:28 -07001177 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001178
Filip Gruszczynskid2e86402015-02-19 13:05:03 -08001179 private void setDisplayOffsetsInternal(int displayId, int x, int y) {
1180 synchronized (mSyncRoot) {
1181 LogicalDisplay display = mLogicalDisplays.get(displayId);
1182 if (display == null) {
1183 return;
1184 }
1185 if (display.getDisplayOffsetXLocked() != x
1186 || display.getDisplayOffsetYLocked() != y) {
1187 if (DEBUG) {
1188 Slog.d(TAG, "Display " + displayId + " burn-in offset set to ("
1189 + x + ", " + y + ")");
1190 }
1191 display.setDisplayOffsetsLocked(x, y);
1192 scheduleTraversalLocked(false);
1193 }
1194 }
1195 }
1196
Andrii Kulianfb1bf692017-01-17 11:17:34 -08001197 // Updates the lists of UIDs that are present on displays.
1198 private void setDisplayAccessUIDsInternal(SparseArray<IntArray> newDisplayAccessUIDs) {
1199 synchronized (mSyncRoot) {
1200 mDisplayAccessUIDs.clear();
1201 for (int i = newDisplayAccessUIDs.size() - 1; i >= 0; i--) {
1202 mDisplayAccessUIDs.append(newDisplayAccessUIDs.keyAt(i),
1203 newDisplayAccessUIDs.valueAt(i));
1204 }
1205 }
1206 }
1207
1208 // Checks if provided UID's content is present on the display and UID has access to it.
1209 private boolean isUidPresentOnDisplayInternal(int uid, int displayId) {
1210 synchronized (mSyncRoot) {
1211 final IntArray displayUIDs = mDisplayAccessUIDs.get(displayId);
1212 return displayUIDs != null && displayUIDs.indexOf(uid) != -1;
1213 }
1214 }
1215
Jeff Brownd728bf52012-09-08 18:05:28 -07001216 private void clearViewportsLocked() {
1217 mDefaultViewport.valid = false;
1218 mExternalTouchViewport.valid = false;
Santos Cordonee8931e2017-04-05 10:31:15 -07001219 mVirtualTouchViewports.clear();
Craig Mautner722285e2012-09-07 13:55:58 -07001220 }
1221
Robert Carrae606b42018-02-15 15:36:23 -08001222 private void configureDisplayLocked(SurfaceControl.Transaction t, DisplayDevice device) {
Jeff Brownd14c8c92014-01-07 18:13:09 -08001223 final DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
1224 final boolean ownContent = (info.flags & DisplayDeviceInfo.FLAG_OWN_CONTENT_ONLY) != 0;
Jeff Browna506a6e2013-06-04 00:02:38 -07001225
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001226 // Find the logical display that the display device is showing.
Jeff Brownd14c8c92014-01-07 18:13:09 -08001227 // Certain displays only ever show their own content.
Craig Mautner722285e2012-09-07 13:55:58 -07001228 LogicalDisplay display = findLogicalDisplayForDeviceLocked(device);
Jeff Brownd14c8c92014-01-07 18:13:09 -08001229 if (!ownContent) {
Jeff Browna506a6e2013-06-04 00:02:38 -07001230 if (display != null && !display.hasContentLocked()) {
1231 // If the display does not have any content of its own, then
1232 // automatically mirror the default logical display contents.
1233 display = null;
1234 }
1235 if (display == null) {
1236 display = mLogicalDisplays.get(Display.DEFAULT_DISPLAY);
1237 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001238 }
1239
1240 // Apply the logical display configuration to the display device.
1241 if (display == null) {
1242 // TODO: no logical display for the device, blank it
Jeff Brownd728bf52012-09-08 18:05:28 -07001243 Slog.w(TAG, "Missing logical display to use for physical display device: "
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001244 + device.getDisplayDeviceInfoLocked());
Jeff Brownd728bf52012-09-08 18:05:28 -07001245 return;
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001246 }
Robert Carrae606b42018-02-15 15:36:23 -08001247 display.configureDisplayLocked(t, device, info.state == Display.STATE_OFF);
Jeff Brownd728bf52012-09-08 18:05:28 -07001248
1249 // Update the viewports if needed.
Jeff Brownd728bf52012-09-08 18:05:28 -07001250 if (!mDefaultViewport.valid
1251 && (info.flags & DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY) != 0) {
1252 setViewportLocked(mDefaultViewport, display, device);
1253 }
1254 if (!mExternalTouchViewport.valid
1255 && info.touch == DisplayDeviceInfo.TOUCH_EXTERNAL) {
1256 setViewportLocked(mExternalTouchViewport, display, device);
1257 }
Santos Cordonee8931e2017-04-05 10:31:15 -07001258
1259 if (info.touch == DisplayDeviceInfo.TOUCH_VIRTUAL && !TextUtils.isEmpty(info.uniqueId)) {
1260 final DisplayViewport viewport = getVirtualTouchViewportLocked(info.uniqueId);
1261 setViewportLocked(viewport, display, device);
1262 }
1263 }
1264
1265 /** Gets the virtual device viewport or creates it if not yet created. */
1266 private DisplayViewport getVirtualTouchViewportLocked(@NonNull String uniqueId) {
1267 DisplayViewport viewport;
1268 final int count = mVirtualTouchViewports.size();
1269 for (int i = 0; i < count; i++) {
1270 viewport = mVirtualTouchViewports.get(i);
1271 if (uniqueId.equals(viewport.uniqueId)) {
1272 return viewport;
1273 }
1274 }
1275
1276 viewport = new DisplayViewport();
1277 viewport.uniqueId = uniqueId;
1278 mVirtualTouchViewports.add(viewport);
1279 return viewport;
Jeff Brownd728bf52012-09-08 18:05:28 -07001280 }
1281
1282 private static void setViewportLocked(DisplayViewport viewport,
1283 LogicalDisplay display, DisplayDevice device) {
1284 viewport.valid = true;
1285 viewport.displayId = display.getDisplayIdLocked();
1286 device.populateViewportLocked(viewport);
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001287 }
1288
1289 private LogicalDisplay findLogicalDisplayForDeviceLocked(DisplayDevice device) {
1290 final int count = mLogicalDisplays.size();
1291 for (int i = 0; i < count; i++) {
1292 LogicalDisplay display = mLogicalDisplays.valueAt(i);
1293 if (display.getPrimaryDisplayDeviceLocked() == device) {
1294 return display;
1295 }
1296 }
1297 return null;
1298 }
1299
Jeff Brownbd6e1502012-08-28 03:27:37 -07001300 private void sendDisplayEventLocked(int displayId, int event) {
1301 Message msg = mHandler.obtainMessage(MSG_DELIVER_DISPLAY_EVENT, displayId, event);
1302 mHandler.sendMessage(msg);
1303 }
1304
Robert Carrae606b42018-02-15 15:36:23 -08001305 // Requests that performTraversals be called at a
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001306 // later time to apply changes to surfaces and displays.
Craig Mautner65d11b32012-10-01 13:59:52 -07001307 private void scheduleTraversalLocked(boolean inTraversal) {
Jeff Brown4ccb8232014-01-16 22:16:42 -08001308 if (!mPendingTraversal && mWindowManagerInternal != null) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001309 mPendingTraversal = true;
Craig Mautner65d11b32012-10-01 13:59:52 -07001310 if (!inTraversal) {
1311 mHandler.sendEmptyMessage(MSG_REQUEST_TRAVERSAL);
1312 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001313 }
1314 }
1315
1316 // Runs on Handler thread.
1317 // Delivers display event notifications to callbacks.
Jeff Brownbd6e1502012-08-28 03:27:37 -07001318 private void deliverDisplayEvent(int displayId, int event) {
1319 if (DEBUG) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001320 Slog.d(TAG, "Delivering display event: displayId="
1321 + displayId + ", event=" + event);
Jeff Brownfa25bf52012-07-23 19:26:30 -07001322 }
Jeff Brownfa25bf52012-07-23 19:26:30 -07001323
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001324 // Grab the lock and copy the callbacks.
Jeff Brownbd6e1502012-08-28 03:27:37 -07001325 final int count;
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001326 synchronized (mSyncRoot) {
Jeff Brownbd6e1502012-08-28 03:27:37 -07001327 count = mCallbacks.size();
1328 mTempCallbacks.clear();
1329 for (int i = 0; i < count; i++) {
1330 mTempCallbacks.add(mCallbacks.valueAt(i));
Craig Mautner4f67ba62012-08-02 11:23:00 -07001331 }
Jeff Brownbd6e1502012-08-28 03:27:37 -07001332 }
Craig Mautner4f67ba62012-08-02 11:23:00 -07001333
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001334 // After releasing the lock, send the notifications out.
Jeff Brownbd6e1502012-08-28 03:27:37 -07001335 for (int i = 0; i < count; i++) {
1336 mTempCallbacks.get(i).notifyDisplayEventAsync(displayId, event);
1337 }
1338 mTempCallbacks.clear();
Craig Mautner4f67ba62012-08-02 11:23:00 -07001339 }
1340
Michael Wrightc39d47a2014-07-08 18:07:36 -07001341 private IMediaProjectionManager getProjectionService() {
1342 if (mProjectionService == null) {
1343 IBinder b = ServiceManager.getService(Context.MEDIA_PROJECTION_SERVICE);
1344 mProjectionService = IMediaProjectionManager.Stub.asInterface(b);
1345 }
1346 return mProjectionService;
1347 }
1348
Michael Wrighteef0e132017-11-21 17:57:52 +00001349 private UserManager getUserManager() {
1350 return mContext.getSystemService(UserManager.class);
1351 }
1352
Jeff Brown4ccb8232014-01-16 22:16:42 -08001353 private void dumpInternal(PrintWriter pw) {
Jeff Brownbd6e1502012-08-28 03:27:37 -07001354 pw.println("DISPLAY MANAGER (dumpsys display)");
Jeff Brownfa25bf52012-07-23 19:26:30 -07001355
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001356 synchronized (mSyncRoot) {
Jeff Brown9e316a12012-10-08 19:17:06 -07001357 pw.println(" mOnlyCode=" + mOnlyCore);
1358 pw.println(" mSafeMode=" + mSafeMode);
1359 pw.println(" mPendingTraversal=" + mPendingTraversal);
Jeff Brown037c33e2014-04-09 00:31:55 -07001360 pw.println(" mGlobalDisplayState=" + Display.stateToString(mGlobalDisplayState));
Jeff Brown9e316a12012-10-08 19:17:06 -07001361 pw.println(" mNextNonDefaultDisplayId=" + mNextNonDefaultDisplayId);
1362 pw.println(" mDefaultViewport=" + mDefaultViewport);
1363 pw.println(" mExternalTouchViewport=" + mExternalTouchViewport);
Santos Cordonee8931e2017-04-05 10:31:15 -07001364 pw.println(" mVirtualTouchViewports=" + mVirtualTouchViewports);
Damien Bargiacchi4364bbf2016-11-01 21:44:20 -07001365 pw.println(" mDefaultDisplayDefaultColorMode=" + mDefaultDisplayDefaultColorMode);
Jeff Brown27f1d672012-10-17 18:32:34 -07001366 pw.println(" mSingleDisplayDemoMode=" + mSingleDisplayDemoMode);
Jeff Brownce468a32013-11-21 16:42:03 -08001367 pw.println(" mWifiDisplayScanRequestCount=" + mWifiDisplayScanRequestCount);
Michael Wrighteedcbf12017-08-16 23:14:54 +01001368 pw.println(" mStableDisplaySize=" + mStableDisplaySize);
1369
Jeff Brown9e316a12012-10-08 19:17:06 -07001370
Jeff Brownbd6e1502012-08-28 03:27:37 -07001371 IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001372 ipw.increaseIndent();
Jeff Brownbd6e1502012-08-28 03:27:37 -07001373
1374 pw.println();
1375 pw.println("Display Adapters: size=" + mDisplayAdapters.size());
Jeff Brown848c2dc2012-08-19 20:18:08 -07001376 for (DisplayAdapter adapter : mDisplayAdapters) {
Jeff Brownbd6e1502012-08-28 03:27:37 -07001377 pw.println(" " + adapter.getName());
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001378 adapter.dumpLocked(ipw);
Jeff Brown848c2dc2012-08-19 20:18:08 -07001379 }
Craig Mautner9de49362012-08-02 14:30:30 -07001380
Jeff Brownbd6e1502012-08-28 03:27:37 -07001381 pw.println();
1382 pw.println("Display Devices: size=" + mDisplayDevices.size());
1383 for (DisplayDevice device : mDisplayDevices) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001384 pw.println(" " + device.getDisplayDeviceInfoLocked());
1385 device.dumpLocked(ipw);
Jeff Brownbd6e1502012-08-28 03:27:37 -07001386 }
1387
1388 final int logicalDisplayCount = mLogicalDisplays.size();
1389 pw.println();
1390 pw.println("Logical Displays: size=" + logicalDisplayCount);
1391 for (int i = 0; i < logicalDisplayCount; i++) {
1392 int displayId = mLogicalDisplays.keyAt(i);
1393 LogicalDisplay display = mLogicalDisplays.valueAt(i);
1394 pw.println(" Display " + displayId + ":");
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001395 display.dumpLocked(ipw);
Jeff Brownbd6e1502012-08-28 03:27:37 -07001396 }
Jeff Brownce468a32013-11-21 16:42:03 -08001397
1398 final int callbackCount = mCallbacks.size();
1399 pw.println();
1400 pw.println("Callbacks: size=" + callbackCount);
1401 for (int i = 0; i < callbackCount; i++) {
1402 CallbackRecord callback = mCallbacks.valueAt(i);
1403 pw.println(" " + i + ": mPid=" + callback.mPid
1404 + ", mWifiDisplayScanRequested=" + callback.mWifiDisplayScanRequested);
1405 }
Jeff Brownad9ef192014-04-08 17:26:30 -07001406
1407 if (mDisplayPowerController != null) {
1408 mDisplayPowerController.dump(pw);
1409 }
Michael Wright1c9977b2016-07-12 13:30:10 -07001410
1411 pw.println();
1412 mPersistentDataStore.dump(pw);
Jeff Brownbd6e1502012-08-28 03:27:37 -07001413 }
1414 }
1415
Dan Gittik122df862018-03-28 16:59:22 +01001416 private static float[] getFloatArray(TypedArray array) {
1417 int length = array.length();
1418 float[] floatArray = new float[length];
1419 for (int i = 0; i < length; i++) {
1420 floatArray[i] = array.getFloat(i, Float.NaN);
1421 }
1422 array.recycle();
1423 return floatArray;
1424 }
1425
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001426 /**
1427 * This is the object that everything in the display manager locks on.
1428 * We make it an inner class within the {@link DisplayManagerService} to so that it is
1429 * clear that the object belongs to the display manager service and that it is
1430 * a unique object with a special purpose.
1431 */
1432 public static final class SyncRoot {
1433 }
1434
Santos Cordonee8931e2017-04-05 10:31:15 -07001435 @VisibleForTesting
1436 static class Injector {
1437 VirtualDisplayAdapter getVirtualDisplayAdapter(SyncRoot syncRoot, Context context,
1438 Handler handler, DisplayAdapter.Listener displayAdapterListener) {
1439 return new VirtualDisplayAdapter(syncRoot, context, handler, displayAdapterListener);
1440 }
Santos Cordonc22c5632017-06-21 16:03:49 -07001441
1442 long getDefaultDisplayDelayTimeout() {
1443 return WAIT_FOR_DEFAULT_DISPLAY_TIMEOUT;
1444 }
Santos Cordonee8931e2017-04-05 10:31:15 -07001445 }
1446
Alex Sakhartchouk879d24f2017-06-20 22:01:19 -04001447 @VisibleForTesting
1448 DisplayDeviceInfo getDisplayDeviceInfoInternal(int displayId) {
1449 synchronized (mSyncRoot) {
1450 LogicalDisplay display = mLogicalDisplays.get(displayId);
1451 if (display != null) {
1452 DisplayDevice displayDevice = display.getPrimaryDisplayDeviceLocked();
1453 return displayDevice.getDisplayDeviceInfoLocked();
1454 }
1455 return null;
1456 }
1457 }
1458
Jeff Brownbd6e1502012-08-28 03:27:37 -07001459 private final class DisplayManagerHandler extends Handler {
1460 public DisplayManagerHandler(Looper looper) {
1461 super(looper, null, true /*async*/);
Jeff Brown848c2dc2012-08-19 20:18:08 -07001462 }
Jeff Brownbf5740e2012-08-19 23:20:02 -07001463
Jeff Brownbd6e1502012-08-28 03:27:37 -07001464 @Override
1465 public void handleMessage(Message msg) {
1466 switch (msg.what) {
Santos Cordonc22c5632017-06-21 16:03:49 -07001467 case MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS:
1468 registerDefaultDisplayAdapters();
Jeff Brownbd6e1502012-08-28 03:27:37 -07001469 break;
1470
1471 case MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS:
1472 registerAdditionalDisplayAdapters();
1473 break;
1474
1475 case MSG_DELIVER_DISPLAY_EVENT:
1476 deliverDisplayEvent(msg.arg1, msg.arg2);
1477 break;
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001478
1479 case MSG_REQUEST_TRAVERSAL:
Jeff Brown4ccb8232014-01-16 22:16:42 -08001480 mWindowManagerInternal.requestTraversalFromDisplayManager();
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001481 break;
Jeff Brownd728bf52012-09-08 18:05:28 -07001482
1483 case MSG_UPDATE_VIEWPORT: {
1484 synchronized (mSyncRoot) {
1485 mTempDefaultViewport.copyFrom(mDefaultViewport);
1486 mTempExternalTouchViewport.copyFrom(mExternalTouchViewport);
Santos Cordonee8931e2017-04-05 10:31:15 -07001487 if (!mTempVirtualTouchViewports.equals(mVirtualTouchViewports)) {
1488 mTempVirtualTouchViewports.clear();
1489 for (DisplayViewport d : mVirtualTouchViewports) {
1490 mTempVirtualTouchViewports.add(d.makeCopy());
1491 }
1492 }
Jeff Brownd728bf52012-09-08 18:05:28 -07001493 }
Santos Cordonee8931e2017-04-05 10:31:15 -07001494 mInputManagerInternal.setDisplayViewports(mTempDefaultViewport,
1495 mTempExternalTouchViewport, mTempVirtualTouchViewports);
Jeff Brownd728bf52012-09-08 18:05:28 -07001496 break;
1497 }
Kenny Guy22bd0442017-10-26 00:15:54 +01001498
Michael Wrighteef0e132017-11-21 17:57:52 +00001499 case MSG_LOAD_BRIGHTNESS_CONFIGURATION:
1500 loadBrightnessConfiguration();
1501 break;
Jeff Brownbd6e1502012-08-28 03:27:37 -07001502 }
1503 }
1504 }
1505
1506 private final class DisplayAdapterListener implements DisplayAdapter.Listener {
1507 @Override
1508 public void onDisplayDeviceEvent(DisplayDevice device, int event) {
1509 switch (event) {
1510 case DisplayAdapter.DISPLAY_DEVICE_EVENT_ADDED:
1511 handleDisplayDeviceAdded(device);
1512 break;
1513
1514 case DisplayAdapter.DISPLAY_DEVICE_EVENT_CHANGED:
1515 handleDisplayDeviceChanged(device);
1516 break;
1517
1518 case DisplayAdapter.DISPLAY_DEVICE_EVENT_REMOVED:
1519 handleDisplayDeviceRemoved(device);
1520 break;
1521 }
1522 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001523
1524 @Override
1525 public void onTraversalRequested() {
1526 synchronized (mSyncRoot) {
Craig Mautner65d11b32012-10-01 13:59:52 -07001527 scheduleTraversalLocked(false);
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001528 }
1529 }
Jeff Brownbd6e1502012-08-28 03:27:37 -07001530 }
1531
1532 private final class CallbackRecord implements DeathRecipient {
Jeff Brownce468a32013-11-21 16:42:03 -08001533 public final int mPid;
Jeff Brownbd6e1502012-08-28 03:27:37 -07001534 private final IDisplayManagerCallback mCallback;
1535
Jeff Brownce468a32013-11-21 16:42:03 -08001536 public boolean mWifiDisplayScanRequested;
1537
Jeff Brownbd6e1502012-08-28 03:27:37 -07001538 public CallbackRecord(int pid, IDisplayManagerCallback callback) {
1539 mPid = pid;
1540 mCallback = callback;
1541 }
1542
1543 @Override
1544 public void binderDied() {
1545 if (DEBUG) {
1546 Slog.d(TAG, "Display listener for pid " + mPid + " died.");
1547 }
Jeff Brownce468a32013-11-21 16:42:03 -08001548 onCallbackDied(this);
Jeff Brownbd6e1502012-08-28 03:27:37 -07001549 }
1550
1551 public void notifyDisplayEventAsync(int displayId, int event) {
1552 try {
1553 mCallback.onDisplayEvent(displayId, event);
1554 } catch (RemoteException ex) {
1555 Slog.w(TAG, "Failed to notify process "
1556 + mPid + " that displays changed, assuming it died.", ex);
1557 binderDied();
1558 }
1559 }
1560 }
Jeff Brown4ccb8232014-01-16 22:16:42 -08001561
Santos Cordonee8931e2017-04-05 10:31:15 -07001562 @VisibleForTesting
1563 final class BinderService extends IDisplayManager.Stub {
Jeff Brown4ccb8232014-01-16 22:16:42 -08001564 /**
1565 * Returns information about the specified logical display.
1566 *
1567 * @param displayId The logical display id.
1568 * @return The logical display info, or null if the display does not exist. The
1569 * returned object must be treated as immutable.
1570 */
1571 @Override // Binder call
1572 public DisplayInfo getDisplayInfo(int displayId) {
1573 final int callingUid = Binder.getCallingUid();
1574 final long token = Binder.clearCallingIdentity();
1575 try {
1576 return getDisplayInfoInternal(displayId, callingUid);
1577 } finally {
1578 Binder.restoreCallingIdentity(token);
1579 }
1580 }
1581
1582 /**
1583 * Returns the list of all display ids.
1584 */
1585 @Override // Binder call
1586 public int[] getDisplayIds() {
1587 final int callingUid = Binder.getCallingUid();
1588 final long token = Binder.clearCallingIdentity();
1589 try {
1590 return getDisplayIdsInternal(callingUid);
1591 } finally {
1592 Binder.restoreCallingIdentity(token);
1593 }
1594 }
1595
Michael Wrighteedcbf12017-08-16 23:14:54 +01001596 /**
1597 * Returns the stable device display size, in pixels.
1598 */
1599 @Override // Binder call
1600 public Point getStableDisplaySize() {
1601 final long token = Binder.clearCallingIdentity();
1602 try {
1603 return getStableDisplaySizeInternal();
1604 } finally {
1605 Binder.restoreCallingIdentity(token);
1606 }
1607 }
1608
Jeff Brown4ccb8232014-01-16 22:16:42 -08001609 @Override // Binder call
1610 public void registerCallback(IDisplayManagerCallback callback) {
1611 if (callback == null) {
1612 throw new IllegalArgumentException("listener must not be null");
1613 }
1614
1615 final int callingPid = Binder.getCallingPid();
1616 final long token = Binder.clearCallingIdentity();
1617 try {
1618 registerCallbackInternal(callback, callingPid);
1619 } finally {
1620 Binder.restoreCallingIdentity(token);
1621 }
1622 }
1623
1624 @Override // Binder call
1625 public void startWifiDisplayScan() {
1626 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
1627 "Permission required to start wifi display scans");
1628
1629 final int callingPid = Binder.getCallingPid();
1630 final long token = Binder.clearCallingIdentity();
1631 try {
1632 startWifiDisplayScanInternal(callingPid);
1633 } finally {
1634 Binder.restoreCallingIdentity(token);
1635 }
1636 }
1637
1638 @Override // Binder call
1639 public void stopWifiDisplayScan() {
1640 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
1641 "Permission required to stop wifi display scans");
1642
1643 final int callingPid = Binder.getCallingPid();
1644 final long token = Binder.clearCallingIdentity();
1645 try {
1646 stopWifiDisplayScanInternal(callingPid);
1647 } finally {
1648 Binder.restoreCallingIdentity(token);
1649 }
1650 }
1651
1652 @Override // Binder call
1653 public void connectWifiDisplay(String address) {
1654 if (address == null) {
1655 throw new IllegalArgumentException("address must not be null");
1656 }
1657 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
1658 "Permission required to connect to a wifi display");
1659
1660 final long token = Binder.clearCallingIdentity();
1661 try {
1662 connectWifiDisplayInternal(address);
1663 } finally {
1664 Binder.restoreCallingIdentity(token);
1665 }
1666 }
1667
1668 @Override // Binder call
1669 public void disconnectWifiDisplay() {
1670 // This request does not require special permissions.
1671 // Any app can request disconnection from the currently active wifi display.
1672 // This exception should no longer be needed once wifi display control moves
1673 // to the media router service.
1674
1675 final long token = Binder.clearCallingIdentity();
1676 try {
1677 disconnectWifiDisplayInternal();
1678 } finally {
1679 Binder.restoreCallingIdentity(token);
1680 }
1681 }
1682
1683 @Override // Binder call
1684 public void renameWifiDisplay(String address, String alias) {
1685 if (address == null) {
1686 throw new IllegalArgumentException("address must not be null");
1687 }
1688 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
1689 "Permission required to rename to a wifi display");
1690
1691 final long token = Binder.clearCallingIdentity();
1692 try {
1693 renameWifiDisplayInternal(address, alias);
1694 } finally {
1695 Binder.restoreCallingIdentity(token);
1696 }
1697 }
1698
1699 @Override // Binder call
1700 public void forgetWifiDisplay(String address) {
1701 if (address == null) {
1702 throw new IllegalArgumentException("address must not be null");
1703 }
1704 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
1705 "Permission required to forget to a wifi display");
1706
1707 final long token = Binder.clearCallingIdentity();
1708 try {
1709 forgetWifiDisplayInternal(address);
1710 } finally {
1711 Binder.restoreCallingIdentity(token);
1712 }
1713 }
1714
1715 @Override // Binder call
1716 public void pauseWifiDisplay() {
1717 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
1718 "Permission required to pause a wifi display session");
1719
1720 final long token = Binder.clearCallingIdentity();
1721 try {
1722 pauseWifiDisplayInternal();
1723 } finally {
1724 Binder.restoreCallingIdentity(token);
1725 }
1726 }
1727
1728 @Override // Binder call
1729 public void resumeWifiDisplay() {
1730 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
1731 "Permission required to resume a wifi display session");
1732
1733 final long token = Binder.clearCallingIdentity();
1734 try {
1735 resumeWifiDisplayInternal();
1736 } finally {
1737 Binder.restoreCallingIdentity(token);
1738 }
1739 }
1740
1741 @Override // Binder call
1742 public WifiDisplayStatus getWifiDisplayStatus() {
1743 // This request does not require special permissions.
1744 // Any app can get information about available wifi displays.
1745
1746 final long token = Binder.clearCallingIdentity();
1747 try {
1748 return getWifiDisplayStatusInternal();
1749 } finally {
1750 Binder.restoreCallingIdentity(token);
1751 }
1752 }
1753
1754 @Override // Binder call
Michael Wright1c9977b2016-07-12 13:30:10 -07001755 public void requestColorMode(int displayId, int colorMode) {
Michael Wright58e829f2015-09-15 00:13:26 +01001756 mContext.enforceCallingOrSelfPermission(
Michael Wright1c9977b2016-07-12 13:30:10 -07001757 Manifest.permission.CONFIGURE_DISPLAY_COLOR_MODE,
1758 "Permission required to change the display color mode");
Michael Wright58e829f2015-09-15 00:13:26 +01001759 final long token = Binder.clearCallingIdentity();
1760 try {
Michael Wright1c9977b2016-07-12 13:30:10 -07001761 requestColorModeInternal(displayId, colorMode);
Michael Wright58e829f2015-09-15 00:13:26 +01001762 } finally {
1763 Binder.restoreCallingIdentity(token);
1764 }
1765 }
1766
1767 @Override // Binder call
Bryan Mawhinney462e29d2018-03-22 15:52:41 +00001768 public void setSaturationLevel(float level) {
1769 mContext.enforceCallingOrSelfPermission(
1770 Manifest.permission.CONTROL_DISPLAY_SATURATION,
1771 "Permission required to set display saturation level");
1772 final long token = Binder.clearCallingIdentity();
1773 try {
1774 setSaturationLevelInternal(level);
1775 } finally {
1776 Binder.restoreCallingIdentity(token);
1777 }
1778 }
1779
1780 @Override // Binder call
Michael Wright75ee9fc2014-09-01 19:55:22 -07001781 public int createVirtualDisplay(IVirtualDisplayCallback callback,
Michael Wrightc39d47a2014-07-08 18:07:36 -07001782 IMediaProjection projection, String packageName, String name,
Santos Cordonee8931e2017-04-05 10:31:15 -07001783 int width, int height, int densityDpi, Surface surface, int flags,
1784 String uniqueId) {
Jeff Brown4ccb8232014-01-16 22:16:42 -08001785 final int callingUid = Binder.getCallingUid();
1786 if (!validatePackageName(callingUid, packageName)) {
1787 throw new SecurityException("packageName must match the calling uid");
1788 }
Michael Wright75ee9fc2014-09-01 19:55:22 -07001789 if (callback == null) {
Jeff Brown4ccb8232014-01-16 22:16:42 -08001790 throw new IllegalArgumentException("appToken must not be null");
1791 }
1792 if (TextUtils.isEmpty(name)) {
1793 throw new IllegalArgumentException("name must be non-null and non-empty");
1794 }
1795 if (width <= 0 || height <= 0 || densityDpi <= 0) {
1796 throw new IllegalArgumentException("width, height, and densityDpi must be "
1797 + "greater than 0");
1798 }
Pablo Ceballoseb3370d2016-08-31 15:00:17 -07001799 if (surface != null && surface.isSingleBuffered()) {
Pablo Ceballosaff2f942016-07-29 14:49:55 -07001800 throw new IllegalArgumentException("Surface can't be single-buffered");
1801 }
Michael Wrightc39d47a2014-07-08 18:07:36 -07001802
Andrii Kulianfc8f82b2017-01-26 13:17:27 -08001803 if ((flags & VIRTUAL_DISPLAY_FLAG_PUBLIC) != 0) {
1804 flags |= VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR;
1805
1806 // Public displays can't be allowed to show content when locked.
Andrii Kulian7211d2e2017-01-27 15:58:05 -08001807 if ((flags & VIRTUAL_DISPLAY_FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD) != 0) {
Andrii Kulianfc8f82b2017-01-26 13:17:27 -08001808 throw new IllegalArgumentException(
1809 "Public display must not be marked as SHOW_WHEN_LOCKED_INSECURE");
1810 }
Michael Wright6720be42014-07-29 19:14:16 -07001811 }
Andrii Kulianfc8f82b2017-01-26 13:17:27 -08001812 if ((flags & VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY) != 0) {
1813 flags &= ~VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR;
Michael Wright6720be42014-07-29 19:14:16 -07001814 }
1815
Michael Wrightc39d47a2014-07-08 18:07:36 -07001816 if (projection != null) {
1817 try {
1818 if (!getProjectionService().isValidMediaProjection(projection)) {
1819 throw new SecurityException("Invalid media projection");
1820 }
Michael Wright6720be42014-07-29 19:14:16 -07001821 flags = projection.applyVirtualDisplayFlags(flags);
Michael Wrightc39d47a2014-07-08 18:07:36 -07001822 } catch (RemoteException e) {
Michael Wright6720be42014-07-29 19:14:16 -07001823 throw new SecurityException("unable to validate media projection or flags");
Michael Wrightc39d47a2014-07-08 18:07:36 -07001824 }
1825 }
1826
Michael Wright6720be42014-07-29 19:14:16 -07001827 if (callingUid != Process.SYSTEM_UID &&
Andrii Kulianfc8f82b2017-01-26 13:17:27 -08001828 (flags & VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR) != 0) {
Michael Wrightc39d47a2014-07-08 18:07:36 -07001829 if (!canProjectVideo(projection)) {
1830 throw new SecurityException("Requires CAPTURE_VIDEO_OUTPUT or "
1831 + "CAPTURE_SECURE_VIDEO_OUTPUT permission, or an appropriate "
1832 + "MediaProjection token in order to create a screen sharing virtual "
1833 + "display.");
1834 }
1835 }
Santos Cordonb6992f22018-01-30 14:51:20 -08001836 if (callingUid != Process.SYSTEM_UID && (flags & VIRTUAL_DISPLAY_FLAG_SECURE) != 0) {
Michael Wrightc39d47a2014-07-08 18:07:36 -07001837 if (!canProjectSecureVideo(projection)) {
Jeff Brown4ccb8232014-01-16 22:16:42 -08001838 throw new SecurityException("Requires CAPTURE_SECURE_VIDEO_OUTPUT "
Michael Wrightc39d47a2014-07-08 18:07:36 -07001839 + "or an appropriate MediaProjection token to create a "
1840 + "secure virtual display.");
Jeff Brown4ccb8232014-01-16 22:16:42 -08001841 }
1842 }
1843
1844 final long token = Binder.clearCallingIdentity();
1845 try {
Santos Cordonee8931e2017-04-05 10:31:15 -07001846 return createVirtualDisplayInternal(callback, projection, callingUid, packageName,
1847 name, width, height, densityDpi, surface, flags, uniqueId);
Jeff Brown4ccb8232014-01-16 22:16:42 -08001848 } finally {
1849 Binder.restoreCallingIdentity(token);
1850 }
1851 }
1852
1853 @Override // Binder call
Michael Wright75ee9fc2014-09-01 19:55:22 -07001854 public void resizeVirtualDisplay(IVirtualDisplayCallback callback,
Michael Wright01e840f2014-06-26 16:03:25 -07001855 int width, int height, int densityDpi) {
1856 final long token = Binder.clearCallingIdentity();
1857 try {
Michael Wright75ee9fc2014-09-01 19:55:22 -07001858 resizeVirtualDisplayInternal(callback.asBinder(), width, height, densityDpi);
Michael Wright01e840f2014-06-26 16:03:25 -07001859 } finally {
1860 Binder.restoreCallingIdentity(token);
1861 }
1862 }
1863
1864 @Override // Binder call
Michael Wright75ee9fc2014-09-01 19:55:22 -07001865 public void setVirtualDisplaySurface(IVirtualDisplayCallback callback, Surface surface) {
Pablo Ceballoseb3370d2016-08-31 15:00:17 -07001866 if (surface != null && surface.isSingleBuffered()) {
1867 throw new IllegalArgumentException("Surface can't be single-buffered");
1868 }
Jeff Brown92207df2014-04-16 13:16:07 -07001869 final long token = Binder.clearCallingIdentity();
1870 try {
Michael Wright75ee9fc2014-09-01 19:55:22 -07001871 setVirtualDisplaySurfaceInternal(callback.asBinder(), surface);
Jeff Brown92207df2014-04-16 13:16:07 -07001872 } finally {
1873 Binder.restoreCallingIdentity(token);
1874 }
1875 }
1876
1877 @Override // Binder call
Michael Wright75ee9fc2014-09-01 19:55:22 -07001878 public void releaseVirtualDisplay(IVirtualDisplayCallback callback) {
Jeff Brown4ccb8232014-01-16 22:16:42 -08001879 final long token = Binder.clearCallingIdentity();
1880 try {
Michael Wright75ee9fc2014-09-01 19:55:22 -07001881 releaseVirtualDisplayInternal(callback.asBinder());
Jeff Brown4ccb8232014-01-16 22:16:42 -08001882 } finally {
1883 Binder.restoreCallingIdentity(token);
1884 }
1885 }
1886
1887 @Override // Binder call
1888 public void dump(FileDescriptor fd, final PrintWriter pw, String[] args) {
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -06001889 if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
Jeff Brown4ccb8232014-01-16 22:16:42 -08001890
1891 final long token = Binder.clearCallingIdentity();
1892 try {
1893 dumpInternal(pw);
1894 } finally {
1895 Binder.restoreCallingIdentity(token);
1896 }
1897 }
1898
Kenny Guy22bd0442017-10-26 00:15:54 +01001899 @Override // Binder call
Kenny Guy29aa30e2017-11-30 13:43:46 +00001900 public ParceledListSlice<BrightnessChangeEvent> getBrightnessEvents(String callingPackage) {
Kenny Guy22bd0442017-10-26 00:15:54 +01001901 mContext.enforceCallingOrSelfPermission(
1902 Manifest.permission.BRIGHTNESS_SLIDER_USAGE,
1903 "Permission to read brightness events.");
Kenny Guy29aa30e2017-11-30 13:43:46 +00001904
1905 final int callingUid = Binder.getCallingUid();
1906 AppOpsManager appOpsManager = mContext.getSystemService(AppOpsManager.class);
Jeff Sharkeyd9311192018-04-16 16:50:34 +00001907 final int mode = appOpsManager.noteOp(AppOpsManager.OP_GET_USAGE_STATS,
Kenny Guy29aa30e2017-11-30 13:43:46 +00001908 callingUid, callingPackage);
1909 final boolean hasUsageStats;
1910 if (mode == AppOpsManager.MODE_DEFAULT) {
1911 // The default behavior here is to check if PackageManager has given the app
1912 // permission.
1913 hasUsageStats = mContext.checkCallingPermission(
1914 Manifest.permission.PACKAGE_USAGE_STATS)
1915 == PackageManager.PERMISSION_GRANTED;
1916 } else {
1917 hasUsageStats = mode == AppOpsManager.MODE_ALLOWED;
1918 }
1919
1920 final int userId = UserHandle.getUserId(callingUid);
Kenny Guy22bd0442017-10-26 00:15:54 +01001921 final long token = Binder.clearCallingIdentity();
1922 try {
Michael Wright144aac92017-12-21 18:37:41 +00001923 synchronized (mSyncRoot) {
1924 return mDisplayPowerController.getBrightnessEvents(userId, hasUsageStats);
1925 }
Kenny Guy22bd0442017-10-26 00:15:54 +01001926 } finally {
1927 Binder.restoreCallingIdentity(token);
1928 }
1929 }
1930
Michael Wrighteef0e132017-11-21 17:57:52 +00001931 @Override // Binder call
Peeyush Agarwalcc155dd2018-01-10 11:51:33 +00001932 public ParceledListSlice<AmbientBrightnessDayStats> getAmbientBrightnessStats() {
1933 mContext.enforceCallingOrSelfPermission(
1934 Manifest.permission.ACCESS_AMBIENT_LIGHT_STATS,
1935 "Permission required to to access ambient light stats.");
1936 final int callingUid = Binder.getCallingUid();
1937 final int userId = UserHandle.getUserId(callingUid);
1938 final long token = Binder.clearCallingIdentity();
1939 try {
1940 synchronized (mSyncRoot) {
1941 return mDisplayPowerController.getAmbientBrightnessStats(userId);
1942 }
1943 } finally {
1944 Binder.restoreCallingIdentity(token);
1945 }
1946 }
1947
1948 @Override // Binder call
Michael Wrighteef0e132017-11-21 17:57:52 +00001949 public void setBrightnessConfigurationForUser(
Kenny Guy05ce8092018-01-17 13:44:20 +00001950 BrightnessConfiguration c, @UserIdInt int userId, String packageName) {
Michael Wrighteef0e132017-11-21 17:57:52 +00001951 mContext.enforceCallingOrSelfPermission(
1952 Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS,
1953 "Permission required to change the display's brightness configuration");
1954 if (userId != UserHandle.getCallingUserId()) {
1955 mContext.enforceCallingOrSelfPermission(
1956 Manifest.permission.INTERACT_ACROSS_USERS,
1957 "Permission required to change the display brightness"
1958 + " configuration of another user");
1959 }
Kenny Guy05ce8092018-01-17 13:44:20 +00001960 if (packageName != null && !validatePackageName(getCallingUid(), packageName)) {
1961 packageName = null;
1962 }
Michael Wrighteef0e132017-11-21 17:57:52 +00001963 final long token = Binder.clearCallingIdentity();
1964 try {
Kenny Guy05ce8092018-01-17 13:44:20 +00001965 setBrightnessConfigurationForUserInternal(c, userId, packageName);
Michael Wrighteef0e132017-11-21 17:57:52 +00001966 } finally {
1967 Binder.restoreCallingIdentity(token);
1968 }
1969 }
1970
Michael Wrightd8460232018-01-16 18:04:59 +00001971 @Override // Binder call
Kenny Guy6d1009f2018-03-14 14:28:23 +00001972 public BrightnessConfiguration getBrightnessConfigurationForUser(int userId) {
1973 mContext.enforceCallingOrSelfPermission(
1974 Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS,
1975 "Permission required to read the display's brightness configuration");
1976 if (userId != UserHandle.getCallingUserId()) {
1977 mContext.enforceCallingOrSelfPermission(
1978 Manifest.permission.INTERACT_ACROSS_USERS,
1979 "Permission required to read the display brightness"
1980 + " configuration of another user");
1981 }
1982 final long token = Binder.clearCallingIdentity();
1983 try {
1984 final int userSerial = getUserManager().getUserSerialNumber(userId);
1985 synchronized (mSyncRoot) {
1986 BrightnessConfiguration config =
1987 mPersistentDataStore.getBrightnessConfiguration(userSerial);
1988 if (config == null) {
1989 config = mDisplayPowerController.getDefaultBrightnessConfiguration();
1990 }
1991 return config;
1992 }
1993 } finally {
1994 Binder.restoreCallingIdentity(token);
1995 }
1996 }
1997
1998 @Override // Binder call
1999 public BrightnessConfiguration getDefaultBrightnessConfiguration() {
2000 mContext.enforceCallingOrSelfPermission(
2001 Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS,
2002 "Permission required to read the display's default brightness configuration");
2003 final long token = Binder.clearCallingIdentity();
2004 try {
2005 synchronized (mSyncRoot) {
2006 return mDisplayPowerController.getDefaultBrightnessConfiguration();
2007 }
2008 } finally {
2009 Binder.restoreCallingIdentity(token);
2010 }
2011 }
2012
2013 @Override // Binder call
Michael Wrightd8460232018-01-16 18:04:59 +00002014 public void setTemporaryBrightness(int brightness) {
2015 mContext.enforceCallingOrSelfPermission(
2016 Manifest.permission.CONTROL_DISPLAY_BRIGHTNESS,
2017 "Permission required to set the display's brightness");
2018 final long token = Binder.clearCallingIdentity();
2019 try {
2020 synchronized (mSyncRoot) {
2021 mDisplayPowerController.setTemporaryBrightness(brightness);
2022 }
2023 } finally {
2024 Binder.restoreCallingIdentity(token);
2025 }
2026 }
2027
2028 @Override // Binder call
2029 public void setTemporaryAutoBrightnessAdjustment(float adjustment) {
2030 mContext.enforceCallingOrSelfPermission(
2031 Manifest.permission.CONTROL_DISPLAY_BRIGHTNESS,
2032 "Permission required to set the display's auto brightness adjustment");
2033 final long token = Binder.clearCallingIdentity();
2034 try {
2035 synchronized (mSyncRoot) {
2036 mDisplayPowerController.setTemporaryAutoBrightnessAdjustment(adjustment);
2037 }
2038 } finally {
2039 Binder.restoreCallingIdentity(token);
2040 }
2041 }
2042
Dan Gittik7a32fba2018-03-28 12:19:38 +01002043 @Override // Binder call
2044 public void onShellCommand(FileDescriptor in, FileDescriptor out,
2045 FileDescriptor err, String[] args, ShellCallback callback,
2046 ResultReceiver resultReceiver) {
2047 final long token = Binder.clearCallingIdentity();
2048 try {
2049 DisplayManagerShellCommand command = new DisplayManagerShellCommand(this);
2050 command.exec(this, in, out, err, args, callback, resultReceiver);
2051 } finally {
2052 Binder.restoreCallingIdentity(token);
2053 }
2054 }
2055
Dan Gittik122df862018-03-28 16:59:22 +01002056 @Override // Binder call
2057 public Curve getMinimumBrightnessCurve() {
2058 final long token = Binder.clearCallingIdentity();
2059 try {
2060 return getMinimumBrightnessCurveInternal();
2061 } finally {
2062 Binder.restoreCallingIdentity(token);
2063 }
2064 }
2065
Dan Gittik7a32fba2018-03-28 12:19:38 +01002066 void setBrightness(int brightness) {
2067 Settings.System.putIntForUser(mContext.getContentResolver(),
2068 Settings.System.SCREEN_BRIGHTNESS, brightness, UserHandle.USER_CURRENT);
2069 }
2070
2071 void resetBrightnessConfiguration() {
2072 setBrightnessConfigurationForUserInternal(null, mContext.getUserId(),
2073 mContext.getPackageName());
2074 }
2075
Jeff Brown4ccb8232014-01-16 22:16:42 -08002076 private boolean validatePackageName(int uid, String packageName) {
2077 if (packageName != null) {
2078 String[] packageNames = mContext.getPackageManager().getPackagesForUid(uid);
2079 if (packageNames != null) {
2080 for (String n : packageNames) {
2081 if (n.equals(packageName)) {
2082 return true;
2083 }
2084 }
2085 }
2086 }
2087 return false;
2088 }
Michael Wrightc39d47a2014-07-08 18:07:36 -07002089
2090 private boolean canProjectVideo(IMediaProjection projection) {
2091 if (projection != null) {
2092 try {
2093 if (projection.canProjectVideo()) {
2094 return true;
2095 }
2096 } catch (RemoteException e) {
2097 Slog.e(TAG, "Unable to query projection service for permissions", e);
2098 }
2099 }
2100 if (mContext.checkCallingPermission(
2101 android.Manifest.permission.CAPTURE_VIDEO_OUTPUT)
Michael Wright0ccc2b02014-07-24 18:20:41 -07002102 == PackageManager.PERMISSION_GRANTED) {
Michael Wrightc39d47a2014-07-08 18:07:36 -07002103 return true;
2104 }
2105 return canProjectSecureVideo(projection);
2106 }
2107
2108 private boolean canProjectSecureVideo(IMediaProjection projection) {
2109 if (projection != null) {
2110 try {
2111 if (projection.canProjectSecureVideo()){
2112 return true;
2113 }
2114 } catch (RemoteException e) {
2115 Slog.e(TAG, "Unable to query projection service for permissions", e);
2116 }
2117 }
2118 return mContext.checkCallingPermission(
2119 android.Manifest.permission.CAPTURE_SECURE_VIDEO_OUTPUT)
Michael Wright0ccc2b02014-07-24 18:20:41 -07002120 == PackageManager.PERMISSION_GRANTED;
Michael Wrightc39d47a2014-07-08 18:07:36 -07002121 }
Jeff Brown4ccb8232014-01-16 22:16:42 -08002122 }
2123
2124 private final class LocalService extends DisplayManagerInternal {
2125 @Override
Jeff Brown037c33e2014-04-09 00:31:55 -07002126 public void initPowerManagement(final DisplayPowerCallbacks callbacks, Handler handler,
Jeff Brownad9ef192014-04-08 17:26:30 -07002127 SensorManager sensorManager) {
2128 synchronized (mSyncRoot) {
Jeff Brown037c33e2014-04-09 00:31:55 -07002129 DisplayBlanker blanker = new DisplayBlanker() {
2130 @Override
Jeff Brown5d6443b2015-04-10 20:15:01 -07002131 public void requestDisplayState(int state, int brightness) {
Jeff Brown037c33e2014-04-09 00:31:55 -07002132 // The order of operations is important for legacy reasons.
2133 if (state == Display.STATE_OFF) {
Jeff Brown5d6443b2015-04-10 20:15:01 -07002134 requestGlobalDisplayStateInternal(state, brightness);
Jeff Brown037c33e2014-04-09 00:31:55 -07002135 }
2136
2137 callbacks.onDisplayStateChange(state);
2138
2139 if (state != Display.STATE_OFF) {
Jeff Brown5d6443b2015-04-10 20:15:01 -07002140 requestGlobalDisplayStateInternal(state, brightness);
Jeff Brown037c33e2014-04-09 00:31:55 -07002141 }
2142 }
2143 };
Jeff Brownad9ef192014-04-08 17:26:30 -07002144 mDisplayPowerController = new DisplayPowerController(
Jeff Brown037c33e2014-04-09 00:31:55 -07002145 mContext, callbacks, handler, sensorManager, blanker);
Jeff Brownad9ef192014-04-08 17:26:30 -07002146 }
Michael Wrighteef0e132017-11-21 17:57:52 +00002147
2148 mHandler.sendEmptyMessage(MSG_LOAD_BRIGHTNESS_CONFIGURATION);
Jeff Brownad9ef192014-04-08 17:26:30 -07002149 }
2150
2151 @Override
2152 public boolean requestPowerState(DisplayPowerRequest request,
2153 boolean waitForNegativeProximity) {
Michael Wrighteef0e132017-11-21 17:57:52 +00002154 synchronized (mSyncRoot) {
2155 return mDisplayPowerController.requestPowerState(request,
2156 waitForNegativeProximity);
2157 }
Jeff Brownad9ef192014-04-08 17:26:30 -07002158 }
2159
2160 @Override
2161 public boolean isProximitySensorAvailable() {
Michael Wrighteef0e132017-11-21 17:57:52 +00002162 synchronized (mSyncRoot) {
2163 return mDisplayPowerController.isProximitySensorAvailable();
2164 }
Jeff Brownad9ef192014-04-08 17:26:30 -07002165 }
2166
2167 @Override
Riddle Hsu654a6f92018-07-13 22:59:36 +08002168 public boolean screenshot(int displayId, Surface outSurface) {
2169 synchronized (mSyncRoot) {
2170 final LogicalDisplay display = mLogicalDisplays.get(displayId);
2171 if (display != null) {
2172 final DisplayDevice device = display.getPrimaryDisplayDeviceLocked();
2173 if (device != null) {
2174 final IBinder token = device.getDisplayTokenLocked();
2175 if (token != null) {
2176 SurfaceControl.screenshot(token, outSurface);
2177 return true;
2178 }
2179 }
2180 }
2181 }
2182 return false;
2183 }
2184
2185 @Override
Jeff Brown4ccb8232014-01-16 22:16:42 -08002186 public DisplayInfo getDisplayInfo(int displayId) {
2187 return getDisplayInfoInternal(displayId, Process.myUid());
2188 }
2189
2190 @Override
2191 public void registerDisplayTransactionListener(DisplayTransactionListener listener) {
2192 if (listener == null) {
2193 throw new IllegalArgumentException("listener must not be null");
2194 }
2195
2196 registerDisplayTransactionListenerInternal(listener);
2197 }
2198
2199 @Override
2200 public void unregisterDisplayTransactionListener(DisplayTransactionListener listener) {
2201 if (listener == null) {
2202 throw new IllegalArgumentException("listener must not be null");
2203 }
2204
2205 unregisterDisplayTransactionListenerInternal(listener);
2206 }
2207
2208 @Override
2209 public void setDisplayInfoOverrideFromWindowManager(int displayId, DisplayInfo info) {
2210 setDisplayInfoOverrideFromWindowManagerInternal(displayId, info);
2211 }
2212
2213 @Override
Andrii Kuliancd097992017-03-23 18:31:59 -07002214 public void getNonOverrideDisplayInfo(int displayId, DisplayInfo outInfo) {
2215 getNonOverrideDisplayInfoInternal(displayId, outInfo);
2216 }
2217
2218 @Override
Robert Carrae606b42018-02-15 15:36:23 -08002219 public void performTraversal(SurfaceControl.Transaction t) {
2220 performTraversalInternal(t);
Jeff Brown4ccb8232014-01-16 22:16:42 -08002221 }
2222
2223 @Override
Michael Wright3f145a22014-07-22 19:46:03 -07002224 public void setDisplayProperties(int displayId, boolean hasContent,
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -07002225 float requestedRefreshRate, int requestedMode, boolean inTraversal) {
2226 setDisplayPropertiesInternal(displayId, hasContent, requestedRefreshRate,
2227 requestedMode, inTraversal);
Jeff Brown4ccb8232014-01-16 22:16:42 -08002228 }
Filip Gruszczynskid2e86402015-02-19 13:05:03 -08002229
2230 @Override
2231 public void setDisplayOffsets(int displayId, int x, int y) {
2232 setDisplayOffsetsInternal(displayId, x, y);
2233 }
Andrii Kulianfb1bf692017-01-17 11:17:34 -08002234
2235 @Override
2236 public void setDisplayAccessUIDs(SparseArray<IntArray> newDisplayAccessUIDs) {
2237 setDisplayAccessUIDsInternal(newDisplayAccessUIDs);
2238 }
2239
2240 @Override
2241 public boolean isUidPresentOnDisplay(int uid, int displayId) {
2242 return isUidPresentOnDisplayInternal(uid, displayId);
2243 }
Kenny Guycfe7b702017-11-14 21:04:58 +00002244
2245 @Override
Peeyush Agarwalcc155dd2018-01-10 11:51:33 +00002246 public void persistBrightnessTrackerState() {
Michael Wright144aac92017-12-21 18:37:41 +00002247 synchronized (mSyncRoot) {
Peeyush Agarwalcc155dd2018-01-10 11:51:33 +00002248 mDisplayPowerController.persistBrightnessTrackerState();
Michael Wright144aac92017-12-21 18:37:41 +00002249 }
Kenny Guycfe7b702017-11-14 21:04:58 +00002250 }
Adrian Roose1d68cd2018-01-17 12:54:50 +01002251
2252 @Override
2253 public void onOverlayChanged() {
2254 synchronized (mSyncRoot) {
Adrian Roos898ec382018-01-17 12:54:50 +01002255 for (int i = 0; i < mDisplayDevices.size(); i++) {
2256 mDisplayDevices.get(i).onOverlayChangedLocked();
Adrian Roose1d68cd2018-01-17 12:54:50 +01002257 }
2258 }
2259 }
Jeff Brown4ccb8232014-01-16 22:16:42 -08002260 }
Jeff Brownfa25bf52012-07-23 19:26:30 -07002261}