Merge "Deferred BOOT_COMPLETED broadcast does not mean queue is not idle." into tm-dev
diff --git a/core/java/android/window/BackEvent.java b/core/java/android/window/BackEvent.java
index 14985c9..1024e2e 100644
--- a/core/java/android/window/BackEvent.java
+++ b/core/java/android/window/BackEvent.java
@@ -46,8 +46,8 @@
@Retention(RetentionPolicy.SOURCE)
public @interface SwipeEdge{}
- private final int mTouchX;
- private final int mTouchY;
+ private final float mTouchX;
+ private final float mTouchY;
private final float mProgress;
@SwipeEdge
@@ -58,14 +58,14 @@
/**
* Creates a new {@link BackEvent} instance.
*
- * @param touchX Absolute X location of the touch point.
- * @param touchY Absolute Y location of the touch point.
+ * @param touchX Absolute X location of the touch point of this event.
+ * @param touchY Absolute Y location of the touch point of this event.
* @param progress Value between 0 and 1 on how far along the back gesture is.
* @param swipeEdge Indicates which edge the swipe starts from.
* @param departingAnimationTarget The remote animation target of the departing application
* window.
*/
- public BackEvent(int touchX, int touchY, float progress, @SwipeEdge int swipeEdge,
+ public BackEvent(float touchX, float touchY, float progress, @SwipeEdge int swipeEdge,
@Nullable RemoteAnimationTarget departingAnimationTarget) {
mTouchX = touchX;
mTouchY = touchY;
@@ -75,8 +75,8 @@
}
private BackEvent(@NonNull Parcel in) {
- mTouchX = in.readInt();
- mTouchY = in.readInt();
+ mTouchX = in.readFloat();
+ mTouchY = in.readFloat();
mProgress = in.readFloat();
mSwipeEdge = in.readInt();
mDepartingAnimationTarget = in.readTypedObject(RemoteAnimationTarget.CREATOR);
@@ -101,8 +101,8 @@
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
- dest.writeInt(mTouchX);
- dest.writeInt(mTouchY);
+ dest.writeFloat(mTouchX);
+ dest.writeFloat(mTouchY);
dest.writeFloat(mProgress);
dest.writeInt(mSwipeEdge);
dest.writeTypedObject(mDepartingAnimationTarget, flags);
@@ -118,14 +118,14 @@
/**
* Returns the absolute X location of the touch point.
*/
- public int getTouchX() {
+ public float getTouchX() {
return mTouchX;
}
/**
* Returns the absolute Y location of the touch point.
*/
- public int getTouchY() {
+ public float getTouchY() {
return mTouchY;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
index 42ac195..cfd0624 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
@@ -301,7 +301,8 @@
int backType = mBackNavigationInfo.getType();
RemoteAnimationTarget animationTarget = mBackNavigationInfo.getDepartingAnimationTarget();
- BackEvent backEvent = new BackEvent(0, 0, progress, swipeEdge, animationTarget);
+ BackEvent backEvent = new BackEvent(
+ event.getX(), event.getY(), progress, swipeEdge, animationTarget);
IOnBackInvokedCallback targetCallback = null;
if (shouldDispatchToLauncher(backType)) {
targetCallback = mBackToLauncherCallback;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
index b6635f3..9dc861c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
@@ -924,6 +924,7 @@
removeContentOverlay(mSwipePipToHomeOverlay, null /* callback */);
mSwipePipToHomeOverlay = null;
}
+ resetShadowRadius();
mPipTransitionState.setInSwipePipToHomeTransition(false);
mPictureInPictureParams = null;
mPipTransitionState.setTransitionState(PipTransitionState.UNDEFINED);
@@ -1569,13 +1570,28 @@
// Avoid double removal, which is fatal.
return;
}
- final SurfaceControl.Transaction tx =
- mSurfaceControlTransactionFactory.getTransaction();
+ final SurfaceControl.Transaction tx = mSurfaceControlTransactionFactory.getTransaction();
tx.remove(surface);
tx.apply();
if (callback != null) callback.run();
}
+ private void resetShadowRadius() {
+ if (mPipTransitionState.getTransitionState() == PipTransitionState.UNDEFINED) {
+ // mLeash is undefined when in PipTransitionState.UNDEFINED
+ return;
+ }
+ final SurfaceControl.Transaction tx = mSurfaceControlTransactionFactory.getTransaction();
+ tx.setShadowRadius(mLeash, 0f);
+ tx.apply();
+ }
+
+ @VisibleForTesting
+ public void setSurfaceControlTransactionFactory(
+ PipSurfaceTransactionHelper.SurfaceControlTransactionFactory factory) {
+ mSurfaceControlTransactionFactory = factory;
+ }
+
/**
* Dumps internal states.
*/
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipAnimationControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipAnimationControllerTest.java
index 8ef1df6..c685fdc 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipAnimationControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipAnimationControllerTest.java
@@ -30,7 +30,6 @@
import static org.mockito.Mockito.verify;
import android.app.TaskInfo;
-import android.graphics.Matrix;
import android.graphics.Rect;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
@@ -104,7 +103,7 @@
final PipAnimationController.PipTransitionAnimator oldAnimator = mPipAnimationController
.getAnimator(mTaskInfo, mLeash, baseValue, startValue, endValue1, null,
TRANSITION_DIRECTION_TO_PIP, 0, ROTATION_0);
- oldAnimator.setSurfaceControlTransactionFactory(DummySurfaceControlTx::new);
+ oldAnimator.setSurfaceControlTransactionFactory(PipDummySurfaceControlTx::new);
oldAnimator.start();
final PipAnimationController.PipTransitionAnimator newAnimator = mPipAnimationController
@@ -134,7 +133,7 @@
@Test
public void pipTransitionAnimator_rotatedEndValue() {
- final DummySurfaceControlTx tx = new DummySurfaceControlTx();
+ final PipDummySurfaceControlTx tx = new PipDummySurfaceControlTx();
final Rect startBounds = new Rect(200, 700, 400, 800);
final Rect endBounds = new Rect(0, 0, 500, 1000);
// Fullscreen to PiP.
@@ -184,7 +183,7 @@
final PipAnimationController.PipTransitionAnimator animator = mPipAnimationController
.getAnimator(mTaskInfo, mLeash, baseValue, startValue, endValue, null,
TRANSITION_DIRECTION_TO_PIP, 0, ROTATION_0);
- animator.setSurfaceControlTransactionFactory(DummySurfaceControlTx::new);
+ animator.setSurfaceControlTransactionFactory(PipDummySurfaceControlTx::new);
animator.setPipAnimationCallback(mPipAnimationCallback);
@@ -201,44 +200,4 @@
verify(mPipAnimationCallback).onPipAnimationEnd(eq(mTaskInfo),
any(SurfaceControl.Transaction.class), eq(animator));
}
-
- /**
- * A dummy {@link SurfaceControl.Transaction} class.
- * This is created as {@link Mock} does not support method chaining.
- */
- public static class DummySurfaceControlTx extends SurfaceControl.Transaction {
- @Override
- public SurfaceControl.Transaction setAlpha(SurfaceControl leash, float alpha) {
- return this;
- }
-
- @Override
- public SurfaceControl.Transaction setPosition(SurfaceControl leash, float x, float y) {
- return this;
- }
-
- @Override
- public SurfaceControl.Transaction setWindowCrop(SurfaceControl leash, int w, int h) {
- return this;
- }
-
- @Override
- public SurfaceControl.Transaction setCornerRadius(SurfaceControl leash, float radius) {
- return this;
- }
-
- @Override
- public SurfaceControl.Transaction setMatrix(SurfaceControl leash, Matrix matrix,
- float[] float9) {
- return this;
- }
-
- @Override
- public SurfaceControl.Transaction setFrameTimelineVsync(long frameTimelineVsyncId) {
- return this;
- }
-
- @Override
- public void apply() {}
- }
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipDummySurfaceControlTx.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipDummySurfaceControlTx.java
new file mode 100644
index 0000000..ccf8f6e
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipDummySurfaceControlTx.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+package com.android.wm.shell.pip;
+
+import android.graphics.Matrix;
+import android.view.SurfaceControl;
+
+/**
+ * A dummy {@link SurfaceControl.Transaction} class for testing purpose and supports
+ * method chaining.
+ */
+public class PipDummySurfaceControlTx extends SurfaceControl.Transaction {
+ @Override
+ public SurfaceControl.Transaction setAlpha(SurfaceControl leash, float alpha) {
+ return this;
+ }
+
+ @Override
+ public SurfaceControl.Transaction setPosition(SurfaceControl leash, float x, float y) {
+ return this;
+ }
+
+ @Override
+ public SurfaceControl.Transaction setWindowCrop(SurfaceControl leash, int w, int h) {
+ return this;
+ }
+
+ @Override
+ public SurfaceControl.Transaction setCornerRadius(SurfaceControl leash, float radius) {
+ return this;
+ }
+
+ @Override
+ public SurfaceControl.Transaction setShadowRadius(SurfaceControl leash, float radius) {
+ return this;
+ }
+
+ @Override
+ public SurfaceControl.Transaction setMatrix(SurfaceControl leash, Matrix matrix,
+ float[] float9) {
+ return this;
+ }
+
+ @Override
+ public SurfaceControl.Transaction setFrameTimelineVsync(long frameTimelineVsyncId) {
+ return this;
+ }
+
+ @Override
+ public void apply() {}
+}
+
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java
index 14d9fb9..def9ad2 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java
@@ -242,6 +242,7 @@
mPipBoundsState.setDisplayLayout(new DisplayLayout(info,
mContext.getResources(), true, true));
mSpiedPipTaskOrganizer.setOneShotAnimationType(PipAnimationController.ANIM_TYPE_ALPHA);
+ mSpiedPipTaskOrganizer.setSurfaceControlTransactionFactory(PipDummySurfaceControlTx::new);
doNothing().when(mSpiedPipTaskOrganizer).enterPipWithAlphaAnimation(any(), anyLong());
doNothing().when(mSpiedPipTaskOrganizer).scheduleAnimateResizePip(any(), anyInt(), any());
}
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 80582ef..a0115e8 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -561,6 +561,9 @@
<!-- The height of the gap between adjacent notification sections. -->
<dimen name="notification_section_divider_height">@dimen/notification_side_paddings</dimen>
+ <!-- The height of the gap between adjacent notification sections on lockscreen. -->
+ <dimen name="notification_section_divider_height_lockscreen">4dp</dimen>
+
<!-- Size of the face pile shown on one-line (children of a group) conversation notifications -->
<dimen name="conversation_single_line_face_pile_size">24dp</dimen>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
index f15df8e..c1ea6bf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
@@ -72,6 +72,9 @@
dumpManager: DumpManager
) : Dumpable {
private var pulseHeight: Float = 0f
+ @get:VisibleForTesting
+ var fractionToShade: Float = 0f
+ private set
private var useSplitShade: Boolean = false
private lateinit var nsslController: NotificationStackScrollLayoutController
lateinit var notificationPanelController: NotificationPanelViewController
@@ -405,9 +408,9 @@
if (field != value || forceApplyAmount) {
field = value
if (!nsslController.isInLockedDownShade() || field == 0f || forceApplyAmount) {
- val notificationShelfProgress =
+ fractionToShade =
MathUtils.saturate(dragDownAmount / notificationShelfTransitionDistance)
- nsslController.setTransitionToFullShadeAmount(notificationShelfProgress)
+ nsslController.setTransitionToFullShadeAmount(fractionToShade)
qSDragProgress = MathUtils.saturate(dragDownAmount / qsTransitionDistance)
qS.setTransitionToFullShadeAmount(field, qSDragProgress)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index 633786f..afce945 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -85,9 +85,6 @@
private NotificationShelfController mController;
private float mActualWidth = -1;
- /** Fraction of lockscreen to shade animation (on lockscreen swipe down). */
- private float mFractionToShade;
-
public NotificationShelf(Context context, AttributeSet attrs) {
super(context, attrs);
}
@@ -234,13 +231,6 @@
}
/**
- * @param fractionToShade Fraction of lockscreen to shade transition
- */
- public void setFractionToShade(float fractionToShade) {
- mFractionToShade = fractionToShade;
- }
-
- /**
* @return Actual width of shelf, accounting for possible ongoing width animation
*/
public int getActualWidth() {
@@ -411,7 +401,8 @@
|| !mShowNotificationShelf
|| numViewsInShelf < 1f;
- final float fractionToShade = Interpolators.STANDARD.getInterpolation(mFractionToShade);
+ final float fractionToShade = Interpolators.STANDARD.getInterpolation(
+ mAmbientState.getFractionToShade());
final float shortestWidth = mShelfIcons.calculateWidthFor(numViewsInShelf);
updateActualWidth(fractionToShade, shortestWidth);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
index efb46b96..7245cb2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
@@ -2658,9 +2658,6 @@
return;
}
- // bail out if no public version
- if (mPublicLayout.getChildCount() == 0) return;
-
if (!animated) {
mPublicLayout.animate().cancel();
mPrivateLayout.animate().cancel();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
index 25999a7..9acd60e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
@@ -82,6 +82,23 @@
private boolean mAppearing;
private float mPulseHeight = MAX_PULSE_HEIGHT;
+ /** Fraction of lockscreen to shade animation (on lockscreen swipe down). */
+ private float mFractionToShade;
+
+ /**
+ * @param fractionToShade Fraction of lockscreen to shade transition
+ */
+ public void setFractionToShade(float fractionToShade) {
+ mFractionToShade = fractionToShade;
+ }
+
+ /**
+ * @return fractionToShade Fraction of lockscreen to shade transition
+ */
+ public float getFractionToShade() {
+ return mFractionToShade;
+ }
+
/** How we much we are sleeping. 1f fully dozing (AOD), 0f fully awake (for all other states) */
private float mDozeAmount = 0.0f;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index b52fd61..851794c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -2295,7 +2295,7 @@
int visibleIndex
) {
return mStackScrollAlgorithm.getGapHeightForChild(mSectionsManager, visibleIndex, current,
- previous);
+ previous, mAmbientState.getFractionToShade(), mAmbientState.isOnKeyguard());
}
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
@@ -5501,7 +5501,7 @@
* where it remains until the next lockscreen-to-shade transition.
*/
public void setFractionToShade(float fraction) {
- mShelf.setFractionToShade(fraction);
+ mAmbientState.setFractionToShade(fraction);
requestChildrenUpdate();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculator.kt
index 9417aac..2b11f69 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculator.kt
@@ -19,9 +19,11 @@
import android.content.res.Resources
import android.util.Log
import android.view.View.GONE
+import androidx.annotation.VisibleForTesting
import com.android.systemui.R
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.statusbar.LockscreenShadeTransitionController
import com.android.systemui.statusbar.StatusBarState.KEYGUARD
import com.android.systemui.statusbar.SysuiStatusBarStateController
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
@@ -41,6 +43,7 @@
@Inject
constructor(
private val statusBarStateController: SysuiStatusBarStateController,
+ private val lockscreenShadeTransitionController: LockscreenShadeTransitionController,
@Main private val resources: Resources
) {
@@ -129,7 +132,7 @@
yield(dividerHeight + shelfIntrinsicHeight) // Only shelf.
children.forEachIndexed { i, currentNotification ->
- height += currentNotification.spaceNeeded(i, previous, stack, onLockscreen)
+ height += spaceNeeded(currentNotification, i, previous, stack, onLockscreen)
previous = currentNotification
val shelfHeight =
@@ -156,22 +159,28 @@
private val NotificationStackScrollLayout.childrenSequence: Sequence<ExpandableView>
get() = children.map { it as ExpandableView }
- private fun onLockscreen() = statusBarStateController.state == KEYGUARD
+ @VisibleForTesting
+ fun onLockscreen() : Boolean {
+ return statusBarStateController.state == KEYGUARD
+ && lockscreenShadeTransitionController.fractionToShade == 0f
+ }
- private fun ExpandableView.spaceNeeded(
+ @VisibleForTesting
+ fun spaceNeeded(
+ view: ExpandableView,
visibleIndex: Int,
previousView: ExpandableView?,
stack: NotificationStackScrollLayout,
onLockscreen: Boolean
): Float {
- assert(isShowable(onLockscreen))
+ assert(view.isShowable(onLockscreen))
var size =
if (onLockscreen) {
- getMinHeight(/* ignoreTemporaryStates= */ true).toFloat()
+ view.getMinHeight(/* ignoreTemporaryStates= */ true).toFloat()
} else {
- intrinsicHeight.toFloat()
+ view.intrinsicHeight.toFloat()
}
- size += calculateGapAndDividerHeight(stack, previousView, current = this, visibleIndex)
+ size += calculateGapAndDividerHeight(stack, previousView, current = view, visibleIndex)
return size
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
index 9204c45e..22242b8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
@@ -54,6 +54,7 @@
private int mPaddingBetweenElements;
private int mGapHeight;
+ private int mGapHeightOnLockscreen;
private int mCollapsedSize;
private StackScrollAlgorithmState mTempAlgorithmState = new StackScrollAlgorithmState();
@@ -87,6 +88,8 @@
mPinnedZTranslationExtra = res.getDimensionPixelSize(
R.dimen.heads_up_pinned_elevation);
mGapHeight = res.getDimensionPixelSize(R.dimen.notification_section_divider_height);
+ mGapHeightOnLockscreen = res.getDimensionPixelSize(
+ R.dimen.notification_section_divider_height_lockscreen);
mNotificationScrimPadding = res.getDimensionPixelSize(R.dimen.notification_side_paddings);
mMarginBottom = res.getDimensionPixelSize(R.dimen.notification_panel_margin_bottom);
}
@@ -305,7 +308,8 @@
ambientState.getSectionProvider(), i,
view, getPreviousView(i, state));
if (applyGapHeight) {
- currentY += mGapHeight;
+ currentY += getGapForLocation(
+ ambientState.getFractionToShade(), ambientState.isOnKeyguard());
}
if (ambientState.getShelf() != null) {
@@ -454,8 +458,10 @@
ambientState.getSectionProvider(), i,
view, getPreviousView(i, algorithmState));
if (applyGapHeight) {
- algorithmState.mCurrentYPosition += expansionFraction * mGapHeight;
- algorithmState.mCurrentExpandedYPosition += mGapHeight;
+ final float gap = getGapForLocation(
+ ambientState.getFractionToShade(), ambientState.isOnKeyguard());
+ algorithmState.mCurrentYPosition += expansionFraction * gap;
+ algorithmState.mCurrentExpandedYPosition += gap;
}
viewState.yTranslation = algorithmState.mCurrentYPosition;
@@ -539,16 +545,29 @@
SectionProvider sectionProvider,
int visibleIndex,
View child,
- View previousChild) {
+ View previousChild,
+ float fractionToShade,
+ boolean onKeyguard) {
if (childNeedsGapHeight(sectionProvider, visibleIndex, child,
previousChild)) {
- return mGapHeight;
+ return getGapForLocation(fractionToShade, onKeyguard);
} else {
return 0;
}
}
+ @VisibleForTesting
+ float getGapForLocation(float fractionToShade, boolean onKeyguard) {
+ if (fractionToShade > 0f) {
+ return MathUtils.lerp(mGapHeightOnLockscreen, mGapHeight, fractionToShade);
+ }
+ if (onKeyguard) {
+ return mGapHeightOnLockscreen;
+ }
+ return mGapHeight;
+ }
+
/**
* Does a given child need a gap, i.e spacing before a view?
*
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationShelfTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationShelfTest.kt
index 5d16036..4270d72 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationShelfTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationShelfTest.kt
@@ -144,7 +144,7 @@
}
private fun setFractionToShade(fraction: Float) {
- shelf.setFractionToShade(fraction)
+ whenever(ambientState.fractionToShade).thenReturn(fraction)
}
private fun setOnLockscreen(isOnLockscreen: Boolean) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculatorTest.kt
index 968e16a..c3658ba 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculatorTest.kt
@@ -23,6 +23,8 @@
import androidx.test.filters.SmallTest
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
+import com.android.systemui.statusbar.LockscreenShadeTransitionController
+import com.android.systemui.statusbar.StatusBarState
import com.android.systemui.statusbar.SysuiStatusBarStateController
import com.android.systemui.statusbar.notification.collection.NotificationEntry
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
@@ -44,7 +46,7 @@
class NotificationStackSizeCalculatorTest : SysuiTestCase() {
@Mock private lateinit var sysuiStatusBarStateController: SysuiStatusBarStateController
-
+ @Mock private lateinit var lockscreenShadeTransitionController: LockscreenShadeTransitionController
@Mock private lateinit var stackLayout: NotificationStackScrollLayout
private val testableResources = mContext.getOrCreateTestableResources()
@@ -63,6 +65,7 @@
sizeCalculator =
NotificationStackSizeCalculator(
statusBarStateController = sysuiStatusBarStateController,
+ lockscreenShadeTransitionController = lockscreenShadeTransitionController,
testableResources.resources)
}
@@ -155,6 +158,55 @@
assertThat(height).isAtMost(availableSpace)
}
+ @Test
+ fun onLockscreen_onKeyguard_AndNotGoingToShade_returnsTrue() {
+ whenever(sysuiStatusBarStateController.state).thenReturn(StatusBarState.KEYGUARD)
+ whenever(lockscreenShadeTransitionController.fractionToShade).thenReturn(0f)
+ assertThat(sizeCalculator.onLockscreen()).isTrue()
+ }
+
+ @Test
+ fun onLockscreen_goingToShade_returnsFalse() {
+ whenever(sysuiStatusBarStateController.state).thenReturn(StatusBarState.KEYGUARD)
+ whenever(lockscreenShadeTransitionController.fractionToShade).thenReturn(0.5f)
+ assertThat(sizeCalculator.onLockscreen()).isFalse()
+ }
+
+ @Test
+ fun onLockscreen_notOnLockscreen_returnsFalse() {
+ whenever(sysuiStatusBarStateController.state).thenReturn(StatusBarState.SHADE)
+ whenever(lockscreenShadeTransitionController.fractionToShade).thenReturn(1f)
+ assertThat(sizeCalculator.onLockscreen()).isFalse()
+ }
+
+ @Test
+ fun spaceNeeded_onLockscreen_usesMinHeight() {
+ setGapHeight(0f)
+ // No divider height since we're testing one element where index = 0
+
+ val expandableView = createMockRow(rowHeight)
+ whenever(expandableView.getMinHeight(any())).thenReturn(5)
+ whenever(expandableView.intrinsicHeight).thenReturn(10)
+
+ val space = sizeCalculator.spaceNeeded(expandableView, visibleIndex = 0,
+ previousView = null, stack = stackLayout, onLockscreen = true)
+ assertThat(space).isEqualTo(5)
+ }
+
+ @Test
+ fun spaceNeeded_notOnLockscreen_usesIntrinsicHeight() {
+ setGapHeight(0f)
+ // No divider height since we're testing one element where index = 0
+
+ val expandableView = createMockRow(rowHeight)
+ whenever(expandableView.getMinHeight(any())).thenReturn(5)
+ whenever(expandableView.intrinsicHeight).thenReturn(10)
+
+ val space = sizeCalculator.spaceNeeded(expandableView, visibleIndex = 0,
+ previousView = null, stack = stackLayout, onLockscreen = false)
+ assertThat(space).isEqualTo(10)
+ }
+
private fun computeMaxKeyguardNotifications(
rows: List<ExpandableView>,
availableSpace: Float,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt
index 6b4dc58..1f90d0c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt
@@ -1,5 +1,6 @@
package com.android.systemui.statusbar.notification.stack
+import android.annotation.DimenRes
import android.widget.FrameLayout
import androidx.test.filters.SmallTest
import com.android.systemui.R
@@ -31,6 +32,14 @@
mStatusBarKeyguardViewManager
)
+ private val testableResources = mContext.orCreateTestableResources
+
+ private fun px(@DimenRes id: Int): Float =
+ testableResources.resources.getDimensionPixelSize(id).toFloat()
+
+ private val bigGap = px(R.dimen.notification_section_divider_height)
+ private val smallGap = px(R.dimen.notification_section_divider_height_lockscreen)
+
@Before
fun setUp() {
whenever(notificationRow.viewState).thenReturn(expandableViewState)
@@ -80,4 +89,25 @@
val centeredY = ambientState.stackY + fullHeight / 2f - emptyShadeView.height / 2f
assertThat(emptyShadeView.viewState?.yTranslation).isEqualTo(centeredY)
}
+
+ @Test
+ fun getGapForLocation_onLockscreen_returnsSmallGap() {
+ val gap = stackScrollAlgorithm.getGapForLocation(
+ /* fractionToShade= */ 0f, /* onKeyguard= */ true)
+ assertThat(gap).isEqualTo(smallGap)
+ }
+
+ @Test
+ fun getGapForLocation_goingToShade_interpolatesGap() {
+ val gap = stackScrollAlgorithm.getGapForLocation(
+ /* fractionToShade= */ 0.5f, /* onKeyguard= */ true)
+ assertThat(gap).isEqualTo(smallGap * 0.5f + bigGap * 0.5f)
+ }
+
+ @Test
+ fun getGapForLocation_notOnLockscreen_returnsBigGap() {
+ val gap = stackScrollAlgorithm.getGapForLocation(
+ /* fractionToShade= */ 0f, /* onKeyguard= */ false)
+ assertThat(gap).isEqualTo(bigGap)
+ }
}
diff --git a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
index 849f530..349174d 100644
--- a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
@@ -207,6 +207,9 @@
STORAGE_PERMISSIONS.add(Manifest.permission.READ_EXTERNAL_STORAGE);
STORAGE_PERMISSIONS.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
STORAGE_PERMISSIONS.add(Manifest.permission.ACCESS_MEDIA_LOCATION);
+ STORAGE_PERMISSIONS.add(Manifest.permission.READ_MEDIA_AUDIO);
+ STORAGE_PERMISSIONS.add(Manifest.permission.READ_MEDIA_VIDEO);
+ STORAGE_PERMISSIONS.add(Manifest.permission.READ_MEDIA_IMAGES);
}
private static final Set<String> NEARBY_DEVICES_PERMISSIONS = new ArraySet<>();