import com.android.internal.view.menu.MenuPopupHelper;
import com.android.internal.widget.ActionBarContextView;
import com.android.internal.widget.BackgroundFallback;
+import com.android.internal.widget.DecorCaptionView;
import com.android.internal.widget.FloatingToolbar;
-import com.android.internal.widget.NonClientDecorView;
import android.animation.Animator;
import android.animation.ObjectAnimator;
private final Rect mFrameOffsets = new Rect();
- // True if a non client area decor exists.
- private boolean mHasNonClientDecor = false;
+ private boolean mHasCaption = false;
private boolean mChanging;
private Rect mTempRect;
private Rect mOutsets = new Rect();
- // This is the non client decor view for the window, containing the caption and window control
+ // This is the caption view for the window, containing the caption and window control
// buttons. The visibility of this decor depends on the workspace and the window type.
// If the window type does not require such a view, this member might be null.
- NonClientDecorView mNonClientDecorView;
+ DecorCaptionView mDecorCaptionView;
- // The non client decor needs to adapt to the used workspace. Since querying and changing the
- // workspace is expensive, this is the workspace value the window is currently set up for.
- int mWorkspaceId;
+ // Stack window is currently in. Since querying and changing the stack is expensive,
+ // this is the stack value the window is currently set up for.
+ int mStackId;
private boolean mWindowResizeCallbacksAdded = false;
- public BackdropFrameRenderer mBackdropFrameRenderer = null;
+ BackdropFrameRenderer mBackdropFrameRenderer = null;
private Drawable mResizingBackgroundDrawable;
private Drawable mCaptionBackgroundDrawable;
setWindow(window);
}
- public void setBackgroundFallback(int resId) {
+ void setBackgroundFallback(int resId) {
mBackgroundFallback.setDrawable(resId != 0 ? getContext().getDrawable(resId) : null);
setWillNotDraw(getBackground() == null && !mBackgroundFallback.hasFallback());
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
int action = event.getAction();
- 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.
+ if (mHasCaption && isShowingCaption()) {
+ // Don't dispatch ACTION_DOWN to the captionr if the window is resizable and the event
+ // was (starting) outside the window. Window resizing events should be handled by
+ // WindowManager.
// TODO: Investigate how to handle the outside touch in window manager
// without generating these events.
// Currently we receive these because we need to enlarge the window's
}
}
- public void startChanging() {
+ void startChanging() {
mChanging = true;
}
- public void finishChanging() {
+ void finishChanging() {
mChanging = false;
drawableChanged();
}
invalidate();
int opacity = PixelFormat.OPAQUE;
- if (windowHasShadow()) {
+ if (ActivityManager.StackId.hasWindowShadow(mStackId)) {
// If the window has a shadow, it must be translucent.
opacity = PixelFormat.TRANSLUCENT;
} else{
}
/**
- * Informs the decor if a non client decor is attached and visible.
+ * Informs the decor if the caption is attached and visible.
* @param attachedAndVisible true when the decor is visible.
- * Note that this will even be called if there is no non client decor.
+ * Note that this will even be called if there is no caption.
**/
- void enableNonClientDecor(boolean attachedAndVisible) {
- if (mHasNonClientDecor != attachedAndVisible) {
- mHasNonClientDecor = attachedAndVisible;
+ void enableCaption(boolean attachedAndVisible) {
+ if (mHasCaption != attachedAndVisible) {
+ mHasCaption = attachedAndVisible;
if (getForeground() != null) {
drawableChanged();
}
}
}
- /**
- * Returns true if the window has a non client decor.
- * @return If there is a non client decor - even if it is not visible.
- **/
- private boolean windowHasNonClientDecor() {
- return mHasNonClientDecor;
- }
-
- /**
- * Returns true if the Window is free floating and has a shadow (although at some times
- * it might not be displaying it, e.g. during a resize). Note that non overlapping windows
- * do not have a shadow since it could not be seen anyways (a small screen / tablet
- * "tiles" the windows side by side but does not overlap them).
- * @return Returns true when the window has a shadow created by the non client decor.
- **/
- private boolean windowHasShadow() {
- return windowHasNonClientDecor() && ActivityManager.StackId.hasWindowShadow(mWorkspaceId);
- }
-
void setWindow(PhoneWindow phoneWindow) {
mWindow = phoneWindow;
Context context = getContext();
}
void onConfigurationChanged() {
- int workspaceId = getWorkspaceId();
- if (mNonClientDecorView != null) {
- if (mWorkspaceId != workspaceId) {
- mWorkspaceId = workspaceId;
+ int workspaceId = getStackId();
+ if (mDecorCaptionView != null) {
+ if (mStackId != workspaceId) {
+ mStackId = workspaceId;
// We might have to change the kind of surface before we do anything else.
- mNonClientDecorView.onConfigurationChanged(
- ActivityManager.StackId.hasWindowDecor(mWorkspaceId));
- enableNonClientDecor(ActivityManager.StackId.hasWindowDecor(workspaceId));
+ mDecorCaptionView.onConfigurationChanged(
+ ActivityManager.StackId.hasWindowDecor(mStackId));
+ enableCaption(ActivityManager.StackId.hasWindowDecor(workspaceId));
}
}
initializeElevation();
}
View onResourcesLoaded(LayoutInflater inflater, int layoutResource) {
- mWorkspaceId = getWorkspaceId();
+ mStackId = getStackId();
mResizingBackgroundDrawable = getResizingBackgroundDrawable(
mWindow.mBackgroundResource, mWindow.mBackgroundFallbackResource);
mCaptionBackgroundDrawable =
- getContext().getDrawable(R.drawable.non_client_decor_title_focused);
+ getContext().getDrawable(R.drawable.decor_caption_title_focused);
if (mBackdropFrameRenderer != null) {
mBackdropFrameRenderer.onResourcesLoaded(
this, mResizingBackgroundDrawable, mCaptionBackgroundDrawable);
}
- mNonClientDecorView = createNonClientDecorView(inflater);
+ mDecorCaptionView = createDecorCaptionView(inflater);
final View root = inflater.inflate(layoutResource, null);
- if (mNonClientDecorView != null) {
- if (mNonClientDecorView.getParent() == null) {
- addView(mNonClientDecorView,
+ if (mDecorCaptionView != null) {
+ if (mDecorCaptionView.getParent() == null) {
+ addView(mDecorCaptionView,
new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
}
- mNonClientDecorView.addView(root,
+ mDecorCaptionView.addView(root,
new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
} else {
addView(root, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
return root;
}
- // Free floating overlapping windows require a non client decor with a caption and shadow..
- private NonClientDecorView createNonClientDecorView(LayoutInflater inflater) {
- NonClientDecorView nonClientDecorView = null;
- for (int i = getChildCount() - 1; i >= 0 && nonClientDecorView == null; i--) {
+ // Free floating overlapping windows require a caption.
+ private DecorCaptionView createDecorCaptionView(LayoutInflater inflater) {
+ DecorCaptionView DecorCaptionView = null;
+ for (int i = getChildCount() - 1; i >= 0 && DecorCaptionView == null; i--) {
View view = getChildAt(i);
- if (view instanceof NonClientDecorView) {
+ if (view instanceof DecorCaptionView) {
// The decor was most likely saved from a relaunch - so reuse it.
- nonClientDecorView = (NonClientDecorView) view;
+ DecorCaptionView = (DecorCaptionView) view;
removeViewAt(i);
}
}
final WindowManager.LayoutParams attrs = mWindow.getAttributes();
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.
+ // Only a non floating application window on one of the allowed workspaces can get a caption
if (!mWindow.isFloating() && isApplication
- && ActivityManager.StackId.hasWindowDecor(mWorkspaceId)) {
+ && ActivityManager.StackId.hasWindowDecor(mStackId)) {
// Dependent on the brightness of the used title we either use the
// dark or the light button frame.
- if (nonClientDecorView == null) {
+ if (DecorCaptionView == null) {
Context context = getContext();
TypedValue value = new TypedValue();
context.getTheme().resolveAttribute(R.attr.colorPrimary, value, true);
inflater = inflater.from(context);
if (Color.luminance(value.data) < 0.5) {
- nonClientDecorView = (NonClientDecorView) inflater.inflate(
- R.layout.non_client_decor_dark, null);
+ DecorCaptionView = (DecorCaptionView) inflater.inflate(
+ R.layout.decor_caption_dark, null);
} else {
- nonClientDecorView = (NonClientDecorView) inflater.inflate(
- R.layout.non_client_decor_light, null);
+ DecorCaptionView = (DecorCaptionView) inflater.inflate(
+ R.layout.decor_caption_light, null);
}
}
- nonClientDecorView.setPhoneWindow(mWindow, true /*showDecor*/);
+ DecorCaptionView.setPhoneWindow(mWindow, true /*showDecor*/);
} else {
- nonClientDecorView = null;
+ DecorCaptionView = null;
}
- // Tell the decor if it has a visible non client decor.
- enableNonClientDecor(nonClientDecorView != null);
- return nonClientDecorView;
+ // Tell the decor if it has a visible caption.
+ enableCaption(DecorCaptionView != null);
+ return DecorCaptionView;
}
/**
}
/**
- * Returns the Id of the workspace which contains this window.
- * Note that if no workspace can be determined - which usually means that it was not
- * created for an activity - the fullscreen workspace ID will be returned.
- * @return Returns the workspace stack id which contains this window.
+ * Returns the Id of the stack which contains this window.
+ * Note that if no stack can be determined - which usually means that it was not
+ * created for an activity - the fullscreen stack ID will be returned.
+ * @return Returns the stack id which contains this window.
**/
- private int getWorkspaceId() {
+ private int getStackId() {
int workspaceId = INVALID_STACK_ID;
final Window.WindowControllerCallback callback = mWindow.getWindowControllerCallback();
if (callback != null) {
}
void clearContentView() {
- if (mNonClientDecorView != null) {
- if (mNonClientDecorView.getChildCount() > 1) {
- mNonClientDecorView.removeViewAt(1);
+ if (mDecorCaptionView != null) {
+ if (mDecorCaptionView.getChildCount() > 1) {
+ mDecorCaptionView.removeViewAt(1);
}
} else {
- // This window doesn't have non client decor, so we need to just remove the
+ // This window doesn't have caption, so we need to just remove the
// children of the decor view.
removeAllViews();
}
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)
+ if (ActivityManager.StackId.hasWindowShadow(mStackId)
&& mBackdropFrameRenderer == null) {
elevation = hasWindowFocus() ?
DECOR_SHADOW_FOCUSED_HEIGHT_IN_DIP : DECOR_SHADOW_UNFOCUSED_HEIGHT_IN_DIP;
}
boolean isShowingCaption() {
- return mNonClientDecorView != null && mNonClientDecorView.isShowingDecor();
+ return mDecorCaptionView != null && mDecorCaptionView.isCaptionShowing();
}
int getCaptionHeight() {
- return isShowingCaption() ? mNonClientDecorView.getDecorCaptionHeight() : 0;
+ return isShowingCaption() ? mDecorCaptionView.getCaptionHeight() : 0;
}
/**
import com.android.internal.policy.PhoneWindow;
/**
- * This class represents the special screen elements to control a window on free form
- * 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.
+ * This class represents the special screen elements to control a window on freeform
+ * environment.
* As such this class handles the following things:
* <ul>
* <li>The caption, containing the system buttons like maximize, close and such as well as
* Note: At this time the application can change various attributes of the DecorView which
* will break things (in settle/unexpected ways):
* <ul>
- * <li>setElevation</li>
* <li>setOutlineProvider</li>
* <li>setSurfaceFormat</li>
* <li>..</li>
* </ul>
- * This will be mitigated once b/22527834 will be addressed.
*/
-public class NonClientDecorView extends LinearLayout
+public class DecorCaptionView extends LinearLayout
implements View.OnClickListener, View.OnTouchListener {
- private final static String TAG = "NonClientDecorView";
+ private final static String TAG = "DecorCaptionView";
private PhoneWindow mOwner = null;
- private boolean mShowDecor = false;
+ private boolean mShow = false;
// True if the window is being dragged.
private boolean mDragging = false;
// True when the left mouse button got released while dragging.
private boolean mLeftMouseButtonReleased;
- public NonClientDecorView(Context context) {
+ public DecorCaptionView(Context context) {
super(context);
}
- public NonClientDecorView(Context context, AttributeSet attrs) {
+ public DecorCaptionView(Context context, AttributeSet attrs) {
super(context, attrs);
}
- public NonClientDecorView(Context context, AttributeSet attrs, int defStyle) {
+ public DecorCaptionView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
- public void setPhoneWindow(PhoneWindow owner, boolean showDecor) {
+ public void setPhoneWindow(PhoneWindow owner, boolean show) {
mOwner = owner;
- mShowDecor = showDecor;
+ mShow = show;
updateCaptionVisibility();
// By changing the outline provider to BOUNDS, the window can remove its
// background without removing the shadow.
// input device we are listening to.
switch (e.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
- if (!mShowDecor) {
- // When there is no decor we should not react to anything.
+ if (!mShow) {
+ // When there is no caption we should not react to anything.
return false;
}
// A drag action is started if we aren't dragging already and the starting event is
}
/**
- * The phone window configuration has changed and the decor needs to be updated.
- * @param showDecor True if the decor should be shown.
+ * The phone window configuration has changed and the caption needs to be updated.
+ * @param show True if the caption should be shown.
*/
- public void onConfigurationChanged(boolean showDecor) {
- mShowDecor = showDecor;
+ public void onConfigurationChanged(boolean show) {
+ mShow = show;
updateCaptionVisibility();
}
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) {
- throw new IllegalStateException("NonClientDecorView can only handle 1 client view");
+ throw new IllegalStateException("DecorCaptionView can only handle 1 client view");
}
super.addView(child, index, params);
}
* Updates the visibility of the caption.
**/
private void updateCaptionVisibility() {
- // Don't show the decor if the window has e.g. entered full screen.
- boolean invisible = isFillingScreen() || !mShowDecor;
+ // Don't show the caption if the window has e.g. entered full screen.
+ boolean invisible = isFillingScreen() || !mShow;
View caption = getChildAt(0);
caption.setVisibility(invisible ? GONE : VISIBLE);
caption.setOnTouchListener(this);
}
}
- public boolean isShowingDecor() {
- return mShowDecor;
+ public boolean isCaptionShowing() {
+ return mShow;
}
- public int getDecorCaptionHeight() {
+ public int getCaptionHeight() {
final View caption = getChildAt(0);
return (caption != null) ? caption.getHeight() : 0;
}