Loading services/core/java/com/android/server/wm/CircularDisplayMask.java 0 → 100644 +110 −0 Original line number Diff line number Diff line /* * Copyright (C) 2014 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.wm; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.PixelFormat; import android.graphics.Rect; import android.util.Log; import android.view.Display; import android.view.Surface; import android.view.Surface.OutOfResourcesException; import android.view.SurfaceControl; import android.view.SurfaceSession; class CircularDisplayMask { private static final String TAG = "CircularDisplayMask"; private static final int STROKE_WIDTH = 2; private final SurfaceControl mSurfaceControl; private final Surface mSurface = new Surface(); private int mLastDW; private int mLastDH; private boolean mDrawNeeded; private Paint mPaint; public CircularDisplayMask(Display display, SurfaceSession session, int zOrder) { SurfaceControl ctrl = null; try { ctrl = new SurfaceControl(session, "CircularDisplayMask", 320, 290, PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN); ctrl.setLayerStack(display.getLayerStack()); ctrl.setLayer(zOrder); ctrl.setPosition(0, 0); ctrl.show(); mSurface.copyFrom(ctrl); } catch (OutOfResourcesException e) { } mSurfaceControl = ctrl; mDrawNeeded = true; mPaint = new Paint(); mPaint.setAntiAlias(true); mPaint.setStyle(Paint.Style.STROKE); mPaint.setColor(Color.BLACK); mPaint.setStrokeWidth(STROKE_WIDTH); } private void drawIfNeeded() { if (!mDrawNeeded) { return; } mDrawNeeded = false; Rect dirty = new Rect(0, 0, mLastDW, mLastDH); Canvas c = null; try { c = mSurface.lockCanvas(dirty); } catch (IllegalArgumentException e) { } catch (Surface.OutOfResourcesException e) { } if (c == null) { return; } c.drawCircle(160, 160, 160, mPaint); mSurface.unlockCanvasAndPost(c); } // Note: caller responsible for being inside // Surface.openTransaction() / closeTransaction() public void setVisibility(boolean on) { if (mSurfaceControl == null) { return; } drawIfNeeded(); if (on) { mSurfaceControl.show(); } else { mSurfaceControl.hide(); } } void positionSurface(int dw, int dh) { if (mLastDW == dw && mLastDH == dh) { return; } mLastDW = dw; mLastDH = dh; mSurfaceControl.setSize(dw, dh); mDrawNeeded = true; } } services/core/java/com/android/server/wm/WindowManagerService.java +45 −0 Original line number Diff line number Diff line Loading @@ -290,6 +290,8 @@ public class WindowManagerService extends IWindowManager.Stub private static final String DENSITY_OVERRIDE = "ro.config.density_override"; private static final String SIZE_OVERRIDE = "ro.config.size_override"; private static final String SCREEN_CIRCULAR = "ro.display.circular"; private static final int MAX_SCREENSHOT_RETRIES = 3; final private KeyguardDisableHandler mKeyguardDisableHandler; Loading Loading @@ -419,6 +421,7 @@ public class WindowManagerService extends IWindowManager.Stub final SurfaceSession mFxSession; Watermark mWatermark; StrictModeFlash mStrictModeFlash; CircularDisplayMask mCircularDisplayMask; FocusedStackFrame mFocusedStackFrame; int mFocusedStackLayer; Loading Loading @@ -816,6 +819,7 @@ public class WindowManagerService extends IWindowManager.Stub } LocalServices.addService(WindowManagerInternal.class, new LocalService()); showCircularDisplayMaskIfNeeded(); } public InputMonitor getInputMonitor() { Loading Loading @@ -5547,6 +5551,37 @@ public class WindowManagerService extends IWindowManager.Stub } } public void showCircularDisplayMaskIfNeeded() { if (SystemProperties.getBoolean(SCREEN_CIRCULAR, false)) { mH.sendMessage(mH.obtainMessage(H.SHOW_DISPLAY_MASK)); } } public void showCircularMask() { synchronized(mWindowMap) { if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION showDisplayMask"); SurfaceControl.openTransaction(); try { // TODO(multi-display): support multiple displays if (mCircularDisplayMask == null) { mCircularDisplayMask = new CircularDisplayMask( getDefaultDisplayContentLocked().getDisplay(), mFxSession, mPolicy.windowTypeToLayerLw( WindowManager.LayoutParams.TYPE_POINTER) * TYPE_LAYER_MULTIPLIER + 10); } mCircularDisplayMask.setVisibility(true); } finally { SurfaceControl.closeTransaction(); if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION showDisplayMask"); } } } // TODO: more accounting of which pid(s) turned it on, keep count, // only allow disables from pids which have count on, etc. @Override Loading Loading @@ -7180,6 +7215,8 @@ public class WindowManagerService extends IWindowManager.Stub public static final int REMOVE_STARTING_TIMEOUT = 33; public static final int SHOW_DISPLAY_MASK = 34; @Override public void handleMessage(Message msg) { if (DEBUG_WINDOW_TRACE) { Loading Loading @@ -7581,6 +7618,11 @@ public class WindowManagerService extends IWindowManager.Stub break; } case SHOW_DISPLAY_MASK: { showCircularMask(); break; } case DO_ANIMATION_CALLBACK: { try { ((IRemoteCallback)msg.obj).sendResult(null); Loading Loading @@ -9052,6 +9094,9 @@ public class WindowManagerService extends IWindowManager.Stub if (mStrictModeFlash != null) { mStrictModeFlash.positionSurface(defaultDw, defaultDh); } if (mCircularDisplayMask != null) { mCircularDisplayMask.positionSurface(defaultDw, defaultDh); } boolean focusDisplayed = false; Loading Loading
services/core/java/com/android/server/wm/CircularDisplayMask.java 0 → 100644 +110 −0 Original line number Diff line number Diff line /* * Copyright (C) 2014 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.wm; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.PixelFormat; import android.graphics.Rect; import android.util.Log; import android.view.Display; import android.view.Surface; import android.view.Surface.OutOfResourcesException; import android.view.SurfaceControl; import android.view.SurfaceSession; class CircularDisplayMask { private static final String TAG = "CircularDisplayMask"; private static final int STROKE_WIDTH = 2; private final SurfaceControl mSurfaceControl; private final Surface mSurface = new Surface(); private int mLastDW; private int mLastDH; private boolean mDrawNeeded; private Paint mPaint; public CircularDisplayMask(Display display, SurfaceSession session, int zOrder) { SurfaceControl ctrl = null; try { ctrl = new SurfaceControl(session, "CircularDisplayMask", 320, 290, PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN); ctrl.setLayerStack(display.getLayerStack()); ctrl.setLayer(zOrder); ctrl.setPosition(0, 0); ctrl.show(); mSurface.copyFrom(ctrl); } catch (OutOfResourcesException e) { } mSurfaceControl = ctrl; mDrawNeeded = true; mPaint = new Paint(); mPaint.setAntiAlias(true); mPaint.setStyle(Paint.Style.STROKE); mPaint.setColor(Color.BLACK); mPaint.setStrokeWidth(STROKE_WIDTH); } private void drawIfNeeded() { if (!mDrawNeeded) { return; } mDrawNeeded = false; Rect dirty = new Rect(0, 0, mLastDW, mLastDH); Canvas c = null; try { c = mSurface.lockCanvas(dirty); } catch (IllegalArgumentException e) { } catch (Surface.OutOfResourcesException e) { } if (c == null) { return; } c.drawCircle(160, 160, 160, mPaint); mSurface.unlockCanvasAndPost(c); } // Note: caller responsible for being inside // Surface.openTransaction() / closeTransaction() public void setVisibility(boolean on) { if (mSurfaceControl == null) { return; } drawIfNeeded(); if (on) { mSurfaceControl.show(); } else { mSurfaceControl.hide(); } } void positionSurface(int dw, int dh) { if (mLastDW == dw && mLastDH == dh) { return; } mLastDW = dw; mLastDH = dh; mSurfaceControl.setSize(dw, dh); mDrawNeeded = true; } }
services/core/java/com/android/server/wm/WindowManagerService.java +45 −0 Original line number Diff line number Diff line Loading @@ -290,6 +290,8 @@ public class WindowManagerService extends IWindowManager.Stub private static final String DENSITY_OVERRIDE = "ro.config.density_override"; private static final String SIZE_OVERRIDE = "ro.config.size_override"; private static final String SCREEN_CIRCULAR = "ro.display.circular"; private static final int MAX_SCREENSHOT_RETRIES = 3; final private KeyguardDisableHandler mKeyguardDisableHandler; Loading Loading @@ -419,6 +421,7 @@ public class WindowManagerService extends IWindowManager.Stub final SurfaceSession mFxSession; Watermark mWatermark; StrictModeFlash mStrictModeFlash; CircularDisplayMask mCircularDisplayMask; FocusedStackFrame mFocusedStackFrame; int mFocusedStackLayer; Loading Loading @@ -816,6 +819,7 @@ public class WindowManagerService extends IWindowManager.Stub } LocalServices.addService(WindowManagerInternal.class, new LocalService()); showCircularDisplayMaskIfNeeded(); } public InputMonitor getInputMonitor() { Loading Loading @@ -5547,6 +5551,37 @@ public class WindowManagerService extends IWindowManager.Stub } } public void showCircularDisplayMaskIfNeeded() { if (SystemProperties.getBoolean(SCREEN_CIRCULAR, false)) { mH.sendMessage(mH.obtainMessage(H.SHOW_DISPLAY_MASK)); } } public void showCircularMask() { synchronized(mWindowMap) { if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION showDisplayMask"); SurfaceControl.openTransaction(); try { // TODO(multi-display): support multiple displays if (mCircularDisplayMask == null) { mCircularDisplayMask = new CircularDisplayMask( getDefaultDisplayContentLocked().getDisplay(), mFxSession, mPolicy.windowTypeToLayerLw( WindowManager.LayoutParams.TYPE_POINTER) * TYPE_LAYER_MULTIPLIER + 10); } mCircularDisplayMask.setVisibility(true); } finally { SurfaceControl.closeTransaction(); if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION showDisplayMask"); } } } // TODO: more accounting of which pid(s) turned it on, keep count, // only allow disables from pids which have count on, etc. @Override Loading Loading @@ -7180,6 +7215,8 @@ public class WindowManagerService extends IWindowManager.Stub public static final int REMOVE_STARTING_TIMEOUT = 33; public static final int SHOW_DISPLAY_MASK = 34; @Override public void handleMessage(Message msg) { if (DEBUG_WINDOW_TRACE) { Loading Loading @@ -7581,6 +7618,11 @@ public class WindowManagerService extends IWindowManager.Stub break; } case SHOW_DISPLAY_MASK: { showCircularMask(); break; } case DO_ANIMATION_CALLBACK: { try { ((IRemoteCallback)msg.obj).sendResult(null); Loading Loading @@ -9052,6 +9094,9 @@ public class WindowManagerService extends IWindowManager.Stub if (mStrictModeFlash != null) { mStrictModeFlash.positionSurface(defaultDw, defaultDh); } if (mCircularDisplayMask != null) { mCircularDisplayMask.positionSurface(defaultDw, defaultDh); } boolean focusDisplayed = false; Loading