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 android.graphics.Canvas; 21import android.graphics.Color; 22import android.graphics.PixelFormat; 23import android.graphics.Rect; 24import android.graphics.Region; 25import android.view.Display; 26import android.view.Surface; 27import android.view.SurfaceSession; 28 29class StrictModeFlash { 30 private static final String TAG = "StrictModeFlash"; 31 32 Surface mSurface; 33 int mLastDW; 34 int mLastDH; 35 boolean mDrawNeeded; 36 final int mThickness = 20; 37 38 public StrictModeFlash(Display display, SurfaceSession session) { 39 try { 40 mSurface = new Surface(session, "StrictModeFlash", 41 1, 1, PixelFormat.TRANSLUCENT, Surface.HIDDEN); 42 } catch (Surface.OutOfResourcesException e) { 43 return; 44 } 45 46 mSurface.setLayerStack(display.getLayerStack()); 47 mSurface.setLayer(WindowManagerService.TYPE_LAYER_MULTIPLIER * 101); // one more than Watermark? arbitrary. 48 mSurface.setPosition(0, 0); 49 mSurface.show(); 50 mDrawNeeded = true; 51 } 52 53 private void drawIfNeeded() { 54 if (!mDrawNeeded) { 55 return; 56 } 57 mDrawNeeded = false; 58 final int dw = mLastDW; 59 final int dh = mLastDH; 60 61 Rect dirty = new Rect(0, 0, dw, dh); 62 Canvas c = null; 63 try { 64 c = mSurface.lockCanvas(dirty); 65 } catch (IllegalArgumentException e) { 66 } catch (Surface.OutOfResourcesException e) { 67 } 68 if (c == null) { 69 return; 70 } 71 72 // Top 73 c.clipRect(new Rect(0, 0, dw, mThickness), Region.Op.REPLACE); 74 c.drawColor(Color.RED); 75 // Left 76 c.clipRect(new Rect(0, 0, mThickness, dh), Region.Op.REPLACE); 77 c.drawColor(Color.RED); 78 // Right 79 c.clipRect(new Rect(dw - mThickness, 0, dw, dh), Region.Op.REPLACE); 80 c.drawColor(Color.RED); 81 // Bottom 82 c.clipRect(new Rect(0, dh - mThickness, dw, dh), Region.Op.REPLACE); 83 c.drawColor(Color.RED); 84 85 mSurface.unlockCanvasAndPost(c); 86 } 87 88 // Note: caller responsible for being inside 89 // Surface.openTransaction() / closeTransaction() 90 public void setVisibility(boolean on) { 91 if (mSurface == null) { 92 return; 93 } 94 drawIfNeeded(); 95 if (on) { 96 mSurface.show(); 97 } else { 98 mSurface.hide(); 99 } 100 } 101 102 void positionSurface(int dw, int dh) { 103 if (mLastDW == dw && mLastDH == dh) { 104 return; 105 } 106 mLastDW = dw; 107 mLastDH = dh; 108 mSurface.setSize(dw, dh); 109 mDrawNeeded = true; 110 } 111 112} 113