1a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner/* 2a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner * Copyright (C) 2013 The Android Open Source Project 3a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner * 4a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner * Licensed under the Apache License, Version 2.0 (the "License"); 5a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner * you may not use this file except in compliance with the License. 6a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner * You may obtain a copy of the License at 7a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner * 8a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner * http://www.apache.org/licenses/LICENSE-2.0 9a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner * 10a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner * Unless required by applicable law or agreed to in writing, software 11a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner * distributed under the License is distributed on an "AS IS" BASIS, 12a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner * See the License for the specific language governing permissions and 14a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner * limitations under the License. 15a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner */ 16a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner 17a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautnerpackage com.android.server.wm; 18a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner 19a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautnerimport static com.android.server.wm.WindowManagerService.DEBUG_STACK; 20f76664673eed1c7b2fa141ce99e01028bc7a1be0Craig Mautnerimport static com.android.server.wm.WindowManagerService.DEBUG_SURFACE_TRACE; 21a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner 22a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautnerimport android.graphics.Canvas; 23a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautnerimport android.graphics.Color; 24a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautnerimport android.graphics.PixelFormat; 25a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautnerimport android.graphics.Rect; 26a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautnerimport android.graphics.Region; 27a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautnerimport android.util.Slog; 28a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautnerimport android.view.Display; 29a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkinimport android.view.Surface.OutOfResourcesException; 30a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautnerimport android.view.Surface; 31a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautnerimport android.view.SurfaceControl; 32a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautnerimport android.view.SurfaceSession; 33a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner 34f76664673eed1c7b2fa141ce99e01028bc7a1be0Craig Mautnerimport com.android.server.wm.WindowStateAnimator.SurfaceTrace; 35f76664673eed1c7b2fa141ce99e01028bc7a1be0Craig Mautner 36a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautnerclass FocusedStackFrame { 37a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner private static final String TAG = "FocusedStackFrame"; 38a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner private static final int THICKNESS = 10; 39a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner private static final float ALPHA = 0.3f; 40a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner 41a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner private final SurfaceControl mSurfaceControl; 42a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner private final Surface mSurface = new Surface(); 43a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin private final Rect mLastBounds = new Rect(); 44bdc748af8ce62778d2ad15040ecdfada6e4635fdCraig Mautner final Rect mBounds = new Rect(); 45a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin private final Rect mTmpDrawRect = new Rect(); 46a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner 47a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner public FocusedStackFrame(Display display, SurfaceSession session) { 48a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner SurfaceControl ctrl = null; 49a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner try { 50f76664673eed1c7b2fa141ce99e01028bc7a1be0Craig Mautner if (DEBUG_SURFACE_TRACE) { 51f76664673eed1c7b2fa141ce99e01028bc7a1be0Craig Mautner ctrl = new SurfaceTrace(session, "FocusedStackFrame", 52f76664673eed1c7b2fa141ce99e01028bc7a1be0Craig Mautner 1, 1, PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN); 53f76664673eed1c7b2fa141ce99e01028bc7a1be0Craig Mautner } else { 54f76664673eed1c7b2fa141ce99e01028bc7a1be0Craig Mautner ctrl = new SurfaceControl(session, "FocusedStackFrame", 55f76664673eed1c7b2fa141ce99e01028bc7a1be0Craig Mautner 1, 1, PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN); 56f76664673eed1c7b2fa141ce99e01028bc7a1be0Craig Mautner } 57a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner ctrl.setLayerStack(display.getLayerStack()); 58a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner ctrl.setAlpha(ALPHA); 59a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner mSurface.copyFrom(ctrl); 60a86ab640f7bb0bf3cb4eaed80473ca8c5d131903Igor Murashkin } catch (OutOfResourcesException e) { 61a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner } 62a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner mSurfaceControl = ctrl; 63a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner } 64a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner 65a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner private void draw(Rect bounds, int color) { 66e2dd83a5b428df5a6ef21c11e71d021c640d843fCraig Mautner if (false && DEBUG_STACK) Slog.i(TAG, "draw: bounds=" + bounds.toShortString() + 67a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner " color=" + Integer.toHexString(color)); 68a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner mTmpDrawRect.set(bounds); 69a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner Canvas c = null; 70a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner try { 71a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner c = mSurface.lockCanvas(mTmpDrawRect); 72a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner } catch (IllegalArgumentException e) { 73a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner } catch (Surface.OutOfResourcesException e) { 74a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner } 75a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner if (c == null) { 76a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner return; 77a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner } 78a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner 79a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner final int w = bounds.width(); 80a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner final int h = bounds.height(); 81a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner 82a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner // Top 83a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner mTmpDrawRect.set(0, 0, w, THICKNESS); 84a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner c.clipRect(mTmpDrawRect, Region.Op.REPLACE); 85a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner c.drawColor(color); 86a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner // Left (not including Top or Bottom stripe). 87a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner mTmpDrawRect.set(0, THICKNESS, THICKNESS, h - THICKNESS); 88a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner c.clipRect(mTmpDrawRect, Region.Op.REPLACE); 89a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner c.drawColor(color); 90a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner // Right (not including Top or Bottom stripe). 91a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner mTmpDrawRect.set(w - THICKNESS, THICKNESS, w, h - THICKNESS); 92a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner c.clipRect(mTmpDrawRect, Region.Op.REPLACE); 93a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner c.drawColor(color); 94a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner // Bottom 95a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner mTmpDrawRect.set(0, h - THICKNESS, w, h); 96a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner c.clipRect(mTmpDrawRect, Region.Op.REPLACE); 97a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner c.drawColor(color); 98a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner 99a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner mSurface.unlockCanvasAndPost(c); 100a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner } 101a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner 102a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner private void positionSurface(Rect bounds) { 103e2dd83a5b428df5a6ef21c11e71d021c640d843fCraig Mautner if (false && DEBUG_STACK) Slog.i(TAG, "positionSurface: bounds=" + bounds.toShortString()); 104a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner mSurfaceControl.setSize(bounds.width(), bounds.height()); 105a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner mSurfaceControl.setPosition(bounds.left, bounds.top); 106a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner } 107a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner 108a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner // Note: caller responsible for being inside 109a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner // Surface.openTransaction() / closeTransaction() 110a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner public void setVisibility(boolean on) { 111e2dd83a5b428df5a6ef21c11e71d021c640d843fCraig Mautner if (false && DEBUG_STACK) Slog.i(TAG, "setVisibility: on=" + on + 112a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner " mLastBounds=" + mLastBounds.toShortString() + 113a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner " mBounds=" + mBounds.toShortString()); 114a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner if (mSurfaceControl == null) { 115a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner return; 116a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner } 117a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner if (on) { 118a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner if (!mLastBounds.equals(mBounds)) { 119a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner // Erase the previous rectangle. 120a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner positionSurface(mLastBounds); 121a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner draw(mLastBounds, Color.TRANSPARENT); 122a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner // Draw the latest rectangle. 123a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner positionSurface(mBounds); 124a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner draw(mBounds, Color.WHITE); 125a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner // Update the history. 126a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner mLastBounds.set(mBounds); 127a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner } 128a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner mSurfaceControl.show(); 129a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner } else { 130a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner mSurfaceControl.hide(); 131a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner } 132a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner } 133a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner 134bdc748af8ce62778d2ad15040ecdfada6e4635fdCraig Mautner public void setBounds(TaskStack stack) { 135bdc748af8ce62778d2ad15040ecdfada6e4635fdCraig Mautner stack.getBounds(mBounds); 136bdc748af8ce62778d2ad15040ecdfada6e4635fdCraig Mautner if (false && DEBUG_STACK) Slog.i(TAG, "setBounds: bounds=" + mBounds); 137a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner } 138f76664673eed1c7b2fa141ce99e01028bc7a1be0Craig Mautner 139f76664673eed1c7b2fa141ce99e01028bc7a1be0Craig Mautner public void setLayer(int layer) { 140f76664673eed1c7b2fa141ce99e01028bc7a1be0Craig Mautner mSurfaceControl.setLayer(layer); 141f76664673eed1c7b2fa141ce99e01028bc7a1be0Craig Mautner } 142a9a3fb1da3d3d41f923e87d5b08b35c3e0c1f72eCraig Mautner} 143