/* * Copyright (C) 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.wm; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SURFACE_TRACE; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.PixelFormat; import android.graphics.Point; import android.graphics.PorterDuff; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.view.Display; import android.view.Surface; import android.view.Surface.OutOfResourcesException; import android.view.SurfaceControl; import android.view.SurfaceSession; class EmulatorDisplayOverlay { private static final String TAG = TAG_WITH_CLASS_NAME ? "EmulatorDisplayOverlay" : TAG_WM; // Display dimensions private Point mScreenSize; private final SurfaceControl mSurfaceControl; private final Surface mSurface = new Surface(); private int mLastDW; private int mLastDH; private boolean mDrawNeeded; private Drawable mOverlay; private int mRotation; private boolean mVisible; public EmulatorDisplayOverlay(Context context, Display display, SurfaceSession session, int zOrder) { mScreenSize = new Point(); display.getSize(mScreenSize); SurfaceControl ctrl = null; try { if (DEBUG_SURFACE_TRACE) { ctrl = new WindowSurfaceController.SurfaceTrace(session, "EmulatorDisplayOverlay", mScreenSize.x, mScreenSize.y, PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN); } else { ctrl = new SurfaceControl(session, "EmulatorDisplayOverlay", mScreenSize.x, mScreenSize.y, PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN); } ctrl.setLayerStack(display.getLayerStack()); ctrl.setLayer(zOrder); ctrl.setPosition(0, 0); ctrl.show(); mSurface.copyFrom(ctrl); } catch (OutOfResourcesException e) { } mSurfaceControl = ctrl; mDrawNeeded = true; mOverlay = context.getDrawable( com.android.internal.R.drawable.emulator_circular_window_overlay); } private void drawIfNeeded() { if (!mDrawNeeded || !mVisible) { return; } mDrawNeeded = false; Rect dirty = new Rect(0, 0, mScreenSize.x, mScreenSize.y); Canvas c = null; try { c = mSurface.lockCanvas(dirty); } catch (IllegalArgumentException e) { } catch (OutOfResourcesException e) { } if (c == null) { return; } c.drawColor(Color.TRANSPARENT, PorterDuff.Mode.SRC); mSurfaceControl.setPosition(0, 0); // Always draw the overlay with square dimensions int size = Math.max(mScreenSize.x, mScreenSize.y); mOverlay.setBounds(0, 0, size, size); mOverlay.draw(c); mSurface.unlockCanvasAndPost(c); } // Note: caller responsible for being inside // Surface.openTransaction() / closeTransaction() public void setVisibility(boolean on) { if (mSurfaceControl == null) { return; } mVisible = on; drawIfNeeded(); if (on) { mSurfaceControl.show(); } else { mSurfaceControl.hide(); } } void positionSurface(int dw, int dh, int rotation) { if (mLastDW == dw && mLastDH == dh && mRotation == rotation) { return; } mLastDW = dw; mLastDH = dh; mDrawNeeded = true; mRotation = rotation; drawIfNeeded(); } }