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 17 package com.android.server.wm; 18 19 20 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; 21 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; 22 23 import android.content.Context; 24 import android.graphics.Canvas; 25 import android.graphics.Color; 26 import android.graphics.PixelFormat; 27 import android.graphics.Point; 28 import android.graphics.PorterDuff; 29 import android.graphics.Rect; 30 import android.graphics.drawable.Drawable; 31 import android.view.Display; 32 import android.view.Surface; 33 import android.view.Surface.OutOfResourcesException; 34 import android.view.SurfaceControl; 35 import android.view.SurfaceSession; 36 37 class EmulatorDisplayOverlay { 38 private static final String TAG = TAG_WITH_CLASS_NAME ? "EmulatorDisplayOverlay" : TAG_WM; 39 40 // Display dimensions 41 private Point mScreenSize; 42 43 private final SurfaceControl mSurfaceControl; 44 private final Surface mSurface = new Surface(); 45 private int mLastDW; 46 private int mLastDH; 47 private boolean mDrawNeeded; 48 private Drawable mOverlay; 49 private int mRotation; 50 private boolean mVisible; 51 52 public EmulatorDisplayOverlay(Context context, DisplayContent dc, 53 int zOrder) { 54 final Display display = dc.getDisplay(); 55 mScreenSize = new Point(); 56 display.getSize(mScreenSize); 57 58 SurfaceControl ctrl = null; 59 try { 60 ctrl = dc.makeOverlay() 61 .setName("EmulatorDisplayOverlay") 62 .setSize(mScreenSize.x, mScreenSize.y) 63 .setFormat(PixelFormat.TRANSLUCENT) 64 .build(); 65 ctrl.setLayer(zOrder); 66 ctrl.setPosition(0, 0); 67 ctrl.show(); 68 mSurface.copyFrom(ctrl); 69 } catch (OutOfResourcesException e) { 70 } 71 mSurfaceControl = ctrl; 72 mDrawNeeded = true; 73 mOverlay = context.getDrawable( 74 com.android.internal.R.drawable.emulator_circular_window_overlay); 75 } 76 77 private void drawIfNeeded() { 78 if (!mDrawNeeded || !mVisible) { 79 return; 80 } 81 mDrawNeeded = false; 82 83 Rect dirty = new Rect(0, 0, mScreenSize.x, mScreenSize.y); 84 Canvas c = null; 85 try { 86 c = mSurface.lockCanvas(dirty); 87 } catch (IllegalArgumentException e) { 88 } catch (OutOfResourcesException e) { 89 } 90 if (c == null) { 91 return; 92 } 93 c.drawColor(Color.TRANSPARENT, PorterDuff.Mode.SRC); 94 mSurfaceControl.setPosition(0, 0); 95 // Always draw the overlay with square dimensions 96 int size = Math.max(mScreenSize.x, mScreenSize.y); 97 mOverlay.setBounds(0, 0, size, size); 98 mOverlay.draw(c); 99 mSurface.unlockCanvasAndPost(c); 100 } 101 102 // Note: caller responsible for being inside 103 // Surface.openTransaction() / closeTransaction() 104 public void setVisibility(boolean on) { 105 if (mSurfaceControl == null) { 106 return; 107 } 108 mVisible = on; 109 drawIfNeeded(); 110 if (on) { 111 mSurfaceControl.show(); 112 } else { 113 mSurfaceControl.hide(); 114 } 115 } 116 117 void positionSurface(int dw, int dh, int rotation) { 118 if (mLastDW == dw && mLastDH == dh && mRotation == rotation) { 119 return; 120 } 121 mLastDW = dw; 122 mLastDH = dh; 123 mDrawNeeded = true; 124 mRotation = rotation; 125 drawIfNeeded(); 126 } 127 128 } 129