CircularDisplayMask.java revision 8b275ca9d34792ba525771e0c1865b3262e569c9
1/* 2 * Copyright (C) 2014 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.Paint; 23import android.graphics.PixelFormat; 24import android.graphics.Rect; 25import android.view.Display; 26import android.view.Surface; 27import android.view.Surface.OutOfResourcesException; 28import android.view.SurfaceControl; 29import android.view.SurfaceSession; 30 31class CircularDisplayMask { 32 private static final String TAG = "CircularDisplayMask"; 33 34 private static final int STROKE_WIDTH = 2; 35 36 private final SurfaceControl mSurfaceControl; 37 private final Surface mSurface = new Surface(); 38 private int mLastDW; 39 private int mLastDH; 40 private boolean mDrawNeeded; 41 private Paint mPaint; 42 private int mRotation; 43 44 public CircularDisplayMask(Display display, SurfaceSession session, int zOrder) { 45 SurfaceControl ctrl = null; 46 try { 47 ctrl = new SurfaceControl(session, "CircularDisplayMask", 48 320, 290, PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN); 49 ctrl.setLayerStack(display.getLayerStack()); 50 ctrl.setLayer(zOrder); 51 ctrl.setPosition(0, 0); 52 ctrl.show(); 53 mSurface.copyFrom(ctrl); 54 } catch (OutOfResourcesException e) { 55 } 56 mSurfaceControl = ctrl; 57 mDrawNeeded = true; 58 mPaint = new Paint(); 59 mPaint.setAntiAlias(true); 60 mPaint.setStyle(Paint.Style.STROKE); 61 mPaint.setColor(Color.BLACK); 62 mPaint.setStrokeWidth(STROKE_WIDTH); 63 } 64 65 private void drawIfNeeded() { 66 if (!mDrawNeeded) { 67 return; 68 } 69 mDrawNeeded = false; 70 71 Rect dirty = new Rect(0, 0, mLastDW, mLastDH); 72 Canvas c = null; 73 try { 74 c = mSurface.lockCanvas(dirty); 75 } catch (IllegalArgumentException e) { 76 } catch (Surface.OutOfResourcesException e) { 77 } 78 if (c == null) { 79 return; 80 } 81 int cx = 160; 82 int cy = 160; 83 switch (mRotation) { 84 case Surface.ROTATION_0: 85 case Surface.ROTATION_90: 86 // chin bottom or right 87 cx = 160; 88 cy = 160; 89 break; 90 case Surface.ROTATION_180: 91 // chin top 92 cx = 160; 93 cy = 145; 94 break; 95 case Surface.ROTATION_270: 96 cx = 145; 97 cy = 160; 98 break; 99 } 100 c.drawCircle(cx, cy, 160, mPaint); 101 102 mSurface.unlockCanvasAndPost(c); 103 } 104 105 // Note: caller responsible for being inside 106 // Surface.openTransaction() / closeTransaction() 107 public void setVisibility(boolean on) { 108 if (mSurfaceControl == null) { 109 return; 110 } 111 drawIfNeeded(); 112 if (on) { 113 mSurfaceControl.show(); 114 } else { 115 mSurfaceControl.hide(); 116 } 117 } 118 119 void positionSurface(int dw, int dh, int rotation) { 120 if (mLastDW == dw && mLastDH == dh) { 121 return; 122 } 123 mLastDW = dw; 124 mLastDH = dh; 125 mSurfaceControl.setSize(dw, dh); 126 mDrawNeeded = true; 127 mRotation = rotation; 128 } 129 130} 131