diff options
Diffstat (limited to 'services/core/java/com/android/server/wm/FocusedStackFrame.java')
-rw-r--r-- | services/core/java/com/android/server/wm/FocusedStackFrame.java | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/services/core/java/com/android/server/wm/FocusedStackFrame.java b/services/core/java/com/android/server/wm/FocusedStackFrame.java new file mode 100644 index 0000000..f1f5fe8 --- /dev/null +++ b/services/core/java/com/android/server/wm/FocusedStackFrame.java @@ -0,0 +1,142 @@ +/* + * 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(); + 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(TaskStack stack) { + stack.getBounds(mBounds); + if (false && DEBUG_STACK) Slog.i(TAG, "setBounds: bounds=" + mBounds); + } + + public void setLayer(int layer) { + mSurfaceControl.setLayer(layer); + } +} |