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