blob: 7d18d36aa4cce5fd8175b28eff3b7e9125fb68a6 [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
24 .VIRTUAL_DISPLAY_FLAG_SHOW_WITH_INSECURE_LOCKSCREEN;
25
Jeff Brownbd6e1502012-08-28 03:27:37 -070026import com.android.internal.util.IndentingPrintWriter;
27
Jeff Brownfa25bf52012-07-23 19:26:30 -070028import android.Manifest;
29import android.content.Context;
30import android.content.pm.PackageManager;
Jeff Brownad9ef192014-04-08 17:26:30 -070031import android.hardware.SensorManager;
Jeff Brown7d00aff2013-08-02 19:03:49 -070032import android.hardware.display.DisplayManager;
Jeff Brownbd6e1502012-08-28 03:27:37 -070033import android.hardware.display.DisplayManagerGlobal;
Jeff Brown4ccb8232014-01-16 22:16:42 -080034import android.hardware.display.DisplayManagerInternal;
35import android.hardware.display.DisplayViewport;
36import android.hardware.display.DisplayManagerInternal.DisplayTransactionListener;
Jeff Brownfa25bf52012-07-23 19:26:30 -070037import android.hardware.display.IDisplayManager;
Jeff Brownbd6e1502012-08-28 03:27:37 -070038import android.hardware.display.IDisplayManagerCallback;
Michael Wright75ee9fc2014-09-01 19:55:22 -070039import android.hardware.display.IVirtualDisplayCallback;
Jeff Browne08ae382012-09-07 20:36:36 -070040import android.hardware.display.WifiDisplayStatus;
Jeff Brown4ccb8232014-01-16 22:16:42 -080041import android.hardware.input.InputManagerInternal;
Michael Wrightc39d47a2014-07-08 18:07:36 -070042import android.media.projection.IMediaProjection;
43import android.media.projection.IMediaProjectionManager;
Jeff Brownfa25bf52012-07-23 19:26:30 -070044import android.os.Binder;
Jeff Brownbd6e1502012-08-28 03:27:37 -070045import android.os.Handler;
Jeff Brown64a55af2012-08-26 02:47:39 -070046import android.os.IBinder;
Jeff Brown4ccb8232014-01-16 22:16:42 -080047import android.os.IBinder.DeathRecipient;
Jeff Brownbd6e1502012-08-28 03:27:37 -070048import android.os.Looper;
49import android.os.Message;
Jeff Brown5d6443b2015-04-10 20:15:01 -070050import android.os.PowerManager;
Craig Mautner4504de52013-12-20 09:06:56 -080051import android.os.Process;
Jeff Brownbd6e1502012-08-28 03:27:37 -070052import android.os.RemoteException;
Michael Wrightc39d47a2014-07-08 18:07:36 -070053import android.os.ServiceManager;
Jeff Brownbd6e1502012-08-28 03:27:37 -070054import android.os.SystemClock;
Jeff Brownfa25bf52012-07-23 19:26:30 -070055import android.os.SystemProperties;
Jeff Brown5d6443b2015-04-10 20:15:01 -070056import android.os.Trace;
Jeff Browna506a6e2013-06-04 00:02:38 -070057import android.text.TextUtils;
Andrii Kulianfb1bf692017-01-17 11:17:34 -080058import android.util.IntArray;
Jeff Brownbd6e1502012-08-28 03:27:37 -070059import android.util.Slog;
60import android.util.SparseArray;
Jeff Brownfa25bf52012-07-23 19:26:30 -070061import android.view.Display;
62import android.view.DisplayInfo;
Jeff Browna506a6e2013-06-04 00:02:38 -070063import android.view.Surface;
Jeff Brown4ccb8232014-01-16 22:16:42 -080064import android.view.WindowManagerInternal;
Jeff Browna506a6e2013-06-04 00:02:38 -070065
Jeff Brown4ccb8232014-01-16 22:16:42 -080066import com.android.server.DisplayThread;
67import com.android.server.LocalServices;
68import com.android.server.SystemService;
Dianne Hackborn8d044e82013-04-30 17:24:15 -070069import com.android.server.UiThread;
Jeff Brownfa25bf52012-07-23 19:26:30 -070070
71import java.io.FileDescriptor;
72import java.io.PrintWriter;
73import java.util.ArrayList;
Jeff Browna506a6e2013-06-04 00:02:38 -070074import java.util.Arrays;
Jeff Browne75926d2014-09-18 15:24:49 -070075import java.util.List;
Jeff Brown7f3994e2012-12-04 14:04:28 -080076import java.util.concurrent.CopyOnWriteArrayList;
Jeff Brownfa25bf52012-07-23 19:26:30 -070077
78/**
Jeff Brownbd6e1502012-08-28 03:27:37 -070079 * Manages attached displays.
Jeff Brownfa25bf52012-07-23 19:26:30 -070080 * <p>
Jeff Brownbd6e1502012-08-28 03:27:37 -070081 * The {@link DisplayManagerService} manages the global lifecycle of displays,
82 * decides how to configure logical displays based on the physical display devices currently
83 * attached, sends notifications to the system and to applications when the state
84 * changes, and so on.
85 * </p><p>
86 * The display manager service relies on a collection of {@link DisplayAdapter} components,
87 * for discovering and configuring physical display devices attached to the system.
88 * There are separate display adapters for each manner that devices are attached:
89 * one display adapter for built-in local displays, one for simulated non-functional
90 * displays when the system is headless, one for simulated overlay displays used for
91 * development, one for wifi displays, etc.
92 * </p><p>
93 * Display adapters are only weakly coupled to the display manager service.
94 * Display adapters communicate changes in display device state to the display manager
Craig Mautner722285e2012-09-07 13:55:58 -070095 * service asynchronously via a {@link DisplayAdapter.Listener} registered
Jeff Brownbd6e1502012-08-28 03:27:37 -070096 * by the display manager service. This separation of concerns is important for
97 * two main reasons. First, it neatly encapsulates the responsibilities of these
98 * two classes: display adapters handle individual display devices whereas
99 * the display manager service handles the global state. Second, it eliminates
100 * the potential for deadlocks resulting from asynchronous display device discovery.
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700101 * </p>
102 *
103 * <h3>Synchronization</h3>
104 * <p>
105 * Because the display manager may be accessed by multiple threads, the synchronization
106 * story gets a little complicated. In particular, the window manager may call into
107 * the display manager while holding a surface transaction with the expectation that
108 * it can apply changes immediately. Unfortunately, that means we can't just do
109 * everything asynchronously (*grump*).
Jeff Brownbd6e1502012-08-28 03:27:37 -0700110 * </p><p>
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700111 * To make this work, all of the objects that belong to the display manager must
112 * use the same lock. We call this lock the synchronization root and it has a unique
113 * type {@link DisplayManagerService.SyncRoot}. Methods that require this lock are
114 * named with the "Locked" suffix.
115 * </p><p>
116 * Where things get tricky is that the display manager is not allowed to make
117 * any potentially reentrant calls, especially into the window manager. We generally
118 * avoid this by making all potentially reentrant out-calls asynchronous.
Jeff Brownfa25bf52012-07-23 19:26:30 -0700119 * </p>
120 */
Jeff Brown4ccb8232014-01-16 22:16:42 -0800121public final class DisplayManagerService extends SystemService {
Jeff Brownfa25bf52012-07-23 19:26:30 -0700122 private static final String TAG = "DisplayManagerService";
Jeff Brownbd6e1502012-08-28 03:27:37 -0700123 private static final boolean DEBUG = false;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700124
Jeff Brownbbd28a22012-09-20 16:47:15 -0700125 // When this system property is set to 0, WFD is forcibly disabled on boot.
126 // When this system property is set to 1, WFD is forcibly enabled on boot.
127 // Otherwise WFD is enabled according to the value of config_enableWifiDisplay.
128 private static final String FORCE_WIFI_DISPLAY_ENABLE = "persist.debug.wfd.enable";
129
Jeff Brownbd6e1502012-08-28 03:27:37 -0700130 private static final long WAIT_FOR_DEFAULT_DISPLAY_TIMEOUT = 10000;
131
132 private static final int MSG_REGISTER_DEFAULT_DISPLAY_ADAPTER = 1;
133 private static final int MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS = 2;
134 private static final int MSG_DELIVER_DISPLAY_EVENT = 3;
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700135 private static final int MSG_REQUEST_TRAVERSAL = 4;
Jeff Brownd728bf52012-09-08 18:05:28 -0700136 private static final int MSG_UPDATE_VIEWPORT = 5;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700137
Jeff Brownb880d882014-02-10 19:47:07 -0800138 private final Context mContext;
Jeff Brownbd6e1502012-08-28 03:27:37 -0700139 private final DisplayManagerHandler mHandler;
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700140 private final Handler mUiHandler;
141 private final DisplayAdapterListener mDisplayAdapterListener;
Jeff Brown4ccb8232014-01-16 22:16:42 -0800142 private WindowManagerInternal mWindowManagerInternal;
143 private InputManagerInternal mInputManagerInternal;
Michael Wrightc39d47a2014-07-08 18:07:36 -0700144 private IMediaProjectionManager mProjectionService;
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700145
146 // The synchronization root for the display manager.
147 // This lock guards most of the display manager's state.
Craig Mautner0bf6ec92012-12-18 08:33:27 -0800148 // NOTE: This is synchronized on while holding WindowManagerService.mWindowMap so never call
149 // into WindowManagerService methods that require mWindowMap while holding this unless you are
150 // very very sure that no deadlock can occur.
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700151 private final SyncRoot mSyncRoot = new SyncRoot();
152
153 // True if in safe mode.
154 // This option may disable certain display adapters.
155 public boolean mSafeMode;
156
157 // True if we are in a special boot mode where only core applications and
158 // services should be started. This option may disable certain display adapters.
159 public boolean mOnlyCore;
160
Jeff Brown27f1d672012-10-17 18:32:34 -0700161 // True if the display manager service should pretend there is only one display
162 // and only tell applications about the existence of the default logical display.
163 // The display manager can still mirror content to secondary displays but applications
164 // cannot present unique content on those displays.
165 // Used for demonstration purposes only.
166 private final boolean mSingleDisplayDemoMode;
167
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700168 // All callback records indexed by calling process id.
169 public final SparseArray<CallbackRecord> mCallbacks =
Jeff Brownbd6e1502012-08-28 03:27:37 -0700170 new SparseArray<CallbackRecord>();
Jeff Brownfa25bf52012-07-23 19:26:30 -0700171
Jeff Brownbd6e1502012-08-28 03:27:37 -0700172 // List of all currently registered display adapters.
173 private final ArrayList<DisplayAdapter> mDisplayAdapters = new ArrayList<DisplayAdapter>();
174
175 // List of all currently connected display devices.
176 private final ArrayList<DisplayDevice> mDisplayDevices = new ArrayList<DisplayDevice>();
177
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700178 // List of all logical displays indexed by logical display id.
179 private final SparseArray<LogicalDisplay> mLogicalDisplays =
180 new SparseArray<LogicalDisplay>();
Jeff Brownbd6e1502012-08-28 03:27:37 -0700181 private int mNextNonDefaultDisplayId = Display.DEFAULT_DISPLAY + 1;
182
Jeff Brown7f3994e2012-12-04 14:04:28 -0800183 // List of all display transaction listeners.
184 private final CopyOnWriteArrayList<DisplayTransactionListener> mDisplayTransactionListeners =
185 new CopyOnWriteArrayList<DisplayTransactionListener>();
186
Jeff Brownad9ef192014-04-08 17:26:30 -0700187 // Display power controller.
188 private DisplayPowerController mDisplayPowerController;
189
Jeff Brown037c33e2014-04-09 00:31:55 -0700190 // The overall display state, independent of changes that might influence one
191 // display or another in particular.
Jeff Brown5d6443b2015-04-10 20:15:01 -0700192 private int mGlobalDisplayState = Display.STATE_ON;
193
194 // The overall display brightness.
195 // For now, this only applies to the built-in display but we may split it up eventually.
196 private int mGlobalDisplayBrightness = PowerManager.BRIGHTNESS_DEFAULT;
Jeff Brown9e316a12012-10-08 19:17:06 -0700197
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700198 // Set to true when there are pending display changes that have yet to be applied
199 // to the surface flinger state.
200 private boolean mPendingTraversal;
Jeff Brownbd6e1502012-08-28 03:27:37 -0700201
Jeff Browne08ae382012-09-07 20:36:36 -0700202 // The Wifi display adapter, or null if not registered.
203 private WifiDisplayAdapter mWifiDisplayAdapter;
204
Jeff Brownce468a32013-11-21 16:42:03 -0800205 // The number of active wifi display scan requests.
206 private int mWifiDisplayScanRequestCount;
207
Jeff Browna506a6e2013-06-04 00:02:38 -0700208 // The virtual display adapter, or null if not registered.
209 private VirtualDisplayAdapter mVirtualDisplayAdapter;
210
Jeff Brownd728bf52012-09-08 18:05:28 -0700211 // Viewports of the default display and the display that should receive touch
212 // input from an external source. Used by the input system.
213 private final DisplayViewport mDefaultViewport = new DisplayViewport();
214 private final DisplayViewport mExternalTouchViewport = new DisplayViewport();
215
Jeff Brown89d55462012-09-19 11:33:42 -0700216 // Persistent data store for all internal settings maintained by the display manager service.
217 private final PersistentDataStore mPersistentDataStore = new PersistentDataStore();
218
Jeff Brownbd6e1502012-08-28 03:27:37 -0700219 // Temporary callback list, used when sending display events to applications.
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700220 // May be used outside of the lock but only on the handler thread.
221 private final ArrayList<CallbackRecord> mTempCallbacks = new ArrayList<CallbackRecord>();
Jeff Brownbd6e1502012-08-28 03:27:37 -0700222
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700223 // Temporary display info, used for comparing display configurations.
224 private final DisplayInfo mTempDisplayInfo = new DisplayInfo();
225
Jeff Brownd728bf52012-09-08 18:05:28 -0700226 // Temporary viewports, used when sending new viewport information to the
227 // input system. May be used outside of the lock but only on the handler thread.
228 private final DisplayViewport mTempDefaultViewport = new DisplayViewport();
229 private final DisplayViewport mTempExternalTouchViewport = new DisplayViewport();
230
Damien Bargiacchi4364bbf2016-11-01 21:44:20 -0700231 // The default color mode for default displays. Overrides the usual
232 // Display.Display.COLOR_MODE_DEFAULT for displays with the
233 // DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY flag set.
234 private final int mDefaultDisplayDefaultColorMode;
235
Jeff Browne75926d2014-09-18 15:24:49 -0700236 // Temporary list of deferred work to perform when setting the display state.
237 // Only used by requestDisplayState. The field is self-synchronized and only
238 // intended for use inside of the requestGlobalDisplayStateInternal function.
239 private final ArrayList<Runnable> mTempDisplayStateWorkQueue = new ArrayList<Runnable>();
240
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800241 // Lists of UIDs that are present on the displays. Maps displayId -> array of UIDs.
242 private final SparseArray<IntArray> mDisplayAccessUIDs = new SparseArray<>();
243
Jeff Brownb880d882014-02-10 19:47:07 -0800244 public DisplayManagerService(Context context) {
245 super(context);
246 mContext = context;
Jeff Brown4ccb8232014-01-16 22:16:42 -0800247 mHandler = new DisplayManagerHandler(DisplayThread.get().getLooper());
Dianne Hackborn8d044e82013-04-30 17:24:15 -0700248 mUiHandler = UiThread.getHandler();
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700249 mDisplayAdapterListener = new DisplayAdapterListener();
Jeff Brown27f1d672012-10-17 18:32:34 -0700250 mSingleDisplayDemoMode = SystemProperties.getBoolean("persist.demo.singledisplay", false);
Damien Bargiacchi4364bbf2016-11-01 21:44:20 -0700251 mDefaultDisplayDefaultColorMode = mContext.getResources().getInteger(
252 com.android.internal.R.integer.config_defaultDisplayDefaultColorMode);
Jeff Brown5d6443b2015-04-10 20:15:01 -0700253
254 PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
255 mGlobalDisplayBrightness = pm.getDefaultScreenBrightnessSetting();
Craig Mautner4f67ba62012-08-02 11:23:00 -0700256 }
257
Jeff Brown4ccb8232014-01-16 22:16:42 -0800258 @Override
Jeff Brown4ccb8232014-01-16 22:16:42 -0800259 public void onStart() {
Michael Wright1c9977b2016-07-12 13:30:10 -0700260 // We need to pre-load the persistent data store so it's ready before the default display
261 // adapter is up so that we have it's configuration. We could load it lazily, but since
262 // we're going to have to read it in eventually we may as well do it here rather than after
263 // we've waited for the diplay to register itself with us.
264 mPersistentDataStore.loadIfNeeded();
Jeff Brown4ccb8232014-01-16 22:16:42 -0800265 mHandler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTER);
266
267 publishBinderService(Context.DISPLAY_SERVICE, new BinderService(),
268 true /*allowIsolated*/);
269 publishLocalService(DisplayManagerInternal.class, new LocalService());
Justin Klaassen22eb1992016-07-11 20:52:23 -0700270 publishLocalService(DisplayTransformManager.class, new DisplayTransformManager());
Jeff Brown4ccb8232014-01-16 22:16:42 -0800271 }
272
273 @Override
274 public void onBootPhase(int phase) {
275 if (phase == PHASE_WAIT_FOR_DEFAULT_DISPLAY) {
276 synchronized (mSyncRoot) {
277 long timeout = SystemClock.uptimeMillis() + WAIT_FOR_DEFAULT_DISPLAY_TIMEOUT;
278 while (mLogicalDisplays.get(Display.DEFAULT_DISPLAY) == null) {
279 long delay = timeout - SystemClock.uptimeMillis();
280 if (delay <= 0) {
281 throw new RuntimeException("Timeout waiting for default display "
282 + "to be initialized.");
283 }
284 if (DEBUG) {
285 Slog.d(TAG, "waitForDefaultDisplay: waiting, timeout=" + delay);
286 }
287 try {
288 mSyncRoot.wait(delay);
289 } catch (InterruptedException ex) {
290 }
Jeff Brownbd6e1502012-08-28 03:27:37 -0700291 }
292 }
293 }
Jeff Brownbd6e1502012-08-28 03:27:37 -0700294 }
295
Jeff Brown4ccb8232014-01-16 22:16:42 -0800296 // TODO: Use dependencies or a boot phase
297 public void windowManagerAndInputReady() {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700298 synchronized (mSyncRoot) {
Jeff Brown4ccb8232014-01-16 22:16:42 -0800299 mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
300 mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);
Craig Mautner65d11b32012-10-01 13:59:52 -0700301 scheduleTraversalLocked(false);
Jeff Brownd728bf52012-09-08 18:05:28 -0700302 }
303 }
304
305 /**
Jeff Brownbd6e1502012-08-28 03:27:37 -0700306 * Called when the system is ready to go.
307 */
308 public void systemReady(boolean safeMode, boolean onlyCore) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700309 synchronized (mSyncRoot) {
Jeff Brownbd6e1502012-08-28 03:27:37 -0700310 mSafeMode = safeMode;
311 mOnlyCore = onlyCore;
312 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700313
Jeff Brownbd6e1502012-08-28 03:27:37 -0700314 mHandler.sendEmptyMessage(MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS);
315 }
316
Jeff Brown4ccb8232014-01-16 22:16:42 -0800317 private void registerDisplayTransactionListenerInternal(
318 DisplayTransactionListener listener) {
Jeff Brown7f3994e2012-12-04 14:04:28 -0800319 // List is self-synchronized copy-on-write.
320 mDisplayTransactionListeners.add(listener);
321 }
322
Jeff Brown4ccb8232014-01-16 22:16:42 -0800323 private void unregisterDisplayTransactionListenerInternal(
324 DisplayTransactionListener listener) {
Jeff Brown7f3994e2012-12-04 14:04:28 -0800325 // List is self-synchronized copy-on-write.
326 mDisplayTransactionListeners.remove(listener);
327 }
328
Jeff Brown4ccb8232014-01-16 22:16:42 -0800329 private void setDisplayInfoOverrideFromWindowManagerInternal(
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700330 int displayId, DisplayInfo info) {
331 synchronized (mSyncRoot) {
Jeff Brownbd6e1502012-08-28 03:27:37 -0700332 LogicalDisplay display = mLogicalDisplays.get(displayId);
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700333 if (display != null) {
Jeff Brownef981a42013-08-07 14:13:37 -0700334 if (display.setDisplayInfoOverrideFromWindowManagerLocked(info)) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700335 sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_CHANGED);
Craig Mautner65d11b32012-10-01 13:59:52 -0700336 scheduleTraversalLocked(false);
Jeff Brownbd6e1502012-08-28 03:27:37 -0700337 }
Jeff Brownbd6e1502012-08-28 03:27:37 -0700338 }
339 }
340 }
341
Jeff Brown4ccb8232014-01-16 22:16:42 -0800342 private void performTraversalInTransactionFromWindowManagerInternal() {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700343 synchronized (mSyncRoot) {
344 if (!mPendingTraversal) {
345 return;
Jeff Brownbd6e1502012-08-28 03:27:37 -0700346 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700347 mPendingTraversal = false;
348
349 performTraversalInTransactionLocked();
Jeff Brownbd6e1502012-08-28 03:27:37 -0700350 }
Jeff Brown7f3994e2012-12-04 14:04:28 -0800351
352 // List is self-synchronized copy-on-write.
353 for (DisplayTransactionListener listener : mDisplayTransactionListeners) {
354 listener.onDisplayTransaction();
355 }
Jeff Brownbd6e1502012-08-28 03:27:37 -0700356 }
357
Jeff Brown5d6443b2015-04-10 20:15:01 -0700358 private void requestGlobalDisplayStateInternal(int state, int brightness) {
359 if (state == Display.STATE_UNKNOWN) {
360 state = Display.STATE_ON;
361 }
362 if (state == Display.STATE_OFF) {
363 brightness = PowerManager.BRIGHTNESS_OFF;
364 } else if (brightness < 0) {
365 brightness = PowerManager.BRIGHTNESS_DEFAULT;
366 } else if (brightness > PowerManager.BRIGHTNESS_ON) {
367 brightness = PowerManager.BRIGHTNESS_ON;
368 }
369
Jeff Browne75926d2014-09-18 15:24:49 -0700370 synchronized (mTempDisplayStateWorkQueue) {
371 try {
372 // Update the display state within the lock.
Jeff Brown8e5d33e2015-06-10 13:05:50 -0700373 // Note that we do not need to schedule traversals here although it
374 // may happen as a side-effect of displays changing state.
Jeff Browne75926d2014-09-18 15:24:49 -0700375 synchronized (mSyncRoot) {
Jeff Brown5d6443b2015-04-10 20:15:01 -0700376 if (mGlobalDisplayState == state
377 && mGlobalDisplayBrightness == brightness) {
378 return; // no change
Jeff Browne75926d2014-09-18 15:24:49 -0700379 }
Jeff Brown5d6443b2015-04-10 20:15:01 -0700380
381 Trace.traceBegin(Trace.TRACE_TAG_POWER, "requestGlobalDisplayState("
382 + Display.stateToString(state)
383 + ", brightness=" + brightness + ")");
384 mGlobalDisplayState = state;
385 mGlobalDisplayBrightness = brightness;
Jeff Brown8e5d33e2015-06-10 13:05:50 -0700386 applyGlobalDisplayStateLocked(mTempDisplayStateWorkQueue);
Jeff Browne75926d2014-09-18 15:24:49 -0700387 }
388
389 // Setting the display power state can take hundreds of milliseconds
390 // to complete so we defer the most expensive part of the work until
391 // after we have exited the critical section to avoid blocking other
392 // threads for a long time.
393 for (int i = 0; i < mTempDisplayStateWorkQueue.size(); i++) {
394 mTempDisplayStateWorkQueue.get(i).run();
395 }
Jeff Brown5d6443b2015-04-10 20:15:01 -0700396 Trace.traceEnd(Trace.TRACE_TAG_POWER);
Jeff Browne75926d2014-09-18 15:24:49 -0700397 } finally {
398 mTempDisplayStateWorkQueue.clear();
Jeff Brown9e316a12012-10-08 19:17:06 -0700399 }
400 }
401 }
402
Jeff Brown4ccb8232014-01-16 22:16:42 -0800403 private DisplayInfo getDisplayInfoInternal(int displayId, int callingUid) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700404 synchronized (mSyncRoot) {
Jeff Brown4ccb8232014-01-16 22:16:42 -0800405 LogicalDisplay display = mLogicalDisplays.get(displayId);
406 if (display != null) {
407 DisplayInfo info = display.getDisplayInfoLocked();
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800408 if (info.hasAccess(callingUid)
409 || isUidPresentOnDisplayInternal(callingUid, displayId)) {
Jeff Brown4ccb8232014-01-16 22:16:42 -0800410 return info;
411 }
412 }
413 return null;
414 }
415 }
416
417 private int[] getDisplayIdsInternal(int callingUid) {
418 synchronized (mSyncRoot) {
419 final int count = mLogicalDisplays.size();
420 int[] displayIds = new int[count];
421 int n = 0;
422 for (int i = 0; i < count; i++) {
423 LogicalDisplay display = mLogicalDisplays.valueAt(i);
424 DisplayInfo info = display.getDisplayInfoLocked();
425 if (info.hasAccess(callingUid)) {
426 displayIds[n++] = mLogicalDisplays.keyAt(i);
427 }
428 }
429 if (n != count) {
430 displayIds = Arrays.copyOfRange(displayIds, 0, n);
431 }
432 return displayIds;
433 }
434 }
435
436 private void registerCallbackInternal(IDisplayManagerCallback callback, int callingPid) {
437 synchronized (mSyncRoot) {
Jeff Brownbd6e1502012-08-28 03:27:37 -0700438 if (mCallbacks.get(callingPid) != null) {
439 throw new SecurityException("The calling process has already "
440 + "registered an IDisplayManagerCallback.");
Jeff Brown64a55af2012-08-26 02:47:39 -0700441 }
442
Jeff Brownbd6e1502012-08-28 03:27:37 -0700443 CallbackRecord record = new CallbackRecord(callingPid, callback);
444 try {
445 IBinder binder = callback.asBinder();
446 binder.linkToDeath(record, 0);
447 } catch (RemoteException ex) {
448 // give up
449 throw new RuntimeException(ex);
450 }
451
452 mCallbacks.put(callingPid, record);
453 }
454 }
455
Jeff Brownce468a32013-11-21 16:42:03 -0800456 private void onCallbackDied(CallbackRecord record) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700457 synchronized (mSyncRoot) {
Jeff Brownce468a32013-11-21 16:42:03 -0800458 mCallbacks.remove(record.mPid);
459 stopWifiDisplayScanLocked(record);
Jeff Brownbd6e1502012-08-28 03:27:37 -0700460 }
461 }
462
Jeff Brown4ccb8232014-01-16 22:16:42 -0800463 private void startWifiDisplayScanInternal(int callingPid) {
464 synchronized (mSyncRoot) {
465 CallbackRecord record = mCallbacks.get(callingPid);
466 if (record == null) {
467 throw new IllegalStateException("The calling process has not "
468 + "registered an IDisplayManagerCallback.");
Jeff Browne08ae382012-09-07 20:36:36 -0700469 }
Jeff Brown4ccb8232014-01-16 22:16:42 -0800470 startWifiDisplayScanLocked(record);
Jeff Browne08ae382012-09-07 20:36:36 -0700471 }
472 }
473
Jeff Brownce468a32013-11-21 16:42:03 -0800474 private void startWifiDisplayScanLocked(CallbackRecord record) {
475 if (!record.mWifiDisplayScanRequested) {
476 record.mWifiDisplayScanRequested = true;
477 if (mWifiDisplayScanRequestCount++ == 0) {
478 if (mWifiDisplayAdapter != null) {
479 mWifiDisplayAdapter.requestStartScanLocked();
480 }
481 }
482 }
483 }
484
Jeff Brown4ccb8232014-01-16 22:16:42 -0800485 private void stopWifiDisplayScanInternal(int callingPid) {
486 synchronized (mSyncRoot) {
487 CallbackRecord record = mCallbacks.get(callingPid);
488 if (record == null) {
489 throw new IllegalStateException("The calling process has not "
490 + "registered an IDisplayManagerCallback.");
Jeff Brownce468a32013-11-21 16:42:03 -0800491 }
Jeff Brown4ccb8232014-01-16 22:16:42 -0800492 stopWifiDisplayScanLocked(record);
Jeff Brownce468a32013-11-21 16:42:03 -0800493 }
494 }
495
496 private void stopWifiDisplayScanLocked(CallbackRecord record) {
497 if (record.mWifiDisplayScanRequested) {
498 record.mWifiDisplayScanRequested = false;
499 if (--mWifiDisplayScanRequestCount == 0) {
500 if (mWifiDisplayAdapter != null) {
501 mWifiDisplayAdapter.requestStopScanLocked();
502 }
503 } else if (mWifiDisplayScanRequestCount < 0) {
Dianne Hackborn8d051722014-10-01 14:59:58 -0700504 Slog.wtf(TAG, "mWifiDisplayScanRequestCount became negative: "
Jeff Brownce468a32013-11-21 16:42:03 -0800505 + mWifiDisplayScanRequestCount);
506 mWifiDisplayScanRequestCount = 0;
507 }
508 }
509 }
510
Jeff Brown4ccb8232014-01-16 22:16:42 -0800511 private void connectWifiDisplayInternal(String address) {
512 synchronized (mSyncRoot) {
513 if (mWifiDisplayAdapter != null) {
514 mWifiDisplayAdapter.requestConnectLocked(address);
Jeff Browne08ae382012-09-07 20:36:36 -0700515 }
Jeff Browne08ae382012-09-07 20:36:36 -0700516 }
517 }
518
Jeff Brown4ccb8232014-01-16 22:16:42 -0800519 private void pauseWifiDisplayInternal() {
520 synchronized (mSyncRoot) {
521 if (mWifiDisplayAdapter != null) {
522 mWifiDisplayAdapter.requestPauseLocked();
Chong Zhang1f3ecaa2013-05-03 15:55:36 -0700523 }
Chong Zhang1f3ecaa2013-05-03 15:55:36 -0700524 }
525 }
526
Jeff Brown4ccb8232014-01-16 22:16:42 -0800527 private void resumeWifiDisplayInternal() {
528 synchronized (mSyncRoot) {
529 if (mWifiDisplayAdapter != null) {
530 mWifiDisplayAdapter.requestResumeLocked();
Chong Zhang1f3ecaa2013-05-03 15:55:36 -0700531 }
Chong Zhang1f3ecaa2013-05-03 15:55:36 -0700532 }
533 }
534
Jeff Brown4ccb8232014-01-16 22:16:42 -0800535 private void disconnectWifiDisplayInternal() {
536 synchronized (mSyncRoot) {
537 if (mWifiDisplayAdapter != null) {
538 mWifiDisplayAdapter.requestDisconnectLocked();
Jeff Browne08ae382012-09-07 20:36:36 -0700539 }
Jeff Browne08ae382012-09-07 20:36:36 -0700540 }
541 }
542
Jeff Brown4ccb8232014-01-16 22:16:42 -0800543 private void renameWifiDisplayInternal(String address, String alias) {
544 synchronized (mSyncRoot) {
545 if (mWifiDisplayAdapter != null) {
546 mWifiDisplayAdapter.requestRenameLocked(address, alias);
Jeff Brown89d55462012-09-19 11:33:42 -0700547 }
Jeff Brown89d55462012-09-19 11:33:42 -0700548 }
549 }
550
Jeff Brown4ccb8232014-01-16 22:16:42 -0800551 private void forgetWifiDisplayInternal(String address) {
552 synchronized (mSyncRoot) {
553 if (mWifiDisplayAdapter != null) {
554 mWifiDisplayAdapter.requestForgetLocked(address);
Jeff Brown89d55462012-09-19 11:33:42 -0700555 }
Jeff Brown89d55462012-09-19 11:33:42 -0700556 }
557 }
558
Jeff Brown4ccb8232014-01-16 22:16:42 -0800559 private WifiDisplayStatus getWifiDisplayStatusInternal() {
560 synchronized (mSyncRoot) {
561 if (mWifiDisplayAdapter != null) {
562 return mWifiDisplayAdapter.getWifiDisplayStatusLocked();
Jeff Browne08ae382012-09-07 20:36:36 -0700563 }
Jeff Brown4ccb8232014-01-16 22:16:42 -0800564 return new WifiDisplayStatus();
Jeff Browne08ae382012-09-07 20:36:36 -0700565 }
566 }
567
Michael Wright1c9977b2016-07-12 13:30:10 -0700568 private void requestColorModeInternal(int displayId, int colorMode) {
Michael Wright58e829f2015-09-15 00:13:26 +0100569 synchronized (mSyncRoot) {
570 LogicalDisplay display = mLogicalDisplays.get(displayId);
571 if (display != null &&
Michael Wright1c9977b2016-07-12 13:30:10 -0700572 display.getRequestedColorModeLocked() != colorMode) {
573 display.setRequestedColorModeLocked(colorMode);
Michael Wright58e829f2015-09-15 00:13:26 +0100574 scheduleTraversalLocked(false);
575 }
576 }
577 }
578
Michael Wright75ee9fc2014-09-01 19:55:22 -0700579 private int createVirtualDisplayInternal(IVirtualDisplayCallback callback,
Michael Wrightc39d47a2014-07-08 18:07:36 -0700580 IMediaProjection projection, int callingUid, String packageName,
Jeff Brown7d00aff2013-08-02 19:03:49 -0700581 String name, int width, int height, int densityDpi, Surface surface, int flags) {
Jeff Brown4ccb8232014-01-16 22:16:42 -0800582 synchronized (mSyncRoot) {
583 if (mVirtualDisplayAdapter == null) {
584 Slog.w(TAG, "Rejecting request to create private virtual display "
585 + "because the virtual display adapter is not available.");
586 return -1;
Jeff Brown7d00aff2013-08-02 19:03:49 -0700587 }
Jeff Brown4ccb8232014-01-16 22:16:42 -0800588
589 DisplayDevice device = mVirtualDisplayAdapter.createVirtualDisplayLocked(
Michael Wright75ee9fc2014-09-01 19:55:22 -0700590 callback, projection, callingUid, packageName,
Michael Wrightc39d47a2014-07-08 18:07:36 -0700591 name, width, height, densityDpi, surface, flags);
Jeff Brown4ccb8232014-01-16 22:16:42 -0800592 if (device == null) {
593 return -1;
Jeff Brown7d00aff2013-08-02 19:03:49 -0700594 }
Jeff Browna506a6e2013-06-04 00:02:38 -0700595
Jeff Brown4ccb8232014-01-16 22:16:42 -0800596 handleDisplayDeviceAddedLocked(device);
597 LogicalDisplay display = findLogicalDisplayForDeviceLocked(device);
598 if (display != null) {
599 return display.getDisplayIdLocked();
Jeff Browna506a6e2013-06-04 00:02:38 -0700600 }
Jeff Brown4ccb8232014-01-16 22:16:42 -0800601
602 // Something weird happened and the logical display was not created.
603 Slog.w(TAG, "Rejecting request to create virtual display "
604 + "because the logical display was not created.");
Michael Wright75ee9fc2014-09-01 19:55:22 -0700605 mVirtualDisplayAdapter.releaseVirtualDisplayLocked(callback.asBinder());
Jeff Brown4ccb8232014-01-16 22:16:42 -0800606 handleDisplayDeviceRemovedLocked(device);
Jeff Browna506a6e2013-06-04 00:02:38 -0700607 }
608 return -1;
609 }
610
Michael Wright01e840f2014-06-26 16:03:25 -0700611 private void resizeVirtualDisplayInternal(IBinder appToken,
612 int width, int height, int densityDpi) {
613 synchronized (mSyncRoot) {
614 if (mVirtualDisplayAdapter == null) {
615 return;
616 }
617
618 mVirtualDisplayAdapter.resizeVirtualDisplayLocked(appToken, width, height, densityDpi);
619 }
620 }
621
Jeff Brown92207df2014-04-16 13:16:07 -0700622 private void setVirtualDisplaySurfaceInternal(IBinder appToken, Surface surface) {
623 synchronized (mSyncRoot) {
624 if (mVirtualDisplayAdapter == null) {
625 return;
626 }
627
628 mVirtualDisplayAdapter.setVirtualDisplaySurfaceLocked(appToken, surface);
629 }
630 }
631
Jeff Brown4ccb8232014-01-16 22:16:42 -0800632 private void releaseVirtualDisplayInternal(IBinder appToken) {
633 synchronized (mSyncRoot) {
634 if (mVirtualDisplayAdapter == null) {
635 return;
Jeff Browna506a6e2013-06-04 00:02:38 -0700636 }
Jeff Browna506a6e2013-06-04 00:02:38 -0700637
Jeff Brown4ccb8232014-01-16 22:16:42 -0800638 DisplayDevice device =
639 mVirtualDisplayAdapter.releaseVirtualDisplayLocked(appToken);
640 if (device != null) {
641 handleDisplayDeviceRemovedLocked(device);
Jeff Browna506a6e2013-06-04 00:02:38 -0700642 }
643 }
Jeff Browna506a6e2013-06-04 00:02:38 -0700644 }
645
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700646 private void registerDefaultDisplayAdapter() {
647 // Register default display adapter.
648 synchronized (mSyncRoot) {
Mike Lockwoode63f6f72013-11-15 11:01:47 -0800649 registerDisplayAdapterLocked(new LocalDisplayAdapter(
650 mSyncRoot, mContext, mHandler, mDisplayAdapterListener));
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700651 }
652 }
653
654 private void registerAdditionalDisplayAdapters() {
655 synchronized (mSyncRoot) {
656 if (shouldRegisterNonEssentialDisplayAdaptersLocked()) {
Jeff Brown89d55462012-09-19 11:33:42 -0700657 registerOverlayDisplayAdapterLocked();
658 registerWifiDisplayAdapterLocked();
Jeff Browna506a6e2013-06-04 00:02:38 -0700659 registerVirtualDisplayAdapterLocked();
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700660 }
661 }
662 }
663
Jeff Brown89d55462012-09-19 11:33:42 -0700664 private void registerOverlayDisplayAdapterLocked() {
665 registerDisplayAdapterLocked(new OverlayDisplayAdapter(
666 mSyncRoot, mContext, mHandler, mDisplayAdapterListener, mUiHandler));
667 }
668
669 private void registerWifiDisplayAdapterLocked() {
670 if (mContext.getResources().getBoolean(
Jeff Brownbbd28a22012-09-20 16:47:15 -0700671 com.android.internal.R.bool.config_enableWifiDisplay)
672 || SystemProperties.getInt(FORCE_WIFI_DISPLAY_ENABLE, -1) == 1) {
Jeff Brown89d55462012-09-19 11:33:42 -0700673 mWifiDisplayAdapter = new WifiDisplayAdapter(
674 mSyncRoot, mContext, mHandler, mDisplayAdapterListener,
675 mPersistentDataStore);
676 registerDisplayAdapterLocked(mWifiDisplayAdapter);
677 }
678 }
679
Jeff Browna506a6e2013-06-04 00:02:38 -0700680 private void registerVirtualDisplayAdapterLocked() {
681 mVirtualDisplayAdapter = new VirtualDisplayAdapter(
682 mSyncRoot, mContext, mHandler, mDisplayAdapterListener);
683 registerDisplayAdapterLocked(mVirtualDisplayAdapter);
684 }
685
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700686 private boolean shouldRegisterNonEssentialDisplayAdaptersLocked() {
687 // In safe mode, we disable non-essential display adapters to give the user
688 // an opportunity to fix broken settings or other problems that might affect
689 // system stability.
690 // In only-core mode, we disable non-essential display adapters to minimize
691 // the number of dependencies that are started while in this mode and to
692 // prevent problems that might occur due to the device being encrypted.
693 return !mSafeMode && !mOnlyCore;
694 }
695
696 private void registerDisplayAdapterLocked(DisplayAdapter adapter) {
697 mDisplayAdapters.add(adapter);
698 adapter.registerLocked();
699 }
700
Jeff Brownbd6e1502012-08-28 03:27:37 -0700701 private void handleDisplayDeviceAdded(DisplayDevice device) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700702 synchronized (mSyncRoot) {
Jeff Browna506a6e2013-06-04 00:02:38 -0700703 handleDisplayDeviceAddedLocked(device);
Jeff Brownbd6e1502012-08-28 03:27:37 -0700704 }
705 }
706
Jeff Browna506a6e2013-06-04 00:02:38 -0700707 private void handleDisplayDeviceAddedLocked(DisplayDevice device) {
Jeff Brown10acf6d2015-04-14 14:20:47 -0700708 DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
Jeff Browna506a6e2013-06-04 00:02:38 -0700709 if (mDisplayDevices.contains(device)) {
Jeff Brown10acf6d2015-04-14 14:20:47 -0700710 Slog.w(TAG, "Attempted to add already added display device: " + info);
Jeff Browna506a6e2013-06-04 00:02:38 -0700711 return;
712 }
713
Jeff Brown10acf6d2015-04-14 14:20:47 -0700714 Slog.i(TAG, "Display device added: " + info);
715 device.mDebugLastLoggedDeviceInfo = info;
Jeff Browna506a6e2013-06-04 00:02:38 -0700716
717 mDisplayDevices.add(device);
Michael Wright1c9977b2016-07-12 13:30:10 -0700718 LogicalDisplay display = addLogicalDisplayLocked(device);
Jeff Brown0033a862014-10-08 12:06:39 -0700719 Runnable work = updateDisplayStateLocked(device);
720 if (work != null) {
721 work.run();
722 }
Michael Wright1c9977b2016-07-12 13:30:10 -0700723 if (display != null && display.getPrimaryDisplayDeviceLocked() == device) {
724 int colorMode = mPersistentDataStore.getColorMode(device);
Damien Bargiacchi4364bbf2016-11-01 21:44:20 -0700725 if (colorMode == Display.COLOR_MODE_INVALID) {
726 if ((device.getDisplayDeviceInfoLocked().flags
727 & DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY) != 0) {
728 colorMode = mDefaultDisplayDefaultColorMode;
729 } else {
730 colorMode = Display.COLOR_MODE_DEFAULT;
731 }
732 }
Michael Wright1c9977b2016-07-12 13:30:10 -0700733 display.setRequestedColorModeLocked(colorMode);
734 }
Jeff Browna506a6e2013-06-04 00:02:38 -0700735 scheduleTraversalLocked(false);
736 }
737
Jeff Brownbd6e1502012-08-28 03:27:37 -0700738 private void handleDisplayDeviceChanged(DisplayDevice device) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700739 synchronized (mSyncRoot) {
Jeff Brown10acf6d2015-04-14 14:20:47 -0700740 DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
Jeff Brownbd6e1502012-08-28 03:27:37 -0700741 if (!mDisplayDevices.contains(device)) {
Jeff Brown10acf6d2015-04-14 14:20:47 -0700742 Slog.w(TAG, "Attempted to change non-existent display device: " + info);
Jeff Brownbd6e1502012-08-28 03:27:37 -0700743 return;
744 }
745
Jeff Brown10acf6d2015-04-14 14:20:47 -0700746 int diff = device.mDebugLastLoggedDeviceInfo.diff(info);
747 if (diff == DisplayDeviceInfo.DIFF_STATE) {
748 Slog.i(TAG, "Display device changed state: \"" + info.name
749 + "\", " + Display.stateToString(info.state));
750 } else if (diff != 0) {
751 Slog.i(TAG, "Display device changed: " + info);
752 }
Michael Wright1c9977b2016-07-12 13:30:10 -0700753 if ((diff & DisplayDeviceInfo.DIFF_COLOR_MODE) != 0) {
754 try {
755 mPersistentDataStore.setColorMode(device, info.colorMode);
756 } finally {
757 mPersistentDataStore.saveIfNeeded();
758 }
759 }
Jeff Brown10acf6d2015-04-14 14:20:47 -0700760 device.mDebugLastLoggedDeviceInfo = info;
Jeff Browne87bf032012-09-20 18:30:13 -0700761
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700762 device.applyPendingDisplayDeviceInfoChangesLocked();
763 if (updateLogicalDisplaysLocked()) {
Craig Mautner65d11b32012-10-01 13:59:52 -0700764 scheduleTraversalLocked(false);
Jeff Brown64a55af2012-08-26 02:47:39 -0700765 }
766 }
767 }
768
Jeff Brownbd6e1502012-08-28 03:27:37 -0700769 private void handleDisplayDeviceRemoved(DisplayDevice device) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700770 synchronized (mSyncRoot) {
Jeff Browna506a6e2013-06-04 00:02:38 -0700771 handleDisplayDeviceRemovedLocked(device);
772 }
773 }
Jeff Brown8e5d33e2015-06-10 13:05:50 -0700774
Jeff Browna506a6e2013-06-04 00:02:38 -0700775 private void handleDisplayDeviceRemovedLocked(DisplayDevice device) {
Jeff Brown10acf6d2015-04-14 14:20:47 -0700776 DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
Jeff Browna506a6e2013-06-04 00:02:38 -0700777 if (!mDisplayDevices.remove(device)) {
Jeff Brown10acf6d2015-04-14 14:20:47 -0700778 Slog.w(TAG, "Attempted to remove non-existent display device: " + info);
Jeff Browna506a6e2013-06-04 00:02:38 -0700779 return;
780 }
781
Jeff Brown10acf6d2015-04-14 14:20:47 -0700782 Slog.i(TAG, "Display device removed: " + info);
783 device.mDebugLastLoggedDeviceInfo = info;
Jeff Browna506a6e2013-06-04 00:02:38 -0700784
Jeff Browna506a6e2013-06-04 00:02:38 -0700785 updateLogicalDisplaysLocked();
786 scheduleTraversalLocked(false);
787 }
788
Jeff Brown8e5d33e2015-06-10 13:05:50 -0700789 private void applyGlobalDisplayStateLocked(List<Runnable> workQueue) {
Jeff Browna506a6e2013-06-04 00:02:38 -0700790 final int count = mDisplayDevices.size();
791 for (int i = 0; i < count; i++) {
792 DisplayDevice device = mDisplayDevices.get(i);
Jeff Browne75926d2014-09-18 15:24:49 -0700793 Runnable runnable = updateDisplayStateLocked(device);
794 if (runnable != null) {
795 workQueue.add(runnable);
796 }
Jeff Browna506a6e2013-06-04 00:02:38 -0700797 }
798 }
799
Jeff Browne75926d2014-09-18 15:24:49 -0700800 private Runnable updateDisplayStateLocked(DisplayDevice device) {
Jeff Browna506a6e2013-06-04 00:02:38 -0700801 // Blank or unblank the display immediately to match the state requested
Jeff Brown037c33e2014-04-09 00:31:55 -0700802 // by the display power controller (if known).
Jeff Browna506a6e2013-06-04 00:02:38 -0700803 DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
804 if ((info.flags & DisplayDeviceInfo.FLAG_NEVER_BLANK) == 0) {
Jeff Brown5d6443b2015-04-10 20:15:01 -0700805 return device.requestDisplayStateLocked(mGlobalDisplayState, mGlobalDisplayBrightness);
Craig Mautner4f67ba62012-08-02 11:23:00 -0700806 }
Jeff Browne75926d2014-09-18 15:24:49 -0700807 return null;
Craig Mautner4f67ba62012-08-02 11:23:00 -0700808 }
809
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700810 // Adds a new logical display based on the given display device.
811 // Sends notifications if needed.
Michael Wright1c9977b2016-07-12 13:30:10 -0700812 private LogicalDisplay addLogicalDisplayLocked(DisplayDevice device) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700813 DisplayDeviceInfo deviceInfo = device.getDisplayDeviceInfoLocked();
814 boolean isDefault = (deviceInfo.flags
815 & DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY) != 0;
816 if (isDefault && mLogicalDisplays.get(Display.DEFAULT_DISPLAY) != null) {
817 Slog.w(TAG, "Ignoring attempt to add a second default display: " + deviceInfo);
818 isDefault = false;
819 }
820
Jeff Brown27f1d672012-10-17 18:32:34 -0700821 if (!isDefault && mSingleDisplayDemoMode) {
822 Slog.i(TAG, "Not creating a logical display for a secondary display "
823 + " because single display demo mode is enabled: " + deviceInfo);
Michael Wright1c9977b2016-07-12 13:30:10 -0700824 return null;
Jeff Brown27f1d672012-10-17 18:32:34 -0700825 }
826
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700827 final int displayId = assignDisplayIdLocked(isDefault);
828 final int layerStack = assignLayerStackLocked(displayId);
829
Jeff Brownd728bf52012-09-08 18:05:28 -0700830 LogicalDisplay display = new LogicalDisplay(displayId, layerStack, device);
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700831 display.updateLocked(mDisplayDevices);
832 if (!display.isValidLocked()) {
833 // This should never happen currently.
834 Slog.w(TAG, "Ignoring display device because the logical display "
835 + "created from it was not considered valid: " + deviceInfo);
Michael Wright1c9977b2016-07-12 13:30:10 -0700836 return null;
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700837 }
838
839 mLogicalDisplays.put(displayId, display);
840
841 // Wake up waitForDefaultDisplay.
842 if (isDefault) {
843 mSyncRoot.notifyAll();
844 }
845
846 sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_ADDED);
Michael Wright1c9977b2016-07-12 13:30:10 -0700847 return display;
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700848 }
849
850 private int assignDisplayIdLocked(boolean isDefault) {
851 return isDefault ? Display.DEFAULT_DISPLAY : mNextNonDefaultDisplayId++;
852 }
853
854 private int assignLayerStackLocked(int displayId) {
855 // Currently layer stacks and display ids are the same.
856 // This need not be the case.
857 return displayId;
858 }
859
860 // Updates all existing logical displays given the current set of display devices.
861 // Removes invalid logical displays.
862 // Sends notifications if needed.
863 private boolean updateLogicalDisplaysLocked() {
864 boolean changed = false;
865 for (int i = mLogicalDisplays.size(); i-- > 0; ) {
866 final int displayId = mLogicalDisplays.keyAt(i);
867 LogicalDisplay display = mLogicalDisplays.valueAt(i);
868
869 mTempDisplayInfo.copyFrom(display.getDisplayInfoLocked());
870 display.updateLocked(mDisplayDevices);
871 if (!display.isValidLocked()) {
872 mLogicalDisplays.removeAt(i);
873 sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_REMOVED);
874 changed = true;
875 } else if (!mTempDisplayInfo.equals(display.getDisplayInfoLocked())) {
876 sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_CHANGED);
877 changed = true;
878 }
879 }
880 return changed;
881 }
882
883 private void performTraversalInTransactionLocked() {
Jeff Brownd728bf52012-09-08 18:05:28 -0700884 // Clear all viewports before configuring displays so that we can keep
885 // track of which ones we have configured.
886 clearViewportsLocked();
887
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700888 // Configure each display device.
889 final int count = mDisplayDevices.size();
890 for (int i = 0; i < count; i++) {
891 DisplayDevice device = mDisplayDevices.get(i);
892 configureDisplayInTransactionLocked(device);
893 device.performTraversalInTransactionLocked();
894 }
Jeff Brownd728bf52012-09-08 18:05:28 -0700895
896 // Tell the input system about these new viewports.
Jeff Brown4ccb8232014-01-16 22:16:42 -0800897 if (mInputManagerInternal != null) {
Jeff Brownd728bf52012-09-08 18:05:28 -0700898 mHandler.sendEmptyMessage(MSG_UPDATE_VIEWPORT);
899 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700900 }
901
Michael Wright3f145a22014-07-22 19:46:03 -0700902 private void setDisplayPropertiesInternal(int displayId, boolean hasContent,
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700903 float requestedRefreshRate, int requestedModeId, boolean inTraversal) {
Craig Mautner722285e2012-09-07 13:55:58 -0700904 synchronized (mSyncRoot) {
905 LogicalDisplay display = mLogicalDisplays.get(displayId);
Michael Wright3f145a22014-07-22 19:46:03 -0700906 if (display == null) {
907 return;
908 }
909 if (display.hasContentLocked() != hasContent) {
Jeff Brown33041bd2013-08-02 21:11:14 -0700910 if (DEBUG) {
911 Slog.d(TAG, "Display " + displayId + " hasContent flag changed: "
912 + "hasContent=" + hasContent + ", inTraversal=" + inTraversal);
913 }
914
Craig Mautner722285e2012-09-07 13:55:58 -0700915 display.setHasContentLocked(hasContent);
Craig Mautner65d11b32012-10-01 13:59:52 -0700916 scheduleTraversalLocked(inTraversal);
Craig Mautner722285e2012-09-07 13:55:58 -0700917 }
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700918 if (requestedModeId == 0 && requestedRefreshRate != 0) {
919 // Scan supported modes returned by display.getInfo() to find a mode with the same
920 // size as the default display mode but with the specified refresh rate instead.
921 requestedModeId = display.getDisplayInfoLocked().findDefaultModeByRefreshRate(
922 requestedRefreshRate);
923 }
924 if (display.getRequestedModeIdLocked() != requestedModeId) {
Michael Wright3f145a22014-07-22 19:46:03 -0700925 if (DEBUG) {
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700926 Slog.d(TAG, "Display " + displayId + " switching to mode " + requestedModeId);
Michael Wright3f145a22014-07-22 19:46:03 -0700927 }
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700928 display.setRequestedModeIdLocked(requestedModeId);
Michael Wright3f145a22014-07-22 19:46:03 -0700929 scheduleTraversalLocked(inTraversal);
930 }
Craig Mautner722285e2012-09-07 13:55:58 -0700931 }
Jeff Brownd728bf52012-09-08 18:05:28 -0700932 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700933
Filip Gruszczynskid2e86402015-02-19 13:05:03 -0800934 private void setDisplayOffsetsInternal(int displayId, int x, int y) {
935 synchronized (mSyncRoot) {
936 LogicalDisplay display = mLogicalDisplays.get(displayId);
937 if (display == null) {
938 return;
939 }
940 if (display.getDisplayOffsetXLocked() != x
941 || display.getDisplayOffsetYLocked() != y) {
942 if (DEBUG) {
943 Slog.d(TAG, "Display " + displayId + " burn-in offset set to ("
944 + x + ", " + y + ")");
945 }
946 display.setDisplayOffsetsLocked(x, y);
947 scheduleTraversalLocked(false);
948 }
949 }
950 }
951
Andrii Kulianfb1bf692017-01-17 11:17:34 -0800952 // Updates the lists of UIDs that are present on displays.
953 private void setDisplayAccessUIDsInternal(SparseArray<IntArray> newDisplayAccessUIDs) {
954 synchronized (mSyncRoot) {
955 mDisplayAccessUIDs.clear();
956 for (int i = newDisplayAccessUIDs.size() - 1; i >= 0; i--) {
957 mDisplayAccessUIDs.append(newDisplayAccessUIDs.keyAt(i),
958 newDisplayAccessUIDs.valueAt(i));
959 }
960 }
961 }
962
963 // Checks if provided UID's content is present on the display and UID has access to it.
964 private boolean isUidPresentOnDisplayInternal(int uid, int displayId) {
965 synchronized (mSyncRoot) {
966 final IntArray displayUIDs = mDisplayAccessUIDs.get(displayId);
967 return displayUIDs != null && displayUIDs.indexOf(uid) != -1;
968 }
969 }
970
Jeff Brownd728bf52012-09-08 18:05:28 -0700971 private void clearViewportsLocked() {
972 mDefaultViewport.valid = false;
973 mExternalTouchViewport.valid = false;
Craig Mautner722285e2012-09-07 13:55:58 -0700974 }
975
976 private void configureDisplayInTransactionLocked(DisplayDevice device) {
Jeff Brownd14c8c92014-01-07 18:13:09 -0800977 final DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
978 final boolean ownContent = (info.flags & DisplayDeviceInfo.FLAG_OWN_CONTENT_ONLY) != 0;
Jeff Browna506a6e2013-06-04 00:02:38 -0700979
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700980 // Find the logical display that the display device is showing.
Jeff Brownd14c8c92014-01-07 18:13:09 -0800981 // Certain displays only ever show their own content.
Craig Mautner722285e2012-09-07 13:55:58 -0700982 LogicalDisplay display = findLogicalDisplayForDeviceLocked(device);
Jeff Brownd14c8c92014-01-07 18:13:09 -0800983 if (!ownContent) {
Jeff Browna506a6e2013-06-04 00:02:38 -0700984 if (display != null && !display.hasContentLocked()) {
985 // If the display does not have any content of its own, then
986 // automatically mirror the default logical display contents.
987 display = null;
988 }
989 if (display == null) {
990 display = mLogicalDisplays.get(Display.DEFAULT_DISPLAY);
991 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700992 }
993
994 // Apply the logical display configuration to the display device.
995 if (display == null) {
996 // TODO: no logical display for the device, blank it
Jeff Brownd728bf52012-09-08 18:05:28 -0700997 Slog.w(TAG, "Missing logical display to use for physical display device: "
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700998 + device.getDisplayDeviceInfoLocked());
Jeff Brownd728bf52012-09-08 18:05:28 -0700999 return;
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001000 }
Jeff Brown037c33e2014-04-09 00:31:55 -07001001 display.configureDisplayInTransactionLocked(device, info.state == Display.STATE_OFF);
Jeff Brownd728bf52012-09-08 18:05:28 -07001002
1003 // Update the viewports if needed.
Jeff Brownd728bf52012-09-08 18:05:28 -07001004 if (!mDefaultViewport.valid
1005 && (info.flags & DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY) != 0) {
1006 setViewportLocked(mDefaultViewport, display, device);
1007 }
1008 if (!mExternalTouchViewport.valid
1009 && info.touch == DisplayDeviceInfo.TOUCH_EXTERNAL) {
1010 setViewportLocked(mExternalTouchViewport, display, device);
1011 }
1012 }
1013
1014 private static void setViewportLocked(DisplayViewport viewport,
1015 LogicalDisplay display, DisplayDevice device) {
1016 viewport.valid = true;
1017 viewport.displayId = display.getDisplayIdLocked();
1018 device.populateViewportLocked(viewport);
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001019 }
1020
1021 private LogicalDisplay findLogicalDisplayForDeviceLocked(DisplayDevice device) {
1022 final int count = mLogicalDisplays.size();
1023 for (int i = 0; i < count; i++) {
1024 LogicalDisplay display = mLogicalDisplays.valueAt(i);
1025 if (display.getPrimaryDisplayDeviceLocked() == device) {
1026 return display;
1027 }
1028 }
1029 return null;
1030 }
1031
Jeff Brownbd6e1502012-08-28 03:27:37 -07001032 private void sendDisplayEventLocked(int displayId, int event) {
1033 Message msg = mHandler.obtainMessage(MSG_DELIVER_DISPLAY_EVENT, displayId, event);
1034 mHandler.sendMessage(msg);
1035 }
1036
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001037 // Requests that performTraversalsInTransactionFromWindowManager be called at a
1038 // later time to apply changes to surfaces and displays.
Craig Mautner65d11b32012-10-01 13:59:52 -07001039 private void scheduleTraversalLocked(boolean inTraversal) {
Jeff Brown4ccb8232014-01-16 22:16:42 -08001040 if (!mPendingTraversal && mWindowManagerInternal != null) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001041 mPendingTraversal = true;
Craig Mautner65d11b32012-10-01 13:59:52 -07001042 if (!inTraversal) {
1043 mHandler.sendEmptyMessage(MSG_REQUEST_TRAVERSAL);
1044 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001045 }
1046 }
1047
1048 // Runs on Handler thread.
1049 // Delivers display event notifications to callbacks.
Jeff Brownbd6e1502012-08-28 03:27:37 -07001050 private void deliverDisplayEvent(int displayId, int event) {
1051 if (DEBUG) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001052 Slog.d(TAG, "Delivering display event: displayId="
1053 + displayId + ", event=" + event);
Jeff Brownfa25bf52012-07-23 19:26:30 -07001054 }
Jeff Brownfa25bf52012-07-23 19:26:30 -07001055
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001056 // Grab the lock and copy the callbacks.
Jeff Brownbd6e1502012-08-28 03:27:37 -07001057 final int count;
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001058 synchronized (mSyncRoot) {
Jeff Brownbd6e1502012-08-28 03:27:37 -07001059 count = mCallbacks.size();
1060 mTempCallbacks.clear();
1061 for (int i = 0; i < count; i++) {
1062 mTempCallbacks.add(mCallbacks.valueAt(i));
Craig Mautner4f67ba62012-08-02 11:23:00 -07001063 }
Jeff Brownbd6e1502012-08-28 03:27:37 -07001064 }
Craig Mautner4f67ba62012-08-02 11:23:00 -07001065
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001066 // After releasing the lock, send the notifications out.
Jeff Brownbd6e1502012-08-28 03:27:37 -07001067 for (int i = 0; i < count; i++) {
1068 mTempCallbacks.get(i).notifyDisplayEventAsync(displayId, event);
1069 }
1070 mTempCallbacks.clear();
Craig Mautner4f67ba62012-08-02 11:23:00 -07001071 }
1072
Michael Wrightc39d47a2014-07-08 18:07:36 -07001073 private IMediaProjectionManager getProjectionService() {
1074 if (mProjectionService == null) {
1075 IBinder b = ServiceManager.getService(Context.MEDIA_PROJECTION_SERVICE);
1076 mProjectionService = IMediaProjectionManager.Stub.asInterface(b);
1077 }
1078 return mProjectionService;
1079 }
1080
Jeff Brown4ccb8232014-01-16 22:16:42 -08001081 private void dumpInternal(PrintWriter pw) {
Jeff Brownbd6e1502012-08-28 03:27:37 -07001082 pw.println("DISPLAY MANAGER (dumpsys display)");
Jeff Brownfa25bf52012-07-23 19:26:30 -07001083
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001084 synchronized (mSyncRoot) {
Jeff Brown9e316a12012-10-08 19:17:06 -07001085 pw.println(" mOnlyCode=" + mOnlyCore);
1086 pw.println(" mSafeMode=" + mSafeMode);
1087 pw.println(" mPendingTraversal=" + mPendingTraversal);
Jeff Brown037c33e2014-04-09 00:31:55 -07001088 pw.println(" mGlobalDisplayState=" + Display.stateToString(mGlobalDisplayState));
Jeff Brown9e316a12012-10-08 19:17:06 -07001089 pw.println(" mNextNonDefaultDisplayId=" + mNextNonDefaultDisplayId);
1090 pw.println(" mDefaultViewport=" + mDefaultViewport);
1091 pw.println(" mExternalTouchViewport=" + mExternalTouchViewport);
Damien Bargiacchi4364bbf2016-11-01 21:44:20 -07001092 pw.println(" mDefaultDisplayDefaultColorMode=" + mDefaultDisplayDefaultColorMode);
Jeff Brown27f1d672012-10-17 18:32:34 -07001093 pw.println(" mSingleDisplayDemoMode=" + mSingleDisplayDemoMode);
Jeff Brownce468a32013-11-21 16:42:03 -08001094 pw.println(" mWifiDisplayScanRequestCount=" + mWifiDisplayScanRequestCount);
Jeff Brown9e316a12012-10-08 19:17:06 -07001095
Jeff Brownbd6e1502012-08-28 03:27:37 -07001096 IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001097 ipw.increaseIndent();
Jeff Brownbd6e1502012-08-28 03:27:37 -07001098
1099 pw.println();
1100 pw.println("Display Adapters: size=" + mDisplayAdapters.size());
Jeff Brown848c2dc2012-08-19 20:18:08 -07001101 for (DisplayAdapter adapter : mDisplayAdapters) {
Jeff Brownbd6e1502012-08-28 03:27:37 -07001102 pw.println(" " + adapter.getName());
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001103 adapter.dumpLocked(ipw);
Jeff Brown848c2dc2012-08-19 20:18:08 -07001104 }
Craig Mautner9de49362012-08-02 14:30:30 -07001105
Jeff Brownbd6e1502012-08-28 03:27:37 -07001106 pw.println();
1107 pw.println("Display Devices: size=" + mDisplayDevices.size());
1108 for (DisplayDevice device : mDisplayDevices) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001109 pw.println(" " + device.getDisplayDeviceInfoLocked());
1110 device.dumpLocked(ipw);
Jeff Brownbd6e1502012-08-28 03:27:37 -07001111 }
1112
1113 final int logicalDisplayCount = mLogicalDisplays.size();
1114 pw.println();
1115 pw.println("Logical Displays: size=" + logicalDisplayCount);
1116 for (int i = 0; i < logicalDisplayCount; i++) {
1117 int displayId = mLogicalDisplays.keyAt(i);
1118 LogicalDisplay display = mLogicalDisplays.valueAt(i);
1119 pw.println(" Display " + displayId + ":");
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001120 display.dumpLocked(ipw);
Jeff Brownbd6e1502012-08-28 03:27:37 -07001121 }
Jeff Brownce468a32013-11-21 16:42:03 -08001122
1123 final int callbackCount = mCallbacks.size();
1124 pw.println();
1125 pw.println("Callbacks: size=" + callbackCount);
1126 for (int i = 0; i < callbackCount; i++) {
1127 CallbackRecord callback = mCallbacks.valueAt(i);
1128 pw.println(" " + i + ": mPid=" + callback.mPid
1129 + ", mWifiDisplayScanRequested=" + callback.mWifiDisplayScanRequested);
1130 }
Jeff Brownad9ef192014-04-08 17:26:30 -07001131
1132 if (mDisplayPowerController != null) {
1133 mDisplayPowerController.dump(pw);
1134 }
Michael Wright1c9977b2016-07-12 13:30:10 -07001135
1136 pw.println();
1137 mPersistentDataStore.dump(pw);
Jeff Brownbd6e1502012-08-28 03:27:37 -07001138 }
1139 }
1140
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001141 /**
1142 * This is the object that everything in the display manager locks on.
1143 * We make it an inner class within the {@link DisplayManagerService} to so that it is
1144 * clear that the object belongs to the display manager service and that it is
1145 * a unique object with a special purpose.
1146 */
1147 public static final class SyncRoot {
1148 }
1149
Jeff Brownbd6e1502012-08-28 03:27:37 -07001150 private final class DisplayManagerHandler extends Handler {
1151 public DisplayManagerHandler(Looper looper) {
1152 super(looper, null, true /*async*/);
Jeff Brown848c2dc2012-08-19 20:18:08 -07001153 }
Jeff Brownbf5740e2012-08-19 23:20:02 -07001154
Jeff Brownbd6e1502012-08-28 03:27:37 -07001155 @Override
1156 public void handleMessage(Message msg) {
1157 switch (msg.what) {
1158 case MSG_REGISTER_DEFAULT_DISPLAY_ADAPTER:
1159 registerDefaultDisplayAdapter();
1160 break;
1161
1162 case MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS:
1163 registerAdditionalDisplayAdapters();
1164 break;
1165
1166 case MSG_DELIVER_DISPLAY_EVENT:
1167 deliverDisplayEvent(msg.arg1, msg.arg2);
1168 break;
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001169
1170 case MSG_REQUEST_TRAVERSAL:
Jeff Brown4ccb8232014-01-16 22:16:42 -08001171 mWindowManagerInternal.requestTraversalFromDisplayManager();
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001172 break;
Jeff Brownd728bf52012-09-08 18:05:28 -07001173
1174 case MSG_UPDATE_VIEWPORT: {
1175 synchronized (mSyncRoot) {
1176 mTempDefaultViewport.copyFrom(mDefaultViewport);
1177 mTempExternalTouchViewport.copyFrom(mExternalTouchViewport);
1178 }
Jeff Brown4ccb8232014-01-16 22:16:42 -08001179 mInputManagerInternal.setDisplayViewports(
Jeff Brownd728bf52012-09-08 18:05:28 -07001180 mTempDefaultViewport, mTempExternalTouchViewport);
1181 break;
1182 }
Jeff Brownbd6e1502012-08-28 03:27:37 -07001183 }
1184 }
1185 }
1186
1187 private final class DisplayAdapterListener implements DisplayAdapter.Listener {
1188 @Override
1189 public void onDisplayDeviceEvent(DisplayDevice device, int event) {
1190 switch (event) {
1191 case DisplayAdapter.DISPLAY_DEVICE_EVENT_ADDED:
1192 handleDisplayDeviceAdded(device);
1193 break;
1194
1195 case DisplayAdapter.DISPLAY_DEVICE_EVENT_CHANGED:
1196 handleDisplayDeviceChanged(device);
1197 break;
1198
1199 case DisplayAdapter.DISPLAY_DEVICE_EVENT_REMOVED:
1200 handleDisplayDeviceRemoved(device);
1201 break;
1202 }
1203 }
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001204
1205 @Override
1206 public void onTraversalRequested() {
1207 synchronized (mSyncRoot) {
Craig Mautner65d11b32012-10-01 13:59:52 -07001208 scheduleTraversalLocked(false);
Jeff Brown4ed8fe72012-08-30 18:18:29 -07001209 }
1210 }
Jeff Brownbd6e1502012-08-28 03:27:37 -07001211 }
1212
1213 private final class CallbackRecord implements DeathRecipient {
Jeff Brownce468a32013-11-21 16:42:03 -08001214 public final int mPid;
Jeff Brownbd6e1502012-08-28 03:27:37 -07001215 private final IDisplayManagerCallback mCallback;
1216
Jeff Brownce468a32013-11-21 16:42:03 -08001217 public boolean mWifiDisplayScanRequested;
1218
Jeff Brownbd6e1502012-08-28 03:27:37 -07001219 public CallbackRecord(int pid, IDisplayManagerCallback callback) {
1220 mPid = pid;
1221 mCallback = callback;
1222 }
1223
1224 @Override
1225 public void binderDied() {
1226 if (DEBUG) {
1227 Slog.d(TAG, "Display listener for pid " + mPid + " died.");
1228 }
Jeff Brownce468a32013-11-21 16:42:03 -08001229 onCallbackDied(this);
Jeff Brownbd6e1502012-08-28 03:27:37 -07001230 }
1231
1232 public void notifyDisplayEventAsync(int displayId, int event) {
1233 try {
1234 mCallback.onDisplayEvent(displayId, event);
1235 } catch (RemoteException ex) {
1236 Slog.w(TAG, "Failed to notify process "
1237 + mPid + " that displays changed, assuming it died.", ex);
1238 binderDied();
1239 }
1240 }
1241 }
Jeff Brown4ccb8232014-01-16 22:16:42 -08001242
1243 private final class BinderService extends IDisplayManager.Stub {
1244 /**
1245 * Returns information about the specified logical display.
1246 *
1247 * @param displayId The logical display id.
1248 * @return The logical display info, or null if the display does not exist. The
1249 * returned object must be treated as immutable.
1250 */
1251 @Override // Binder call
1252 public DisplayInfo getDisplayInfo(int displayId) {
1253 final int callingUid = Binder.getCallingUid();
1254 final long token = Binder.clearCallingIdentity();
1255 try {
1256 return getDisplayInfoInternal(displayId, callingUid);
1257 } finally {
1258 Binder.restoreCallingIdentity(token);
1259 }
1260 }
1261
1262 /**
1263 * Returns the list of all display ids.
1264 */
1265 @Override // Binder call
1266 public int[] getDisplayIds() {
1267 final int callingUid = Binder.getCallingUid();
1268 final long token = Binder.clearCallingIdentity();
1269 try {
1270 return getDisplayIdsInternal(callingUid);
1271 } finally {
1272 Binder.restoreCallingIdentity(token);
1273 }
1274 }
1275
1276 @Override // Binder call
1277 public void registerCallback(IDisplayManagerCallback callback) {
1278 if (callback == null) {
1279 throw new IllegalArgumentException("listener must not be null");
1280 }
1281
1282 final int callingPid = Binder.getCallingPid();
1283 final long token = Binder.clearCallingIdentity();
1284 try {
1285 registerCallbackInternal(callback, callingPid);
1286 } finally {
1287 Binder.restoreCallingIdentity(token);
1288 }
1289 }
1290
1291 @Override // Binder call
1292 public void startWifiDisplayScan() {
1293 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
1294 "Permission required to start wifi display scans");
1295
1296 final int callingPid = Binder.getCallingPid();
1297 final long token = Binder.clearCallingIdentity();
1298 try {
1299 startWifiDisplayScanInternal(callingPid);
1300 } finally {
1301 Binder.restoreCallingIdentity(token);
1302 }
1303 }
1304
1305 @Override // Binder call
1306 public void stopWifiDisplayScan() {
1307 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
1308 "Permission required to stop wifi display scans");
1309
1310 final int callingPid = Binder.getCallingPid();
1311 final long token = Binder.clearCallingIdentity();
1312 try {
1313 stopWifiDisplayScanInternal(callingPid);
1314 } finally {
1315 Binder.restoreCallingIdentity(token);
1316 }
1317 }
1318
1319 @Override // Binder call
1320 public void connectWifiDisplay(String address) {
1321 if (address == null) {
1322 throw new IllegalArgumentException("address must not be null");
1323 }
1324 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
1325 "Permission required to connect to a wifi display");
1326
1327 final long token = Binder.clearCallingIdentity();
1328 try {
1329 connectWifiDisplayInternal(address);
1330 } finally {
1331 Binder.restoreCallingIdentity(token);
1332 }
1333 }
1334
1335 @Override // Binder call
1336 public void disconnectWifiDisplay() {
1337 // This request does not require special permissions.
1338 // Any app can request disconnection from the currently active wifi display.
1339 // This exception should no longer be needed once wifi display control moves
1340 // to the media router service.
1341
1342 final long token = Binder.clearCallingIdentity();
1343 try {
1344 disconnectWifiDisplayInternal();
1345 } finally {
1346 Binder.restoreCallingIdentity(token);
1347 }
1348 }
1349
1350 @Override // Binder call
1351 public void renameWifiDisplay(String address, String alias) {
1352 if (address == null) {
1353 throw new IllegalArgumentException("address must not be null");
1354 }
1355 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
1356 "Permission required to rename to a wifi display");
1357
1358 final long token = Binder.clearCallingIdentity();
1359 try {
1360 renameWifiDisplayInternal(address, alias);
1361 } finally {
1362 Binder.restoreCallingIdentity(token);
1363 }
1364 }
1365
1366 @Override // Binder call
1367 public void forgetWifiDisplay(String address) {
1368 if (address == null) {
1369 throw new IllegalArgumentException("address must not be null");
1370 }
1371 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
1372 "Permission required to forget to a wifi display");
1373
1374 final long token = Binder.clearCallingIdentity();
1375 try {
1376 forgetWifiDisplayInternal(address);
1377 } finally {
1378 Binder.restoreCallingIdentity(token);
1379 }
1380 }
1381
1382 @Override // Binder call
1383 public void pauseWifiDisplay() {
1384 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
1385 "Permission required to pause a wifi display session");
1386
1387 final long token = Binder.clearCallingIdentity();
1388 try {
1389 pauseWifiDisplayInternal();
1390 } finally {
1391 Binder.restoreCallingIdentity(token);
1392 }
1393 }
1394
1395 @Override // Binder call
1396 public void resumeWifiDisplay() {
1397 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
1398 "Permission required to resume a wifi display session");
1399
1400 final long token = Binder.clearCallingIdentity();
1401 try {
1402 resumeWifiDisplayInternal();
1403 } finally {
1404 Binder.restoreCallingIdentity(token);
1405 }
1406 }
1407
1408 @Override // Binder call
1409 public WifiDisplayStatus getWifiDisplayStatus() {
1410 // This request does not require special permissions.
1411 // Any app can get information about available wifi displays.
1412
1413 final long token = Binder.clearCallingIdentity();
1414 try {
1415 return getWifiDisplayStatusInternal();
1416 } finally {
1417 Binder.restoreCallingIdentity(token);
1418 }
1419 }
1420
1421 @Override // Binder call
Michael Wright1c9977b2016-07-12 13:30:10 -07001422 public void requestColorMode(int displayId, int colorMode) {
Michael Wright58e829f2015-09-15 00:13:26 +01001423 mContext.enforceCallingOrSelfPermission(
Michael Wright1c9977b2016-07-12 13:30:10 -07001424 Manifest.permission.CONFIGURE_DISPLAY_COLOR_MODE,
1425 "Permission required to change the display color mode");
Michael Wright58e829f2015-09-15 00:13:26 +01001426 final long token = Binder.clearCallingIdentity();
1427 try {
Michael Wright1c9977b2016-07-12 13:30:10 -07001428 requestColorModeInternal(displayId, colorMode);
Michael Wright58e829f2015-09-15 00:13:26 +01001429 } finally {
1430 Binder.restoreCallingIdentity(token);
1431 }
1432 }
1433
1434 @Override // Binder call
Michael Wright75ee9fc2014-09-01 19:55:22 -07001435 public int createVirtualDisplay(IVirtualDisplayCallback callback,
Michael Wrightc39d47a2014-07-08 18:07:36 -07001436 IMediaProjection projection, String packageName, String name,
1437 int width, int height, int densityDpi, Surface surface, int flags) {
Jeff Brown4ccb8232014-01-16 22:16:42 -08001438 final int callingUid = Binder.getCallingUid();
1439 if (!validatePackageName(callingUid, packageName)) {
1440 throw new SecurityException("packageName must match the calling uid");
1441 }
Michael Wright75ee9fc2014-09-01 19:55:22 -07001442 if (callback == null) {
Jeff Brown4ccb8232014-01-16 22:16:42 -08001443 throw new IllegalArgumentException("appToken must not be null");
1444 }
1445 if (TextUtils.isEmpty(name)) {
1446 throw new IllegalArgumentException("name must be non-null and non-empty");
1447 }
1448 if (width <= 0 || height <= 0 || densityDpi <= 0) {
1449 throw new IllegalArgumentException("width, height, and densityDpi must be "
1450 + "greater than 0");
1451 }
Pablo Ceballoseb3370d2016-08-31 15:00:17 -07001452 if (surface != null && surface.isSingleBuffered()) {
Pablo Ceballosaff2f942016-07-29 14:49:55 -07001453 throw new IllegalArgumentException("Surface can't be single-buffered");
1454 }
Michael Wrightc39d47a2014-07-08 18:07:36 -07001455
Andrii Kulianfc8f82b2017-01-26 13:17:27 -08001456 if ((flags & VIRTUAL_DISPLAY_FLAG_PUBLIC) != 0) {
1457 flags |= VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR;
1458
1459 // Public displays can't be allowed to show content when locked.
1460 if ((flags & VIRTUAL_DISPLAY_FLAG_SHOW_WITH_INSECURE_LOCKSCREEN) != 0) {
1461 throw new IllegalArgumentException(
1462 "Public display must not be marked as SHOW_WHEN_LOCKED_INSECURE");
1463 }
Michael Wright6720be42014-07-29 19:14:16 -07001464 }
Andrii Kulianfc8f82b2017-01-26 13:17:27 -08001465 if ((flags & VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY) != 0) {
1466 flags &= ~VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR;
Michael Wright6720be42014-07-29 19:14:16 -07001467 }
1468
Michael Wrightc39d47a2014-07-08 18:07:36 -07001469 if (projection != null) {
1470 try {
1471 if (!getProjectionService().isValidMediaProjection(projection)) {
1472 throw new SecurityException("Invalid media projection");
1473 }
Michael Wright6720be42014-07-29 19:14:16 -07001474 flags = projection.applyVirtualDisplayFlags(flags);
Michael Wrightc39d47a2014-07-08 18:07:36 -07001475 } catch (RemoteException e) {
Michael Wright6720be42014-07-29 19:14:16 -07001476 throw new SecurityException("unable to validate media projection or flags");
Michael Wrightc39d47a2014-07-08 18:07:36 -07001477 }
1478 }
1479
Michael Wright6720be42014-07-29 19:14:16 -07001480 if (callingUid != Process.SYSTEM_UID &&
Andrii Kulianfc8f82b2017-01-26 13:17:27 -08001481 (flags & VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR) != 0) {
Michael Wrightc39d47a2014-07-08 18:07:36 -07001482 if (!canProjectVideo(projection)) {
1483 throw new SecurityException("Requires CAPTURE_VIDEO_OUTPUT or "
1484 + "CAPTURE_SECURE_VIDEO_OUTPUT permission, or an appropriate "
1485 + "MediaProjection token in order to create a screen sharing virtual "
1486 + "display.");
1487 }
1488 }
Andrii Kulianfc8f82b2017-01-26 13:17:27 -08001489 if ((flags & VIRTUAL_DISPLAY_FLAG_SECURE) != 0) {
Michael Wrightc39d47a2014-07-08 18:07:36 -07001490 if (!canProjectSecureVideo(projection)) {
Jeff Brown4ccb8232014-01-16 22:16:42 -08001491 throw new SecurityException("Requires CAPTURE_SECURE_VIDEO_OUTPUT "
Michael Wrightc39d47a2014-07-08 18:07:36 -07001492 + "or an appropriate MediaProjection token to create a "
1493 + "secure virtual display.");
Jeff Brown4ccb8232014-01-16 22:16:42 -08001494 }
1495 }
1496
1497 final long token = Binder.clearCallingIdentity();
1498 try {
Michael Wright75ee9fc2014-09-01 19:55:22 -07001499 return createVirtualDisplayInternal(callback, projection, callingUid,
Michael Wrightc39d47a2014-07-08 18:07:36 -07001500 packageName, name, width, height, densityDpi, surface, flags);
Jeff Brown4ccb8232014-01-16 22:16:42 -08001501 } finally {
1502 Binder.restoreCallingIdentity(token);
1503 }
1504 }
1505
1506 @Override // Binder call
Michael Wright75ee9fc2014-09-01 19:55:22 -07001507 public void resizeVirtualDisplay(IVirtualDisplayCallback callback,
Michael Wright01e840f2014-06-26 16:03:25 -07001508 int width, int height, int densityDpi) {
1509 final long token = Binder.clearCallingIdentity();
1510 try {
Michael Wright75ee9fc2014-09-01 19:55:22 -07001511 resizeVirtualDisplayInternal(callback.asBinder(), width, height, densityDpi);
Michael Wright01e840f2014-06-26 16:03:25 -07001512 } finally {
1513 Binder.restoreCallingIdentity(token);
1514 }
1515 }
1516
1517 @Override // Binder call
Michael Wright75ee9fc2014-09-01 19:55:22 -07001518 public void setVirtualDisplaySurface(IVirtualDisplayCallback callback, Surface surface) {
Pablo Ceballoseb3370d2016-08-31 15:00:17 -07001519 if (surface != null && surface.isSingleBuffered()) {
1520 throw new IllegalArgumentException("Surface can't be single-buffered");
1521 }
Jeff Brown92207df2014-04-16 13:16:07 -07001522 final long token = Binder.clearCallingIdentity();
1523 try {
Michael Wright75ee9fc2014-09-01 19:55:22 -07001524 setVirtualDisplaySurfaceInternal(callback.asBinder(), surface);
Jeff Brown92207df2014-04-16 13:16:07 -07001525 } finally {
1526 Binder.restoreCallingIdentity(token);
1527 }
1528 }
1529
1530 @Override // Binder call
Michael Wright75ee9fc2014-09-01 19:55:22 -07001531 public void releaseVirtualDisplay(IVirtualDisplayCallback callback) {
Jeff Brown4ccb8232014-01-16 22:16:42 -08001532 final long token = Binder.clearCallingIdentity();
1533 try {
Michael Wright75ee9fc2014-09-01 19:55:22 -07001534 releaseVirtualDisplayInternal(callback.asBinder());
Jeff Brown4ccb8232014-01-16 22:16:42 -08001535 } finally {
1536 Binder.restoreCallingIdentity(token);
1537 }
1538 }
1539
1540 @Override // Binder call
1541 public void dump(FileDescriptor fd, final PrintWriter pw, String[] args) {
1542 if (mContext == null
1543 || mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP)
1544 != PackageManager.PERMISSION_GRANTED) {
1545 pw.println("Permission Denial: can't dump DisplayManager from from pid="
1546 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
1547 return;
1548 }
1549
1550 final long token = Binder.clearCallingIdentity();
1551 try {
1552 dumpInternal(pw);
1553 } finally {
1554 Binder.restoreCallingIdentity(token);
1555 }
1556 }
1557
1558 private boolean validatePackageName(int uid, String packageName) {
1559 if (packageName != null) {
1560 String[] packageNames = mContext.getPackageManager().getPackagesForUid(uid);
1561 if (packageNames != null) {
1562 for (String n : packageNames) {
1563 if (n.equals(packageName)) {
1564 return true;
1565 }
1566 }
1567 }
1568 }
1569 return false;
1570 }
Michael Wrightc39d47a2014-07-08 18:07:36 -07001571
1572 private boolean canProjectVideo(IMediaProjection projection) {
1573 if (projection != null) {
1574 try {
1575 if (projection.canProjectVideo()) {
1576 return true;
1577 }
1578 } catch (RemoteException e) {
1579 Slog.e(TAG, "Unable to query projection service for permissions", e);
1580 }
1581 }
1582 if (mContext.checkCallingPermission(
1583 android.Manifest.permission.CAPTURE_VIDEO_OUTPUT)
Michael Wright0ccc2b02014-07-24 18:20:41 -07001584 == PackageManager.PERMISSION_GRANTED) {
Michael Wrightc39d47a2014-07-08 18:07:36 -07001585 return true;
1586 }
1587 return canProjectSecureVideo(projection);
1588 }
1589
1590 private boolean canProjectSecureVideo(IMediaProjection projection) {
1591 if (projection != null) {
1592 try {
1593 if (projection.canProjectSecureVideo()){
1594 return true;
1595 }
1596 } catch (RemoteException e) {
1597 Slog.e(TAG, "Unable to query projection service for permissions", e);
1598 }
1599 }
1600 return mContext.checkCallingPermission(
1601 android.Manifest.permission.CAPTURE_SECURE_VIDEO_OUTPUT)
Michael Wright0ccc2b02014-07-24 18:20:41 -07001602 == PackageManager.PERMISSION_GRANTED;
Michael Wrightc39d47a2014-07-08 18:07:36 -07001603 }
Jeff Brown4ccb8232014-01-16 22:16:42 -08001604 }
1605
1606 private final class LocalService extends DisplayManagerInternal {
1607 @Override
Jeff Brown037c33e2014-04-09 00:31:55 -07001608 public void initPowerManagement(final DisplayPowerCallbacks callbacks, Handler handler,
Jeff Brownad9ef192014-04-08 17:26:30 -07001609 SensorManager sensorManager) {
1610 synchronized (mSyncRoot) {
Jeff Brown037c33e2014-04-09 00:31:55 -07001611 DisplayBlanker blanker = new DisplayBlanker() {
1612 @Override
Jeff Brown5d6443b2015-04-10 20:15:01 -07001613 public void requestDisplayState(int state, int brightness) {
Jeff Brown037c33e2014-04-09 00:31:55 -07001614 // The order of operations is important for legacy reasons.
1615 if (state == Display.STATE_OFF) {
Jeff Brown5d6443b2015-04-10 20:15:01 -07001616 requestGlobalDisplayStateInternal(state, brightness);
Jeff Brown037c33e2014-04-09 00:31:55 -07001617 }
1618
1619 callbacks.onDisplayStateChange(state);
1620
1621 if (state != Display.STATE_OFF) {
Jeff Brown5d6443b2015-04-10 20:15:01 -07001622 requestGlobalDisplayStateInternal(state, brightness);
Jeff Brown037c33e2014-04-09 00:31:55 -07001623 }
1624 }
1625 };
Jeff Brownad9ef192014-04-08 17:26:30 -07001626 mDisplayPowerController = new DisplayPowerController(
Jeff Brown037c33e2014-04-09 00:31:55 -07001627 mContext, callbacks, handler, sensorManager, blanker);
Jeff Brownad9ef192014-04-08 17:26:30 -07001628 }
1629 }
1630
1631 @Override
1632 public boolean requestPowerState(DisplayPowerRequest request,
1633 boolean waitForNegativeProximity) {
1634 return mDisplayPowerController.requestPowerState(request,
1635 waitForNegativeProximity);
1636 }
1637
1638 @Override
1639 public boolean isProximitySensorAvailable() {
1640 return mDisplayPowerController.isProximitySensorAvailable();
1641 }
1642
1643 @Override
Jeff Brown4ccb8232014-01-16 22:16:42 -08001644 public DisplayInfo getDisplayInfo(int displayId) {
1645 return getDisplayInfoInternal(displayId, Process.myUid());
1646 }
1647
1648 @Override
1649 public void registerDisplayTransactionListener(DisplayTransactionListener listener) {
1650 if (listener == null) {
1651 throw new IllegalArgumentException("listener must not be null");
1652 }
1653
1654 registerDisplayTransactionListenerInternal(listener);
1655 }
1656
1657 @Override
1658 public void unregisterDisplayTransactionListener(DisplayTransactionListener listener) {
1659 if (listener == null) {
1660 throw new IllegalArgumentException("listener must not be null");
1661 }
1662
1663 unregisterDisplayTransactionListenerInternal(listener);
1664 }
1665
1666 @Override
1667 public void setDisplayInfoOverrideFromWindowManager(int displayId, DisplayInfo info) {
1668 setDisplayInfoOverrideFromWindowManagerInternal(displayId, info);
1669 }
1670
1671 @Override
1672 public void performTraversalInTransactionFromWindowManager() {
1673 performTraversalInTransactionFromWindowManagerInternal();
1674 }
1675
1676 @Override
Michael Wright3f145a22014-07-22 19:46:03 -07001677 public void setDisplayProperties(int displayId, boolean hasContent,
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -07001678 float requestedRefreshRate, int requestedMode, boolean inTraversal) {
1679 setDisplayPropertiesInternal(displayId, hasContent, requestedRefreshRate,
1680 requestedMode, inTraversal);
Jeff Brown4ccb8232014-01-16 22:16:42 -08001681 }
Filip Gruszczynskid2e86402015-02-19 13:05:03 -08001682
1683 @Override
1684 public void setDisplayOffsets(int displayId, int x, int y) {
1685 setDisplayOffsetsInternal(displayId, x, y);
1686 }
Andrii Kulianfb1bf692017-01-17 11:17:34 -08001687
1688 @Override
1689 public void setDisplayAccessUIDs(SparseArray<IntArray> newDisplayAccessUIDs) {
1690 setDisplayAccessUIDsInternal(newDisplayAccessUIDs);
1691 }
1692
1693 @Override
1694 public boolean isUidPresentOnDisplay(int uid, int displayId) {
1695 return isUidPresentOnDisplayInternal(uid, displayId);
1696 }
Jeff Brown4ccb8232014-01-16 22:16:42 -08001697 }
Jeff Brownfa25bf52012-07-23 19:26:30 -07001698}