blob: 9c18331e068fe89ad8a7acc0b5b6d4ff8c147de9 [file] [log] [blame]
Craig Mautnera9a3fb12013-04-18 10:01:00 -07001/*
2 * Copyright (C) 2013 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
17package com.android.server.wm;
18
19import static com.android.server.wm.WindowManagerService.DEBUG_STACK;
Craig Mautnerf7666462013-04-28 08:58:21 -070020import static com.android.server.wm.WindowManagerService.DEBUG_SURFACE_TRACE;
Craig Mautnera9a3fb12013-04-18 10:01:00 -070021
22import android.graphics.Canvas;
23import android.graphics.Color;
24import android.graphics.PixelFormat;
25import android.graphics.Rect;
26import android.graphics.Region;
27import android.util.Slog;
28import android.view.Display;
29import android.view.Surface;
30import android.view.SurfaceControl;
31import android.view.SurfaceSession;
32
Craig Mautnerf7666462013-04-28 08:58:21 -070033import com.android.server.wm.WindowStateAnimator.SurfaceTrace;
34
Craig Mautnera9a3fb12013-04-18 10:01:00 -070035class FocusedStackFrame {
36 private static final String TAG = "FocusedStackFrame";
37 private static final int THICKNESS = 10;
38 private static final float ALPHA = 0.3f;
39
40 private final SurfaceControl mSurfaceControl;
41 private final Surface mSurface = new Surface();
42 private Rect mLastBounds = new Rect();
43 private Rect mBounds = new Rect();
44 private Rect mTmpDrawRect = new Rect();
45
46 public FocusedStackFrame(Display display, SurfaceSession session) {
47 SurfaceControl ctrl = null;
48 try {
Craig Mautnerf7666462013-04-28 08:58:21 -070049 if (DEBUG_SURFACE_TRACE) {
50 ctrl = new SurfaceTrace(session, "FocusedStackFrame",
51 1, 1, PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN);
52 } else {
53 ctrl = new SurfaceControl(session, "FocusedStackFrame",
54 1, 1, PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN);
55 }
Craig Mautnera9a3fb12013-04-18 10:01:00 -070056 ctrl.setLayerStack(display.getLayerStack());
Craig Mautnera9a3fb12013-04-18 10:01:00 -070057 ctrl.setAlpha(ALPHA);
58 mSurface.copyFrom(ctrl);
59 } catch (SurfaceControl.OutOfResourcesException e) {
60 }
61 mSurfaceControl = ctrl;
62 }
63
64 private void draw(Rect bounds, int color) {
65 if (DEBUG_STACK) Slog.i(TAG, "draw: bounds=" + bounds.toShortString() +
66 " color=" + Integer.toHexString(color));
67 mTmpDrawRect.set(bounds);
68 Canvas c = null;
69 try {
70 c = mSurface.lockCanvas(mTmpDrawRect);
71 } catch (IllegalArgumentException e) {
72 } catch (Surface.OutOfResourcesException e) {
73 }
74 if (c == null) {
75 return;
76 }
77
78 final int w = bounds.width();
79 final int h = bounds.height();
80
81 // Top
82 mTmpDrawRect.set(0, 0, w, THICKNESS);
83 c.clipRect(mTmpDrawRect, Region.Op.REPLACE);
84 c.drawColor(color);
85 // Left (not including Top or Bottom stripe).
86 mTmpDrawRect.set(0, THICKNESS, THICKNESS, h - THICKNESS);
87 c.clipRect(mTmpDrawRect, Region.Op.REPLACE);
88 c.drawColor(color);
89 // Right (not including Top or Bottom stripe).
90 mTmpDrawRect.set(w - THICKNESS, THICKNESS, w, h - THICKNESS);
91 c.clipRect(mTmpDrawRect, Region.Op.REPLACE);
92 c.drawColor(color);
93 // Bottom
94 mTmpDrawRect.set(0, h - THICKNESS, w, h);
95 c.clipRect(mTmpDrawRect, Region.Op.REPLACE);
96 c.drawColor(color);
97
98 mSurface.unlockCanvasAndPost(c);
99 }
100
101 private void positionSurface(Rect bounds) {
102 if (DEBUG_STACK) Slog.i(TAG, "positionSurface: bounds=" + bounds.toShortString());
103 mSurfaceControl.setSize(bounds.width(), bounds.height());
104 mSurfaceControl.setPosition(bounds.left, bounds.top);
105 }
106
107 // Note: caller responsible for being inside
108 // Surface.openTransaction() / closeTransaction()
109 public void setVisibility(boolean on) {
110 if (DEBUG_STACK) Slog.i(TAG, "setVisibility: on=" + on +
111 " mLastBounds=" + mLastBounds.toShortString() +
112 " mBounds=" + mBounds.toShortString());
113 if (mSurfaceControl == null) {
114 return;
115 }
116 if (on) {
117 if (!mLastBounds.equals(mBounds)) {
118 // Erase the previous rectangle.
119 positionSurface(mLastBounds);
120 draw(mLastBounds, Color.TRANSPARENT);
121 // Draw the latest rectangle.
122 positionSurface(mBounds);
123 draw(mBounds, Color.WHITE);
124 // Update the history.
125 mLastBounds.set(mBounds);
126 }
127 mSurfaceControl.show();
128 } else {
129 mSurfaceControl.hide();
130 }
131 }
132
133 public void setBounds(Rect bounds) {
134 if (DEBUG_STACK) Slog.i(TAG, "setBounds: bounds=" + bounds);
135 mBounds.set(bounds);
136 }
Craig Mautnerf7666462013-04-28 08:58:21 -0700137
138 public void setLayer(int layer) {
139 mSurfaceControl.setLayer(layer);
140 }
Craig Mautnera9a3fb12013-04-18 10:01:00 -0700141}