private void dumpInternal(PrintWriter pw) { pw.println("DISPLAY MANAGER (dumpsys display)"); synchronized (mSyncRoot) { pw.println(" mOnlyCode=" + mOnlyCore); pw.println(" mSafeMode=" + mSafeMode); pw.println(" mPendingTraversal=" + mPendingTraversal); pw.println(" mGlobalDisplayState=" + Display.stateToString(mGlobalDisplayState)); pw.println(" mNextNonDefaultDisplayId=" + mNextNonDefaultDisplayId); pw.println(" mDefaultViewport=" + mDefaultViewport); pw.println(" mExternalTouchViewport=" + mExternalTouchViewport); pw.println(" mSingleDisplayDemoMode=" + mSingleDisplayDemoMode); pw.println(" mWifiDisplayScanRequestCount=" + mWifiDisplayScanRequestCount); IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " "); ipw.increaseIndent(); pw.println(); pw.println("Display Adapters: size=" + mDisplayAdapters.size()); for (DisplayAdapter adapter : mDisplayAdapters) { pw.println(" " + adapter.getName()); adapter.dumpLocked(ipw); } pw.println(); pw.println("Display Devices: size=" + mDisplayDevices.size()); for (DisplayDevice device : mDisplayDevices) { pw.println(" " + device.getDisplayDeviceInfoLocked()); device.dumpLocked(ipw); } final int logicalDisplayCount = mLogicalDisplays.size(); pw.println(); pw.println("Logical Displays: size=" + logicalDisplayCount); for (int i = 0; i < logicalDisplayCount; i++) { int displayId = mLogicalDisplays.keyAt(i); LogicalDisplay display = mLogicalDisplays.valueAt(i); pw.println(" Display " + displayId + ":"); display.dumpLocked(ipw); } final int callbackCount = mCallbacks.size(); pw.println(); pw.println("Callbacks: size=" + callbackCount); for (int i = 0; i < callbackCount; i++) { CallbackRecord callback = mCallbacks.valueAt(i); pw.println( " " + i + ": mPid=" + callback.mPid + ", mWifiDisplayScanRequested=" + callback.mWifiDisplayScanRequested); } if (mDisplayPowerController != null) { mDisplayPowerController.dump(pw); } } }
private void configureDisplayInTransactionLocked(DisplayDevice device) { // Find the logical display that the display device is showing. LogicalDisplay display = findLogicalDisplayForDeviceLocked(device); if (display != null && !display.hasContentLocked()) { display = null; } if (display == null) { display = mLogicalDisplays.get(Display.DEFAULT_DISPLAY); } // Apply the logical display configuration to the display device. if (display == null) { // TODO: no logical display for the device, blank it Slog.w( TAG, "Missing logical display to use for physical display device: " + device.getDisplayDeviceInfoLocked()); return; } else { boolean isBlanked = (mAllDisplayBlankStateFromPowerManager == DISPLAY_BLANK_STATE_BLANKED); display.configureDisplayInTransactionLocked(device, isBlanked); } // Update the viewports if needed. DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked(); if (!mDefaultViewport.valid && (info.flags & DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY) != 0) { setViewportLocked(mDefaultViewport, display, device); } if (!mExternalTouchViewport.valid && info.touch == DisplayDeviceInfo.TOUCH_EXTERNAL) { setViewportLocked(mExternalTouchViewport, display, device); } }
/** * Tells the display manager whether there is interesting unique content on the specified logical * display. This is used to control automatic mirroring. * * <p>If the display has unique content, then the display manager arranges for it to be presented * on a physical display if appropriate. Otherwise, the display manager may choose to make the * physical display mirror some other logical display. * * @param displayId The logical display id to update. * @param hasContent True if the logical display has content. * @param inTraversal True if called from WindowManagerService during a window traversal prior to * call to performTraversalInTransactionFromWindowManager. */ public void setDisplayHasContent(int displayId, boolean hasContent, boolean inTraversal) { synchronized (mSyncRoot) { LogicalDisplay display = mLogicalDisplays.get(displayId); if (display != null && display.hasContentLocked() != hasContent) { display.setHasContentLocked(hasContent); scheduleTraversalLocked(inTraversal); } } }
private LogicalDisplay findLogicalDisplayForDeviceLocked(DisplayDevice device) { final int count = mLogicalDisplays.size(); for (int i = 0; i < count; i++) { LogicalDisplay display = mLogicalDisplays.valueAt(i); if (display.getPrimaryDisplayDeviceLocked() == device) { return display; } } return null; }
/** * Returns information about the specified logical display. * * @param displayId The logical display id. * @return The logical display info, or null if the display does not exist. The returned object * must be treated as immutable. */ @Override // Binder call public DisplayInfo getDisplayInfo(int displayId) { synchronized (mSyncRoot) { LogicalDisplay display = mLogicalDisplays.get(displayId); if (display != null) { return display.getDisplayInfoLocked(); } return null; } }
@Override // Binder call public void dump(FileDescriptor fd, final PrintWriter pw, String[] args) { if (mContext == null || mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP) != PackageManager.PERMISSION_GRANTED) { pw.println( "Permission Denial: can't dump DisplayManager from from pid=" + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()); return; } pw.println("DISPLAY MANAGER (dumpsys display)"); synchronized (mSyncRoot) { pw.println(" mHeadless=" + mHeadless); pw.println(" mOnlyCode=" + mOnlyCore); pw.println(" mSafeMode=" + mSafeMode); pw.println(" mPendingTraversal=" + mPendingTraversal); pw.println( " mAllDisplayBlankStateFromPowerManager=" + mAllDisplayBlankStateFromPowerManager); pw.println(" mNextNonDefaultDisplayId=" + mNextNonDefaultDisplayId); pw.println(" mDefaultViewport=" + mDefaultViewport); pw.println(" mExternalTouchViewport=" + mExternalTouchViewport); pw.println(" mSingleDisplayDemoMode=" + mSingleDisplayDemoMode); IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " "); ipw.increaseIndent(); pw.println(); pw.println("Display Adapters: size=" + mDisplayAdapters.size()); for (DisplayAdapter adapter : mDisplayAdapters) { pw.println(" " + adapter.getName()); adapter.dumpLocked(ipw); } pw.println(); pw.println("Display Devices: size=" + mDisplayDevices.size()); for (DisplayDevice device : mDisplayDevices) { pw.println(" " + device.getDisplayDeviceInfoLocked()); device.dumpLocked(ipw); } final int logicalDisplayCount = mLogicalDisplays.size(); pw.println(); pw.println("Logical Displays: size=" + logicalDisplayCount); for (int i = 0; i < logicalDisplayCount; i++) { int displayId = mLogicalDisplays.keyAt(i); LogicalDisplay display = mLogicalDisplays.valueAt(i); pw.println(" Display " + displayId + ":"); display.dumpLocked(ipw); } } }
private void setDisplayInfoOverrideFromWindowManagerInternal(int displayId, DisplayInfo info) { synchronized (mSyncRoot) { LogicalDisplay display = mLogicalDisplays.get(displayId); if (display != null) { if (display.setDisplayInfoOverrideFromWindowManagerLocked(info)) { sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_CHANGED); scheduleTraversalLocked(false); } } } }
private DisplayInfo getDisplayInfoInternal(int displayId, int callingUid) { synchronized (mSyncRoot) { LogicalDisplay display = mLogicalDisplays.get(displayId); if (display != null) { DisplayInfo info = display.getDisplayInfoLocked(); if (info.hasAccess(callingUid)) { return info; } } return null; } }
/** * Overrides the display information of a particular logical display. This is used by the window * manager to control the size and characteristics of the default display. It is expected to apply * the requested change to the display information synchronously so that applications will * immediately observe the new state. * * @param displayId The logical display id. * @param info The new data to be stored. */ public void setDisplayInfoOverrideFromWindowManager(int displayId, DisplayInfo info) { synchronized (mSyncRoot) { LogicalDisplay display = mLogicalDisplays.get(displayId); if (display != null) { mTempDisplayInfo.copyFrom(display.getDisplayInfoLocked()); display.setDisplayInfoOverrideFromWindowManagerLocked(info); if (!mTempDisplayInfo.equals(display.getDisplayInfoLocked())) { sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_CHANGED); scheduleTraversalLocked(false); } } } }
private int[] getDisplayIdsInternal(int callingUid) { synchronized (mSyncRoot) { final int count = mLogicalDisplays.size(); int[] displayIds = new int[count]; int n = 0; for (int i = 0; i < count; i++) { LogicalDisplay display = mLogicalDisplays.valueAt(i); DisplayInfo info = display.getDisplayInfoLocked(); if (info.hasAccess(callingUid)) { displayIds[n++] = mLogicalDisplays.keyAt(i); } } if (n != count) { displayIds = Arrays.copyOfRange(displayIds, 0, n); } return displayIds; } }
// Updates all existing logical displays given the current set of display devices. // Removes invalid logical displays. // Sends notifications if needed. private boolean updateLogicalDisplaysLocked() { boolean changed = false; for (int i = mLogicalDisplays.size(); i-- > 0; ) { final int displayId = mLogicalDisplays.keyAt(i); LogicalDisplay display = mLogicalDisplays.valueAt(i); mTempDisplayInfo.copyFrom(display.getDisplayInfoLocked()); display.updateLocked(mDisplayDevices); if (!display.isValidLocked()) { mLogicalDisplays.removeAt(i); sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_REMOVED); changed = true; } else if (!mTempDisplayInfo.equals(display.getDisplayInfoLocked())) { sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_CHANGED); changed = true; } } return changed; }
private int createVirtualDisplayInternal( IBinder appToken, int callingUid, String packageName, String name, int width, int height, int densityDpi, Surface surface, int flags) { synchronized (mSyncRoot) { if (mVirtualDisplayAdapter == null) { Slog.w( TAG, "Rejecting request to create private virtual display " + "because the virtual display adapter is not available."); return -1; } DisplayDevice device = mVirtualDisplayAdapter.createVirtualDisplayLocked( appToken, callingUid, packageName, name, width, height, densityDpi, surface, flags); if (device == null) { return -1; } handleDisplayDeviceAddedLocked(device); LogicalDisplay display = findLogicalDisplayForDeviceLocked(device); if (display != null) { return display.getDisplayIdLocked(); } // Something weird happened and the logical display was not created. Slog.w( TAG, "Rejecting request to create virtual display " + "because the logical display was not created."); mVirtualDisplayAdapter.releaseVirtualDisplayLocked(appToken); handleDisplayDeviceRemovedLocked(device); } return -1; }
// Adds a new logical display based on the given display device. // Sends notifications if needed. private void addLogicalDisplayLocked(DisplayDevice device) { DisplayDeviceInfo deviceInfo = device.getDisplayDeviceInfoLocked(); boolean isDefault = (deviceInfo.flags & DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY) != 0; if (isDefault && mLogicalDisplays.get(Display.DEFAULT_DISPLAY) != null) { Slog.w(TAG, "Ignoring attempt to add a second default display: " + deviceInfo); isDefault = false; } if (!isDefault && mSingleDisplayDemoMode) { Slog.i( TAG, "Not creating a logical display for a secondary display " + " because single display demo mode is enabled: " + deviceInfo); return; } final int displayId = assignDisplayIdLocked(isDefault); final int layerStack = assignLayerStackLocked(displayId); LogicalDisplay display = new LogicalDisplay(displayId, layerStack, device); display.updateLocked(mDisplayDevices); if (!display.isValidLocked()) { // This should never happen currently. Slog.w( TAG, "Ignoring display device because the logical display " + "created from it was not considered valid: " + deviceInfo); return; } mLogicalDisplays.put(displayId, display); // Wake up waitForDefaultDisplay. if (isDefault) { mSyncRoot.notifyAll(); } sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_ADDED); }
private void setDisplayHasContentInternal( int displayId, boolean hasContent, boolean inTraversal) { synchronized (mSyncRoot) { LogicalDisplay display = mLogicalDisplays.get(displayId); if (display != null && display.hasContentLocked() != hasContent) { if (DEBUG) { Slog.d( TAG, "Display " + displayId + " hasContent flag changed: " + "hasContent=" + hasContent + ", inTraversal=" + inTraversal); } display.setHasContentLocked(hasContent); scheduleTraversalLocked(inTraversal); } } }
private void configureDisplayInTransactionLocked(DisplayDevice device) { final DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked(); final boolean ownContent = (info.flags & DisplayDeviceInfo.FLAG_OWN_CONTENT_ONLY) != 0; // Find the logical display that the display device is showing. // Certain displays only ever show their own content. LogicalDisplay display = findLogicalDisplayForDeviceLocked(device); if (!ownContent) { if (display != null && !display.hasContentLocked()) { // If the display does not have any content of its own, then // automatically mirror the default logical display contents. display = null; } if (display == null) { display = mLogicalDisplays.get(Display.DEFAULT_DISPLAY); } } // Apply the logical display configuration to the display device. if (display == null) { // TODO: no logical display for the device, blank it Slog.w( TAG, "Missing logical display to use for physical display device: " + device.getDisplayDeviceInfoLocked()); return; } display.configureDisplayInTransactionLocked(device, info.state == Display.STATE_OFF); // Update the viewports if needed. if (!mDefaultViewport.valid && (info.flags & DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY) != 0) { setViewportLocked(mDefaultViewport, display, device); } if (!mExternalTouchViewport.valid && info.touch == DisplayDeviceInfo.TOUCH_EXTERNAL) { setViewportLocked(mExternalTouchViewport, display, device); } }
private static void setViewportLocked( DisplayViewport viewport, LogicalDisplay display, DisplayDevice device) { viewport.valid = true; viewport.displayId = display.getDisplayIdLocked(); device.populateViewportLocked(viewport); }