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