143 lines
5.0 KiB
Java
143 lines
5.0 KiB
Java
/*
|
|
* Copyright (C) 2013 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.WindowManagerService.DEBUG_STACK;
|
|
import static com.android.server.wm.WindowManagerService.DEBUG_SURFACE_TRACE;
|
|
|
|
import android.graphics.Canvas;
|
|
import android.graphics.Color;
|
|
import android.graphics.PixelFormat;
|
|
import android.graphics.Rect;
|
|
import android.graphics.Region;
|
|
import android.util.Slog;
|
|
import android.view.Display;
|
|
import android.view.Surface.OutOfResourcesException;
|
|
import android.view.Surface;
|
|
import android.view.SurfaceControl;
|
|
import android.view.SurfaceSession;
|
|
|
|
import com.android.server.wm.WindowStateAnimator.SurfaceTrace;
|
|
|
|
class FocusedStackFrame {
|
|
private static final String TAG = "FocusedStackFrame";
|
|
private static final int THICKNESS = 10;
|
|
private static final float ALPHA = 0.3f;
|
|
|
|
private final SurfaceControl mSurfaceControl;
|
|
private final Surface mSurface = new Surface();
|
|
private final Rect mLastBounds = new Rect();
|
|
private final Rect mBounds = new Rect();
|
|
private final Rect mTmpDrawRect = new Rect();
|
|
|
|
public FocusedStackFrame(Display display, SurfaceSession session) {
|
|
SurfaceControl ctrl = null;
|
|
try {
|
|
if (DEBUG_SURFACE_TRACE) {
|
|
ctrl = new SurfaceTrace(session, "FocusedStackFrame",
|
|
1, 1, PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN);
|
|
} else {
|
|
ctrl = new SurfaceControl(session, "FocusedStackFrame",
|
|
1, 1, PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN);
|
|
}
|
|
ctrl.setLayerStack(display.getLayerStack());
|
|
ctrl.setAlpha(ALPHA);
|
|
mSurface.copyFrom(ctrl);
|
|
} catch (OutOfResourcesException e) {
|
|
}
|
|
mSurfaceControl = ctrl;
|
|
}
|
|
|
|
private void draw(Rect bounds, int color) {
|
|
if (false && DEBUG_STACK) Slog.i(TAG, "draw: bounds=" + bounds.toShortString() +
|
|
" color=" + Integer.toHexString(color));
|
|
mTmpDrawRect.set(bounds);
|
|
Canvas c = null;
|
|
try {
|
|
c = mSurface.lockCanvas(mTmpDrawRect);
|
|
} catch (IllegalArgumentException e) {
|
|
} catch (Surface.OutOfResourcesException e) {
|
|
}
|
|
if (c == null) {
|
|
return;
|
|
}
|
|
|
|
final int w = bounds.width();
|
|
final int h = bounds.height();
|
|
|
|
// Top
|
|
mTmpDrawRect.set(0, 0, w, THICKNESS);
|
|
c.clipRect(mTmpDrawRect, Region.Op.REPLACE);
|
|
c.drawColor(color);
|
|
// Left (not including Top or Bottom stripe).
|
|
mTmpDrawRect.set(0, THICKNESS, THICKNESS, h - THICKNESS);
|
|
c.clipRect(mTmpDrawRect, Region.Op.REPLACE);
|
|
c.drawColor(color);
|
|
// Right (not including Top or Bottom stripe).
|
|
mTmpDrawRect.set(w - THICKNESS, THICKNESS, w, h - THICKNESS);
|
|
c.clipRect(mTmpDrawRect, Region.Op.REPLACE);
|
|
c.drawColor(color);
|
|
// Bottom
|
|
mTmpDrawRect.set(0, h - THICKNESS, w, h);
|
|
c.clipRect(mTmpDrawRect, Region.Op.REPLACE);
|
|
c.drawColor(color);
|
|
|
|
mSurface.unlockCanvasAndPost(c);
|
|
}
|
|
|
|
private void positionSurface(Rect bounds) {
|
|
if (false && DEBUG_STACK) Slog.i(TAG, "positionSurface: bounds=" + bounds.toShortString());
|
|
mSurfaceControl.setSize(bounds.width(), bounds.height());
|
|
mSurfaceControl.setPosition(bounds.left, bounds.top);
|
|
}
|
|
|
|
// Note: caller responsible for being inside
|
|
// Surface.openTransaction() / closeTransaction()
|
|
public void setVisibility(boolean on) {
|
|
if (false && DEBUG_STACK) Slog.i(TAG, "setVisibility: on=" + on +
|
|
" mLastBounds=" + mLastBounds.toShortString() +
|
|
" mBounds=" + mBounds.toShortString());
|
|
if (mSurfaceControl == null) {
|
|
return;
|
|
}
|
|
if (on) {
|
|
if (!mLastBounds.equals(mBounds)) {
|
|
// Erase the previous rectangle.
|
|
positionSurface(mLastBounds);
|
|
draw(mLastBounds, Color.TRANSPARENT);
|
|
// Draw the latest rectangle.
|
|
positionSurface(mBounds);
|
|
draw(mBounds, Color.WHITE);
|
|
// Update the history.
|
|
mLastBounds.set(mBounds);
|
|
}
|
|
mSurfaceControl.show();
|
|
} else {
|
|
mSurfaceControl.hide();
|
|
}
|
|
}
|
|
|
|
public void setBounds(Rect bounds) {
|
|
if (false && DEBUG_STACK) Slog.i(TAG, "setBounds: bounds=" + bounds);
|
|
mBounds.set(bounds);
|
|
}
|
|
|
|
public void setLayer(int layer) {
|
|
mSurfaceControl.setLayer(layer);
|
|
}
|
|
}
|