1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.wm; 18 19 20import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; 21import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; 22 23import android.graphics.Canvas; 24import android.graphics.Color; 25import android.graphics.PixelFormat; 26import android.graphics.Rect; 27import android.graphics.Region; 28import android.view.Display; 29import android.view.Surface.OutOfResourcesException; 30import android.view.Surface; 31import android.view.SurfaceControl; 32import android.view.SurfaceSession; 33 34class StrictModeFlash { 35 private static final String TAG = TAG_WITH_CLASS_NAME ? "StrictModeFlash" : TAG_WM; 36 37 private final SurfaceControl mSurfaceControl; 38 private final Surface mSurface = new Surface(); 39 private int mLastDW; 40 private int mLastDH; 41 private boolean mDrawNeeded; 42 private final int mThickness = 20; 43 44 public StrictModeFlash(Display display, SurfaceSession session) { 45 SurfaceControl ctrl = null; 46 try { 47 ctrl = new SurfaceControl(session, "StrictModeFlash", 48 1, 1, PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN); 49 ctrl.setLayerStack(display.getLayerStack()); 50 ctrl.setLayer(WindowManagerService.TYPE_LAYER_MULTIPLIER * 101); // one more than Watermark? arbitrary. 51 ctrl.setPosition(0, 0); 52 ctrl.show(); 53 mSurface.copyFrom(ctrl); 54 } catch (OutOfResourcesException e) { 55 } 56 mSurfaceControl = ctrl; 57 mDrawNeeded = true; 58 } 59 60 private void drawIfNeeded() { 61 if (!mDrawNeeded) { 62 return; 63 } 64 mDrawNeeded = false; 65 final int dw = mLastDW; 66 final int dh = mLastDH; 67 68 Rect dirty = new Rect(0, 0, dw, dh); 69 Canvas c = null; 70 try { 71 c = mSurface.lockCanvas(dirty); 72 } catch (IllegalArgumentException e) { 73 } catch (Surface.OutOfResourcesException e) { 74 } 75 if (c == null) { 76 return; 77 } 78 79 // Top 80 c.clipRect(new Rect(0, 0, dw, mThickness), Region.Op.REPLACE); 81 c.drawColor(Color.RED); 82 // Left 83 c.clipRect(new Rect(0, 0, mThickness, dh), Region.Op.REPLACE); 84 c.drawColor(Color.RED); 85 // Right 86 c.clipRect(new Rect(dw - mThickness, 0, dw, dh), Region.Op.REPLACE); 87 c.drawColor(Color.RED); 88 // Bottom 89 c.clipRect(new Rect(0, dh - mThickness, dw, dh), Region.Op.REPLACE); 90 c.drawColor(Color.RED); 91 92 mSurface.unlockCanvasAndPost(c); 93 } 94 95 // Note: caller responsible for being inside 96 // Surface.openTransaction() / closeTransaction() 97 public void setVisibility(boolean on) { 98 if (mSurfaceControl == null) { 99 return; 100 } 101 drawIfNeeded(); 102 if (on) { 103 mSurfaceControl.show(); 104 } else { 105 mSurfaceControl.hide(); 106 } 107 } 108 109 void positionSurface(int dw, int dh) { 110 if (mLastDW == dw && mLastDH == dh) { 111 return; 112 } 113 mLastDW = dw; 114 mLastDH = dh; 115 mSurfaceControl.setSize(dw, dh); 116 mDrawNeeded = true; 117 } 118 119} 120