Loading api/current.xml +11 −0 Original line number Diff line number Diff line Loading @@ -144242,6 +144242,17 @@ visibility="public" > </method> <method name="penaltyFlashScreen" return="android.os.StrictMode.ThreadPolicy.Builder" abstract="false" native="false" synchronized="false" static="false" final="false" deprecated="not deprecated" visibility="public" > </method> <method name="penaltyLog" return="android.os.StrictMode.ThreadPolicy.Builder" abstract="false" core/java/android/os/StrictMode.java +37 −2 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import android.app.ApplicationErrorReport; import android.content.Intent; import android.util.Log; import android.util.Printer; import android.view.IWindowManager; import com.android.internal.os.RuntimeInit; Loading Loading @@ -108,6 +109,7 @@ public final class StrictMode { private static final boolean LOG_V = Log.isLoggable(TAG, Log.VERBOSE); private static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); private static final boolean IS_ENG_BUILD = "eng".equals(Build.TYPE); // Only log a duplicate stack trace to the logs every second. private static final long MIN_LOG_INTERVAL_MS = 1000; Loading Loading @@ -179,6 +181,13 @@ public final class StrictMode { */ public static final int PENALTY_DEATH_ON_NETWORK = 0x200; /** * Flash the screen during violations. * * @hide */ public static final int PENALTY_FLASH = 0x800; /** * @hide */ Loading @@ -202,7 +211,7 @@ public final class StrictMode { */ private static final int PENALTY_MASK = PENALTY_LOG | PENALTY_DIALOG | PENALTY_DEATH | PENALTY_DROPBOX | PENALTY_GATHER | PENALTY_DEATH_ON_NETWORK; PENALTY_DEATH_ON_NETWORK | PENALTY_FLASH; /** * The current VmPolicy in effect. Loading Loading @@ -376,6 +385,13 @@ public final class StrictMode { return enable(PENALTY_DEATH_ON_NETWORK); } /** * Flash the screen during a violation. */ public Builder penaltyFlashScreen() { return enable(PENALTY_FLASH); } /** * Log detected violations to the system log. */ Loading Loading @@ -710,7 +726,9 @@ public final class StrictMode { StrictMode.DETECT_DISK_WRITE | StrictMode.DETECT_DISK_READ | StrictMode.DETECT_NETWORK | StrictMode.PENALTY_DROPBOX); StrictMode.PENALTY_DROPBOX | (IS_ENG_BUILD ? StrictMode.PENALTY_FLASH : 0) ); sVmPolicyMask = StrictMode.DETECT_VM_CURSOR_LEAKS | StrictMode.DETECT_VM_CLOSABLE_LEAKS | StrictMode.PENALTY_DROPBOX; Loading Loading @@ -904,6 +922,17 @@ public final class StrictMode { return; } // TODO: cache the window manager stub? final IWindowManager windowManager = (info.policy & PENALTY_FLASH) != 0 ? IWindowManager.Stub.asInterface(ServiceManager.getService("window")) : null; if (windowManager != null) { try { windowManager.showStrictModeViolation(true); } catch (RemoteException unused) { } } queue.addIdleHandler(new MessageQueue.IdleHandler() { public boolean queueIdle() { long loopFinishTime = SystemClock.uptimeMillis(); Loading @@ -915,6 +944,12 @@ public final class StrictMode { handleViolation(v); } records.clear(); if (windowManager != null) { try { windowManager.showStrictModeViolation(false); } catch (RemoteException unused) { } } return false; // remove this idle handler from the array } }); Loading core/java/android/view/IWindowManager.aidl +9 −2 Original line number Diff line number Diff line Loading @@ -133,6 +133,13 @@ interface IWindowManager // For testing void setInTouchMode(boolean showFocus); // For StrictMode flashing a red border on violations from the UI // thread. The uid/pid is implicit from the Binder call, and the Window // Manager uses that to determine whether or not the red border should // actually be shown. (it will be ignored that pid doesn't have windows // on screen) void showStrictModeViolation(boolean on); // These can only be called with the SET_ORIENTATION permission. /** * Change the current screen rotation, constants as per Loading services/java/com/android/server/StrictModeFlash.java 0 → 100644 +114 −0 Original line number Diff line number Diff line /* * Copyright (C) 2010 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; // TODO: use com.android.server.wm, once things move there import android.graphics.Canvas; import android.graphics.Color; import android.graphics.PixelFormat; import android.graphics.PorterDuff; import android.graphics.Rect; import android.graphics.Region; import android.util.DisplayMetrics; import android.util.Slog; import android.view.Display; import android.view.Surface; import android.view.SurfaceSession; class StrictModeFlash { private static final String TAG = "StrictModeFlash"; Surface mSurface; int mLastDW; int mLastDH; boolean mDrawNeeded; final int mThickness = 20; public StrictModeFlash(Display display, SurfaceSession session) { final DisplayMetrics dm = new DisplayMetrics(); display.getMetrics(dm); try { mSurface = new Surface(session, 0, "StrictModeFlash", -1, 1, 1, PixelFormat.TRANSLUCENT, 0); } catch (Surface.OutOfResourcesException e) { return; } mSurface.setLayer(WindowManagerService.TYPE_LAYER_MULTIPLIER * 101); // one more than Watermark? arbitrary. mSurface.setPosition(0, 0); mDrawNeeded = true; } private void drawIfNeeded() { if (!mDrawNeeded) { return; } mDrawNeeded = false; final int dw = mLastDW; final int dh = mLastDH; Rect dirty = new Rect(0, 0, dw, dh); Canvas c = null; try { c = mSurface.lockCanvas(dirty); } catch (IllegalArgumentException e) { } catch (Surface.OutOfResourcesException e) { } if (c == null) { return; } // Top c.clipRect(new Rect(0, 0, dw, mThickness), Region.Op.REPLACE); c.drawColor(Color.RED); // Left c.clipRect(new Rect(0, 0, mThickness, dh), Region.Op.REPLACE); c.drawColor(Color.RED); // Right c.clipRect(new Rect(dw - mThickness, 0, dw, dh), Region.Op.REPLACE); c.drawColor(Color.RED); // Bottom c.clipRect(new Rect(0, dh - mThickness, dw, dh), Region.Op.REPLACE); c.drawColor(Color.RED); mSurface.unlockCanvasAndPost(c); } // Note: caller responsible for being inside // Surface.openTransaction() / closeTransaction() public void setVisibility(boolean on) { if (mSurface == null) { return; } drawIfNeeded(); if (on) { mSurface.show(); } else { mSurface.hide(); } } void positionSurface(int dw, int dh) { if (mLastDW == dw && mLastDH == dh) { return; } mLastDW = dw; mLastDH = dh; mSurface.setSize(dw, dh); mDrawNeeded = true; } } services/java/com/android/server/WindowManagerService.java +35 −0 Original line number Diff line number Diff line Loading @@ -376,6 +376,7 @@ public class WindowManagerService extends IWindowManager.Stub Surface mBlurSurface; boolean mBlurShown; Watermark mWatermark; StrictModeFlash mStrictModeFlash; int mTransactionSequence = 0; Loading Loading @@ -4883,6 +4884,36 @@ public class WindowManagerService extends IWindowManager.Stub } } // TODO: more accounting of which pid(s) turned it on, keep count, // only allow disables from pids which have count on, etc. public void showStrictModeViolation(boolean on) { int pid = Binder.getCallingPid(); synchronized(mWindowMap) { // Ignoring requests to enable the red border from clients // which aren't on screen. (e.g. Broadcast Receivers in // the background..) if (on) { boolean isVisible = false; for (WindowState ws : mWindows) { if (ws.mSession.mPid == pid && ws.isVisibleLw()) { isVisible = true; break; } } if (!isVisible) { return; } } Surface.openTransaction(); if (mStrictModeFlash == null) { mStrictModeFlash = new StrictModeFlash(mDisplay, mFxSession); } mStrictModeFlash.setVisibility(on); Surface.closeTransaction(); } } public void freezeRotation() { if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION, "setRotation()")) { Loading Loading @@ -9198,6 +9229,7 @@ public class WindowManagerService extends IWindowManager.Stub return mPolicy.finishLayoutLw(); } // "Something has changed! Let's make it correct now." private final void performLayoutAndPlaceSurfacesLockedInner( boolean recoveringMemory) { if (mDisplay == null) { Loading Loading @@ -9249,6 +9281,9 @@ public class WindowManagerService extends IWindowManager.Stub if (mWatermark != null) { mWatermark.positionSurface(dw, dh); } if (mStrictModeFlash != null) { mStrictModeFlash.positionSurface(dw, dh); } try { boolean wallpaperForceHidingChanged = false; Loading Loading
api/current.xml +11 −0 Original line number Diff line number Diff line Loading @@ -144242,6 +144242,17 @@ visibility="public" > </method> <method name="penaltyFlashScreen" return="android.os.StrictMode.ThreadPolicy.Builder" abstract="false" native="false" synchronized="false" static="false" final="false" deprecated="not deprecated" visibility="public" > </method> <method name="penaltyLog" return="android.os.StrictMode.ThreadPolicy.Builder" abstract="false"
core/java/android/os/StrictMode.java +37 −2 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import android.app.ApplicationErrorReport; import android.content.Intent; import android.util.Log; import android.util.Printer; import android.view.IWindowManager; import com.android.internal.os.RuntimeInit; Loading Loading @@ -108,6 +109,7 @@ public final class StrictMode { private static final boolean LOG_V = Log.isLoggable(TAG, Log.VERBOSE); private static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); private static final boolean IS_ENG_BUILD = "eng".equals(Build.TYPE); // Only log a duplicate stack trace to the logs every second. private static final long MIN_LOG_INTERVAL_MS = 1000; Loading Loading @@ -179,6 +181,13 @@ public final class StrictMode { */ public static final int PENALTY_DEATH_ON_NETWORK = 0x200; /** * Flash the screen during violations. * * @hide */ public static final int PENALTY_FLASH = 0x800; /** * @hide */ Loading @@ -202,7 +211,7 @@ public final class StrictMode { */ private static final int PENALTY_MASK = PENALTY_LOG | PENALTY_DIALOG | PENALTY_DEATH | PENALTY_DROPBOX | PENALTY_GATHER | PENALTY_DEATH_ON_NETWORK; PENALTY_DEATH_ON_NETWORK | PENALTY_FLASH; /** * The current VmPolicy in effect. Loading Loading @@ -376,6 +385,13 @@ public final class StrictMode { return enable(PENALTY_DEATH_ON_NETWORK); } /** * Flash the screen during a violation. */ public Builder penaltyFlashScreen() { return enable(PENALTY_FLASH); } /** * Log detected violations to the system log. */ Loading Loading @@ -710,7 +726,9 @@ public final class StrictMode { StrictMode.DETECT_DISK_WRITE | StrictMode.DETECT_DISK_READ | StrictMode.DETECT_NETWORK | StrictMode.PENALTY_DROPBOX); StrictMode.PENALTY_DROPBOX | (IS_ENG_BUILD ? StrictMode.PENALTY_FLASH : 0) ); sVmPolicyMask = StrictMode.DETECT_VM_CURSOR_LEAKS | StrictMode.DETECT_VM_CLOSABLE_LEAKS | StrictMode.PENALTY_DROPBOX; Loading Loading @@ -904,6 +922,17 @@ public final class StrictMode { return; } // TODO: cache the window manager stub? final IWindowManager windowManager = (info.policy & PENALTY_FLASH) != 0 ? IWindowManager.Stub.asInterface(ServiceManager.getService("window")) : null; if (windowManager != null) { try { windowManager.showStrictModeViolation(true); } catch (RemoteException unused) { } } queue.addIdleHandler(new MessageQueue.IdleHandler() { public boolean queueIdle() { long loopFinishTime = SystemClock.uptimeMillis(); Loading @@ -915,6 +944,12 @@ public final class StrictMode { handleViolation(v); } records.clear(); if (windowManager != null) { try { windowManager.showStrictModeViolation(false); } catch (RemoteException unused) { } } return false; // remove this idle handler from the array } }); Loading
core/java/android/view/IWindowManager.aidl +9 −2 Original line number Diff line number Diff line Loading @@ -133,6 +133,13 @@ interface IWindowManager // For testing void setInTouchMode(boolean showFocus); // For StrictMode flashing a red border on violations from the UI // thread. The uid/pid is implicit from the Binder call, and the Window // Manager uses that to determine whether or not the red border should // actually be shown. (it will be ignored that pid doesn't have windows // on screen) void showStrictModeViolation(boolean on); // These can only be called with the SET_ORIENTATION permission. /** * Change the current screen rotation, constants as per Loading
services/java/com/android/server/StrictModeFlash.java 0 → 100644 +114 −0 Original line number Diff line number Diff line /* * Copyright (C) 2010 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; // TODO: use com.android.server.wm, once things move there import android.graphics.Canvas; import android.graphics.Color; import android.graphics.PixelFormat; import android.graphics.PorterDuff; import android.graphics.Rect; import android.graphics.Region; import android.util.DisplayMetrics; import android.util.Slog; import android.view.Display; import android.view.Surface; import android.view.SurfaceSession; class StrictModeFlash { private static final String TAG = "StrictModeFlash"; Surface mSurface; int mLastDW; int mLastDH; boolean mDrawNeeded; final int mThickness = 20; public StrictModeFlash(Display display, SurfaceSession session) { final DisplayMetrics dm = new DisplayMetrics(); display.getMetrics(dm); try { mSurface = new Surface(session, 0, "StrictModeFlash", -1, 1, 1, PixelFormat.TRANSLUCENT, 0); } catch (Surface.OutOfResourcesException e) { return; } mSurface.setLayer(WindowManagerService.TYPE_LAYER_MULTIPLIER * 101); // one more than Watermark? arbitrary. mSurface.setPosition(0, 0); mDrawNeeded = true; } private void drawIfNeeded() { if (!mDrawNeeded) { return; } mDrawNeeded = false; final int dw = mLastDW; final int dh = mLastDH; Rect dirty = new Rect(0, 0, dw, dh); Canvas c = null; try { c = mSurface.lockCanvas(dirty); } catch (IllegalArgumentException e) { } catch (Surface.OutOfResourcesException e) { } if (c == null) { return; } // Top c.clipRect(new Rect(0, 0, dw, mThickness), Region.Op.REPLACE); c.drawColor(Color.RED); // Left c.clipRect(new Rect(0, 0, mThickness, dh), Region.Op.REPLACE); c.drawColor(Color.RED); // Right c.clipRect(new Rect(dw - mThickness, 0, dw, dh), Region.Op.REPLACE); c.drawColor(Color.RED); // Bottom c.clipRect(new Rect(0, dh - mThickness, dw, dh), Region.Op.REPLACE); c.drawColor(Color.RED); mSurface.unlockCanvasAndPost(c); } // Note: caller responsible for being inside // Surface.openTransaction() / closeTransaction() public void setVisibility(boolean on) { if (mSurface == null) { return; } drawIfNeeded(); if (on) { mSurface.show(); } else { mSurface.hide(); } } void positionSurface(int dw, int dh) { if (mLastDW == dw && mLastDH == dh) { return; } mLastDW = dw; mLastDH = dh; mSurface.setSize(dw, dh); mDrawNeeded = true; } }
services/java/com/android/server/WindowManagerService.java +35 −0 Original line number Diff line number Diff line Loading @@ -376,6 +376,7 @@ public class WindowManagerService extends IWindowManager.Stub Surface mBlurSurface; boolean mBlurShown; Watermark mWatermark; StrictModeFlash mStrictModeFlash; int mTransactionSequence = 0; Loading Loading @@ -4883,6 +4884,36 @@ public class WindowManagerService extends IWindowManager.Stub } } // TODO: more accounting of which pid(s) turned it on, keep count, // only allow disables from pids which have count on, etc. public void showStrictModeViolation(boolean on) { int pid = Binder.getCallingPid(); synchronized(mWindowMap) { // Ignoring requests to enable the red border from clients // which aren't on screen. (e.g. Broadcast Receivers in // the background..) if (on) { boolean isVisible = false; for (WindowState ws : mWindows) { if (ws.mSession.mPid == pid && ws.isVisibleLw()) { isVisible = true; break; } } if (!isVisible) { return; } } Surface.openTransaction(); if (mStrictModeFlash == null) { mStrictModeFlash = new StrictModeFlash(mDisplay, mFxSession); } mStrictModeFlash.setVisibility(on); Surface.closeTransaction(); } } public void freezeRotation() { if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION, "setRotation()")) { Loading Loading @@ -9198,6 +9229,7 @@ public class WindowManagerService extends IWindowManager.Stub return mPolicy.finishLayoutLw(); } // "Something has changed! Let's make it correct now." private final void performLayoutAndPlaceSurfacesLockedInner( boolean recoveringMemory) { if (mDisplay == null) { Loading Loading @@ -9249,6 +9281,9 @@ public class WindowManagerService extends IWindowManager.Stub if (mWatermark != null) { mWatermark.positionSurface(dw, dh); } if (mStrictModeFlash != null) { mStrictModeFlash.positionSurface(dw, dh); } try { boolean wallpaperForceHidingChanged = false; Loading