diff options
Diffstat (limited to 'services')
6 files changed, 447 insertions, 74 deletions
diff --git a/services/java/com/android/server/display/DisplayDeviceInfo.java b/services/java/com/android/server/display/DisplayDeviceInfo.java index 247d8a0..11f8d6a 100644 --- a/services/java/com/android/server/display/DisplayDeviceInfo.java +++ b/services/java/com/android/server/display/DisplayDeviceInfo.java @@ -61,6 +61,18 @@ final class DisplayDeviceInfo { public static final int FLAG_SUPPORTS_PROTECTED_BUFFERS = 1 << 3; /** + * Flag: Indicates that the display device is owned by a particular application + * and that no other application should be able to interact with it. + */ + public static final int FLAG_PRIVATE = 1 << 4; + + /** + * Flag: Indicates that the display device is not blanked automatically by + * the power manager. + */ + public static final int FLAG_NEVER_BLANK = 1 << 5; + + /** * Touch attachment: Display does not receive touch. */ public static final int TOUCH_NONE = 0; @@ -150,6 +162,23 @@ final class DisplayDeviceInfo { */ public String address; + /** + * The UID of the application that owns this display, or zero if it is owned by the system. + * <p> + * If the display is private, then only the owner can use it. + * </p> + */ + public int ownerUid; + + /** + * The package name of the application that owns this display, or null if it is + * owned by the system. + * <p> + * If the display is private, then only the owner can use it. + * </p> + */ + public String ownerPackageName; + public void setAssumedDensityForExternalDisplay(int width, int height) { densityDpi = Math.min(width, height) * DisplayMetrics.DENSITY_XHIGH / 1080; // Technically, these values should be smaller than the apparent density @@ -176,7 +205,9 @@ final class DisplayDeviceInfo { && touch == other.touch && rotation == other.rotation && type == other.type - && Objects.equal(address, other.address); + && Objects.equal(address, other.address) + && ownerUid == other.ownerUid + && Objects.equal(ownerPackageName, other.ownerPackageName); } @Override @@ -197,19 +228,32 @@ final class DisplayDeviceInfo { rotation = other.rotation; type = other.type; address = other.address; + ownerUid = other.ownerUid; + ownerPackageName = other.ownerPackageName; } // For debugging purposes @Override public String toString() { - return "DisplayDeviceInfo{\"" + name + "\": " + width + " x " + height + ", " - + refreshRate + " fps, " - + "density " + densityDpi + ", " + xDpi + " x " + yDpi + " dpi" - + ", touch " + touchToString(touch) + flagsToString(flags) - + ", rotation " + rotation - + ", type " + Display.typeToString(type) - + ", address " + address - + "}"; + StringBuilder sb = new StringBuilder(); + sb.append("DisplayDeviceInfo{\""); + sb.append(name).append("\": ").append(width).append(" x ").append(height); + sb.append(", ").append(refreshRate).append(" fps, "); + sb.append("density ").append(densityDpi); + sb.append(", ").append(xDpi).append(" x ").append(yDpi).append(" dpi"); + sb.append(", touch ").append(touchToString(touch)); + sb.append(", rotation ").append(rotation); + sb.append(", type ").append(Display.typeToString(type)); + if (address != null) { + sb.append(", address ").append(address); + } + if (ownerUid != 0 || ownerPackageName != null) { + sb.append(", owner ").append(ownerPackageName); + sb.append(" (uid ").append(ownerUid).append(")"); + } + sb.append(flagsToString(flags)); + sb.append("}"); + return sb.toString(); } private static String touchToString(int touch) { @@ -239,6 +283,12 @@ final class DisplayDeviceInfo { if ((flags & FLAG_SUPPORTS_PROTECTED_BUFFERS) != 0) { msg.append(", FLAG_SUPPORTS_PROTECTED_BUFFERS"); } + if ((flags & FLAG_PRIVATE) != 0) { + msg.append(", FLAG_PRIVATE"); + } + if ((flags & FLAG_NEVER_BLANK) != 0) { + msg.append(", FLAG_NEVER_BLANK"); + } return msg.toString(); } } diff --git a/services/java/com/android/server/display/DisplayManagerService.java b/services/java/com/android/server/display/DisplayManagerService.java index ca85e42..c339c26 100644 --- a/services/java/com/android/server/display/DisplayManagerService.java +++ b/services/java/com/android/server/display/DisplayManagerService.java @@ -33,15 +33,19 @@ import android.os.Message; import android.os.RemoteException; import android.os.SystemClock; import android.os.SystemProperties; +import android.text.TextUtils; import android.util.Slog; import android.util.SparseArray; import android.view.Display; import android.view.DisplayInfo; +import android.view.Surface; + import com.android.server.UiThread; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; +import java.util.Arrays; import java.util.concurrent.CopyOnWriteArrayList; /** @@ -171,6 +175,9 @@ public final class DisplayManagerService extends IDisplayManager.Stub { // The Wifi display adapter, or null if not registered. private WifiDisplayAdapter mWifiDisplayAdapter; + // The virtual display adapter, or null if not registered. + private VirtualDisplayAdapter mVirtualDisplayAdapter; + // Viewports of the default display and the display that should receive touch // input from an external source. Used by the input system. private final DisplayViewport mDefaultViewport = new DisplayViewport(); @@ -363,13 +370,7 @@ public final class DisplayManagerService extends IDisplayManager.Stub { synchronized (mSyncRoot) { if (mAllDisplayBlankStateFromPowerManager != DISPLAY_BLANK_STATE_BLANKED) { mAllDisplayBlankStateFromPowerManager = DISPLAY_BLANK_STATE_BLANKED; - - final int count = mDisplayDevices.size(); - for (int i = 0; i < count; i++) { - DisplayDevice device = mDisplayDevices.get(i); - device.blankLocked(); - } - + updateAllDisplayBlankingLocked(); scheduleTraversalLocked(false); } } @@ -382,13 +383,7 @@ public final class DisplayManagerService extends IDisplayManager.Stub { synchronized (mSyncRoot) { if (mAllDisplayBlankStateFromPowerManager != DISPLAY_BLANK_STATE_UNBLANKED) { mAllDisplayBlankStateFromPowerManager = DISPLAY_BLANK_STATE_UNBLANKED; - - final int count = mDisplayDevices.size(); - for (int i = 0; i < count; i++) { - DisplayDevice device = mDisplayDevices.get(i); - device.unblankLocked(); - } - + updateAllDisplayBlankingLocked(); scheduleTraversalLocked(false); } } @@ -403,12 +398,21 @@ public final class DisplayManagerService extends IDisplayManager.Stub { */ @Override // Binder call public DisplayInfo getDisplayInfo(int displayId) { - synchronized (mSyncRoot) { - LogicalDisplay display = mLogicalDisplays.get(displayId); - if (display != null) { - return display.getDisplayInfoLocked(); + final int callingUid = Binder.getCallingUid(); + final long token = Binder.clearCallingIdentity(); + try { + synchronized (mSyncRoot) { + LogicalDisplay display = mLogicalDisplays.get(displayId); + if (display != null) { + DisplayInfo info = display.getDisplayInfoLocked(); + if (info.hasAccess(callingUid)) { + return info; + } + } + return null; } - return null; + } finally { + Binder.restoreCallingIdentity(token); } } @@ -417,13 +421,27 @@ public final class DisplayManagerService extends IDisplayManager.Stub { */ @Override // Binder call public int[] getDisplayIds() { - synchronized (mSyncRoot) { - final int count = mLogicalDisplays.size(); - int[] displayIds = new int[count]; - for (int i = 0; i < count; i++) { - displayIds[i] = mLogicalDisplays.keyAt(i); + final int callingUid = Binder.getCallingUid(); + final long token = Binder.clearCallingIdentity(); + try { + 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; } - return displayIds; + } finally { + Binder.restoreCallingIdentity(token); } } @@ -570,6 +588,95 @@ public final class DisplayManagerService extends IDisplayManager.Stub { == PackageManager.PERMISSION_GRANTED; } + @Override // Binder call + public int createPrivateVirtualDisplay(IBinder appToken, String packageName, + String name, int width, int height, int densityDpi, Surface surface) { + final int callingUid = Binder.getCallingUid(); + if (!validatePackageName(callingUid, packageName)) { + throw new SecurityException("packageName must match the calling uid"); + } + if (appToken == null) { + throw new IllegalArgumentException("appToken must not be null"); + } + if (TextUtils.isEmpty(name)) { + throw new IllegalArgumentException("name must be non-null and non-empty"); + } + if (width <= 0 || height <= 0 || densityDpi <= 0) { + throw new IllegalArgumentException("width, height, and densityDpi must be " + + "greater than 0"); + } + if (surface == null) { + throw new IllegalArgumentException("surface must not be null"); + } + + final long token = Binder.clearCallingIdentity(); + try { + 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.createPrivateVirtualDisplayLocked( + appToken, callingUid, packageName, name, width, height, densityDpi, + surface); + 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 private virtual display " + + "because the logical display was not created."); + mVirtualDisplayAdapter.releaseVirtualDisplayLocked(appToken); + handleDisplayDeviceRemovedLocked(device); + } + } finally { + Binder.restoreCallingIdentity(token); + } + return -1; + } + + @Override // Binder call + public void releaseVirtualDisplay(IBinder appToken) { + final long token = Binder.clearCallingIdentity(); + try { + synchronized (mSyncRoot) { + if (mVirtualDisplayAdapter == null) { + return; + } + + DisplayDevice device = + mVirtualDisplayAdapter.releaseVirtualDisplayLocked(appToken); + if (device != null) { + handleDisplayDeviceRemovedLocked(device); + } + } + } finally { + Binder.restoreCallingIdentity(token); + } + } + + private boolean validatePackageName(int uid, String packageName) { + if (packageName != null) { + String[] packageNames = mContext.getPackageManager().getPackagesForUid(uid); + if (packageNames != null) { + for (String n : packageNames) { + if (n.equals(packageName)) { + return true; + } + } + } + } + return false; + } + private void registerDefaultDisplayAdapter() { // Register default display adapter. synchronized (mSyncRoot) { @@ -588,6 +695,7 @@ public final class DisplayManagerService extends IDisplayManager.Stub { if (shouldRegisterNonEssentialDisplayAdaptersLocked()) { registerOverlayDisplayAdapterLocked(); registerWifiDisplayAdapterLocked(); + registerVirtualDisplayAdapterLocked(); } } } @@ -608,6 +716,12 @@ public final class DisplayManagerService extends IDisplayManager.Stub { } } + private void registerVirtualDisplayAdapterLocked() { + mVirtualDisplayAdapter = new VirtualDisplayAdapter( + mSyncRoot, mContext, mHandler, mDisplayAdapterListener); + registerDisplayAdapterLocked(mVirtualDisplayAdapter); + } + private boolean shouldRegisterNonEssentialDisplayAdaptersLocked() { // In safe mode, we disable non-essential display adapters to give the user // an opportunity to fix broken settings or other problems that might affect @@ -625,29 +739,23 @@ public final class DisplayManagerService extends IDisplayManager.Stub { private void handleDisplayDeviceAdded(DisplayDevice device) { synchronized (mSyncRoot) { - if (mDisplayDevices.contains(device)) { - Slog.w(TAG, "Attempted to add already added display device: " - + device.getDisplayDeviceInfoLocked()); - return; - } + handleDisplayDeviceAddedLocked(device); + } + } - Slog.i(TAG, "Display device added: " + device.getDisplayDeviceInfoLocked()); + private void handleDisplayDeviceAddedLocked(DisplayDevice device) { + if (mDisplayDevices.contains(device)) { + Slog.w(TAG, "Attempted to add already added display device: " + + device.getDisplayDeviceInfoLocked()); + return; + } - mDisplayDevices.add(device); - addLogicalDisplayLocked(device); - scheduleTraversalLocked(false); + Slog.i(TAG, "Display device added: " + device.getDisplayDeviceInfoLocked()); - // Blank or unblank the display immediately to match the state requested - // by the power manager (if known). - switch (mAllDisplayBlankStateFromPowerManager) { - case DISPLAY_BLANK_STATE_BLANKED: - device.blankLocked(); - break; - case DISPLAY_BLANK_STATE_UNBLANKED: - device.unblankLocked(); - break; - } - } + mDisplayDevices.add(device); + addLogicalDisplayLocked(device); + updateDisplayBlankingLocked(device); + scheduleTraversalLocked(false); } private void handleDisplayDeviceChanged(DisplayDevice device) { @@ -669,17 +777,44 @@ public final class DisplayManagerService extends IDisplayManager.Stub { private void handleDisplayDeviceRemoved(DisplayDevice device) { synchronized (mSyncRoot) { - if (!mDisplayDevices.remove(device)) { - Slog.w(TAG, "Attempted to remove non-existent display device: " - + device.getDisplayDeviceInfoLocked()); - return; - } + handleDisplayDeviceRemovedLocked(device); + } + } + private void handleDisplayDeviceRemovedLocked(DisplayDevice device) { + if (!mDisplayDevices.remove(device)) { + Slog.w(TAG, "Attempted to remove non-existent display device: " + + device.getDisplayDeviceInfoLocked()); + return; + } - Slog.i(TAG, "Display device removed: " + device.getDisplayDeviceInfoLocked()); + Slog.i(TAG, "Display device removed: " + device.getDisplayDeviceInfoLocked()); - mRemovedDisplayDevices.add(device); - updateLogicalDisplaysLocked(); - scheduleTraversalLocked(false); + mRemovedDisplayDevices.add(device); + updateLogicalDisplaysLocked(); + scheduleTraversalLocked(false); + } + + private void updateAllDisplayBlankingLocked() { + final int count = mDisplayDevices.size(); + for (int i = 0; i < count; i++) { + DisplayDevice device = mDisplayDevices.get(i); + updateDisplayBlankingLocked(device); + } + } + + private void updateDisplayBlankingLocked(DisplayDevice device) { + // Blank or unblank the display immediately to match the state requested + // by the power manager (if known). + DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked(); + if ((info.flags & DisplayDeviceInfo.FLAG_NEVER_BLANK) == 0) { + switch (mAllDisplayBlankStateFromPowerManager) { + case DISPLAY_BLANK_STATE_BLANKED: + device.blankLocked(); + break; + case DISPLAY_BLANK_STATE_UNBLANKED: + device.unblankLocked(); + break; + } } } @@ -812,13 +947,21 @@ public final class DisplayManagerService extends IDisplayManager.Stub { } private void configureDisplayInTransactionLocked(DisplayDevice device) { + DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked(); + boolean isPrivate = (info.flags & DisplayDeviceInfo.FLAG_PRIVATE) != 0; + // Find the logical display that the display device is showing. + // Private displays never mirror other displays. LogicalDisplay display = findLogicalDisplayForDeviceLocked(device); - if (display != null && !display.hasContentLocked()) { - display = null; - } - if (display == null) { - display = mLogicalDisplays.get(Display.DEFAULT_DISPLAY); + if (!isPrivate) { + 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. @@ -828,11 +971,11 @@ public final class DisplayManagerService extends IDisplayManager.Stub { + device.getDisplayDeviceInfoLocked()); return; } - boolean isBlanked = (mAllDisplayBlankStateFromPowerManager == DISPLAY_BLANK_STATE_BLANKED); + boolean isBlanked = (mAllDisplayBlankStateFromPowerManager == DISPLAY_BLANK_STATE_BLANKED) + && (info.flags & DisplayDeviceInfo.FLAG_NEVER_BLANK) == 0; 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); diff --git a/services/java/com/android/server/display/LogicalDisplay.java b/services/java/com/android/server/display/LogicalDisplay.java index 424ec36..775ebb2 100644 --- a/services/java/com/android/server/display/LogicalDisplay.java +++ b/services/java/com/android/server/display/LogicalDisplay.java @@ -202,6 +202,9 @@ final class LogicalDisplay { if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_SECURE) != 0) { mBaseDisplayInfo.flags |= Display.FLAG_SECURE; } + if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_PRIVATE) != 0) { + mBaseDisplayInfo.flags |= Display.FLAG_PRIVATE; + } mBaseDisplayInfo.type = deviceInfo.type; mBaseDisplayInfo.address = deviceInfo.address; mBaseDisplayInfo.name = deviceInfo.name; @@ -218,6 +221,8 @@ final class LogicalDisplay { mBaseDisplayInfo.smallestNominalAppHeight = deviceInfo.height; mBaseDisplayInfo.largestNominalAppWidth = deviceInfo.width; mBaseDisplayInfo.largestNominalAppHeight = deviceInfo.height; + mBaseDisplayInfo.ownerUid = deviceInfo.ownerUid; + mBaseDisplayInfo.ownerPackageName = deviceInfo.ownerPackageName; mPrimaryDisplayDeviceInfo = deviceInfo; mInfo = null; diff --git a/services/java/com/android/server/display/VirtualDisplayAdapter.java b/services/java/com/android/server/display/VirtualDisplayAdapter.java new file mode 100644 index 0000000..634fba7 --- /dev/null +++ b/services/java/com/android/server/display/VirtualDisplayAdapter.java @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.display; + +import android.content.Context; +import android.os.Handler; +import android.os.IBinder; +import android.os.IBinder.DeathRecipient; +import android.os.RemoteException; +import android.util.ArrayMap; +import android.util.Slog; +import android.view.Display; +import android.view.Surface; +import android.view.SurfaceControl; + +/** + * A display adapter that provides virtual displays on behalf of applications. + * <p> + * Display adapters are guarded by the {@link DisplayManagerService.SyncRoot} lock. + * </p> + */ +final class VirtualDisplayAdapter extends DisplayAdapter { + static final String TAG = "VirtualDisplayAdapter"; + static final boolean DEBUG = false; + + private final ArrayMap<IBinder, VirtualDisplayDevice> mVirtualDisplayDevices = + new ArrayMap<IBinder, VirtualDisplayDevice>(); + + // Called with SyncRoot lock held. + public VirtualDisplayAdapter(DisplayManagerService.SyncRoot syncRoot, + Context context, Handler handler, Listener listener) { + super(syncRoot, context, handler, listener, TAG); + } + + public DisplayDevice createPrivateVirtualDisplayLocked(IBinder appToken, + int ownerUid, String ownerPackageName, + String name, int width, int height, int densityDpi, Surface surface) { + IBinder displayToken = SurfaceControl.createDisplay(name, false /*secure*/); + VirtualDisplayDevice device = new VirtualDisplayDevice(displayToken, appToken, + ownerUid, ownerPackageName, name, width, height, densityDpi, surface); + + try { + appToken.linkToDeath(device, 0); + } catch (RemoteException ex) { + device.releaseLocked(); + return null; + } + + mVirtualDisplayDevices.put(appToken, device); + + // Return the display device without actually sending the event indicating + // that it was added. The caller will handle it. + return device; + } + + public DisplayDevice releaseVirtualDisplayLocked(IBinder appToken) { + VirtualDisplayDevice device = mVirtualDisplayDevices.remove(appToken); + if (device != null) { + appToken.unlinkToDeath(device, 0); + } + + // Return the display device that was removed without actually sending the + // event indicating that it was removed. The caller will handle it. + return device; + } + + private void handleBinderDiedLocked(IBinder appToken) { + VirtualDisplayDevice device = mVirtualDisplayDevices.remove(appToken); + if (device != null) { + Slog.i(TAG, "Virtual display device released because application token died: " + + device.mOwnerPackageName); + sendDisplayDeviceEventLocked(device, DISPLAY_DEVICE_EVENT_REMOVED); + } + } + + private final class VirtualDisplayDevice extends DisplayDevice + implements DeathRecipient { + private final IBinder mAppToken; + private final int mOwnerUid; + final String mOwnerPackageName; + private final String mName; + private final int mWidth; + private final int mHeight; + private final int mDensityDpi; + + private boolean mReleased; + private Surface mSurface; + private DisplayDeviceInfo mInfo; + + public VirtualDisplayDevice(IBinder displayToken, + IBinder appToken, int ownerUid, String ownerPackageName, + String name, int width, int height, int densityDpi, Surface surface) { + super(VirtualDisplayAdapter.this, displayToken); + mAppToken = appToken; + mOwnerUid = ownerUid; + mOwnerPackageName = ownerPackageName; + mName = name; + mWidth = width; + mHeight = height; + mDensityDpi = densityDpi; + mSurface = surface; + } + + @Override + public void binderDied() { + synchronized (getSyncRoot()) { + if (!mReleased) { + handleBinderDiedLocked(mAppToken); + } + } + } + + public void releaseLocked() { + mReleased = true; + sendTraversalRequestLocked(); + } + + @Override + public void performTraversalInTransactionLocked() { + if (mReleased && mSurface != null) { + mSurface.destroy(); + mSurface = null; + } + setSurfaceInTransactionLocked(mSurface); + } + + @Override + public DisplayDeviceInfo getDisplayDeviceInfoLocked() { + if (mInfo == null) { + mInfo = new DisplayDeviceInfo(); + mInfo.name = mName; + mInfo.width = mWidth; + mInfo.height = mHeight; + mInfo.refreshRate = 60; + mInfo.densityDpi = mDensityDpi; + mInfo.xDpi = mDensityDpi; + mInfo.yDpi = mDensityDpi; + mInfo.flags = DisplayDeviceInfo.FLAG_PRIVATE | DisplayDeviceInfo.FLAG_NEVER_BLANK; + mInfo.type = Display.TYPE_VIRTUAL; + mInfo.touch = DisplayDeviceInfo.TOUCH_NONE; + mInfo.ownerUid = mOwnerUid; + mInfo.ownerPackageName = mOwnerPackageName; + } + return mInfo; + } + } +} diff --git a/services/java/com/android/server/wm/DisplayContent.java b/services/java/com/android/server/wm/DisplayContent.java index 82e8c7f..feac370 100644 --- a/services/java/com/android/server/wm/DisplayContent.java +++ b/services/java/com/android/server/wm/DisplayContent.java @@ -140,6 +140,13 @@ class DisplayContent { return mDisplayInfo; } + /** + * Returns true if the specified UID has access to this display. + */ + public boolean hasAccess(int uid) { + return mDisplay.hasAccess(uid); + } + boolean homeOnTop() { return mStackBoxes.get(0).mStack != mHomeStack; } diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java index faeb37c..afbc4a9 100644 --- a/services/java/com/android/server/wm/WindowManagerService.java +++ b/services/java/com/android/server/wm/WindowManagerService.java @@ -2105,6 +2105,13 @@ public class WindowManagerService extends IWindowManager.Stub final DisplayContent displayContent = getDisplayContentLocked(displayId); if (displayContent == null) { + Slog.w(TAG, "Attempted to add window to a display that does not exist: " + + displayId + ". Aborting."); + return WindowManagerGlobal.ADD_INVALID_DISPLAY; + } + if (!displayContent.hasAccess(session.mUid)) { + Slog.w(TAG, "Attempted to add window to a display for which the application " + + "does not have access: " + displayId + ". Aborting."); return WindowManagerGlobal.ADD_INVALID_DISPLAY; } @@ -7521,7 +7528,7 @@ public class WindowManagerService extends IWindowManager.Stub public void getInitialDisplaySize(int displayId, Point size) { synchronized (mWindowMap) { final DisplayContent displayContent = getDisplayContentLocked(displayId); - if (displayContent != null) { + if (displayContent != null && displayContent.hasAccess(Binder.getCallingUid())) { synchronized(displayContent.mDisplaySizeLock) { size.x = displayContent.mInitialDisplayWidth; size.y = displayContent.mInitialDisplayHeight; @@ -7534,7 +7541,7 @@ public class WindowManagerService extends IWindowManager.Stub public void getBaseDisplaySize(int displayId, Point size) { synchronized (mWindowMap) { final DisplayContent displayContent = getDisplayContentLocked(displayId); - if (displayContent != null) { + if (displayContent != null && displayContent.hasAccess(Binder.getCallingUid())) { synchronized(displayContent.mDisplaySizeLock) { size.x = displayContent.mBaseDisplayWidth; size.y = displayContent.mBaseDisplayHeight; @@ -7649,7 +7656,7 @@ public class WindowManagerService extends IWindowManager.Stub public int getInitialDisplayDensity(int displayId) { synchronized (mWindowMap) { final DisplayContent displayContent = getDisplayContentLocked(displayId); - if (displayContent != null) { + if (displayContent != null && displayContent.hasAccess(Binder.getCallingUid())) { synchronized(displayContent.mDisplaySizeLock) { return displayContent.mInitialDisplayDensity; } @@ -7662,7 +7669,7 @@ public class WindowManagerService extends IWindowManager.Stub public int getBaseDisplayDensity(int displayId) { synchronized (mWindowMap) { final DisplayContent displayContent = getDisplayContentLocked(displayId); - if (displayContent != null) { + if (displayContent != null && displayContent.hasAccess(Binder.getCallingUid())) { synchronized(displayContent.mDisplaySizeLock) { return displayContent.mBaseDisplayDensity; } |