Merge cherrypicks of ['ag/20911782', 'ag/20911787', 'ag/20928109', 'ag/20931541', 'ag/20946106'] into tm-qpr2-release.

Change-Id: I3b539e4fe213b68109336c1ff1f69640e1dbd30e
This commit is contained in:
Android Build Coastguard Worker
2023-01-11 20:52:05 +00:00
11 changed files with 124 additions and 52 deletions

View File

@@ -24,6 +24,7 @@ import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.Toolbar;
@@ -74,8 +75,8 @@ public class QSCustomizer extends LinearLayout {
toolbar.setNavigationIcon(
getResources().getDrawable(value.resourceId, mContext.getTheme()));
toolbar.getMenu().add(Menu.NONE, MENU_RESET, 0,
mContext.getString(com.android.internal.R.string.reset));
toolbar.getMenu().add(Menu.NONE, MENU_RESET, 0, com.android.internal.R.string.reset)
.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
toolbar.setTitle(R.string.qs_edit);
mRecyclerView = findViewById(android.R.id.list);
mTransparentView = findViewById(R.id.customizer_transparent_view);

View File

@@ -175,9 +175,10 @@ class LargeScreenShadeHeaderController @Inject constructor(
*/
var shadeExpandedFraction = -1f
set(value) {
if (visible && field != value) {
if (field != value) {
header.alpha = ShadeInterpolation.getContentAlpha(value)
field = value
updateVisibility()
}
}
@@ -331,6 +332,9 @@ class LargeScreenShadeHeaderController @Inject constructor(
.setDuration(duration)
.alpha(if (show) 0f else 1f)
.setInterpolator(if (show) Interpolators.ALPHA_OUT else Interpolators.ALPHA_IN)
.setUpdateListener {
updateVisibility()
}
.start()
}
@@ -414,7 +418,7 @@ class LargeScreenShadeHeaderController @Inject constructor(
private fun updateVisibility() {
val visibility = if (!largeScreenActive && !combinedHeaders || qsDisabled) {
View.GONE
} else if (qsVisible) {
} else if (qsVisible && header.alpha > 0f) {
View.VISIBLE
} else {
View.INVISIBLE

View File

@@ -1431,6 +1431,22 @@ public class NotificationChildrenContainer extends ViewGroup
@Override
public void applyRoundnessAndInvalidate() {
boolean last = true;
if (mUseRoundnessSourceTypes) {
if (mNotificationHeaderWrapper != null) {
mNotificationHeaderWrapper.requestTopRoundness(
/* value = */ getTopRoundness(),
/* sourceType = */ FROM_PARENT,
/* animate = */ false
);
}
if (mNotificationHeaderWrapperLowPriority != null) {
mNotificationHeaderWrapperLowPriority.requestTopRoundness(
/* value = */ getTopRoundness(),
/* sourceType = */ FROM_PARENT,
/* animate = */ false
);
}
}
for (int i = mAttachedChildren.size() - 1; i >= 0; i--) {
ExpandableNotificationRow child = mAttachedChildren.get(i);
if (child.getVisibility() == View.GONE) {

View File

@@ -5193,7 +5193,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
println(pw, "intrinsicPadding", mIntrinsicPadding);
println(pw, "topPadding", mTopPadding);
println(pw, "bottomPadding", mBottomPadding);
mNotificationStackSizeCalculator.dump(pw, args);
});
pw.println();
pw.println("Contents:");

View File

@@ -30,7 +30,6 @@ import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
import com.android.systemui.statusbar.notification.row.ExpandableView
import com.android.systemui.util.Compile
import com.android.systemui.util.children
import java.io.PrintWriter
import javax.inject.Inject
import kotlin.math.max
import kotlin.math.min
@@ -54,8 +53,6 @@ constructor(
@Main private val resources: Resources
) {
private lateinit var lastComputeHeightLog : String
/**
* Maximum # notifications to show on Keyguard; extras will be collapsed in an overflow shelf.
* If there are exactly 1 + mMaxKeyguardNotifications, and they fit in the available space
@@ -117,9 +114,7 @@ constructor(
shelfIntrinsicHeight: Float
): Int {
log { "\n" }
val stackHeightSequence = computeHeightPerNotificationLimit(stack, shelfIntrinsicHeight,
/* computeHeight= */ false)
val stackHeightSequence = computeHeightPerNotificationLimit(stack, shelfIntrinsicHeight)
var maxNotifications =
stackHeightSequence.lastIndexWhile { heightResult ->
@@ -162,21 +157,18 @@ constructor(
shelfIntrinsicHeight: Float
): Float {
log { "\n" }
lastComputeHeightLog = ""
val heightPerMaxNotifications =
computeHeightPerNotificationLimit(stack, shelfIntrinsicHeight,
/* computeHeight= */ true)
computeHeightPerNotificationLimit(stack, shelfIntrinsicHeight)
val (notificationsHeight, shelfHeightWithSpaceBefore) =
heightPerMaxNotifications.elementAtOrElse(maxNotifications) {
heightPerMaxNotifications.last() // Height with all notifications visible.
}
lastComputeHeightLog += "\ncomputeHeight(maxNotifications=$maxNotifications," +
log {
"computeHeight(maxNotifications=$maxNotifications," +
"shelfIntrinsicHeight=$shelfIntrinsicHeight) -> " +
"${notificationsHeight + shelfHeightWithSpaceBefore}" +
" = ($notificationsHeight + $shelfHeightWithSpaceBefore)"
log {
lastComputeHeightLog
}
return notificationsHeight + shelfHeightWithSpaceBefore
}
@@ -192,8 +184,7 @@ constructor(
private fun computeHeightPerNotificationLimit(
stack: NotificationStackScrollLayout,
shelfHeight: Float,
computeHeight: Boolean
shelfHeight: Float
): Sequence<StackHeight> = sequence {
log { "computeHeightPerNotificationLimit" }
@@ -222,14 +213,9 @@ constructor(
currentIndex = firstViewInShelfIndex)
spaceBeforeShelf + shelfHeight
}
val currentLog = "computeHeight | i=$i notificationsHeight=$notifications " +
"shelfHeightWithSpaceBefore=$shelfWithSpaceBefore"
if (computeHeight) {
lastComputeHeightLog += "\n" + currentLog
}
log {
currentLog
"i=$i notificationsHeight=$notifications " +
"shelfHeightWithSpaceBefore=$shelfWithSpaceBefore"
}
yield(
StackHeight(
@@ -274,10 +260,6 @@ constructor(
return size
}
fun dump(pw: PrintWriter, args: Array<out String>) {
pw.println("NotificationStackSizeCalculator lastComputeHeightLog = $lastComputeHeightLog")
}
private fun ExpandableView.isShowable(onLockscreen: Boolean): Boolean {
if (visibility == GONE || hasNoContentHeight()) return false
if (onLockscreen) {

View File

@@ -182,6 +182,7 @@ class LargeScreenShadeHeaderControllerCombinedTest : SysuiTestCase() {
null
}
whenever(view.visibility).thenAnswer { _ -> viewVisibility }
whenever(view.alpha).thenReturn(1f)
whenever(iconManagerFactory.create(any(), any())).thenReturn(iconManager)

View File

@@ -1,5 +1,6 @@
package com.android.systemui.shade
import android.animation.ValueAnimator
import android.app.StatusBarManager
import android.content.Context
import android.testing.AndroidTestingRunner
@@ -30,6 +31,7 @@ import com.android.systemui.statusbar.policy.VariableDateViewController
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.argumentCaptor
import com.android.systemui.util.mockito.capture
import com.android.systemui.util.mockito.mock
import com.google.common.truth.Truth.assertThat
import org.junit.After
import org.junit.Before
@@ -37,6 +39,7 @@ import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Answers
import org.mockito.ArgumentMatchers.anyFloat
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.Mock
import org.mockito.Mockito.mock
@@ -75,6 +78,7 @@ class LargeScreenShadeHeaderControllerTest : SysuiTestCase() {
@JvmField @Rule val mockitoRule = MockitoJUnit.rule()
var viewVisibility = View.GONE
var viewAlpha = 1f
private lateinit var mLargeScreenShadeHeaderController: LargeScreenShadeHeaderController
private lateinit var carrierIconSlots: List<String>
@@ -101,6 +105,13 @@ class LargeScreenShadeHeaderControllerTest : SysuiTestCase() {
null
}
whenever(view.visibility).thenAnswer { _ -> viewVisibility }
whenever(view.setAlpha(anyFloat())).then {
viewAlpha = it.arguments[0] as Float
null
}
whenever(view.alpha).thenAnswer { _ -> viewAlpha }
whenever(variableDateViewControllerFactory.create(any()))
.thenReturn(variableDateViewController)
whenever(iconManagerFactory.create(any(), any())).thenReturn(iconManager)
@@ -154,6 +165,16 @@ class LargeScreenShadeHeaderControllerTest : SysuiTestCase() {
verify(view).setAlpha(ShadeInterpolation.getContentAlpha(0.5f))
}
@Test
fun alphaChangesUpdateVisibility() {
makeShadeVisible()
mLargeScreenShadeHeaderController.shadeExpandedFraction = 0f
assertThat(viewVisibility).isEqualTo(View.INVISIBLE)
mLargeScreenShadeHeaderController.shadeExpandedFraction = 1f
assertThat(viewVisibility).isEqualTo(View.VISIBLE)
}
@Test
fun singleCarrier_enablesCarrierIconsInStatusIcons() {
whenever(qsCarrierGroupController.isSingleCarrier).thenReturn(true)
@@ -238,6 +259,39 @@ class LargeScreenShadeHeaderControllerTest : SysuiTestCase() {
verify(animator).start()
}
@Test
fun testShadeExpanded_true_alpha_zero_invisible() {
view.alpha = 0f
mLargeScreenShadeHeaderController.largeScreenActive = true
mLargeScreenShadeHeaderController.qsVisible = true
assertThat(viewVisibility).isEqualTo(View.INVISIBLE)
}
@Test
fun animatorCallsUpdateVisibilityOnUpdate() {
val animator = mock(ViewPropertyAnimator::class.java, Answers.RETURNS_SELF)
whenever(view.animate()).thenReturn(animator)
mLargeScreenShadeHeaderController.startCustomizingAnimation(show = false, 0L)
val updateCaptor = argumentCaptor<ValueAnimator.AnimatorUpdateListener>()
verify(animator).setUpdateListener(capture(updateCaptor))
mLargeScreenShadeHeaderController.largeScreenActive = true
mLargeScreenShadeHeaderController.qsVisible = true
view.alpha = 1f
updateCaptor.value.onAnimationUpdate(mock())
assertThat(viewVisibility).isEqualTo(View.VISIBLE)
view.alpha = 0f
updateCaptor.value.onAnimationUpdate(mock())
assertThat(viewVisibility).isEqualTo(View.INVISIBLE)
}
@Test
fun demoMode_attachDemoMode() {
val cb = argumentCaptor<DemoMode>()

View File

@@ -29,6 +29,7 @@ import com.android.systemui.statusbar.notification.LegacySourceType;
import com.android.systemui.statusbar.notification.SourceType;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.NotificationTestHelper;
import com.android.systemui.statusbar.notification.row.wrapper.NotificationHeaderViewWrapper;
import org.junit.Assert;
import org.junit.Before;
@@ -216,4 +217,29 @@ public class NotificationChildrenContainerTest extends SysuiTestCase {
Assert.assertEquals(1f, mChildrenContainer.getBottomRoundness(), 0.001f);
Assert.assertEquals(1f, notificationRow.getBottomRoundness(), 0.001f);
}
@Test
public void applyRoundnessAndInvalidate_should_be_immediately_applied_on_header() {
mChildrenContainer.useRoundnessSourceTypes(true);
NotificationHeaderViewWrapper header = mChildrenContainer.getNotificationHeaderWrapper();
Assert.assertEquals(0f, header.getTopRoundness(), 0.001f);
mChildrenContainer.requestTopRoundness(1f, SourceType.from(""), false);
Assert.assertEquals(1f, header.getTopRoundness(), 0.001f);
}
@Test
public void applyRoundnessAndInvalidate_should_be_immediately_applied_on_headerLowPriority() {
mChildrenContainer.useRoundnessSourceTypes(true);
mChildrenContainer.setIsLowPriority(true);
NotificationHeaderViewWrapper header = mChildrenContainer.getNotificationHeaderWrapper();
Assert.assertEquals(0f, header.getTopRoundness(), 0.001f);
mChildrenContainer.requestTopRoundness(1f, SourceType.from(""), false);
Assert.assertEquals(1f, header.getTopRoundness(), 0.001f);
}
}

View File

@@ -379,16 +379,11 @@ public final class PendingIntentRecord extends IIntentSender.Stub {
resolvedType = key.requestResolvedType;
}
// Apply any launch flags from the ActivityOptions. This is used only by SystemUI
// to ensure that we can launch the pending intent with a consistent launch mode even
// if the provided PendingIntent is immutable (ie. to force an activity to launch into
// a new task, or to launch multiple instances if supported by the app)
// Apply any launch flags from the ActivityOptions. This is to ensure that the caller
// can specify a consistent launch mode even if the PendingIntent is immutable
final ActivityOptions opts = ActivityOptions.fromBundle(options);
if (opts != null) {
// TODO(b/254490217): Move this check into SafeActivityOptions
if (controller.mAtmInternal.isCallerRecents(Binder.getCallingUid())) {
finalIntent.addFlags(opts.getPendingIntentLaunchFlags());
}
finalIntent.addFlags(opts.getPendingIntentLaunchFlags());
}
// Extract options before clearing calling identity

View File

@@ -817,9 +817,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
mDisplayDeviceConfig = config;
loadFromDisplayDeviceConfig(token, info);
// Since the underlying display-device changed, we really don't know the
// last command that was sent to change it's state. Lets assume it is off and we
// trigger a change immediately.
/// Since the underlying display-device changed, we really don't know the
// last command that was sent to change it's state. Lets assume it is unknown so
// that we trigger a change immediately.
mPowerState.resetScreenState();
}
if (mIsEnabled != isEnabled || mIsInTransition != isInTransition) {

View File

@@ -340,20 +340,12 @@ final class DisplayPowerState {
}
/**
* Resets the screen state to {@link Display#STATE_OFF}. Even though we do not know the last
* state that was sent to the underlying display-device, we assume it is off.
*
* We do not set the screen state to {@link Display#STATE_UNKNOWN} to avoid getting in the state
* where PhotonicModulator holds onto the lock. This happens because we currently try to keep
* the mScreenState and mPendingState in sync, however if the screenState is set to
* {@link Display#STATE_UNKNOWN} here, mPendingState will get progressed to this, which will
* force the PhotonicModulator thread to wait onto the lock to take it out of that state.
* b/262294651 for more info.
* Resets the screen state to unknown. Useful when the underlying display-device changes for the
* LogicalDisplay and we do not know the last state that was sent to it.
*/
void resetScreenState() {
mScreenState = Display.STATE_OFF;
mScreenState = Display.STATE_UNKNOWN;
mScreenReady = false;
scheduleScreenUpdate();
}
private void scheduleScreenUpdate() {
@@ -514,6 +506,8 @@ final class DisplayPowerState {
boolean valid = state != Display.STATE_UNKNOWN && !Float.isNaN(brightnessState);
boolean changed = stateChanged || backlightChanged;
if (!valid || !changed) {
mStateChangeInProgress = false;
mBacklightChangeInProgress = false;
try {
mLock.wait();
} catch (InterruptedException ex) {