Merge changes Ib786d55e,Ibcda3d72
* changes: Only add NonClientDecorView when needed Move management of BackdropFrameRenderer to DecorView
This commit is contained in:
committed by
Android (Google) Code Review
commit
c02f58f718
@@ -16,8 +16,6 @@
|
||||
|
||||
package com.android.internal.policy;
|
||||
|
||||
import com.android.internal.widget.NonClientDecorView;
|
||||
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Looper;
|
||||
@@ -37,7 +35,7 @@ import android.view.View;
|
||||
*/
|
||||
public class BackdropFrameRenderer extends Thread implements Choreographer.FrameCallback {
|
||||
|
||||
private NonClientDecorView mNonClientDecorView;
|
||||
private DecorView mDecorView;
|
||||
|
||||
// This is containing the last requested size by a resize command. Note that this size might
|
||||
// or might not have been applied to the output already.
|
||||
@@ -62,12 +60,15 @@ public class BackdropFrameRenderer extends Thread implements Choreographer.Frame
|
||||
// Whether to report when next frame is drawn or not.
|
||||
private boolean mReportNextDraw;
|
||||
|
||||
public BackdropFrameRenderer(NonClientDecorView nonClientDecorView,
|
||||
ThreadedRenderer renderer,
|
||||
Rect initialBounds) {
|
||||
mNonClientDecorView = nonClientDecorView;
|
||||
private Drawable mCaptionBackgroundDrawable;
|
||||
private Drawable mResizingBackgroundDrawable;
|
||||
|
||||
public BackdropFrameRenderer(DecorView decorView, ThreadedRenderer renderer, Rect initialBounds,
|
||||
Drawable resizingBackgroundDrawable, Drawable captionBackgroundDrawable) {
|
||||
setName("ResizeFrame");
|
||||
|
||||
mRenderer = renderer;
|
||||
onResourcesLoaded(decorView, resizingBackgroundDrawable, captionBackgroundDrawable);
|
||||
|
||||
// Create a render node for the content and frame backdrop
|
||||
// which can be resized independently from the content.
|
||||
@@ -85,6 +86,13 @@ public class BackdropFrameRenderer extends Thread implements Choreographer.Frame
|
||||
start();
|
||||
}
|
||||
|
||||
void onResourcesLoaded(DecorView decorView, Drawable resizingBackgroundDrawable,
|
||||
Drawable captionBackgroundDrawableDrawable) {
|
||||
mDecorView = decorView;
|
||||
mResizingBackgroundDrawable = resizingBackgroundDrawable;
|
||||
mCaptionBackgroundDrawable = captionBackgroundDrawableDrawable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this function asynchronously when the window size has been changed. The change will
|
||||
* be picked up once per frame and the frame will be re-rendered accordingly.
|
||||
@@ -201,7 +209,8 @@ public class BackdropFrameRenderer extends Thread implements Choreographer.Frame
|
||||
mLastYOffset + mLastCaptionHeight + mLastContentHeight);
|
||||
// If this was the first call and changeWindowSizeLocked got already called prior
|
||||
// to us, we should re-issue a changeWindowSizeLocked now.
|
||||
return firstCall && (mLastCaptionHeight != 0 || !mNonClientDecorView.mShowDecor);
|
||||
return firstCall
|
||||
&& (mLastCaptionHeight != 0 || !mDecorView.isShowingCaption());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -218,25 +227,25 @@ public class BackdropFrameRenderer extends Thread implements Choreographer.Frame
|
||||
* @param newBounds The window bounds which needs to be drawn.
|
||||
*/
|
||||
private void changeWindowSizeLocked(Rect newBounds) {
|
||||
|
||||
// While a configuration change is taking place the view hierarchy might become
|
||||
// inaccessible. For that case we remember the previous metrics to avoid flashes.
|
||||
// Note that even when there is no visible caption, the caption child will exist.
|
||||
View caption = mNonClientDecorView.getChildAt(0);
|
||||
if (caption != null) {
|
||||
final int captionHeight = caption.getHeight();
|
||||
// The caption height will probably never dynamically change while we are resizing.
|
||||
// Once set to something other then 0 it should be kept that way.
|
||||
if (captionHeight != 0) {
|
||||
// Remember the height of the caption.
|
||||
mLastCaptionHeight = captionHeight;
|
||||
}
|
||||
final int captionHeight = mDecorView.getCaptionHeight();
|
||||
// The caption height will probably never dynamically change while we are resizing.
|
||||
// Once set to something other then 0 it should be kept that way.
|
||||
if (captionHeight != 0) {
|
||||
// Remember the height of the caption.
|
||||
mLastCaptionHeight = captionHeight;
|
||||
}
|
||||
|
||||
// Make sure that the other thread has already prepared the render draw calls for the
|
||||
// content. If any size is 0, we have to wait for it to be drawn first.
|
||||
if ((mLastCaptionHeight == 0 && mNonClientDecorView.mShowDecor) ||
|
||||
if ((mLastCaptionHeight == 0 && mDecorView.isShowingCaption()) ||
|
||||
mLastContentWidth == 0 || mLastContentHeight == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Since the surface is spanning the entire screen, we have to add the start offset of
|
||||
// the bounds to get to the surface location.
|
||||
final int left = mLastXOffset + newBounds.left;
|
||||
@@ -247,15 +256,13 @@ public class BackdropFrameRenderer extends Thread implements Choreographer.Frame
|
||||
mFrameAndBackdropNode.setLeftTopRightBottom(left, top, left + width, top + height);
|
||||
|
||||
// Draw the caption and content backdrops in to our render node.
|
||||
DisplayListCanvas canvas = mFrameAndBackdropNode.start(width, height);
|
||||
mNonClientDecorView.mCaptionBackgroundDrawable.setBounds(
|
||||
0, 0, left + width, top + mLastCaptionHeight);
|
||||
mNonClientDecorView.mCaptionBackgroundDrawable.draw(canvas);
|
||||
final DisplayListCanvas canvas = mFrameAndBackdropNode.start(width, height);
|
||||
mCaptionBackgroundDrawable.setBounds(0, 0, left + width, top + mLastCaptionHeight);
|
||||
mCaptionBackgroundDrawable.draw(canvas);
|
||||
|
||||
// The backdrop: clear everything with the background. Clipping is done elsewhere.
|
||||
mNonClientDecorView.mResizingBackgroundDrawable.setBounds(
|
||||
0, mLastCaptionHeight, left + width, top + height);
|
||||
mNonClientDecorView.mResizingBackgroundDrawable.draw(canvas);
|
||||
mResizingBackgroundDrawable.setBounds(0, mLastCaptionHeight, left + width, top + height);
|
||||
mResizingBackgroundDrawable.draw(canvas);
|
||||
mFrameAndBackdropNode.end(canvas);
|
||||
|
||||
// We need to render the node explicitly
|
||||
@@ -264,13 +271,11 @@ public class BackdropFrameRenderer extends Thread implements Choreographer.Frame
|
||||
reportDrawIfNeeded();
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify view root that a frame has been drawn by us, if it has requested so.
|
||||
*/
|
||||
/** Notify view root that a frame has been drawn by us, if it has requested so. */
|
||||
private void reportDrawIfNeeded() {
|
||||
if (mReportNextDraw) {
|
||||
if (mNonClientDecorView.isAttachedToWindow()) {
|
||||
mNonClientDecorView.getViewRootImpl().reportDrawFinish();
|
||||
if (mDecorView.isAttachedToWindow()) {
|
||||
mDecorView.getViewRootImpl().reportDrawFinish();
|
||||
}
|
||||
mReportNextDraw = false;
|
||||
}
|
||||
|
||||
@@ -52,11 +52,13 @@ import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.ThreadedRenderer;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewStub;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.view.Window;
|
||||
import android.view.WindowCallbacks;
|
||||
import android.view.WindowInsets;
|
||||
import android.view.WindowManager;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
@@ -80,7 +82,8 @@ import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
|
||||
|
||||
class DecorView extends FrameLayout implements RootViewSurfaceTaker {
|
||||
/** @hide */
|
||||
public class DecorView extends FrameLayout implements RootViewSurfaceTaker, WindowCallbacks {
|
||||
private static final String TAG = "DecorView";
|
||||
|
||||
private static final boolean SWEEP_OPEN_MENU = false;
|
||||
@@ -167,6 +170,12 @@ class DecorView extends FrameLayout implements RootViewSurfaceTaker {
|
||||
// workspace is expensive, this is the workspace value the window is currently set up for.
|
||||
int mWorkspaceId;
|
||||
|
||||
private boolean mWindowResizeCallbacksAdded = false;
|
||||
|
||||
public BackdropFrameRenderer mBackdropFrameRenderer = null;
|
||||
private Drawable mResizingBackgroundDrawable;
|
||||
private Drawable mCaptionBackgroundDrawable;
|
||||
|
||||
DecorView(Context context, int featureId, PhoneWindow window) {
|
||||
super(context);
|
||||
mFeatureId = featureId;
|
||||
@@ -1225,6 +1234,17 @@ class DecorView extends FrameLayout implements RootViewSurfaceTaker {
|
||||
*/
|
||||
mWindow.openPanelsAfterRestore();
|
||||
}
|
||||
|
||||
if (!mWindowResizeCallbacksAdded) {
|
||||
// If there is no window callback installed there was no window set before. Set it now.
|
||||
// Note that our ViewRootImpl object will not change.
|
||||
getViewRootImpl().addWindowCallbacks(this);
|
||||
mWindowResizeCallbacksAdded = true;
|
||||
} else if (mBackdropFrameRenderer != null) {
|
||||
// We are resizing and this call happened due to a configuration change. Tell the
|
||||
// renderer about it.
|
||||
mBackdropFrameRenderer.onConfigurationChange();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1256,6 +1276,11 @@ class DecorView extends FrameLayout implements RootViewSurfaceTaker {
|
||||
if (st != null && st.menu != null && mFeatureId < 0) {
|
||||
st.menu.close();
|
||||
}
|
||||
|
||||
if (mWindowResizeCallbacksAdded) {
|
||||
getViewRootImpl().removeWindowCallbacks(this);
|
||||
mWindowResizeCallbacksAdded = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1526,6 +1551,18 @@ class DecorView extends FrameLayout implements RootViewSurfaceTaker {
|
||||
}
|
||||
|
||||
View onResourcesLoaded(LayoutInflater inflater, int layoutResource) {
|
||||
mWorkspaceId = getWorkspaceId();
|
||||
|
||||
mResizingBackgroundDrawable = getResizingBackgroundDrawable(
|
||||
mWindow.mBackgroundResource, mWindow.mBackgroundFallbackResource);
|
||||
mCaptionBackgroundDrawable =
|
||||
getContext().getDrawable(R.drawable.non_client_decor_title_focused);
|
||||
|
||||
if (mBackdropFrameRenderer != null) {
|
||||
mBackdropFrameRenderer.onResourcesLoaded(
|
||||
this, mResizingBackgroundDrawable, mCaptionBackgroundDrawable);
|
||||
}
|
||||
|
||||
mNonClientDecorView = createNonClientDecorView(inflater);
|
||||
final View root = inflater.inflate(layoutResource, null);
|
||||
if (mNonClientDecorView != null) {
|
||||
@@ -1556,12 +1593,10 @@ class DecorView extends FrameLayout implements RootViewSurfaceTaker {
|
||||
final WindowManager.LayoutParams attrs = mWindow.getAttributes();
|
||||
boolean isApplication = attrs.type == TYPE_BASE_APPLICATION ||
|
||||
attrs.type == TYPE_APPLICATION;
|
||||
mWorkspaceId = getWorkspaceId();
|
||||
// Only a non floating application window on one of the allowed workspaces can get a non
|
||||
// client decor.
|
||||
if (!mWindow.isFloating()
|
||||
&& isApplication
|
||||
&& ActivityManager.StackId.isStaticStack(mWorkspaceId)) {
|
||||
final boolean hasNonClientDecor = ActivityManager.StackId.hasWindowDecor(mWorkspaceId);
|
||||
if (!mWindow.isFloating() && isApplication && hasNonClientDecor) {
|
||||
// Dependent on the brightness of the used title we either use the
|
||||
// dark or the light button frame.
|
||||
if (nonClientDecorView == null) {
|
||||
@@ -1579,34 +1614,32 @@ class DecorView extends FrameLayout implements RootViewSurfaceTaker {
|
||||
}
|
||||
nonClientDecorView.setPhoneWindow(mWindow,
|
||||
ActivityManager.StackId.hasWindowDecor(mWorkspaceId),
|
||||
ActivityManager.StackId.hasWindowShadow(mWorkspaceId),
|
||||
getResizingBackgroundDrawable(),
|
||||
getContext().getDrawable(R.drawable.non_client_decor_title_focused));
|
||||
ActivityManager.StackId.hasWindowShadow(mWorkspaceId));
|
||||
} else {
|
||||
nonClientDecorView = null;
|
||||
}
|
||||
// Tell the decor if it has a visible non client decor.
|
||||
enableNonClientDecor(
|
||||
nonClientDecorView != null && ActivityManager.StackId.hasWindowDecor(mWorkspaceId));
|
||||
|
||||
// Tell the decor if it has a visible non client decor.
|
||||
enableNonClientDecor(nonClientDecorView != null && hasNonClientDecor);
|
||||
return nonClientDecorView;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the color used to fill areas the app has not rendered content to yet when the user
|
||||
* is resizing the window of an activity in multi-window mode.
|
||||
* */
|
||||
private Drawable getResizingBackgroundDrawable() {
|
||||
* Returns the color used to fill areas the app has not rendered content to yet when the
|
||||
* user is resizing the window of an activity in multi-window mode.
|
||||
*/
|
||||
private Drawable getResizingBackgroundDrawable(int backgroundRes, int backgroundFallbackRes) {
|
||||
final Context context = getContext();
|
||||
|
||||
if (mWindow.mBackgroundResource != 0) {
|
||||
final Drawable drawable = context.getDrawable(mWindow.mBackgroundResource);
|
||||
if (backgroundRes != 0) {
|
||||
final Drawable drawable = context.getDrawable(backgroundRes);
|
||||
if (drawable != null) {
|
||||
return drawable;
|
||||
}
|
||||
}
|
||||
|
||||
if (mWindow.mBackgroundFallbackResource != 0) {
|
||||
final Drawable fallbackDrawable =
|
||||
context.getDrawable(mWindow.mBackgroundFallbackResource);
|
||||
if (backgroundFallbackRes != 0) {
|
||||
final Drawable fallbackDrawable = context.getDrawable(backgroundFallbackRes);
|
||||
if (fallbackDrawable != null) {
|
||||
return fallbackDrawable;
|
||||
}
|
||||
@@ -1652,6 +1685,84 @@ class DecorView extends FrameLayout implements RootViewSurfaceTaker {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWindowSizeIsChanging(Rect newBounds) {
|
||||
if (mBackdropFrameRenderer != null) {
|
||||
mBackdropFrameRenderer.setTargetRect(newBounds);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWindowDragResizeStart(Rect initialBounds) {
|
||||
if (mWindow.isDestroyed()) {
|
||||
// If the owner's window is gone, we should not be able to come here anymore.
|
||||
releaseThreadedRenderer();
|
||||
return;
|
||||
}
|
||||
if (mBackdropFrameRenderer != null) {
|
||||
return;
|
||||
}
|
||||
final ThreadedRenderer renderer = (ThreadedRenderer) getHardwareRenderer();
|
||||
if (renderer != null) {
|
||||
mBackdropFrameRenderer = new BackdropFrameRenderer(this, renderer,
|
||||
initialBounds, mResizingBackgroundDrawable, mCaptionBackgroundDrawable);
|
||||
|
||||
// Get rid of the shadow while we are resizing. Shadow drawing takes considerable time.
|
||||
// If we want to get the shadow shown while resizing, we would need to elevate a new
|
||||
// element which owns the caption and has the elevation.
|
||||
updateElevation();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWindowDragResizeEnd() {
|
||||
releaseThreadedRenderer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onContentDrawn(int offsetX, int offsetY, int sizeX, int sizeY) {
|
||||
if (mBackdropFrameRenderer == null) {
|
||||
return false;
|
||||
}
|
||||
return mBackdropFrameRenderer.onContentDrawn(offsetX, offsetY, sizeX, sizeY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestDraw(boolean reportNextDraw) {
|
||||
if (mBackdropFrameRenderer != null) {
|
||||
mBackdropFrameRenderer.onRequestDraw(reportNextDraw);
|
||||
} else if (reportNextDraw) {
|
||||
// If render thread is gone, just report immediately.
|
||||
if (isAttachedToWindow()) {
|
||||
getViewRootImpl().reportDrawFinish();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Release the renderer thread which is usually done when the user stops resizing. */
|
||||
private void releaseThreadedRenderer() {
|
||||
if (mBackdropFrameRenderer != null) {
|
||||
mBackdropFrameRenderer.releaseRenderer();
|
||||
mBackdropFrameRenderer = null;
|
||||
// Bring the shadow back.
|
||||
updateElevation();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateElevation() {
|
||||
if (mNonClientDecorView != null) {
|
||||
mNonClientDecorView.updateElevation();
|
||||
}
|
||||
}
|
||||
|
||||
boolean isShowingCaption() {
|
||||
return mNonClientDecorView != null && mNonClientDecorView.isShowingDecor();
|
||||
}
|
||||
|
||||
int getCaptionHeight() {
|
||||
return isShowingCaption() ? mNonClientDecorView.getDecorCaptionHeight() : 0;
|
||||
}
|
||||
|
||||
private static class ColorViewState {
|
||||
View view = null;
|
||||
int targetVisibility = View.INVISIBLE;
|
||||
|
||||
@@ -19,23 +19,19 @@ package com.android.internal.widget;
|
||||
import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.RemoteException;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.ThreadedRenderer;
|
||||
import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewOutlineProvider;
|
||||
import android.view.Window;
|
||||
import android.view.WindowCallbacks;
|
||||
import android.util.Log;
|
||||
import android.util.TypedValue;
|
||||
|
||||
import com.android.internal.R;
|
||||
import com.android.internal.policy.BackdropFrameRenderer;
|
||||
import com.android.internal.policy.DecorView;
|
||||
import com.android.internal.policy.PhoneWindow;
|
||||
|
||||
/**
|
||||
@@ -64,7 +60,7 @@ import com.android.internal.policy.PhoneWindow;
|
||||
* This will be mitigated once b/22527834 will be addressed.
|
||||
*/
|
||||
public class NonClientDecorView extends LinearLayout
|
||||
implements View.OnClickListener, View.OnTouchListener, WindowCallbacks {
|
||||
implements View.OnClickListener, View.OnTouchListener {
|
||||
private final static String TAG = "NonClientDecorView";
|
||||
// The height of a window which has focus in DIP.
|
||||
private final int DECOR_SHADOW_FOCUSED_HEIGHT_IN_DIP = 20;
|
||||
@@ -72,9 +68,7 @@ public class NonClientDecorView extends LinearLayout
|
||||
private final int DECOR_SHADOW_UNFOCUSED_HEIGHT_IN_DIP = 5;
|
||||
private PhoneWindow mOwner = null;
|
||||
private boolean mWindowHasShadow = false;
|
||||
public boolean mShowDecor = false;
|
||||
// True when this object is listening for window size changes.
|
||||
private boolean mAttachedCallbacksToRootViewImpl = false;
|
||||
private boolean mShowDecor = false;
|
||||
|
||||
// True if the window is being dragged.
|
||||
private boolean mDragging = false;
|
||||
@@ -93,11 +87,6 @@ public class NonClientDecorView extends LinearLayout
|
||||
// to max until the first layout command has been executed.
|
||||
private boolean mAllowUpdateElevation = false;
|
||||
|
||||
private BackdropFrameRenderer mBackdropFrameRenderer = null;
|
||||
|
||||
public Drawable mResizingBackgroundDrawable;
|
||||
public Drawable mCaptionBackgroundDrawable;
|
||||
|
||||
public NonClientDecorView(Context context) {
|
||||
super(context);
|
||||
}
|
||||
@@ -110,37 +99,10 @@ public class NonClientDecorView extends LinearLayout
|
||||
super(context, attrs, defStyle);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
if (!mAttachedCallbacksToRootViewImpl) {
|
||||
// If there is no window callback installed there was no window set before. Set it now.
|
||||
// Note that our ViewRootImpl object will not change.
|
||||
getViewRootImpl().addWindowCallbacks(this);
|
||||
mAttachedCallbacksToRootViewImpl = true;
|
||||
} else if (mBackdropFrameRenderer != null) {
|
||||
// We are resizing and this call happened due to a configuration change. Tell the
|
||||
// renderer about it.
|
||||
mBackdropFrameRenderer.onConfigurationChange();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow();
|
||||
if (mAttachedCallbacksToRootViewImpl) {
|
||||
getViewRootImpl().removeWindowCallbacks(this);
|
||||
mAttachedCallbacksToRootViewImpl = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void setPhoneWindow(PhoneWindow owner, boolean showDecor, boolean windowHasShadow,
|
||||
Drawable resizingBackgroundDrawable, Drawable captionBackgroundDrawableDrawable) {
|
||||
public void setPhoneWindow(PhoneWindow owner, boolean showDecor, boolean windowHasShadow) {
|
||||
mOwner = owner;
|
||||
mWindowHasShadow = windowHasShadow;
|
||||
mShowDecor = showDecor;
|
||||
mResizingBackgroundDrawable = resizingBackgroundDrawable;
|
||||
mCaptionBackgroundDrawable = captionBackgroundDrawableDrawable;
|
||||
updateCaptionVisibility();
|
||||
if (mWindowHasShadow) {
|
||||
initializeElevation();
|
||||
@@ -290,11 +252,12 @@ public class NonClientDecorView extends LinearLayout
|
||||
* Note: Windows which have (temporarily) changed their attributes to cover the SystemUI
|
||||
* will get no shadow as they are expected to be "full screen".
|
||||
**/
|
||||
private void updateElevation() {
|
||||
public void updateElevation() {
|
||||
float elevation = 0;
|
||||
// Do not use a shadow when we are in resizing mode (mRenderer not null) since the shadow
|
||||
// is bound to the content size and not the target size.
|
||||
if (mWindowHasShadow && mBackdropFrameRenderer == null) {
|
||||
if (mWindowHasShadow
|
||||
&& ((DecorView) mOwner.getDecorView()).mBackdropFrameRenderer == null) {
|
||||
boolean fill = isFillingScreen();
|
||||
elevation = fill ? 0 :
|
||||
(mWindowHasFocus ? DECOR_SHADOW_FOCUSED_HEIGHT_IN_DIP :
|
||||
@@ -336,77 +299,12 @@ public class NonClientDecorView extends LinearLayout
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWindowDragResizeStart(Rect initialBounds) {
|
||||
if (mOwner.isDestroyed()) {
|
||||
// If the owner's window is gone, we should not be able to come here anymore.
|
||||
releaseResources();
|
||||
return;
|
||||
}
|
||||
if (mBackdropFrameRenderer != null) {
|
||||
return;
|
||||
}
|
||||
final ThreadedRenderer renderer =
|
||||
(ThreadedRenderer) mOwner.getDecorView().getHardwareRenderer();
|
||||
if (renderer != null) {
|
||||
mBackdropFrameRenderer = new BackdropFrameRenderer(this, renderer, initialBounds);
|
||||
// Get rid of the shadow while we are resizing. Shadow drawing takes considerable time.
|
||||
// If we want to get the shadow shown while resizing, we would need to elevate a new
|
||||
// element which owns the caption and has the elevation.
|
||||
updateElevation();
|
||||
}
|
||||
public boolean isShowingDecor() {
|
||||
return mShowDecor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onContentDrawn(int xOffset, int yOffset, int xSize, int ySize) {
|
||||
if (mBackdropFrameRenderer == null) {
|
||||
return false;
|
||||
}
|
||||
return mBackdropFrameRenderer.onContentDrawn(xOffset, yOffset, xSize, ySize);
|
||||
public int getDecorCaptionHeight() {
|
||||
final View caption = getChildAt(0);
|
||||
return (caption != null) ? caption.getHeight() : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestDraw(boolean reportNextDraw) {
|
||||
if (mBackdropFrameRenderer != null) {
|
||||
mBackdropFrameRenderer.onRequestDraw(reportNextDraw);
|
||||
} else if (reportNextDraw) {
|
||||
// If render thread is gone, just report immediately.
|
||||
if (isAttachedToWindow()) {
|
||||
getViewRootImpl().reportDrawFinish();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWindowDragResizeEnd() {
|
||||
releaseThreadedRenderer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWindowSizeIsChanging(Rect newBounds) {
|
||||
if (mBackdropFrameRenderer != null) {
|
||||
mBackdropFrameRenderer.setTargetRect(newBounds);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Release the renderer thread which is usually done when the user stops resizing.
|
||||
*/
|
||||
private void releaseThreadedRenderer() {
|
||||
if (mBackdropFrameRenderer != null) {
|
||||
mBackdropFrameRenderer.releaseRenderer();
|
||||
mBackdropFrameRenderer = null;
|
||||
// Bring the shadow back.
|
||||
updateElevation();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the parent window is destroyed to release all resources. Note that this will also
|
||||
* destroy the renderer thread.
|
||||
*/
|
||||
private void releaseResources() {
|
||||
releaseThreadedRenderer();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user