EmulatorDisplayOverlay.java revision 1ad0fe6c3670f185bddeb0b4d17aba237765ea6b
17fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen/*
27fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen * Copyright (C) 2014 The Android Open Source Project
37fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen *
47fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen * Licensed under the Apache License, Version 2.0 (the "License");
57fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen * you may not use this file except in compliance with the License.
67fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen * You may obtain a copy of the License at
77fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen *
87fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen *      http://www.apache.org/licenses/LICENSE-2.0
97fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen *
107fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen * Unless required by applicable law or agreed to in writing, software
117fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen * distributed under the License is distributed on an "AS IS" BASIS,
127fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen * See the License for the specific language governing permissions and
147fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen * limitations under the License.
157fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen */
167fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen
177fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazenpackage com.android.server.wm;
187fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen
197fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen
207fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazenimport android.content.Context;
217fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazenimport android.graphics.Canvas;
227fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazenimport android.graphics.Color;
237fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazenimport android.graphics.PixelFormat;
247fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazenimport android.graphics.Point;
257fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazenimport android.graphics.PorterDuff;
267fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazenimport android.graphics.Rect;
277fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazenimport android.graphics.drawable.Drawable;
287fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazenimport android.util.Slog;
297fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazenimport android.view.Display;
307fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazenimport android.view.Surface;
317fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazenimport android.view.Surface.OutOfResourcesException;
327fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazenimport android.view.SurfaceControl;
337fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazenimport android.view.SurfaceSession;
347fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen
357fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazenclass EmulatorDisplayOverlay {
367fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen    private static final String TAG = "EmulatorDisplayOverlay";
377fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen
387fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen    // Display dimensions
397fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen    private Point mScreenSize;
407fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen
417fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen    private final SurfaceControl mSurfaceControl;
427fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen    private final Surface mSurface = new Surface();
437fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen    private int mLastDW;
447fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen    private int mLastDH;
457fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen    private boolean mDrawNeeded;
467fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen    private Drawable mOverlay;
477fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen    private int mRotation;
487fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen    private boolean mVisible;
497fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen
507fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen    public EmulatorDisplayOverlay(Context context, Display display, SurfaceSession session,
517fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen            int zOrder) {
527fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen        mScreenSize = new Point();
537fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen        display.getSize(mScreenSize);
547fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen
557fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen        SurfaceControl ctrl = null;
567fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen        try {
577fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen            if (WindowManagerService.DEBUG_SURFACE_TRACE) {
587fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen                ctrl = new WindowStateAnimator.SurfaceTrace(session, "EmulatorDisplayOverlay",
597fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen                        mScreenSize.x, mScreenSize.y, PixelFormat.TRANSLUCENT,
607fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen                        SurfaceControl.HIDDEN);
617fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen            } else {
627fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen                ctrl = new SurfaceControl(session, "EmulatorDisplayOverlay", mScreenSize.x,
637fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen                        mScreenSize.y, PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN);
647fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen            }
657fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen            ctrl.setLayerStack(display.getLayerStack());
667fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen            ctrl.setLayer(zOrder);
677fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen            ctrl.setPosition(0, 0);
687fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen            ctrl.show();
697fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen            mSurface.copyFrom(ctrl);
707fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen        } catch (OutOfResourcesException e) {
717fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen        }
727fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen        mSurfaceControl = ctrl;
737fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen        mDrawNeeded = true;
747fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen        mOverlay = context.getDrawable(
757fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen                com.android.internal.R.drawable.emulator_circular_window_overlay);
767fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen    }
777fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen
787fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen    private void drawIfNeeded() {
797fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen        if (!mDrawNeeded || !mVisible) {
807fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen            return;
817fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen        }
827fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen        mDrawNeeded = false;
837fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen
847fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen        Rect dirty = new Rect(0, 0, mScreenSize.x, mScreenSize.y);
857fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen        Canvas c = null;
867fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen        try {
877fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen            c = mSurface.lockCanvas(dirty);
887fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen        } catch (IllegalArgumentException e) {
897fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen        } catch (OutOfResourcesException e) {
907fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen        }
917fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen        if (c == null) {
927fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen            return;
937fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen        }
947fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen        c.drawColor(Color.TRANSPARENT, PorterDuff.Mode.SRC);
957fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen        mSurfaceControl.setPosition(0, 0);
961ad0fe6c3670f185bddeb0b4d17aba237765ea6bGriff Hazen        // Always draw the overlay with square dimensions
971ad0fe6c3670f185bddeb0b4d17aba237765ea6bGriff Hazen        int size = Math.max(mScreenSize.x, mScreenSize.y);
981ad0fe6c3670f185bddeb0b4d17aba237765ea6bGriff Hazen        mOverlay.setBounds(0, 0, size, size);
997fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen        mOverlay.draw(c);
1007fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen        mSurface.unlockCanvasAndPost(c);
1017fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen    }
1027fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen
1037fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen    // Note: caller responsible for being inside
1047fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen    // Surface.openTransaction() / closeTransaction()
1057fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen    public void setVisibility(boolean on) {
1067fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen        if (mSurfaceControl == null) {
1077fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen            return;
1087fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen        }
1097fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen        mVisible = on;
1107fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen        drawIfNeeded();
1117fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen        if (on) {
1127fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen            mSurfaceControl.show();
1137fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen        } else {
1147fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen            mSurfaceControl.hide();
1157fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen        }
1167fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen    }
1177fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen
1187fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen    void positionSurface(int dw, int dh, int rotation) {
1197fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen        if (mLastDW == dw && mLastDH == dh && mRotation == rotation) {
1207fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen            return;
1217fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen        }
1227fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen        mLastDW = dw;
1237fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen        mLastDH = dh;
1247fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen        mDrawNeeded = true;
1257fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen        mRotation = rotation;
1267fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen        drawIfNeeded();
1277fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen    }
1287fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen
1297fb614664707f4c67dbbad8320e7d3cc10750df1Griff Hazen}
130