summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Tracy Zhou <tracyzhou@google.com> 2018-03-19 20:15:14 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2018-03-19 20:15:14 +0000
commit017f44be88d68b721d443ee91f5436e1431fec53 (patch)
treeedfb975aa87de1c6762e249b229b17200d07c7b0
parente24c95fac5a6fe179c7d1dd61e88bf4ce501f619 (diff)
parent43513086d28f0e35a08b46de4f2c3373266763a1 (diff)
Merge "Move default pip position to right above the shelf." into pi-dev
-rw-r--r--core/java/android/app/ActivityManagerInternal.java6
-rw-r--r--core/java/android/view/IPinnedStackListener.aidl12
-rw-r--r--core/java/android/view/IWindowManager.aidl11
-rw-r--r--core/java/com/android/internal/policy/PipSnapAlgorithm.java4
-rw-r--r--core/res/res/values/config.xml4
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java70
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java6
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java7
-rw-r--r--services/core/java/com/android/server/wm/PinnedStackController.java64
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java10
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/PinnedStackControllerTest.java63
14 files changed, 229 insertions, 59 deletions
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index 2752fa9f1eb3..db9d9234aeb8 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -385,4 +385,10 @@ public abstract class ActivityManagerInternal {
* Returns a list that contains the memory stats for currently running processes.
*/
public abstract List<ProcessMemoryState> getMemoryStateForProcesses();
+
+ /**
+ * This enforces {@code func} can only be called if either the caller is Recents activity or
+ * has {@code permission}.
+ */
+ public abstract void enforceCallerIsRecentsOrHasPermission(String permission, String func);
}
diff --git a/core/java/android/view/IPinnedStackListener.aidl b/core/java/android/view/IPinnedStackListener.aidl
index 9382741a81ec..2da353b1f0ee 100644
--- a/core/java/android/view/IPinnedStackListener.aidl
+++ b/core/java/android/view/IPinnedStackListener.aidl
@@ -47,17 +47,25 @@ oneway interface IPinnedStackListener {
* the WM has changed in the mean time but the client has not received onMovementBoundsChanged).
*/
void onMovementBoundsChanged(in Rect insetBounds, in Rect normalBounds, in Rect animatingBounds,
- boolean fromImeAdjustement, int displayRotation);
+ boolean fromImeAdjustment, boolean fromShelfAdjustment, int displayRotation);
/**
* Called when window manager decides to adjust the pinned stack bounds because of the IME, or
* when the listener is first registered to allow the listener to synchronized its state with
* the controller. This call will always be followed by a onMovementBoundsChanged() call
- * with fromImeAdjustement set to true.
+ * with fromImeAdjustement set to {@code true}.
*/
void onImeVisibilityChanged(boolean imeVisible, int imeHeight);
/**
+ * Called when window manager decides to adjust the pinned stack bounds because of the shelf, or
+ * when the listener is first registered to allow the listener to synchronized its state with
+ * the controller. This call will always be followed by a onMovementBoundsChanged() call
+ * with fromShelfAdjustment set to {@code true}.
+ */
+ void onShelfVisibilityChanged(boolean shelfVisible, int shelfHeight);
+
+ /**
* Called when window manager decides to adjust the minimized state, or when the listener
* is first registered to allow the listener to synchronized its state with the controller.
*/
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index d172fb5cd9ad..613e6d8c6b14 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -284,7 +284,12 @@ interface IWindowManager
*/
oneway void setPipVisibility(boolean visible);
- /**
+ /**
+ * Called by System UI to notify of changes to the visibility and height of the shelf.
+ */
+ void setShelfHeight(boolean visible, int shelfHeight);
+
+ /**
* Called by System UI to enable or disable haptic feedback on the navigation bar buttons.
*/
void setNavBarVirtualKeyHapticFeedbackEnabled(boolean enabled);
@@ -295,8 +300,8 @@ interface IWindowManager
boolean hasNavigationBar();
/**
- * Get the position of the nav bar
- */
+ * Get the position of the nav bar
+ */
int getNavBarPosition();
/**
diff --git a/core/java/com/android/internal/policy/PipSnapAlgorithm.java b/core/java/com/android/internal/policy/PipSnapAlgorithm.java
index 749d00c136ec..5b6b619ed7d2 100644
--- a/core/java/com/android/internal/policy/PipSnapAlgorithm.java
+++ b/core/java/com/android/internal/policy/PipSnapAlgorithm.java
@@ -325,14 +325,14 @@ public class PipSnapAlgorithm {
* {@param stackBounds}.
*/
public void getMovementBounds(Rect stackBounds, Rect insetBounds, Rect movementBoundsOut,
- int imeHeight) {
+ int bottomOffset) {
// Adjust the right/bottom to ensure the stack bounds never goes offscreen
movementBoundsOut.set(insetBounds);
movementBoundsOut.right = Math.max(insetBounds.left, insetBounds.right -
stackBounds.width());
movementBoundsOut.bottom = Math.max(insetBounds.top, insetBounds.bottom -
stackBounds.height());
- movementBoundsOut.bottom -= imeHeight;
+ movementBoundsOut.bottom -= bottomOffset;
}
/**
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index cf13d1c63db5..eea1a47614d3 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2956,8 +2956,8 @@
<item name="config_pictureInPictureAspectRatioLimitForMinSize" format="float" type="dimen">1.777778</item>
<!-- The default gravity for the picture-in-picture window.
- Currently, this maps to Gravity.TOP | Gravity.RIGHT -->
- <integer name="config_defaultPictureInPictureGravity">0x35</integer>
+ Currently, this maps to Gravity.BOTTOM | Gravity.RIGHT -->
+ <integer name="config_defaultPictureInPictureGravity">0x55</integer>
<!-- The minimum aspect ratio (width/height) that is supported for picture-in-picture. Any
ratio smaller than this is considered too tall and thin to be usable. Currently, this
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java
index 2de3ae2bd9e4..9355acf1db1d 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java
@@ -23,7 +23,6 @@ import android.graphics.Rect;
import android.os.Handler;
import android.os.RemoteException;
import android.util.Log;
-import android.view.RemoteAnimationAdapter;
import android.view.WindowManager;
import android.view.WindowManagerGlobal;
@@ -124,4 +123,12 @@ public class WindowManagerWrapper {
Log.w(TAG, "Failed to enable or disable navigation bar button haptics: ", e);
}
}
+
+ public void setShelfHeight(boolean visible, int shelfHeight) {
+ try {
+ WindowManagerGlobal.getWindowManagerService().setShelfHeight(visible, shelfHeight);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed to set shelf height");
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
index 24d0126a1494..2af7ae27873c 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
@@ -133,6 +133,13 @@ public class PipManager implements BasePipManager {
}
@Override
+ public void onShelfVisibilityChanged(boolean shelfVisible, int shelfHeight) {
+ mHandler.post(() -> {
+ mTouchHandler.onShelfVisibilityChanged(shelfVisible, shelfHeight);
+ });
+ }
+
+ @Override
public void onMinimizedStateChanged(boolean isMinimized) {
mHandler.post(() -> {
mTouchHandler.setMinimizedState(isMinimized, true /* fromController */);
@@ -141,10 +148,11 @@ public class PipManager implements BasePipManager {
@Override
public void onMovementBoundsChanged(Rect insetBounds, Rect normalBounds,
- Rect animatingBounds, boolean fromImeAdjustement, int displayRotation) {
+ Rect animatingBounds, boolean fromImeAdjustment, boolean fromShelfAdjustment,
+ int displayRotation) {
mHandler.post(() -> {
mTouchHandler.onMovementBoundsChanged(insetBounds, normalBounds, animatingBounds,
- fromImeAdjustement, displayRotation);
+ fromImeAdjustment, fromShelfAdjustment, displayRotation);
});
}
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java
index 21a836c030cb..31d8cbb5d19d 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java
@@ -16,8 +16,6 @@
package com.android.systemui.pip.phone;
-import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
-
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static com.android.systemui.Interpolators.FAST_OUT_LINEAR_IN;
@@ -71,7 +69,7 @@ public class PipMotionHelper implements Handler.Callback {
private static final int EXPAND_STACK_TO_MENU_DURATION = 250;
private static final int EXPAND_STACK_TO_FULLSCREEN_DURATION = 300;
private static final int MINIMIZE_STACK_MAX_DURATION = 200;
- private static final int IME_SHIFT_DURATION = 300;
+ private static final int SHIFT_DURATION = 300;
// The fraction of the stack width that the user has to drag offscreen to minimize the PiP
private static final float MINIMIZE_OFFSCREEN_FRACTION = 0.3f;
@@ -354,11 +352,11 @@ public class PipMotionHelper implements Handler.Callback {
}
/**
- * Animates the PiP to offset it from the IME.
+ * Animates the PiP to offset it from the IME or shelf.
*/
- void animateToIMEOffset(Rect toBounds) {
+ void animateToOffset(Rect toBounds) {
cancelAnimations();
- resizeAndAnimatePipUnchecked(toBounds, IME_SHIFT_DURATION);
+ resizeAndAnimatePipUnchecked(toBounds, SHIFT_DURATION);
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
index 77931e447e1d..3ba3d0eb4974 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
@@ -120,6 +120,8 @@ public class PipTouchHandler {
private boolean mIsImeShowing;
private int mImeHeight;
private int mImeOffset;
+ private boolean mIsShelfShowing;
+ private int mShelfHeight;
private float mSavedSnapFraction = -1f;
private boolean mSendingHoverAccessibilityEvents;
private boolean mMovementWithinMinimize;
@@ -249,13 +251,20 @@ public class PipTouchHandler {
mImeHeight = imeHeight;
}
+ public void onShelfVisibilityChanged(boolean shelfVisible, int shelfHeight) {
+ mIsShelfShowing = shelfVisible;
+ mShelfHeight = shelfHeight;
+ }
+
public void onMovementBoundsChanged(Rect insetBounds, Rect normalBounds, Rect animatingBounds,
- boolean fromImeAdjustement, int displayRotation) {
+ boolean fromImeAdjustment, boolean fromShelfAdjustment, int displayRotation) {
+ final int bottomOffset = mIsImeShowing ? mImeHeight : 0;
+
// Re-calculate the expanded bounds
mNormalBounds = normalBounds;
Rect normalMovementBounds = new Rect();
mSnapAlgorithm.getMovementBounds(mNormalBounds, insetBounds, normalMovementBounds,
- mIsImeShowing ? mImeHeight : 0);
+ bottomOffset);
// Calculate the expanded size
float aspectRatio = (float) normalBounds.width() / normalBounds.height();
@@ -266,40 +275,23 @@ public class PipTouchHandler {
mExpandedBounds.set(0, 0, expandedSize.getWidth(), expandedSize.getHeight());
Rect expandedMovementBounds = new Rect();
mSnapAlgorithm.getMovementBounds(mExpandedBounds, insetBounds, expandedMovementBounds,
- mIsImeShowing ? mImeHeight : 0);
+ bottomOffset);
- // If this is from an IME adjustment, then we should move the PiP so that it is not occluded
- // by the IME
- if (fromImeAdjustement) {
+ // If this is from an IME or shelf adjustment, then we should move the PiP so that it is not
+ // occluded by the IME or shelf.
+ if (fromImeAdjustment || fromShelfAdjustment) {
if (mTouchState.isUserInteracting()) {
// Defer the update of the current movement bounds until after the user finishes
// touching the screen
} else {
- final Rect bounds = new Rect(animatingBounds);
final Rect toMovementBounds = mMenuState == MENU_STATE_FULL
? expandedMovementBounds
: normalMovementBounds;
- if (mIsImeShowing) {
- // IME visible, apply the IME offset if the space allows for it
- final int imeOffset = toMovementBounds.bottom - Math.max(toMovementBounds.top,
- toMovementBounds.bottom - mImeOffset);
- if (bounds.top == mMovementBounds.bottom) {
- // If the PIP is currently resting on top of the IME, then adjust it with
- // the showing IME
- bounds.offsetTo(bounds.left, toMovementBounds.bottom - imeOffset);
- } else {
- bounds.offset(0, Math.min(0, toMovementBounds.bottom - imeOffset
- - bounds.top));
- }
- } else {
- // IME hidden
- if (bounds.top >= (mMovementBounds.bottom - mImeOffset)) {
- // If the PIP is resting on top of the IME, then adjust it with the hiding
- // IME
- bounds.offsetTo(bounds.left, toMovementBounds.bottom);
- }
- }
- mMotionHelper.animateToIMEOffset(bounds);
+ animateToOffset(animatingBounds, toMovementBounds,
+ fromImeAdjustment,
+ fromImeAdjustment ? mIsImeShowing : mIsShelfShowing,
+ // Shelf height serves as an offset, but does not change movement bounds.
+ fromImeAdjustment ? mImeOffset : mShelfHeight);
}
}
@@ -321,6 +313,26 @@ public class PipTouchHandler {
}
}
+ private void animateToOffset(Rect animatingBounds, Rect toMovementBounds,
+ boolean fromImeAdjustment, boolean showing, int offset) {
+ final Rect bounds = new Rect(animatingBounds);
+ if (showing) {
+ // IME/shelf visible, apply the IME/shelf offset if the space allows for it
+ final int calculatedOffset = toMovementBounds.bottom - Math.max(toMovementBounds.top,
+ toMovementBounds.bottom - offset);
+ bounds.offset(0,
+ Math.min(0, toMovementBounds.bottom - calculatedOffset - bounds.top));
+ } else {
+ // IME/shelf hidden
+ if (bounds.top >= (mMovementBounds.bottom - offset)) {
+ bounds.offset(0, toMovementBounds.bottom - bounds.top -
+ // Counter going back home from search where keyboard is up.
+ (fromImeAdjustment ? mShelfHeight : 0));
+ }
+ }
+ mMotionHelper.animateToOffset(bounds);
+ }
+
private void onRegistrationChanged(boolean isRegistered) {
mAccessibilityManager.setPictureInPictureActionReplacingConnection(isRegistered
? new PipAccessibilityInteractionConnection(mMotionHelper,
@@ -801,6 +813,8 @@ public class PipTouchHandler {
pw.println(innerPrefix + "mIsMinimized=" + mIsMinimized);
pw.println(innerPrefix + "mIsImeShowing=" + mIsImeShowing);
pw.println(innerPrefix + "mImeHeight=" + mImeHeight);
+ pw.println(innerPrefix + "mIsShelfShowing=" + mIsShelfShowing);
+ pw.println(innerPrefix + "mShelfHeight=" + mShelfHeight);
pw.println(innerPrefix + "mSavedSnapFraction=" + mSavedSnapFraction);
pw.println(innerPrefix + "mEnableDragToEdgeDismiss=" + ENABLE_DISMISS_DRAG_TO_EDGE);
pw.println(innerPrefix + "mEnableMinimize=" + ENABLE_MINIMIZE);
diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
index a98468017f17..d6f67604a050 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
@@ -200,11 +200,15 @@ public class PipManager implements BasePipManager {
}
@Override
+ public void onShelfVisibilityChanged(boolean shelfVisible, int shelfHeight) {}
+
+ @Override
public void onMinimizedStateChanged(boolean isMinimized) {}
@Override
public void onMovementBoundsChanged(Rect insetBounds, Rect normalBounds,
- Rect animatingBounds, boolean fromImeAdjustement, int displayRotation) {
+ Rect animatingBounds, boolean fromImeAdjustment, boolean fromShelfAdjustment,
+ int displayRotation) {
mHandler.post(() -> {
mDefaultPipBounds.set(normalBounds);
});
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 063c1f1cb597..5f605c4b5c80 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -26259,10 +26259,12 @@ public class ActivityManagerService extends IActivityManager.Stub
return mUserController.mMaxRunningUsers;
}
+ @Override
public boolean isCallerRecents(int callingUid) {
return getRecentTasks().isCallerRecents(callingUid);
}
+ @Override
public boolean isRecentsComponentHomeActivity(int userId) {
return getRecentTasks().isRecentsComponentHomeActivity(userId);
}
@@ -26301,6 +26303,11 @@ public class ActivityManagerService extends IActivityManager.Stub
}
return processMemoryStates;
}
+
+ @Override
+ public void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
+ ActivityManagerService.this.enforceCallerIsRecentsOrHasPermission(permission, func);
+ }
}
/**
diff --git a/services/core/java/com/android/server/wm/PinnedStackController.java b/services/core/java/com/android/server/wm/PinnedStackController.java
index 6966f1bb135d..2293fb2bea4e 100644
--- a/services/core/java/com/android/server/wm/PinnedStackController.java
+++ b/services/core/java/com/android/server/wm/PinnedStackController.java
@@ -88,6 +88,8 @@ class PinnedStackController {
private boolean mIsMinimized;
private boolean mIsImeShowing;
private int mImeHeight;
+ private boolean mIsShelfShowing;
+ private int mShelfHeight;
// The set of actions and aspect-ratio for the that are currently allowed on the PiP activity
private ArrayList<RemoteAction> mActions = new ArrayList<>();
@@ -213,9 +215,11 @@ class PinnedStackController {
listener.onListenerRegistered(mCallbacks);
mPinnedStackListener = listener;
notifyImeVisibilityChanged(mIsImeShowing, mImeHeight);
+ notifyShelfVisibilityChanged(mIsShelfShowing, mShelfHeight);
// The movement bounds notification needs to be sent before the minimized state, since
// SystemUI may use the bounds to retore the minimized position
- notifyMovementBoundsChanged(false /* fromImeAdjustment */);
+ notifyMovementBoundsChanged(false /* fromImeAdjustment */,
+ false /* fromShelfAdjustment */);
notifyActionsChanged(mActions);
notifyMinimizeChanged(mIsMinimized);
} catch (RemoteException e) {
@@ -297,7 +301,9 @@ class PinnedStackController {
mSnapAlgorithm.applySnapFraction(defaultBounds, movementBounds, snapFraction);
} else {
Gravity.apply(mDefaultStackGravity, size.getWidth(), size.getHeight(), insetBounds,
- 0, mIsImeShowing ? mImeHeight : 0, defaultBounds);
+ 0, Math.max(mIsImeShowing ? mImeHeight : 0,
+ mIsShelfShowing ? mShelfHeight : 0),
+ defaultBounds);
}
return defaultBounds;
}
@@ -310,7 +316,7 @@ class PinnedStackController {
*/
synchronized void onDisplayInfoChanged() {
mDisplayInfo.copyFrom(mDisplayContent.getDisplayInfo());
- notifyMovementBoundsChanged(false /* fromImeAdjustment */);
+ notifyMovementBoundsChanged(false /* fromImeAdjustment */, false /* fromShelfAdjustment */);
}
/**
@@ -342,14 +348,15 @@ class PinnedStackController {
// Calculate the stack bounds in the new orientation to the same same fraction along the
// rotated movement bounds.
final Rect postChangeMovementBounds = getMovementBounds(postChangeStackBounds,
- false /* adjustForIme */);
+ false /* adjustForIme */, false /* adjustForShelf */);
mSnapAlgorithm.applySnapFraction(postChangeStackBounds, postChangeMovementBounds,
snapFraction);
if (mIsMinimized) {
applyMinimizedOffset(postChangeStackBounds, postChangeMovementBounds);
}
- notifyMovementBoundsChanged(false /* fromImeAdjustment */);
+ notifyMovementBoundsChanged(false /* fromImeAdjustment */,
+ false /* fromShelfAdjustment */);
outBounds.set(postChangeStackBounds);
return true;
@@ -373,7 +380,22 @@ class PinnedStackController {
mIsImeShowing = imeShowing;
mImeHeight = imeHeight;
notifyImeVisibilityChanged(imeShowing, imeHeight);
- notifyMovementBoundsChanged(true /* fromImeAdjustment */);
+ notifyMovementBoundsChanged(true /* fromImeAdjustment */, false /* fromShelfAdjustment */);
+ }
+
+ /**
+ * Sets the shelf state and height.
+ */
+ void setAdjustedForShelf(boolean adjustedForShelf, int shelfHeight) {
+ final boolean shelfShowing = adjustedForShelf && shelfHeight > 0;
+ if (shelfShowing == mIsShelfShowing && shelfHeight == mShelfHeight) {
+ return;
+ }
+
+ mIsShelfShowing = shelfShowing;
+ mShelfHeight = shelfHeight;
+ notifyShelfVisibilityChanged(shelfShowing, shelfHeight);
+ notifyMovementBoundsChanged(false /* fromImeAdjustment */, true /* fromShelfAdjustment */);
}
/**
@@ -382,7 +404,8 @@ class PinnedStackController {
void setAspectRatio(float aspectRatio) {
if (Float.compare(mAspectRatio, aspectRatio) != 0) {
mAspectRatio = aspectRatio;
- notifyMovementBoundsChanged(false /* fromImeAdjustment */);
+ notifyMovementBoundsChanged(false /* fromImeAdjustment */,
+ false /* fromShelfAdjustment */);
}
}
@@ -417,6 +440,16 @@ class PinnedStackController {
}
}
+ private void notifyShelfVisibilityChanged(boolean shelfVisible, int shelfHeight) {
+ if (mPinnedStackListener != null) {
+ try {
+ mPinnedStackListener.onShelfVisibilityChanged(shelfVisible, shelfHeight);
+ } catch (RemoteException e) {
+ Slog.e(TAG_WM, "Error delivering bounds changed event.", e);
+ }
+ }
+ }
+
/**
* Notifies listeners that the PIP minimized state has changed.
*/
@@ -446,7 +479,8 @@ class PinnedStackController {
/**
* Notifies listeners that the PIP movement bounds have changed.
*/
- private void notifyMovementBoundsChanged(boolean fromImeAdjustement) {
+ private void notifyMovementBoundsChanged(boolean fromImeAdjustment,
+ boolean fromShelfAdjustment) {
synchronized (mService.mWindowMap) {
if (mPinnedStackListener == null) {
return;
@@ -467,7 +501,8 @@ class PinnedStackController {
animatingBounds.set(normalBounds);
}
mPinnedStackListener.onMovementBoundsChanged(insetBounds, normalBounds,
- animatingBounds, fromImeAdjustement, mDisplayInfo.rotation);
+ animatingBounds, fromImeAdjustment, fromShelfAdjustment,
+ mDisplayInfo.rotation);
} catch (RemoteException e) {
Slog.e(TAG_WM, "Error delivering actions changed event.", e);
}
@@ -493,7 +528,8 @@ class PinnedStackController {
*/
private Rect getMovementBounds(Rect stackBounds) {
synchronized (mService.mWindowMap) {
- return getMovementBounds(stackBounds, true /* adjustForIme */);
+ return getMovementBounds(stackBounds, true /* adjustForIme */,
+ true /* adjustForShelf */);
}
}
@@ -501,14 +537,15 @@ class PinnedStackController {
* @return the movement bounds for the given {@param stackBounds} and the current state of the
* controller.
*/
- private Rect getMovementBounds(Rect stackBounds, boolean adjustForIme) {
+ private Rect getMovementBounds(Rect stackBounds, boolean adjustForIme, boolean adjustForShelf) {
synchronized (mService.mWindowMap) {
final Rect movementBounds = new Rect();
getInsetBounds(movementBounds);
// Apply the movement bounds adjustments based on the current state
mSnapAlgorithm.getMovementBounds(stackBounds, movementBounds, movementBounds,
- (adjustForIme && mIsImeShowing) ? mImeHeight : 0);
+ Math.max((adjustForIme && mIsImeShowing) ? mImeHeight : 0,
+ (adjustForShelf && mIsShelfShowing) ? mShelfHeight : 0));
return movementBounds;
}
}
@@ -549,6 +586,9 @@ class PinnedStackController {
pw.print(prefix + " movementBounds="); getMovementBounds(mTmpRect).printShortString(pw);
pw.println();
pw.println(prefix + " mIsImeShowing=" + mIsImeShowing);
+ pw.println(prefix + " mImeHeight=" + mImeHeight);
+ pw.println(prefix + " mIsShelfShowing=" + mIsShelfShowing);
+ pw.println(prefix + " mShelfHeight=" + mShelfHeight);
pw.println(prefix + " mIsMinimized=" + mIsMinimized);
if (mActions.isEmpty()) {
pw.println(prefix + " mActions=[]");
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index ea84b22a6237..9f8de58b16cf 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -5892,6 +5892,16 @@ public class WindowManagerService extends IWindowManager.Stub
}
@Override
+ public void setShelfHeight(boolean visible, int shelfHeight) {
+ mAmInternal.enforceCallerIsRecentsOrHasPermission(android.Manifest.permission.STATUS_BAR,
+ "setShelfHeight()");
+ synchronized (mWindowMap) {
+ getDefaultDisplayContentLocked().getPinnedStackController().setAdjustedForShelf(visible,
+ shelfHeight);
+ }
+ }
+
+ @Override
public void statusBarVisibilityChanged(int visibility) {
if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR)
!= PackageManager.PERMISSION_GRANTED) {
diff --git a/services/tests/servicestests/src/com/android/server/wm/PinnedStackControllerTest.java b/services/tests/servicestests/src/com/android/server/wm/PinnedStackControllerTest.java
new file mode 100644
index 000000000000..96745fa5956e
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/PinnedStackControllerTest.java
@@ -0,0 +1,63 @@
+package com.android.server.wm;
+
+import static android.view.Display.DEFAULT_DISPLAY;
+
+import android.os.RemoteException;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.view.IPinnedStackListener;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class PinnedStackControllerTest extends WindowTestsBase {
+
+ @Mock private IPinnedStackListener mIPinnedStackListener;
+ @Mock private IPinnedStackListener.Stub mIPinnedStackListenerStub;
+
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+ MockitoAnnotations.initMocks(this);
+ when(mIPinnedStackListener.asBinder()).thenReturn(mIPinnedStackListenerStub);
+ }
+
+ @Test
+ public void setShelfHeight_shelfVisibilityChangedTriggered() throws RemoteException {
+ sWm.mSupportsPictureInPicture = true;
+ sWm.registerPinnedStackListener(DEFAULT_DISPLAY, mIPinnedStackListener);
+
+ verify(mIPinnedStackListener).onImeVisibilityChanged(false, 0);
+ verify(mIPinnedStackListener).onShelfVisibilityChanged(false, 0);
+ verify(mIPinnedStackListener).onMovementBoundsChanged(any(), any(), any(), eq(false),
+ eq(false), anyInt());
+ verify(mIPinnedStackListener).onActionsChanged(any());
+ verify(mIPinnedStackListener).onMinimizedStateChanged(anyBoolean());
+
+ reset(mIPinnedStackListener);
+
+ final int SHELF_HEIGHT = 300;
+
+ sWm.setShelfHeight(true, SHELF_HEIGHT);
+ verify(mIPinnedStackListener).onShelfVisibilityChanged(true, SHELF_HEIGHT);
+ verify(mIPinnedStackListener).onMovementBoundsChanged(any(), any(), any(), eq(false),
+ eq(true), anyInt());
+ verify(mIPinnedStackListener, never()).onImeVisibilityChanged(anyBoolean(), anyInt());
+ }
+}