Loading core/java/android/view/SurfaceControl.java +203 −23 Original line number Diff line number Diff line Loading @@ -16,27 +16,22 @@ package android.view; import static android.view.WindowManager.LayoutParams.INVALID_WINDOW_TYPE; import android.annotation.Size; import android.graphics.Bitmap; import android.graphics.GraphicBuffer; import android.graphics.Point; import android.graphics.PointF; import android.graphics.PixelFormat; import android.graphics.Rect; import android.graphics.Region; import android.os.Binder; import android.os.Debug; import android.os.IBinder; import android.os.Process; import android.os.UserHandle; import android.util.Log; import android.view.Surface.OutOfResourcesException; import dalvik.system.CloseGuard; import libcore.util.NativeAllocationRegistry; import java.io.Closeable; import libcore.util.NativeAllocationRegistry; /** * SurfaceControl * @hide Loading Loading @@ -186,7 +181,7 @@ public class SurfaceControl { /** * Surface creation flag: Indicates that the surface must be considered opaque, * even if its pixel format is set to translucent. This can be useful if an * even if its pixel format contains an alpha channel. This can be useful if an * application needs full RGBA 8888 support for instance but will * still draw every pixel opaque. * <p> Loading Loading @@ -306,6 +301,203 @@ public class SurfaceControl { */ public static final int WINDOW_TYPE_DONT_SCREENSHOT = 441731; /** * Builder class for {@link SurfaceControl} objects. */ public static class Builder { private SurfaceSession mSession; private int mFlags = HIDDEN; private int mWidth; private int mHeight; private int mFormat = PixelFormat.OPAQUE; private String mName; private SurfaceControl mParent; private int mWindowType; private int mOwnerUid; /** * Begin building a SurfaceControl with a given {@link SurfaceSession}. * * @param session The {@link SurfaceSession} with which to eventually construct the surface. */ public Builder(SurfaceSession session) { mSession = session; } /** * Construct a new {@link SurfaceControl} with the set parameters. */ public SurfaceControl build() { if (mWidth <= 0 || mHeight <= 0) { throw new IllegalArgumentException( "width and height must be set"); } return new SurfaceControl(mSession, mName, mWidth, mHeight, mFormat, mFlags, mParent, mWindowType, mOwnerUid); } /** * Set a debugging-name for the SurfaceControl. * * @param name A name to identify the Surface in debugging. */ public Builder setName(String name) { mName = name; return this; } /** * Set the initial size of the controlled surface's buffers in pixels. * * @param width The buffer width in pixels. * @param height The buffer height in pixels. */ public Builder setSize(int width, int height) { if (width <= 0 || height <= 0) { throw new IllegalArgumentException( "width and height must be positive"); } mWidth = width; mHeight = height; return this; } /** * Set the pixel format of the controlled surface's buffers, using constants from * {@link android.graphics.PixelFormat}. */ public Builder setFormat(@PixelFormat.Format int format) { mFormat = format; return this; } /** * Specify if the app requires a hardware-protected path to * an external display sync. If protected content is enabled, but * such a path is not available, then the controlled Surface will * not be displayed. * * @param protectedContent Whether to require a protected sink. */ public Builder setProtected(boolean protectedContent) { if (protectedContent) { mFlags |= PROTECTED_APP; } else { mFlags &= ~PROTECTED_APP; } return this; } /** * Specify whether the Surface contains secure content. If true, the system * will prevent the surfaces content from being copied by another process. In * particular screenshots and VNC servers will be disabled. This is however * not a complete prevention of readback as {@link #setProtected}. */ public Builder setSecure(boolean secure) { if (secure) { mFlags |= SECURE; } else { mFlags &= ~SECURE; } return this; } /** * Indicates whether the surface must be considered opaque, * even if its pixel format is set to translucent. This can be useful if an * application needs full RGBA 8888 support for instance but will * still draw every pixel opaque. * <p> * This flag only determines whether opacity will be sampled from the alpha channel. * Plane-alpha from calls to setAlpha() can still result in blended composition * regardless of the opaque setting. * * Combined effects are (assuming a buffer format with an alpha channel): * <ul> * <li>OPAQUE + alpha(1.0) == opaque composition * <li>OPAQUE + alpha(0.x) == blended composition * <li>OPAQUE + alpha(0.0) == no composition * <li>!OPAQUE + alpha(1.0) == blended composition * <li>!OPAQUE + alpha(0.x) == blended composition * <li>!OPAQUE + alpha(0.0) == no composition * </ul> * If the underlying buffer lacks an alpha channel, it is as if setOpaque(true) * were set automatically. * @param opaque Whether the Surface is OPAQUE. */ public Builder setOpaque(boolean opaque) { if (opaque) { mFlags |= OPAQUE; } else { mFlags &= ~OPAQUE; } return this; } /** * Set a parent surface for our new SurfaceControl. * * Child surfaces are constrained to the onscreen region of their parent. * Furthermore they stack relatively in Z order, and inherit the transformation * of the parent. * * @param parent The parent control. */ public Builder setParent(SurfaceControl parent) { mParent = parent; return this; } /** * Set surface metadata. * * Currently these are window-types as per {@link WindowManager.LayoutParams} and * owner UIDs. Child surfaces inherit their parents * metadata so only the WindowManager needs to set this on root Surfaces. * * @param windowType A window-type * @param ownerUid UID of the window owner. */ public Builder setMetadata(int windowType, int ownerUid) { if (UserHandle.getAppId(Process.myUid()) != Process.SYSTEM_UID) { throw new UnsupportedOperationException( "It only makes sense to set Surface metadata from the WindowManager"); } mWindowType = windowType; mOwnerUid = ownerUid; return this; } /** * Indicate whether a 'ColorLayer' is to be constructed. * * Color layers will not have an associated BufferQueue and will instead always render a * solid color (that is, solid before plane alpha). Currently that color is black. * * @param isColorLayer Whether to create a color layer. */ public Builder setColorLayer(boolean isColorLayer) { if (isColorLayer) { mFlags |= FX_SURFACE_DIM; } else { mFlags &= ~FX_SURFACE_DIM; } return this; } /** * Set 'Surface creation flags' such as {@link HIDDEN}, {@link SECURE}. * * TODO: Finish conversion to individual builder methods? * @param flags The combined flags */ public Builder setFlags(int flags) { mFlags = flags; return this; } } /** * Create a surface with a name. * <p> Loading @@ -331,19 +523,7 @@ public class SurfaceControl { * * @throws throws OutOfResourcesException If the SurfaceControl cannot be created. */ public SurfaceControl(SurfaceSession session, String name, int w, int h, int format, int flags, int windowType, int ownerUid) throws OutOfResourcesException { this(session, name, w, h, format, flags, null, windowType, ownerUid); } public SurfaceControl(SurfaceSession session, String name, int w, int h, int format, int flags) throws OutOfResourcesException { this(session, name, w, h, format, flags, null, INVALID_WINDOW_TYPE, Binder.getCallingUid()); } public SurfaceControl(SurfaceSession session, String name, int w, int h, int format, int flags, private SurfaceControl(SurfaceSession session, String name, int w, int h, int format, int flags, SurfaceControl parent, int windowType, int ownerUid) throws OutOfResourcesException { if (session == null) { Loading core/java/android/view/SurfaceView.java +17 −10 Original line number Diff line number Diff line Loading @@ -532,10 +532,15 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb mDeferredDestroySurfaceControl = mSurfaceControl; updateOpaqueFlag(); mSurfaceControl = new SurfaceControlWithBackground(mSurfaceSession, "SurfaceView - " + viewRoot.getTitle().toString(), mSurfaceWidth, mSurfaceHeight, mFormat, mSurfaceFlags); final String name = "SurfaceView - " + viewRoot.getTitle().toString(); mSurfaceControl = new SurfaceControlWithBackground( name, (mSurfaceFlags & SurfaceControl.OPAQUE) != 0, new SurfaceControl.Builder(mSurfaceSession) .setSize(mSurfaceWidth, mSurfaceHeight) .setFormat(mFormat) .setFlags(mSurfaceFlags)); } else if (mSurfaceControl == null) { return; } Loading Loading @@ -1098,13 +1103,15 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb private boolean mOpaque = true; public boolean mVisible = false; public SurfaceControlWithBackground(SurfaceSession s, String name, int w, int h, int format, int flags) public SurfaceControlWithBackground(String name, boolean opaque, SurfaceControl.Builder b) throws Exception { super(s, name, w, h, format, flags); mBackgroundControl = new SurfaceControl(s, "Background for - " + name, w, h, PixelFormat.OPAQUE, flags | SurfaceControl.FX_SURFACE_DIM); mOpaque = (flags & SurfaceControl.OPAQUE) != 0; super(b.setName(name).build()); mBackgroundControl = b.setName("Background for -" + name) .setFormat(OPAQUE) .setColorLayer(true) .build(); mOpaque = opaque; } @Override Loading services/core/java/com/android/server/display/ColorFade.java +5 −3 Original line number Diff line number Diff line Loading @@ -585,9 +585,11 @@ final class ColorFade { } else { flags = SurfaceControl.OPAQUE | SurfaceControl.HIDDEN; } mSurfaceControl = new SurfaceControl(mSurfaceSession, "ColorFade", mDisplayWidth, mDisplayHeight, PixelFormat.OPAQUE, flags); mSurfaceControl = new SurfaceControl.Builder(mSurfaceSession) .setName("ColorFade") .setSize(mDisplayWidth, mDisplayHeight) .setFlags(flags) .build(); } catch (OutOfResourcesException ex) { Slog.e(TAG, "Unable to create surface.", ex); return false; Loading services/core/java/com/android/server/wm/AccessibilityController.java +37 −35 Original line number Diff line number Diff line Loading @@ -74,12 +74,12 @@ import java.util.Set; */ final class AccessibilityController { private final WindowManagerService mWindowManagerService; private final WindowManagerService mService; private static final float[] sTempFloats = new float[9]; public AccessibilityController(WindowManagerService service) { mWindowManagerService = service; mService = service; } private DisplayMagnifier mDisplayMagnifier; Loading @@ -91,7 +91,7 @@ final class AccessibilityController { if (mDisplayMagnifier != null) { throw new IllegalStateException("Magnification callbacks already set!"); } mDisplayMagnifier = new DisplayMagnifier(mWindowManagerService, callbacks); mDisplayMagnifier = new DisplayMagnifier(mService, callbacks); } else { if (mDisplayMagnifier == null) { throw new IllegalStateException("Magnification callbacks already cleared!"); Loading @@ -108,7 +108,7 @@ final class AccessibilityController { "Windows for accessibility callback already set!"); } mWindowsForAccessibilityObserver = new WindowsForAccessibilityObserver( mWindowManagerService, callback); mService, callback); } else { if (mWindowsForAccessibilityObserver == null) { throw new IllegalStateException( Loading @@ -120,7 +120,7 @@ final class AccessibilityController { public void performComputeChangedWindowsNotLocked() { WindowsForAccessibilityObserver observer = null; synchronized (mWindowManagerService) { synchronized (mService) { observer = mWindowsForAccessibilityObserver; } if (observer != null) { Loading Loading @@ -188,7 +188,7 @@ final class AccessibilityController { // Not relevant for the display magnifier. WindowsForAccessibilityObserver observer = null; synchronized (mWindowManagerService) { synchronized (mService) { observer = mWindowsForAccessibilityObserver; } if (observer != null) { Loading Loading @@ -268,7 +268,7 @@ final class AccessibilityController { private final Region mTempRegion4 = new Region(); private final Context mContext; private final WindowManagerService mWindowManagerService; private final WindowManagerService mService; private final MagnifiedViewport mMagnifedViewport; private final Handler mHandler; Loading @@ -281,9 +281,9 @@ final class AccessibilityController { public DisplayMagnifier(WindowManagerService windowManagerService, MagnificationCallbacks callbacks) { mContext = windowManagerService.mContext; mWindowManagerService = windowManagerService; mService = windowManagerService; mCallbacks = callbacks; mHandler = new MyHandler(mWindowManagerService.mH.getLooper()); mHandler = new MyHandler(mService.mH.getLooper()); mMagnifedViewport = new MagnifiedViewport(); mLongAnimationDuration = mContext.getResources().getInteger( com.android.internal.R.integer.config_longAnimTime); Loading @@ -292,7 +292,7 @@ final class AccessibilityController { public void setMagnificationSpecLocked(MagnificationSpec spec) { mMagnifedViewport.updateMagnificationSpecLocked(spec); mMagnifedViewport.recomputeBoundsLocked(); mWindowManagerService.scheduleAnimationLocked(); mService.scheduleAnimationLocked(); } public void setForceShowMagnifiableBoundsLocked(boolean show) { Loading Loading @@ -330,7 +330,7 @@ final class AccessibilityController { Slog.i(LOG_TAG, "Layers changed."); } mMagnifedViewport.recomputeBoundsLocked(); mWindowManagerService.scheduleAnimationLocked(); mService.scheduleAnimationLocked(); } public void onRotationChangedLocked(DisplayContent displayContent) { Loading Loading @@ -421,7 +421,7 @@ final class AccessibilityController { public MagnificationSpec getMagnificationSpecForWindowLocked(WindowState windowState) { MagnificationSpec spec = mMagnifedViewport.getMagnificationSpecLocked(); if (spec != null && !spec.isNop()) { if (!mWindowManagerService.mPolicy.canMagnifyWindow(windowState.mAttrs.type)) { if (!mService.mPolicy.canMagnifyWindow(windowState.mAttrs.type)) { return null; } } Loading Loading @@ -565,7 +565,7 @@ final class AccessibilityController { portionOfWindowAlreadyAccountedFor.op(nonMagnifiedBounds, Region.Op.UNION); windowBounds.op(portionOfWindowAlreadyAccountedFor, Region.Op.DIFFERENCE); if (mWindowManagerService.mPolicy.canMagnifyWindow(windowState.mAttrs.type)) { if (mService.mPolicy.canMagnifyWindow(windowState.mAttrs.type)) { mMagnificationRegion.op(windowBounds, Region.Op.UNION); mMagnificationRegion.op(availableBounds, Region.Op.INTERSECT); } else { Loading Loading @@ -632,7 +632,7 @@ final class AccessibilityController { if (isMagnifyingLocked() || isForceShowingMagnifiableBoundsLocked()) { setMagnifiedRegionBorderShownLocked(false, false); final long delay = (long) (mLongAnimationDuration * mWindowManagerService.getWindowAnimationScaleLocked()); * mService.getWindowAnimationScaleLocked()); Message message = mHandler.obtainMessage( MyHandler.MESSAGE_SHOW_MAGNIFIED_REGION_BOUNDS_IF_NEEDED); mHandler.sendMessageDelayed(message, delay); Loading Loading @@ -675,7 +675,7 @@ final class AccessibilityController { } private void populateWindowsOnScreenLocked(SparseArray<WindowState> outWindows) { final DisplayContent dc = mWindowManagerService.getDefaultDisplayContentLocked(); final DisplayContent dc = mService.getDefaultDisplayContentLocked(); dc.forAllWindows((w) -> { if (w.isOnScreen() && w.isVisibleLw() && !w.mWinAnimator.mEnterAnimationPending) { Loading Loading @@ -705,23 +705,25 @@ final class AccessibilityController { SurfaceControl surfaceControl = null; try { mWindowManager.getDefaultDisplay().getRealSize(mTempPoint); surfaceControl = new SurfaceControl(mWindowManagerService.mFxSession, SURFACE_TITLE, mTempPoint.x, mTempPoint.y, PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN); surfaceControl = new SurfaceControl.Builder(mService.mFxSession) .setName(SURFACE_TITLE) .setSize(mTempPoint.x, mTempPoint.y) // not a typo .setFormat(PixelFormat.TRANSLUCENT) .build(); } catch (OutOfResourcesException oore) { /* ignore */ } mSurfaceControl = surfaceControl; mSurfaceControl.setLayerStack(mWindowManager.getDefaultDisplay() .getLayerStack()); mSurfaceControl.setLayer(mWindowManagerService.mPolicy.getWindowLayerFromTypeLw( mSurfaceControl.setLayer(mService.mPolicy.getWindowLayerFromTypeLw( TYPE_MAGNIFICATION_OVERLAY) * WindowManagerService.TYPE_LAYER_MULTIPLIER); mSurfaceControl.setPosition(0, 0); mSurface.copyFrom(mSurfaceControl); mAnimationController = new AnimationController(context, mWindowManagerService.mH.getLooper()); mService.mH.getLooper()); TypedValue typedValue = new TypedValue(); context.getTheme().resolveAttribute(R.attr.colorActivatedHighlight, Loading @@ -736,7 +738,7 @@ final class AccessibilityController { } public void setShown(boolean shown, boolean animate) { synchronized (mWindowManagerService.mWindowMap) { synchronized (mService.mWindowMap) { if (mShown == shown) { return; } Loading @@ -751,13 +753,13 @@ final class AccessibilityController { @SuppressWarnings("unused") // Called reflectively from an animator. public int getAlpha() { synchronized (mWindowManagerService.mWindowMap) { synchronized (mService.mWindowMap) { return mAlpha; } } public void setAlpha(int alpha) { synchronized (mWindowManagerService.mWindowMap) { synchronized (mService.mWindowMap) { if (mAlpha == alpha) { return; } Loading @@ -770,7 +772,7 @@ final class AccessibilityController { } public void setBounds(Region bounds) { synchronized (mWindowManagerService.mWindowMap) { synchronized (mService.mWindowMap) { if (mBounds.equals(bounds)) { return; } Loading @@ -783,7 +785,7 @@ final class AccessibilityController { } public void updateSize() { synchronized (mWindowManagerService.mWindowMap) { synchronized (mService.mWindowMap) { mWindowManager.getDefaultDisplay().getRealSize(mTempPoint); mSurfaceControl.setSize(mTempPoint.x, mTempPoint.y); invalidate(mDirtyRect); Loading @@ -797,12 +799,12 @@ final class AccessibilityController { mDirtyRect.setEmpty(); } mInvalidated = true; mWindowManagerService.scheduleAnimationLocked(); mService.scheduleAnimationLocked(); } /** NOTE: This has to be called within a surface transaction. */ public void drawIfNeeded() { synchronized (mWindowManagerService.mWindowMap) { synchronized (mService.mWindowMap) { if (!mInvalidated) { return; } Loading Loading @@ -950,11 +952,11 @@ final class AccessibilityController { } break; case MESSAGE_SHOW_MAGNIFIED_REGION_BOUNDS_IF_NEEDED : { synchronized (mWindowManagerService.mWindowMap) { synchronized (mService.mWindowMap) { if (mMagnifedViewport.isMagnifyingLocked() || isForceShowingMagnifiableBoundsLocked()) { mMagnifedViewport.setMagnifiedRegionBorderShownLocked(true, true); mWindowManagerService.scheduleAnimationLocked(); mService.scheduleAnimationLocked(); } } } break; Loading Loading @@ -995,7 +997,7 @@ final class AccessibilityController { private final Context mContext; private final WindowManagerService mWindowManagerService; private final WindowManagerService mService; private final Handler mHandler; Loading @@ -1006,9 +1008,9 @@ final class AccessibilityController { public WindowsForAccessibilityObserver(WindowManagerService windowManagerService, WindowsForAccessibilityCallback callback) { mContext = windowManagerService.mContext; mWindowManagerService = windowManagerService; mService = windowManagerService; mCallback = callback; mHandler = new MyHandler(mWindowManagerService.mH.getLooper()); mHandler = new MyHandler(mService.mH.getLooper()); mRecurringAccessibilityEventsIntervalMillis = ViewConfiguration .getSendRecurringAccessibilityEventsInterval(); computeChangedWindows(); Loading @@ -1034,11 +1036,11 @@ final class AccessibilityController { boolean windowsChanged = false; List<WindowInfo> windows = new ArrayList<WindowInfo>(); synchronized (mWindowManagerService.mWindowMap) { synchronized (mService.mWindowMap) { // Do not send the windows if there is no current focus as // the window manager is still looking for where to put it. // We will do the work when we get a focus change callback. if (mWindowManagerService.mCurrentFocus == null) { if (mService.mCurrentFocus == null) { return; } Loading Loading @@ -1320,7 +1322,7 @@ final class AccessibilityController { } private void populateVisibleWindowsOnScreenLocked(SparseArray<WindowState> outWindows) { final DisplayContent dc = mWindowManagerService.getDefaultDisplayContentLocked(); final DisplayContent dc = mService.getDefaultDisplayContentLocked(); dc.forAllWindows((w) -> { if (w.isVisibleLw()) { outWindows.put(w.mLayer, w); Loading services/core/java/com/android/server/wm/BlackFrame.java +5 −2 Original line number Diff line number Diff line Loading @@ -50,8 +50,11 @@ public class BlackFrame { int w = r-l; int h = b-t; surface = new SurfaceControl(session, "BlackSurface", w, h, OPAQUE, FX_SURFACE_DIM | SurfaceControl.HIDDEN); surface = new SurfaceControl.Builder(session) .setName("BlackSurface") .setSize(w, h) .setColorLayer(true) .build(); surface.setAlpha(1); surface.setLayerStack(layerStack); Loading Loading
core/java/android/view/SurfaceControl.java +203 −23 Original line number Diff line number Diff line Loading @@ -16,27 +16,22 @@ package android.view; import static android.view.WindowManager.LayoutParams.INVALID_WINDOW_TYPE; import android.annotation.Size; import android.graphics.Bitmap; import android.graphics.GraphicBuffer; import android.graphics.Point; import android.graphics.PointF; import android.graphics.PixelFormat; import android.graphics.Rect; import android.graphics.Region; import android.os.Binder; import android.os.Debug; import android.os.IBinder; import android.os.Process; import android.os.UserHandle; import android.util.Log; import android.view.Surface.OutOfResourcesException; import dalvik.system.CloseGuard; import libcore.util.NativeAllocationRegistry; import java.io.Closeable; import libcore.util.NativeAllocationRegistry; /** * SurfaceControl * @hide Loading Loading @@ -186,7 +181,7 @@ public class SurfaceControl { /** * Surface creation flag: Indicates that the surface must be considered opaque, * even if its pixel format is set to translucent. This can be useful if an * even if its pixel format contains an alpha channel. This can be useful if an * application needs full RGBA 8888 support for instance but will * still draw every pixel opaque. * <p> Loading Loading @@ -306,6 +301,203 @@ public class SurfaceControl { */ public static final int WINDOW_TYPE_DONT_SCREENSHOT = 441731; /** * Builder class for {@link SurfaceControl} objects. */ public static class Builder { private SurfaceSession mSession; private int mFlags = HIDDEN; private int mWidth; private int mHeight; private int mFormat = PixelFormat.OPAQUE; private String mName; private SurfaceControl mParent; private int mWindowType; private int mOwnerUid; /** * Begin building a SurfaceControl with a given {@link SurfaceSession}. * * @param session The {@link SurfaceSession} with which to eventually construct the surface. */ public Builder(SurfaceSession session) { mSession = session; } /** * Construct a new {@link SurfaceControl} with the set parameters. */ public SurfaceControl build() { if (mWidth <= 0 || mHeight <= 0) { throw new IllegalArgumentException( "width and height must be set"); } return new SurfaceControl(mSession, mName, mWidth, mHeight, mFormat, mFlags, mParent, mWindowType, mOwnerUid); } /** * Set a debugging-name for the SurfaceControl. * * @param name A name to identify the Surface in debugging. */ public Builder setName(String name) { mName = name; return this; } /** * Set the initial size of the controlled surface's buffers in pixels. * * @param width The buffer width in pixels. * @param height The buffer height in pixels. */ public Builder setSize(int width, int height) { if (width <= 0 || height <= 0) { throw new IllegalArgumentException( "width and height must be positive"); } mWidth = width; mHeight = height; return this; } /** * Set the pixel format of the controlled surface's buffers, using constants from * {@link android.graphics.PixelFormat}. */ public Builder setFormat(@PixelFormat.Format int format) { mFormat = format; return this; } /** * Specify if the app requires a hardware-protected path to * an external display sync. If protected content is enabled, but * such a path is not available, then the controlled Surface will * not be displayed. * * @param protectedContent Whether to require a protected sink. */ public Builder setProtected(boolean protectedContent) { if (protectedContent) { mFlags |= PROTECTED_APP; } else { mFlags &= ~PROTECTED_APP; } return this; } /** * Specify whether the Surface contains secure content. If true, the system * will prevent the surfaces content from being copied by another process. In * particular screenshots and VNC servers will be disabled. This is however * not a complete prevention of readback as {@link #setProtected}. */ public Builder setSecure(boolean secure) { if (secure) { mFlags |= SECURE; } else { mFlags &= ~SECURE; } return this; } /** * Indicates whether the surface must be considered opaque, * even if its pixel format is set to translucent. This can be useful if an * application needs full RGBA 8888 support for instance but will * still draw every pixel opaque. * <p> * This flag only determines whether opacity will be sampled from the alpha channel. * Plane-alpha from calls to setAlpha() can still result in blended composition * regardless of the opaque setting. * * Combined effects are (assuming a buffer format with an alpha channel): * <ul> * <li>OPAQUE + alpha(1.0) == opaque composition * <li>OPAQUE + alpha(0.x) == blended composition * <li>OPAQUE + alpha(0.0) == no composition * <li>!OPAQUE + alpha(1.0) == blended composition * <li>!OPAQUE + alpha(0.x) == blended composition * <li>!OPAQUE + alpha(0.0) == no composition * </ul> * If the underlying buffer lacks an alpha channel, it is as if setOpaque(true) * were set automatically. * @param opaque Whether the Surface is OPAQUE. */ public Builder setOpaque(boolean opaque) { if (opaque) { mFlags |= OPAQUE; } else { mFlags &= ~OPAQUE; } return this; } /** * Set a parent surface for our new SurfaceControl. * * Child surfaces are constrained to the onscreen region of their parent. * Furthermore they stack relatively in Z order, and inherit the transformation * of the parent. * * @param parent The parent control. */ public Builder setParent(SurfaceControl parent) { mParent = parent; return this; } /** * Set surface metadata. * * Currently these are window-types as per {@link WindowManager.LayoutParams} and * owner UIDs. Child surfaces inherit their parents * metadata so only the WindowManager needs to set this on root Surfaces. * * @param windowType A window-type * @param ownerUid UID of the window owner. */ public Builder setMetadata(int windowType, int ownerUid) { if (UserHandle.getAppId(Process.myUid()) != Process.SYSTEM_UID) { throw new UnsupportedOperationException( "It only makes sense to set Surface metadata from the WindowManager"); } mWindowType = windowType; mOwnerUid = ownerUid; return this; } /** * Indicate whether a 'ColorLayer' is to be constructed. * * Color layers will not have an associated BufferQueue and will instead always render a * solid color (that is, solid before plane alpha). Currently that color is black. * * @param isColorLayer Whether to create a color layer. */ public Builder setColorLayer(boolean isColorLayer) { if (isColorLayer) { mFlags |= FX_SURFACE_DIM; } else { mFlags &= ~FX_SURFACE_DIM; } return this; } /** * Set 'Surface creation flags' such as {@link HIDDEN}, {@link SECURE}. * * TODO: Finish conversion to individual builder methods? * @param flags The combined flags */ public Builder setFlags(int flags) { mFlags = flags; return this; } } /** * Create a surface with a name. * <p> Loading @@ -331,19 +523,7 @@ public class SurfaceControl { * * @throws throws OutOfResourcesException If the SurfaceControl cannot be created. */ public SurfaceControl(SurfaceSession session, String name, int w, int h, int format, int flags, int windowType, int ownerUid) throws OutOfResourcesException { this(session, name, w, h, format, flags, null, windowType, ownerUid); } public SurfaceControl(SurfaceSession session, String name, int w, int h, int format, int flags) throws OutOfResourcesException { this(session, name, w, h, format, flags, null, INVALID_WINDOW_TYPE, Binder.getCallingUid()); } public SurfaceControl(SurfaceSession session, String name, int w, int h, int format, int flags, private SurfaceControl(SurfaceSession session, String name, int w, int h, int format, int flags, SurfaceControl parent, int windowType, int ownerUid) throws OutOfResourcesException { if (session == null) { Loading
core/java/android/view/SurfaceView.java +17 −10 Original line number Diff line number Diff line Loading @@ -532,10 +532,15 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb mDeferredDestroySurfaceControl = mSurfaceControl; updateOpaqueFlag(); mSurfaceControl = new SurfaceControlWithBackground(mSurfaceSession, "SurfaceView - " + viewRoot.getTitle().toString(), mSurfaceWidth, mSurfaceHeight, mFormat, mSurfaceFlags); final String name = "SurfaceView - " + viewRoot.getTitle().toString(); mSurfaceControl = new SurfaceControlWithBackground( name, (mSurfaceFlags & SurfaceControl.OPAQUE) != 0, new SurfaceControl.Builder(mSurfaceSession) .setSize(mSurfaceWidth, mSurfaceHeight) .setFormat(mFormat) .setFlags(mSurfaceFlags)); } else if (mSurfaceControl == null) { return; } Loading Loading @@ -1098,13 +1103,15 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb private boolean mOpaque = true; public boolean mVisible = false; public SurfaceControlWithBackground(SurfaceSession s, String name, int w, int h, int format, int flags) public SurfaceControlWithBackground(String name, boolean opaque, SurfaceControl.Builder b) throws Exception { super(s, name, w, h, format, flags); mBackgroundControl = new SurfaceControl(s, "Background for - " + name, w, h, PixelFormat.OPAQUE, flags | SurfaceControl.FX_SURFACE_DIM); mOpaque = (flags & SurfaceControl.OPAQUE) != 0; super(b.setName(name).build()); mBackgroundControl = b.setName("Background for -" + name) .setFormat(OPAQUE) .setColorLayer(true) .build(); mOpaque = opaque; } @Override Loading
services/core/java/com/android/server/display/ColorFade.java +5 −3 Original line number Diff line number Diff line Loading @@ -585,9 +585,11 @@ final class ColorFade { } else { flags = SurfaceControl.OPAQUE | SurfaceControl.HIDDEN; } mSurfaceControl = new SurfaceControl(mSurfaceSession, "ColorFade", mDisplayWidth, mDisplayHeight, PixelFormat.OPAQUE, flags); mSurfaceControl = new SurfaceControl.Builder(mSurfaceSession) .setName("ColorFade") .setSize(mDisplayWidth, mDisplayHeight) .setFlags(flags) .build(); } catch (OutOfResourcesException ex) { Slog.e(TAG, "Unable to create surface.", ex); return false; Loading
services/core/java/com/android/server/wm/AccessibilityController.java +37 −35 Original line number Diff line number Diff line Loading @@ -74,12 +74,12 @@ import java.util.Set; */ final class AccessibilityController { private final WindowManagerService mWindowManagerService; private final WindowManagerService mService; private static final float[] sTempFloats = new float[9]; public AccessibilityController(WindowManagerService service) { mWindowManagerService = service; mService = service; } private DisplayMagnifier mDisplayMagnifier; Loading @@ -91,7 +91,7 @@ final class AccessibilityController { if (mDisplayMagnifier != null) { throw new IllegalStateException("Magnification callbacks already set!"); } mDisplayMagnifier = new DisplayMagnifier(mWindowManagerService, callbacks); mDisplayMagnifier = new DisplayMagnifier(mService, callbacks); } else { if (mDisplayMagnifier == null) { throw new IllegalStateException("Magnification callbacks already cleared!"); Loading @@ -108,7 +108,7 @@ final class AccessibilityController { "Windows for accessibility callback already set!"); } mWindowsForAccessibilityObserver = new WindowsForAccessibilityObserver( mWindowManagerService, callback); mService, callback); } else { if (mWindowsForAccessibilityObserver == null) { throw new IllegalStateException( Loading @@ -120,7 +120,7 @@ final class AccessibilityController { public void performComputeChangedWindowsNotLocked() { WindowsForAccessibilityObserver observer = null; synchronized (mWindowManagerService) { synchronized (mService) { observer = mWindowsForAccessibilityObserver; } if (observer != null) { Loading Loading @@ -188,7 +188,7 @@ final class AccessibilityController { // Not relevant for the display magnifier. WindowsForAccessibilityObserver observer = null; synchronized (mWindowManagerService) { synchronized (mService) { observer = mWindowsForAccessibilityObserver; } if (observer != null) { Loading Loading @@ -268,7 +268,7 @@ final class AccessibilityController { private final Region mTempRegion4 = new Region(); private final Context mContext; private final WindowManagerService mWindowManagerService; private final WindowManagerService mService; private final MagnifiedViewport mMagnifedViewport; private final Handler mHandler; Loading @@ -281,9 +281,9 @@ final class AccessibilityController { public DisplayMagnifier(WindowManagerService windowManagerService, MagnificationCallbacks callbacks) { mContext = windowManagerService.mContext; mWindowManagerService = windowManagerService; mService = windowManagerService; mCallbacks = callbacks; mHandler = new MyHandler(mWindowManagerService.mH.getLooper()); mHandler = new MyHandler(mService.mH.getLooper()); mMagnifedViewport = new MagnifiedViewport(); mLongAnimationDuration = mContext.getResources().getInteger( com.android.internal.R.integer.config_longAnimTime); Loading @@ -292,7 +292,7 @@ final class AccessibilityController { public void setMagnificationSpecLocked(MagnificationSpec spec) { mMagnifedViewport.updateMagnificationSpecLocked(spec); mMagnifedViewport.recomputeBoundsLocked(); mWindowManagerService.scheduleAnimationLocked(); mService.scheduleAnimationLocked(); } public void setForceShowMagnifiableBoundsLocked(boolean show) { Loading Loading @@ -330,7 +330,7 @@ final class AccessibilityController { Slog.i(LOG_TAG, "Layers changed."); } mMagnifedViewport.recomputeBoundsLocked(); mWindowManagerService.scheduleAnimationLocked(); mService.scheduleAnimationLocked(); } public void onRotationChangedLocked(DisplayContent displayContent) { Loading Loading @@ -421,7 +421,7 @@ final class AccessibilityController { public MagnificationSpec getMagnificationSpecForWindowLocked(WindowState windowState) { MagnificationSpec spec = mMagnifedViewport.getMagnificationSpecLocked(); if (spec != null && !spec.isNop()) { if (!mWindowManagerService.mPolicy.canMagnifyWindow(windowState.mAttrs.type)) { if (!mService.mPolicy.canMagnifyWindow(windowState.mAttrs.type)) { return null; } } Loading Loading @@ -565,7 +565,7 @@ final class AccessibilityController { portionOfWindowAlreadyAccountedFor.op(nonMagnifiedBounds, Region.Op.UNION); windowBounds.op(portionOfWindowAlreadyAccountedFor, Region.Op.DIFFERENCE); if (mWindowManagerService.mPolicy.canMagnifyWindow(windowState.mAttrs.type)) { if (mService.mPolicy.canMagnifyWindow(windowState.mAttrs.type)) { mMagnificationRegion.op(windowBounds, Region.Op.UNION); mMagnificationRegion.op(availableBounds, Region.Op.INTERSECT); } else { Loading Loading @@ -632,7 +632,7 @@ final class AccessibilityController { if (isMagnifyingLocked() || isForceShowingMagnifiableBoundsLocked()) { setMagnifiedRegionBorderShownLocked(false, false); final long delay = (long) (mLongAnimationDuration * mWindowManagerService.getWindowAnimationScaleLocked()); * mService.getWindowAnimationScaleLocked()); Message message = mHandler.obtainMessage( MyHandler.MESSAGE_SHOW_MAGNIFIED_REGION_BOUNDS_IF_NEEDED); mHandler.sendMessageDelayed(message, delay); Loading Loading @@ -675,7 +675,7 @@ final class AccessibilityController { } private void populateWindowsOnScreenLocked(SparseArray<WindowState> outWindows) { final DisplayContent dc = mWindowManagerService.getDefaultDisplayContentLocked(); final DisplayContent dc = mService.getDefaultDisplayContentLocked(); dc.forAllWindows((w) -> { if (w.isOnScreen() && w.isVisibleLw() && !w.mWinAnimator.mEnterAnimationPending) { Loading Loading @@ -705,23 +705,25 @@ final class AccessibilityController { SurfaceControl surfaceControl = null; try { mWindowManager.getDefaultDisplay().getRealSize(mTempPoint); surfaceControl = new SurfaceControl(mWindowManagerService.mFxSession, SURFACE_TITLE, mTempPoint.x, mTempPoint.y, PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN); surfaceControl = new SurfaceControl.Builder(mService.mFxSession) .setName(SURFACE_TITLE) .setSize(mTempPoint.x, mTempPoint.y) // not a typo .setFormat(PixelFormat.TRANSLUCENT) .build(); } catch (OutOfResourcesException oore) { /* ignore */ } mSurfaceControl = surfaceControl; mSurfaceControl.setLayerStack(mWindowManager.getDefaultDisplay() .getLayerStack()); mSurfaceControl.setLayer(mWindowManagerService.mPolicy.getWindowLayerFromTypeLw( mSurfaceControl.setLayer(mService.mPolicy.getWindowLayerFromTypeLw( TYPE_MAGNIFICATION_OVERLAY) * WindowManagerService.TYPE_LAYER_MULTIPLIER); mSurfaceControl.setPosition(0, 0); mSurface.copyFrom(mSurfaceControl); mAnimationController = new AnimationController(context, mWindowManagerService.mH.getLooper()); mService.mH.getLooper()); TypedValue typedValue = new TypedValue(); context.getTheme().resolveAttribute(R.attr.colorActivatedHighlight, Loading @@ -736,7 +738,7 @@ final class AccessibilityController { } public void setShown(boolean shown, boolean animate) { synchronized (mWindowManagerService.mWindowMap) { synchronized (mService.mWindowMap) { if (mShown == shown) { return; } Loading @@ -751,13 +753,13 @@ final class AccessibilityController { @SuppressWarnings("unused") // Called reflectively from an animator. public int getAlpha() { synchronized (mWindowManagerService.mWindowMap) { synchronized (mService.mWindowMap) { return mAlpha; } } public void setAlpha(int alpha) { synchronized (mWindowManagerService.mWindowMap) { synchronized (mService.mWindowMap) { if (mAlpha == alpha) { return; } Loading @@ -770,7 +772,7 @@ final class AccessibilityController { } public void setBounds(Region bounds) { synchronized (mWindowManagerService.mWindowMap) { synchronized (mService.mWindowMap) { if (mBounds.equals(bounds)) { return; } Loading @@ -783,7 +785,7 @@ final class AccessibilityController { } public void updateSize() { synchronized (mWindowManagerService.mWindowMap) { synchronized (mService.mWindowMap) { mWindowManager.getDefaultDisplay().getRealSize(mTempPoint); mSurfaceControl.setSize(mTempPoint.x, mTempPoint.y); invalidate(mDirtyRect); Loading @@ -797,12 +799,12 @@ final class AccessibilityController { mDirtyRect.setEmpty(); } mInvalidated = true; mWindowManagerService.scheduleAnimationLocked(); mService.scheduleAnimationLocked(); } /** NOTE: This has to be called within a surface transaction. */ public void drawIfNeeded() { synchronized (mWindowManagerService.mWindowMap) { synchronized (mService.mWindowMap) { if (!mInvalidated) { return; } Loading Loading @@ -950,11 +952,11 @@ final class AccessibilityController { } break; case MESSAGE_SHOW_MAGNIFIED_REGION_BOUNDS_IF_NEEDED : { synchronized (mWindowManagerService.mWindowMap) { synchronized (mService.mWindowMap) { if (mMagnifedViewport.isMagnifyingLocked() || isForceShowingMagnifiableBoundsLocked()) { mMagnifedViewport.setMagnifiedRegionBorderShownLocked(true, true); mWindowManagerService.scheduleAnimationLocked(); mService.scheduleAnimationLocked(); } } } break; Loading Loading @@ -995,7 +997,7 @@ final class AccessibilityController { private final Context mContext; private final WindowManagerService mWindowManagerService; private final WindowManagerService mService; private final Handler mHandler; Loading @@ -1006,9 +1008,9 @@ final class AccessibilityController { public WindowsForAccessibilityObserver(WindowManagerService windowManagerService, WindowsForAccessibilityCallback callback) { mContext = windowManagerService.mContext; mWindowManagerService = windowManagerService; mService = windowManagerService; mCallback = callback; mHandler = new MyHandler(mWindowManagerService.mH.getLooper()); mHandler = new MyHandler(mService.mH.getLooper()); mRecurringAccessibilityEventsIntervalMillis = ViewConfiguration .getSendRecurringAccessibilityEventsInterval(); computeChangedWindows(); Loading @@ -1034,11 +1036,11 @@ final class AccessibilityController { boolean windowsChanged = false; List<WindowInfo> windows = new ArrayList<WindowInfo>(); synchronized (mWindowManagerService.mWindowMap) { synchronized (mService.mWindowMap) { // Do not send the windows if there is no current focus as // the window manager is still looking for where to put it. // We will do the work when we get a focus change callback. if (mWindowManagerService.mCurrentFocus == null) { if (mService.mCurrentFocus == null) { return; } Loading Loading @@ -1320,7 +1322,7 @@ final class AccessibilityController { } private void populateVisibleWindowsOnScreenLocked(SparseArray<WindowState> outWindows) { final DisplayContent dc = mWindowManagerService.getDefaultDisplayContentLocked(); final DisplayContent dc = mService.getDefaultDisplayContentLocked(); dc.forAllWindows((w) -> { if (w.isVisibleLw()) { outWindows.put(w.mLayer, w); Loading
services/core/java/com/android/server/wm/BlackFrame.java +5 −2 Original line number Diff line number Diff line Loading @@ -50,8 +50,11 @@ public class BlackFrame { int w = r-l; int h = b-t; surface = new SurfaceControl(session, "BlackSurface", w, h, OPAQUE, FX_SURFACE_DIM | SurfaceControl.HIDDEN); surface = new SurfaceControl.Builder(session) .setName("BlackSurface") .setSize(w, h) .setColorLayer(true) .build(); surface.setAlpha(1); surface.setLayerStack(layerStack); Loading