Merge "AAPT2: Fix issue with parsing escape sequences when the parser only gives us part at a time"
diff --git a/core/java/com/android/internal/view/menu/CascadingMenuPopup.java b/core/java/com/android/internal/view/menu/CascadingMenuPopup.java
index 4c829a2..4e3e40f2 100644
--- a/core/java/com/android/internal/view/menu/CascadingMenuPopup.java
+++ b/core/java/com/android/internal/view/menu/CascadingMenuPopup.java
@@ -15,6 +15,7 @@
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
+import android.view.ViewTreeObserver;
import android.view.View.OnKeyListener;
import android.widget.AdapterView;
import android.widget.DropDownListView;
@@ -31,7 +32,8 @@
* @hide
*/
final class CascadingMenuPopup extends MenuPopup implements AdapterView.OnItemClickListener,
- MenuPresenter, OnKeyListener, PopupWindow.OnDismissListener {
+ MenuPresenter, OnKeyListener, PopupWindow.OnDismissListener,
+ ViewTreeObserver.OnGlobalLayoutListener, View.OnAttachStateChangeListener{
@Retention(RetentionPolicy.SOURCE)
@IntDef({HORIZ_POSITION_LEFT, HORIZ_POSITION_RIGHT})
public @interface HorizPosition {}
@@ -47,13 +49,15 @@
private final int mLayoutDirection;
private int mDropDownGravity = Gravity.NO_GRAVITY;
- private View mAnchor;
+ private View mAnchorView;
+ private View mShownAnchorView;
private List<DropDownListView> mListViews;
private List<MenuPopupWindow> mPopupWindows;
private List<int[]> mOffsets;
private int mPreferredPosition;
private boolean mForceShowIcon;
private Callback mPresenterCallback;
+ private ViewTreeObserver mTreeObserver;
private PopupWindow.OnDismissListener mOnDismissListener;
/**
@@ -64,7 +68,7 @@
public CascadingMenuPopup(Context context, View anchor, int popupStyleAttr,
int popupStyleRes, boolean overflowOnly) {
mContext = Preconditions.checkNotNull(context);
- mAnchor = Preconditions.checkNotNull(anchor);
+ mAnchorView = Preconditions.checkNotNull(anchor);
mPopupStyleAttr = popupStyleAttr;
mPopupStyleRes = popupStyleRes;
mOverflowOnly = overflowOnly;
@@ -94,7 +98,7 @@
mContext, null, mPopupStyleAttr, mPopupStyleRes);
popupWindow.setOnItemClickListener(this);
popupWindow.setOnDismissListener(this);
- popupWindow.setAnchorView(mAnchor);
+ popupWindow.setAnchorView(mAnchorView);
popupWindow.setDropDownGravity(mDropDownGravity);
popupWindow.setModal(true);
popupWindow.setTouchModal(false);
@@ -116,6 +120,14 @@
popupWindow.show();
mListViews.add((DropDownListView) popupWindow.getListView());
}
+
+ mShownAnchorView = mAnchorView;
+ if (mShownAnchorView != null) {
+ final boolean addGlobalListener = mTreeObserver == null;
+ mTreeObserver = mShownAnchorView.getViewTreeObserver(); // Refresh to latest
+ if (addGlobalListener) mTreeObserver.addOnGlobalLayoutListener(this);
+ mShownAnchorView.addOnAttachStateChangeListener(this);
+ }
}
@Override
@@ -160,7 +172,7 @@
lastListView.getLocationOnScreen(screenLocation);
final Rect displayFrame = new Rect();
- mAnchor.getWindowVisibleDisplayFrame(displayFrame);
+ mShownAnchorView.getWindowVisibleDisplayFrame(displayFrame);
if (mPreferredPosition == HORIZ_POSITION_RIGHT) {
final int right = screenLocation[0] + lastListView.getWidth() + nextMenuWidth;
@@ -352,6 +364,13 @@
}
if (mPopupWindows.size() == 0) {
+ if (mTreeObserver != null) {
+ if (!mTreeObserver.isAlive()) mTreeObserver =
+ mShownAnchorView.getViewTreeObserver();
+ mTreeObserver.removeGlobalOnLayoutListener(this);
+ mTreeObserver = null;
+ }
+ mShownAnchorView.removeOnAttachStateChangeListener(this);
// If every [sub]menu was dismissed, that means the whole thing was dismissed, so notify
// the owner.
mOnDismissListener.onDismiss();
@@ -379,7 +398,7 @@
@Override
public void setAnchorView(View anchor) {
- mAnchor = anchor;
+ mAnchorView = anchor;
}
@Override
@@ -391,4 +410,32 @@
public ListView getListView() {
return mListViews.size() > 0 ? mListViews.get(mListViews.size() - 1) : null;
}
+
+ @Override
+ public void onGlobalLayout() {
+ if (isShowing()) {
+ final View anchor = mShownAnchorView;
+ if (anchor == null || !anchor.isShown()) {
+ dismiss();
+ } else if (isShowing()) {
+ // Recompute window sizes and positions.
+ for (MenuPopupWindow popup : mPopupWindows) {
+ popup.show();
+ }
+ }
+ }
+ }
+
+ @Override
+ public void onViewAttachedToWindow(View v) {
+ }
+
+ @Override
+ public void onViewDetachedFromWindow(View v) {
+ if (mTreeObserver != null) {
+ if (!mTreeObserver.isAlive()) mTreeObserver = v.getViewTreeObserver();
+ mTreeObserver.removeGlobalOnLayoutListener(this);
+ }
+ v.removeOnAttachStateChangeListener(this);
+ }
}
\ No newline at end of file
diff --git a/core/java/com/android/internal/view/menu/MenuPopupHelper.java b/core/java/com/android/internal/view/menu/MenuPopupHelper.java
index e0d7fee..ea79983 100644
--- a/core/java/com/android/internal/view/menu/MenuPopupHelper.java
+++ b/core/java/com/android/internal/view/menu/MenuPopupHelper.java
@@ -16,10 +16,11 @@
package com.android.internal.view.menu;
+import com.android.internal.view.menu.MenuPresenter.Callback;
+
import android.content.Context;
import android.view.Gravity;
import android.view.View;
-import android.view.ViewTreeObserver;
import android.widget.PopupWindow;
/**
@@ -27,8 +28,7 @@
*
* @hide
*/
-public class MenuPopupHelper implements ViewTreeObserver.OnGlobalLayoutListener,
- PopupWindow.OnDismissListener, View.OnAttachStateChangeListener {
+public class MenuPopupHelper implements PopupWindow.OnDismissListener {
private final Context mContext;
private final MenuBuilder mMenu;
private final boolean mOverflowOnly;
@@ -37,9 +37,9 @@
private View mAnchorView;
private MenuPopup mPopup;
- private ViewTreeObserver mTreeObserver;
private int mDropDownGravity = Gravity.NO_GRAVITY;
+ private Callback mPresenterCallback;
public MenuPopupHelper(Context context, MenuBuilder menu) {
this(context, menu, null, false, com.android.internal.R.attr.popupMenuStyle, 0);
@@ -114,18 +114,15 @@
return true;
}
- final View anchor = mAnchorView;
- if (anchor != null) {
- final boolean addGlobalListener = mTreeObserver == null;
- mTreeObserver = anchor.getViewTreeObserver(); // Refresh to latest
- if (addGlobalListener) mTreeObserver.addOnGlobalLayoutListener(this);
- anchor.addOnAttachStateChangeListener(this);
- mPopup.setAnchorView(anchor);
- mPopup.setGravity(mDropDownGravity);
- } else {
+ if (mAnchorView == null) {
return false;
}
+ mPopup = createMenuPopup();
+ mPopup.setAnchorView(mAnchorView);
+ mPopup.setGravity(mDropDownGravity);
+ mPopup.setCallback(mPresenterCallback);
+
// In order for subclasses of MenuPopupHelper to satisfy the OnDismissedListener interface,
// we must set the listener to this outer Helper rather than to the inner MenuPopup.
// Not to worry -- the inner MenuPopup will call our own #onDismiss method after it's done
@@ -146,45 +143,15 @@
@Override
public void onDismiss() {
mPopup = null;
- if (mTreeObserver != null) {
- if (!mTreeObserver.isAlive()) mTreeObserver = mAnchorView.getViewTreeObserver();
- mTreeObserver.removeGlobalOnLayoutListener(this);
- mTreeObserver = null;
- }
- mAnchorView.removeOnAttachStateChangeListener(this);
}
public boolean isShowing() {
return mPopup != null && mPopup.isShowing();
}
- @Override
- public void onGlobalLayout() {
- if (isShowing()) {
- final View anchor = mAnchorView;
- if (anchor == null || !anchor.isShown()) {
- dismiss();
- } else if (isShowing()) {
- // Recompute window size and position
- mPopup.show();
- }
- }
- }
-
- @Override
- public void onViewAttachedToWindow(View v) {
- }
-
- @Override
- public void onViewDetachedFromWindow(View v) {
- if (mTreeObserver != null) {
- if (!mTreeObserver.isAlive()) mTreeObserver = v.getViewTreeObserver();
- mTreeObserver.removeGlobalOnLayoutListener(this);
- }
- v.removeOnAttachStateChangeListener(this);
- }
public void setCallback(MenuPresenter.Callback cb) {
+ mPresenterCallback = cb;
mPopup.setCallback(cb);
}
}
diff --git a/core/java/com/android/internal/view/menu/StandardMenuPopup.java b/core/java/com/android/internal/view/menu/StandardMenuPopup.java
index 9a30ffa..530b16a 100644
--- a/core/java/com/android/internal/view/menu/StandardMenuPopup.java
+++ b/core/java/com/android/internal/view/menu/StandardMenuPopup.java
@@ -10,6 +10,7 @@
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnKeyListener;
+import android.view.ViewTreeObserver;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.MenuPopupWindow;
@@ -24,7 +25,8 @@
* viewport.
*/
final class StandardMenuPopup extends MenuPopup implements OnDismissListener, OnItemClickListener,
- MenuPresenter, OnKeyListener {
+ MenuPresenter, OnKeyListener, ViewTreeObserver.OnGlobalLayoutListener,
+ View.OnAttachStateChangeListener {
private final Context mContext;
private final LayoutInflater mInflater;
@@ -34,15 +36,22 @@
private final int mPopupMaxWidth;
private final int mPopupStyleAttr;
private final int mPopupStyleRes;
+ // The popup window is final in order to couple its lifecycle to the lifecycle of the
+ // StandardMenuPopup.
+ private final MenuPopupWindow mPopup;
private PopupWindow.OnDismissListener mOnDismissListener;
private View mAnchorView;
- private MenuPopupWindow mPopup;
+ private View mShownAnchorView;
private Callback mPresenterCallback;
+ private ViewTreeObserver mTreeObserver;
private ViewGroup mMeasureParent;
+ /** Whether the popup has been dismissed. Once dismissed, it cannot be opened again. */
+ private boolean wasDismissed;
+
/** Whether the cached content width value is valid. */
private boolean mHasContentWidth;
@@ -88,18 +97,26 @@
return true;
}
+ if (mAnchorView == null) {
+ return false;
+ }
+
+ mShownAnchorView = mAnchorView;
+
mPopup.setOnDismissListener(this);
mPopup.setOnItemClickListener(this);
mPopup.setAdapter(mAdapter);
mPopup.setModal(true);
- final View anchor = mAnchorView;
- if (anchor != null) {
- mPopup.setAnchorView(anchor);
- mPopup.setDropDownGravity(mDropDownGravity);
- } else {
- return false;
+ final View anchor = mShownAnchorView;
+ final boolean addGlobalListener = mTreeObserver == null;
+ mTreeObserver = anchor.getViewTreeObserver(); // Refresh to latest
+ if (addGlobalListener) {
+ mTreeObserver.addOnGlobalLayoutListener(this);
}
+ anchor.addOnAttachStateChangeListener(this);
+ mPopup.setAnchorView(anchor);
+ mPopup.setDropDownGravity(mDropDownGravity);
if (!mHasContentWidth) {
mContentWidth = measureIndividualMenuWidth(
@@ -141,14 +158,20 @@
@Override
public boolean isShowing() {
- return mPopup != null && mPopup.isShowing();
+ return !wasDismissed && mPopup.isShowing();
}
@Override
public void onDismiss() {
- mPopup = null;
+ wasDismissed = true;
mMenu.close();
+ if (mTreeObserver != null) {
+ if (!mTreeObserver.isAlive()) mTreeObserver = mShownAnchorView.getViewTreeObserver();
+ mTreeObserver.removeGlobalOnLayoutListener(this);
+ mTreeObserver = null;
+ }
+ mShownAnchorView.removeOnAttachStateChangeListener(this);
mOnDismissListener.onDismiss();
}
@@ -170,7 +193,8 @@
public boolean onSubMenuSelected(SubMenuBuilder subMenu) {
if (subMenu.hasVisibleItems()) {
MenuPopupHelper subPopup = new MenuPopupHelper(
- mContext, subMenu, mAnchorView, mOverflowOnly, mPopupStyleAttr, mPopupStyleRes);
+ mContext, subMenu, mShownAnchorView, mOverflowOnly, mPopupStyleAttr,
+ mPopupStyleRes);
subPopup.setCallback(mPresenterCallback);
boolean preserveIconSpacing = false;
@@ -243,4 +267,30 @@
public ListView getListView() {
return mPopup.getListView();
}
+
+ @Override
+ public void onGlobalLayout() {
+ if (isShowing()) {
+ final View anchor = mShownAnchorView;
+ if (anchor == null || !anchor.isShown()) {
+ dismiss();
+ } else if (isShowing()) {
+ // Recompute window size and position
+ mPopup.show();
+ }
+ }
+ }
+
+ @Override
+ public void onViewAttachedToWindow(View v) {
+ }
+
+ @Override
+ public void onViewDetachedFromWindow(View v) {
+ if (mTreeObserver != null) {
+ if (!mTreeObserver.isAlive()) mTreeObserver = v.getViewTreeObserver();
+ mTreeObserver.removeGlobalOnLayoutListener(this);
+ }
+ v.removeOnAttachStateChangeListener(this);
+ }
}
\ No newline at end of file
diff --git a/packages/DocumentsUI/res/color/item_doc_grid_overlay.xml b/packages/DocumentsUI/res/color/item_doc_grid_overlay.xml
index 6959c65..6dcbb38 100644
--- a/packages/DocumentsUI/res/color/item_doc_grid_overlay.xml
+++ b/packages/DocumentsUI/res/color/item_doc_grid_overlay.xml
@@ -17,7 +17,8 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_activated="true"
- android:color="?android:attr/colorControlHighlight" />
+ android:color="?android:attr/colorAccent"
+ android:alpha="0.1" />
<item
android:state_enabled="false"
android:color="?android:attr/colorBackground"
diff --git a/packages/DocumentsUI/res/values/attrs.xml b/packages/DocumentsUI/res/values/attrs.xml
new file mode 100644
index 0000000..0afc3a2
--- /dev/null
+++ b/packages/DocumentsUI/res/values/attrs.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 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.
+-->
+<resources>
+ <declare-styleable name="DocumentsBaseTheme">
+ <attr name="colorActionMode" format="color"/>
+ </declare-styleable>
+</resources>
diff --git a/packages/DocumentsUI/res/values/colors.xml b/packages/DocumentsUI/res/values/colors.xml
index 6002dde..cb6957d 100644
--- a/packages/DocumentsUI/res/values/colors.xml
+++ b/packages/DocumentsUI/res/values/colors.xml
@@ -19,18 +19,20 @@
<color name="material_grey_300">#ffeeeeee</color>
<color name="material_grey_600">#ff757575</color>
<color name="material_grey_800">#ff424242</color>
- <color name="material_blue_700">#ff1976d2</color>
- <color name="material_blue_500">#ff2196f3</color>
<color name="primary_dark">@*android:color/material_blue_grey_900</color>
<color name="primary">@*android:color/material_blue_grey_800</color>
<color name="accent">@*android:color/material_deep_teal_500</color>
+ <color name="platform_blue_100">#ffd0d9ff</color>
+ <color name="platform_blue_500">#ff5677fc</color>
+ <color name="platform_blue_700">#ff455ede</color>
+ <color name="platform_blue_a100">#ffa6baff</color>
+ <color name="platform_blue_a200">#ffff5177</color>
+
<color name="directory_background">@color/material_grey_300</color>
<color name="item_doc_grid_background">#FFFFFFFF</color>
<color name="item_doc_grid_protect_background">#88000000</color>
- <color name="status_bar_background">@color/material_blue_700</color>
- <color name="action_mode_status_bar_background">@color/material_grey_800</color>
<color name="band_select_background">#88ffffff</color>
<color name="band_select_border">#44000000</color>
</resources>
diff --git a/packages/DocumentsUI/res/values/styles.xml b/packages/DocumentsUI/res/values/styles.xml
index e67f956..8301816 100644
--- a/packages/DocumentsUI/res/values/styles.xml
+++ b/packages/DocumentsUI/res/values/styles.xml
@@ -28,6 +28,7 @@
<item name="android:colorPrimaryDark">@color/primary_dark</item>
<item name="android:colorPrimary">@color/primary</item>
<item name="android:colorAccent">@color/accent</item>
+ <item name="colorActionMode">@color/material_grey_800</item>
<item name="android:listDivider">@*android:drawable/list_divider_material</item>
@@ -43,6 +44,7 @@
<item name="actionBarWidgetTheme">@null</item>
<item name="actionBarTheme">@style/ActionBarTheme</item>
<item name="actionBarPopupTheme">@style/ActionBarPopupTheme</item>
+ <item name="colorActionMode">@color/material_grey_800</item>
<item name="android:listDivider">@*android:drawable/list_divider_material</item>
@@ -68,16 +70,21 @@
</style>
<style name="AlertDialogTheme" parent="@android:style/Theme.Material.Light.Dialog.Alert">
- <item name="android:colorAccent">@color/material_blue_700</item>
+ <item name="android:colorAccent">@color/platform_blue_700</item>
</style>
<style name="FilesTheme" parent="@style/DocumentsBaseTheme.FullScreen">
- <item name="android:colorPrimaryDark">@color/material_blue_700</item>
- <item name="android:colorPrimary">@color/material_blue_500</item>
- <item name="android:colorAccent">@color/material_blue_700</item>
- <item name="android:actionModeStyle">@style/ActionModeStyle</item>
+ <item name="android:colorPrimaryDark">@color/platform_blue_700</item>
+ <item name="android:colorPrimary">@color/platform_blue_500</item>
+ <item name="android:colorAccent">@color/platform_blue_700</item>
+ <item name="android:actionModeStyle">@style/FilesActionModeStyle</item>
+ <item name="colorActionMode">@color/platform_blue_700</item>
<item name="android:alertDialogTheme">@style/AlertDialogTheme</item>
</style>
+ <style name="FilesActionModeStyle" parent="@android:style/Widget.Material.Light.ActionMode">
+ <item name="android:background">@color/platform_blue_100</item>
+ </style>
+
</resources>
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
index cfd4ecb..046f3df 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
@@ -637,27 +637,25 @@
@Override
public void onSelectionChanged() {
mModel.getSelection(mSelected);
+ TypedValue color = new TypedValue();
if (mSelected.size() > 0) {
if (DEBUG) Log.d(TAG, "Maybe starting action mode.");
if (mActionMode == null) {
if (DEBUG) Log.d(TAG, "Yeah. Starting action mode.");
mActionMode = getActivity().startActionMode(this);
- getActivity().getWindow().setStatusBarColor(
- getResources().getColor(R.color.action_mode_status_bar_background));
}
+ getActivity().getTheme().resolveAttribute(
+ R.attr.colorActionMode, color, true);
updateActionMenu();
} else {
if (DEBUG) Log.d(TAG, "Finishing action mode.");
if (mActionMode != null) {
mActionMode.finish();
}
- // Obtain the original status bar color from the theme, and restore it.
- TypedValue color = new TypedValue();
getActivity().getTheme().resolveAttribute(
android.R.attr.colorPrimaryDark, color, true);
- getActivity().getWindow().setStatusBarColor(color.data);
-
}
+ getActivity().getWindow().setStatusBarColor(color.data);
if (mActionMode != null) {
mActionMode.setTitle(TextUtils.formatSelectedCount(mSelected.size()));
diff --git a/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java b/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java
index 8f9025a..450def7 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java
@@ -90,10 +90,6 @@
mClipper = new DocumentClipper(this);
mDrawer = DrawerController.create(this);
- if (mDrawer.isPresent()) {
- setTheme(R.style.DocumentsNonDialogTheme);
- }
-
RootsFragment.show(getFragmentManager(), null);
if (!mState.restored) {
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 325196d..bfeddb3 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -234,7 +234,7 @@
for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
final Task task = tasks.get(taskNdx);
task.getBounds(mTmpRect);
- if (mTmpRect.contains(x, y)) {
+ if (task.inFreeformWorkspace() && mTmpRect.contains(x, y)) {
return task.mTaskId;
}
}
@@ -299,7 +299,7 @@
* (For freeform focused task, the below logic will first remove the enlarged
* area, then add back the inner area.)
*/
- final boolean isFreeformed = win.inFreeformWorkspace();
+ final boolean isFreeformed = task.inFreeformWorkspace();
if (task != focusedTask || isFreeformed) {
mTmpRect.set(win.mVisibleFrame);
mTmpRect.intersect(win.mVisibleInsets);
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 07a850b..cc9efdb 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -426,6 +426,10 @@
return (tokensCount != 0) && mAppTokens.get(tokensCount - 1).showForAllUsers;
}
+ boolean inFreeformWorkspace() {
+ return mStack != null && mStack.mStackId == FREEFORM_WORKSPACE_STACK_ID;
+ }
+
@Override
public boolean isFullscreen() {
return mFullscreen;
diff --git a/services/core/java/com/android/server/wm/TaskPositioner.java b/services/core/java/com/android/server/wm/TaskPositioner.java
index 6e4d1c3..8d377fd 100644
--- a/services/core/java/com/android/server/wm/TaskPositioner.java
+++ b/services/core/java/com/android/server/wm/TaskPositioner.java
@@ -85,6 +85,7 @@
private int mTaskId;
private TaskStack mStack;
+ private boolean mResizing;
private final Rect mWindowOriginalBounds = new Rect();
private final Rect mWindowDragBounds = new Rect();
private float mStartDragX;
@@ -131,8 +132,8 @@
notifyMoveLocked(newX, newY);
}
try {
- mService.mActivityManager.resizeTask(mTaskId, mWindowDragBounds,
- true /* resizedByUser */);
+ mService.mActivityManager.resizeTask(
+ mTaskId, mWindowDragBounds, true /* resizedByUser */);
} catch(RemoteException e) {}
} break;
@@ -152,6 +153,11 @@
}
if (endDrag) {
+ mResizing = false;
+ try {
+ mService.mActivityManager.resizeTask(
+ mTaskId, mWindowDragBounds, true /* resizedByUser */);
+ } catch(RemoteException e) {}
// Post back to WM to handle clean-ups. We still need the input
// event handler for the last finishInputEvent()!
mService.mH.sendEmptyMessage(H.FINISH_TASK_POSITIONING);
@@ -280,6 +286,10 @@
mService.resumeRotationLocked();
}
+ boolean isTaskResizing(final Task task) {
+ return mResizing && task != null && mTaskId == task.mTaskId;
+ }
+
void startDragLocked(WindowState win, boolean resize, float startX, float startY) {
if (DEBUG_TASK_POSITIONING) {
Slog.d(TAG, "startDragLocked: win=" + win + ", resize=" + resize
@@ -300,6 +310,7 @@
if (startY > visibleFrame.bottom) {
mCtrlType |= CTRL_BOTTOM;
}
+ mResizing = true;
}
final Task task = win.getTask();
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 789354d..e467b19 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -557,7 +557,7 @@
final Task task = mAppToken != null ? getTask() : null;
final boolean nonFullscreenTask = task != null && !task.isFullscreen();
- final boolean freeformWorkspace = inFreeformWorkspace();
+ final boolean freeformWorkspace = task != null && task.inFreeformWorkspace();
if (nonFullscreenTask) {
task.getBounds(mContainingFrame);
final WindowState imeWin = mService.mInputMethodWindow;
@@ -897,6 +897,11 @@
return stack == null ? mDisplayContent : stack.getDisplayContent();
}
+ public DisplayInfo getDisplayInfo() {
+ final DisplayContent displayContent = getDisplayContent();
+ return displayContent != null ? displayContent.getDisplayInfo() : null;
+ }
+
public int getDisplayId() {
final DisplayContent displayContent = getDisplayContent();
if (displayContent == null) {
@@ -935,7 +940,7 @@
if (task != null) {
task.getBounds(bounds);
if (forTouch == BOUNDS_FOR_TOUCH) {
- if (inFreeformWorkspace()) {
+ if (task.inFreeformWorkspace()) {
final int delta = calculatePixelFromDp(RESIZE_HANDLE_WIDTH_IN_DP);
bounds.inset(-delta, -delta);
}
@@ -1668,9 +1673,13 @@
}
boolean inFreeformWorkspace() {
- final Task task = getTask();
- return task != null && task.mStack != null &&
- task.mStack.mStackId == FREEFORM_WORKSPACE_STACK_ID;
+ final Task task = mAppToken != null ? getTask() : null;
+ return task != null && task.inFreeformWorkspace();
+ }
+
+ boolean isDragResizing() {
+ final Task task = mAppToken != null ? getTask() : null;
+ return mService.mTaskPositioner != null && mService.mTaskPositioner.isTaskResizing(task);
}
private int calculatePixelFromDp(int dp) {
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 0ab96d6..dfc9784 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -804,8 +804,17 @@
width = w.mRequestedWidth;
height = w.mRequestedHeight;
} else {
- width = w.mCompatFrame.width();
- height = w.mCompatFrame.height();
+ // When we're doing a drag-resizing, request a surface that's fullscreen size,
+ // so that we don't need to reallocate during the process. This also prevents
+ // buffer drops due to size mismatch.
+ final DisplayInfo displayInfo = w.getDisplayInfo();
+ if (displayInfo != null && w.isDragResizing()) {
+ width = displayInfo.logicalWidth;
+ height = displayInfo.logicalHeight;
+ } else {
+ width = w.mCompatFrame.width();
+ height = w.mCompatFrame.height();
+ }
}
// Something is wrong and SurfaceFlinger will not like this,
@@ -1315,9 +1324,15 @@
final boolean fullscreen = w.isFullscreen(displayInfo.appWidth, displayInfo.appHeight);
final Rect clipRect = mTmpClipRect;
- // We use the clip rect as provided by the tranformation for non-fullscreen windows to
- // avoid premature clipping with the system decor rect.
- clipRect.set((mHasClipRect && !fullscreen) ? mClipRect : w.mSystemDecorRect);
+ if (w.isDragResizing()) {
+ // When we're doing a drag-resizing, the surface is set up to cover full screen.
+ // Set the clip rect to be the same size so that we don't get any scaling.
+ clipRect.set(0, 0, displayInfo.logicalWidth, displayInfo.logicalHeight);
+ } else {
+ // We use the clip rect as provided by the tranformation for non-fullscreen windows to
+ // avoid premature clipping with the system decor rect.
+ clipRect.set((mHasClipRect && !fullscreen) ? mClipRect : w.mSystemDecorRect);
+ }
// Expand the clip rect for surface insets.
final WindowManager.LayoutParams attrs = w.mAttrs;
@@ -1391,8 +1406,17 @@
width = w.mRequestedWidth;
height = w.mRequestedHeight;
} else {
- width = w.mCompatFrame.width();
- height = w.mCompatFrame.height();
+ // When we're doing a drag-resizing, request a surface that's fullscreen size,
+ // so that we don't need to reallocate during the process. This also prevents
+ // buffer drops due to size mismatch.
+ final DisplayInfo displayInfo = w.getDisplayInfo();
+ if (displayInfo != null && w.isDragResizing()) {
+ width = displayInfo.logicalWidth;
+ height = displayInfo.logicalHeight;
+ } else {
+ width = w.mCompatFrame.width();
+ height = w.mCompatFrame.height();
+ }
}
// Something is wrong and SurfaceFlinger will not like this,
diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
index 52efa68..86da94f 100644
--- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
+++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
@@ -712,7 +712,12 @@
}
}
}
-
+ /*
+ * Updates the shown frame before we set up the surface. This is needed because
+ * the resizing could change the top-left position (in addition to size) of the
+ * window. setSurfaceBoundariesLocked uses mShownFrame to position the surface.
+ */
+ winAnimator.computeShownFrameLocked();
winAnimator.setSurfaceBoundariesLocked(recoveringMemory);
}