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