diff options
| -rw-r--r-- | core/java/com/android/internal/policy/DecorView.java | 86 | ||||
| -rw-r--r-- | core/java/com/android/internal/widget/NonClientDecorView.java | 110 |
2 files changed, 77 insertions, 119 deletions
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java index 077cebc4ebf9..4b88dc96cc1f 100644 --- a/core/java/com/android/internal/policy/DecorView.java +++ b/core/java/com/android/internal/policy/DecorView.java @@ -88,6 +88,18 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind private static final boolean SWEEP_OPEN_MENU = false; + // The height of a window which has focus in DIP. + private final static int DECOR_SHADOW_FOCUSED_HEIGHT_IN_DIP = 20; + // The height of a window which has not in DIP. + private final static int DECOR_SHADOW_UNFOCUSED_HEIGHT_IN_DIP = 5; + + // Cludge to address b/22668382: Set the shadow size to the maximum so that the layer + // size calculation takes the shadow size into account. We set the elevation currently + // to max until the first layout command has been executed. + private boolean mAllowUpdateElevation = false; + + private boolean mElevationAdjustedForStack = false; + int mDefaultOpacity = PixelFormat.OPAQUE; /** The feature ID of the panel, or -1 if this is the application's DecorView */ @@ -351,7 +363,7 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind @Override public boolean onInterceptTouchEvent(MotionEvent event) { int action = event.getAction(); - if (mHasNonClientDecor && mNonClientDecorView.mVisible) { + if (mHasNonClientDecor && isShowingCaption()) { // Don't dispatch ACTION_DOWN to the non client decor if the window is // resizable and the event was (starting) outside the window. // Window resizing events should be handled by WindowManager. @@ -630,6 +642,11 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind if (mOutsets.top > 0) { offsetTopAndBottom(-mOutsets.top); } + + // If the application changed its SystemUI metrics, we might also have to adapt + // our shadow elevation. + updateElevation(); + mAllowUpdateElevation = true; } @Override @@ -1213,6 +1230,8 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind if (mFloatingActionMode != null) { mFloatingActionMode.onWindowFocusChanged(hasWindowFocus); } + + updateElevation(); } @Override @@ -1537,17 +1556,17 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind } void onConfigurationChanged() { + int workspaceId = getWorkspaceId(); if (mNonClientDecorView != null) { - int workspaceId = getWorkspaceId(); if (mWorkspaceId != workspaceId) { mWorkspaceId = workspaceId; // We might have to change the kind of surface before we do anything else. mNonClientDecorView.onConfigurationChanged( - ActivityManager.StackId.hasWindowDecor(mWorkspaceId), - ActivityManager.StackId.hasWindowShadow(mWorkspaceId)); + ActivityManager.StackId.hasWindowDecor(mWorkspaceId)); enableNonClientDecor(ActivityManager.StackId.hasWindowDecor(workspaceId)); } } + initializeElevation(); } View onResourcesLoaded(LayoutInflater inflater, int layoutResource) { @@ -1576,6 +1595,7 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind addView(root, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT)); } mContentRoot = (ViewGroup) root; + initializeElevation(); return root; } @@ -1591,12 +1611,12 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind } } final WindowManager.LayoutParams attrs = mWindow.getAttributes(); - boolean isApplication = attrs.type == TYPE_BASE_APPLICATION || + final boolean isApplication = attrs.type == TYPE_BASE_APPLICATION || attrs.type == TYPE_APPLICATION; // Only a non floating application window on one of the allowed workspaces can get a non // client decor. - final boolean hasNonClientDecor = ActivityManager.StackId.hasWindowDecor(mWorkspaceId); - if (!mWindow.isFloating() && isApplication && hasNonClientDecor) { + if (!mWindow.isFloating() && isApplication + && ActivityManager.StackId.hasWindowDecor(mWorkspaceId)) { // Dependent on the brightness of the used title we either use the // dark or the light button frame. if (nonClientDecorView == null) { @@ -1612,15 +1632,13 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind R.layout.non_client_decor_light, null); } } - nonClientDecorView.setPhoneWindow(mWindow, - ActivityManager.StackId.hasWindowDecor(mWorkspaceId), - ActivityManager.StackId.hasWindowShadow(mWorkspaceId)); + nonClientDecorView.setPhoneWindow(mWindow, true /*showDecor*/); } else { nonClientDecorView = null; } // Tell the decor if it has a visible non client decor. - enableNonClientDecor(nonClientDecorView != null && hasNonClientDecor); + enableNonClientDecor(nonClientDecorView != null); return nonClientDecorView; } @@ -1749,9 +1767,41 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind } } + /** + * The elevation gets set for the first time and the framework needs to be informed that + * the surface layer gets created with the shadow size in mind. + */ + private void initializeElevation() { + // TODO(skuhne): Call setMaxElevation here accordingly after b/22668382 got fixed. + mAllowUpdateElevation = false; + updateElevation(); + } + private void updateElevation() { - if (mNonClientDecorView != null) { - mNonClientDecorView.updateElevation(); + float elevation = 0; + final boolean wasAdjustedForStack = mElevationAdjustedForStack; + // Do not use a shadow when we are in resizing mode (mBackdropFrameRenderer not null) + // since the shadow is bound to the content size and not the target size. + if (ActivityManager.StackId.hasWindowShadow(mWorkspaceId) + && mBackdropFrameRenderer == null) { + elevation = hasWindowFocus() ? + DECOR_SHADOW_FOCUSED_HEIGHT_IN_DIP : DECOR_SHADOW_UNFOCUSED_HEIGHT_IN_DIP; + // TODO(skuhne): Remove this if clause once b/22668382 got fixed. + if (!mAllowUpdateElevation) { + elevation = DECOR_SHADOW_FOCUSED_HEIGHT_IN_DIP; + } + // Convert the DP elevation into physical pixels. + elevation = dipToPx(elevation); + mElevationAdjustedForStack = true; + } else { + mElevationAdjustedForStack = false; + } + + // Don't change the elevation if we didn't previously adjust it for the stack it was in + // or it didn't change. + if ((wasAdjustedForStack || mElevationAdjustedForStack) + && getElevation() != elevation) { + mWindow.setElevation(elevation); } } @@ -1763,6 +1813,16 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind return isShowingCaption() ? mNonClientDecorView.getDecorCaptionHeight() : 0; } + /** + * Converts a DIP measure into physical pixels. + * @param dip The dip value. + * @return Returns the number of pixels. + */ + private float dipToPx(float dip) { + return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dip, + getResources().getDisplayMetrics()); + } + private static class ColorViewState { View view = null; int targetVisibility = View.INVISIBLE; diff --git a/core/java/com/android/internal/widget/NonClientDecorView.java b/core/java/com/android/internal/widget/NonClientDecorView.java index 33b8e0515ab0..1f01759253cf 100644 --- a/core/java/com/android/internal/widget/NonClientDecorView.java +++ b/core/java/com/android/internal/widget/NonClientDecorView.java @@ -28,24 +28,18 @@ import android.view.ViewGroup; import android.view.ViewOutlineProvider; import android.view.Window; import android.util.Log; -import android.util.TypedValue; import com.android.internal.R; -import com.android.internal.policy.DecorView; import com.android.internal.policy.PhoneWindow; /** * This class represents the special screen elements to control a window on free form - * environment. All thse screen elements are added in the "non client area" which is the area of + * environment. All these screen elements are added in the "non client area" which is the area of * the window which is handled by the OS and not the application. * As such this class handles the following things: * <ul> * <li>The caption, containing the system buttons like maximize, close and such as well as * allowing the user to drag the window around.</li> - * <li>The shadow - which is changing dependent on the window focus.</li> - * <li>The border around the client area (if there is one).</li> - * <li>The resize handles which allow to resize the window.</li> - * </ul> * After creating the view, the function * {@link #setPhoneWindow} needs to be called to make * the connection to it's owning PhoneWindow. @@ -62,12 +56,7 @@ import com.android.internal.policy.PhoneWindow; public class NonClientDecorView extends LinearLayout 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; - // The height of a window which has not in DIP. - private final int DECOR_SHADOW_UNFOCUSED_HEIGHT_IN_DIP = 5; private PhoneWindow mOwner = null; - private boolean mWindowHasShadow = false; private boolean mShowDecor = false; // True if the window is being dragged. @@ -76,17 +65,6 @@ public class NonClientDecorView extends LinearLayout // True when the left mouse button got released while dragging. private boolean mLeftMouseButtonReleased; - // True if this window is resizable (which is currently only true when the decor is shown). - public boolean mVisible = false; - - // The current focus state of the window for updating the window elevation. - private boolean mWindowHasFocus = true; - - // Cludge to address b/22668382: Set the shadow size to the maximum so that the layer - // size calculation takes the shadow size into account. We set the elevation currently - // to max until the first layout command has been executed. - private boolean mAllowUpdateElevation = false; - public NonClientDecorView(Context context) { super(context); } @@ -99,14 +77,10 @@ public class NonClientDecorView extends LinearLayout super(context, attrs, defStyle); } - public void setPhoneWindow(PhoneWindow owner, boolean showDecor, boolean windowHasShadow) { + public void setPhoneWindow(PhoneWindow owner, boolean showDecor) { mOwner = owner; - mWindowHasShadow = windowHasShadow; mShowDecor = showDecor; updateCaptionVisibility(); - if (mWindowHasShadow) { - initializeElevation(); - } // By changing the outline provider to BOUNDS, the window can remove its // background without removing the shadow. mOwner.getDecorView().setOutlineProvider(ViewOutlineProvider.BOUNDS); @@ -164,15 +138,10 @@ public class NonClientDecorView extends LinearLayout /** * The phone window configuration has changed and the decor needs to be updated. * @param showDecor True if the decor should be shown. - * @param windowHasShadow True when the window should show a shadow. - **/ - public void onConfigurationChanged(boolean showDecor, boolean windowHasShadow) { + */ + public void onConfigurationChanged(boolean showDecor) { mShowDecor = showDecor; updateCaptionVisibility(); - if (windowHasShadow != mWindowHasShadow) { - mWindowHasShadow = windowHasShadow; - initializeElevation(); - } } @Override @@ -185,23 +154,6 @@ public class NonClientDecorView extends LinearLayout } @Override - public void onWindowFocusChanged(boolean hasWindowFocus) { - mWindowHasFocus = hasWindowFocus; - updateElevation(); - super.onWindowFocusChanged(hasWindowFocus); - } - - @Override - protected void onLayout(boolean changed, int left, int top, int right, int bottom) { - // If the application changed its SystemUI metrics, we might also have to adapt - // our shadow elevation. - updateElevation(); - mAllowUpdateElevation = true; - - super.onLayout(changed, left, top, right, bottom); - } - - @Override public void addView(View child, int index, ViewGroup.LayoutParams params) { // Make sure that we never get more then one client area in our view. if (index >= 2 || getChildCount() >= 2) { @@ -229,60 +181,6 @@ public class NonClientDecorView extends LinearLayout View caption = getChildAt(0); caption.setVisibility(invisible ? GONE : VISIBLE); caption.setOnTouchListener(this); - mVisible = !invisible; - } - - /** - * The elevation gets set for the first time and the framework needs to be informed that - * the surface layer gets created with the shadow size in mind. - **/ - private void initializeElevation() { - // TODO(skuhne): Call setMaxElevation here accordingly after b/22668382 got fixed. - mAllowUpdateElevation = false; - if (mWindowHasShadow) { - updateElevation(); - } else { - mOwner.setElevation(0); - } - } - - /** - * The shadow height gets controlled by the focus to visualize highlighted windows. - * Note: This will overwrite application elevation properties. - * Note: Windows which have (temporarily) changed their attributes to cover the SystemUI - * will get no shadow as they are expected to be "full screen". - **/ - 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 - && ((DecorView) mOwner.getDecorView()).mBackdropFrameRenderer == null) { - boolean fill = isFillingScreen(); - elevation = fill ? 0 : - (mWindowHasFocus ? DECOR_SHADOW_FOCUSED_HEIGHT_IN_DIP : - DECOR_SHADOW_UNFOCUSED_HEIGHT_IN_DIP); - // TODO(skuhne): Remove this if clause once b/22668382 got fixed. - if (!mAllowUpdateElevation && !fill) { - elevation = DECOR_SHADOW_FOCUSED_HEIGHT_IN_DIP; - } - // Convert the DP elevation into physical pixels. - elevation = dipToPx(elevation); - } - // Don't change the elevation if it didn't change since it can require some time. - if (mOwner.getDecorView().getElevation() != elevation) { - mOwner.setElevation(elevation); - } - } - - /** - * Converts a DIP measure into physical pixels. - * @param dip The dip value. - * @return Returns the number of pixels. - */ - private float dipToPx(float dip) { - return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dip, - getResources().getDisplayMetrics()); } /** |