summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AconfigFlags.bp14
-rw-r--r--core/api/current.txt1
-rw-r--r--core/api/removed.txt4
-rw-r--r--core/java/android/app/ApplicationStartInfo.java5
-rw-r--r--core/java/android/app/GrammaticalInflectionManager.java5
-rw-r--r--core/java/android/app/Notification.java6
-rw-r--r--core/java/android/provider/Settings.java31
-rw-r--r--core/java/android/service/voice/flags/flags.aconfig8
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipAspectRatioChangeTest.kt64
-rw-r--r--libs/hwui/OWNERS3
-rw-r--r--packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java5
-rw-r--r--packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java1
-rw-r--r--packages/SystemUI/src/com/android/keyguard/LockIconViewController.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/flags/FlagCommand.java27
-rw-r--r--packages/SystemUI/src/com/android/systemui/flags/Flags.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt83
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceViewBinder.kt11
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconAreaControllerViewBinderWrapperImpl.kt49
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java17
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyNotificationIconAreaControllerImpl.java50
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerTest.java8
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerWithCoroutinesTest.kt7
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt428
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java19
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt11
-rw-r--r--services/core/java/com/android/server/OWNERS5
-rwxr-xr-xservices/core/java/com/android/server/notification/NotificationManagerService.java13
-rw-r--r--services/tests/uiservicestests/Android.bp1
-rwxr-xr-xservices/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java139
-rw-r--r--telephony/java/android/telephony/CarrierConfigManager.java8
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/helpers/PipAppHelper.kt6
-rw-r--r--tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/PipActivity.java6
35 files changed, 874 insertions, 195 deletions
diff --git a/AconfigFlags.bp b/AconfigFlags.bp
index 49b152b85ca1..c30164c065af 100644
--- a/AconfigFlags.bp
+++ b/AconfigFlags.bp
@@ -41,6 +41,7 @@ aconfig_srcjars = [
":android.app.flags-aconfig-java{.generated_srcjars}",
":android.credentials.flags-aconfig-java{.generated_srcjars}",
":android.view.contentprotection.flags-aconfig-java{.generated_srcjars}",
+ ":android.service.voice.flags-aconfig-java{.generated_srcjars}",
]
filegroup {
@@ -402,3 +403,16 @@ java_aconfig_library {
aconfig_declarations: "android.view.contentprotection.flags-aconfig",
defaults: ["framework-minus-apex-aconfig-java-defaults"],
}
+
+// Voice
+aconfig_declarations {
+ name: "android.service.voice.flags-aconfig",
+ package: "android.service.voice.flags",
+ srcs: ["core/java/android/service/voice/flags/*.aconfig"],
+}
+
+java_aconfig_library {
+ name: "android.service.voice.flags-aconfig-java",
+ aconfig_declarations: "android.service.voice.flags-aconfig",
+ defaults: ["framework-minus-apex-aconfig-java-defaults"],
+}
diff --git a/core/api/current.txt b/core/api/current.txt
index a304080f7579..96a959572949 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -42982,7 +42982,6 @@ package android.telephony {
field public static final String KEY_GSM_ROAMING_NETWORKS_STRING_ARRAY = "gsm_roaming_networks_string_array";
field public static final String KEY_HAS_IN_CALL_NOISE_SUPPRESSION_BOOL = "has_in_call_noise_suppression_bool";
field public static final String KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL = "hide_carrier_network_settings_bool";
- field @Deprecated public static final String KEY_HIDE_ENABLE_2G = "hide_enable_2g_bool";
field public static final String KEY_HIDE_ENHANCED_4G_LTE_BOOL = "hide_enhanced_4g_lte_bool";
field public static final String KEY_HIDE_IMS_APN_BOOL = "hide_ims_apn_bool";
field public static final String KEY_HIDE_LTE_PLUS_DATA_ICON_BOOL = "hide_lte_plus_data_icon_bool";
diff --git a/core/api/removed.txt b/core/api/removed.txt
index 57e2e73854c1..5a4be65ef559 100644
--- a/core/api/removed.txt
+++ b/core/api/removed.txt
@@ -472,6 +472,10 @@ package android.speech.tts {
package android.telephony {
+ public class CarrierConfigManager {
+ field @Deprecated public static final String KEY_HIDE_ENABLE_2G = "hide_enable_2g_bool";
+ }
+
public class NetworkScan {
method @Deprecated public void stop() throws android.os.RemoteException;
}
diff --git a/core/java/android/app/ApplicationStartInfo.java b/core/java/android/app/ApplicationStartInfo.java
index a6a57cd5745a..37111e931d71 100644
--- a/core/java/android/app/ApplicationStartInfo.java
+++ b/core/java/android/app/ApplicationStartInfo.java
@@ -473,9 +473,8 @@ public final class ApplicationStartInfo implements Parcelable {
* available.
* For {@link #STARTUP_STATE_ERROR}, no additional timestamps are guaranteed available.
* For {@link #STARTUP_STATE_FIRST_FRAME_DRAWN}, timestamps
- * {@link #START_TIMESTAMP_JAVA_CLASSLOADING_COMPLETE}, {@link #START_TIMESTAMP_APPLICATION_ONCREATE},
- * {@link #START_TIMESTAMP_BIND_APPLICATION}, and {@link #START_TIMESTAMP_FIRST_FRAME} will
- * additionally be available.
+ * {@link #START_TIMESTAMP_APPLICATION_ONCREATE}, {@link #START_TIMESTAMP_BIND_APPLICATION},
+ * and {@link #START_TIMESTAMP_FIRST_FRAME} will additionally be available.
*
* Timestamp {@link #START_TIMESTAMP_FULLY_DRAWN} is never guaranteed to be available as it is
* dependant on devloper calling {@link Activity#reportFullyDrawn}.
diff --git a/core/java/android/app/GrammaticalInflectionManager.java b/core/java/android/app/GrammaticalInflectionManager.java
index bc6fe6146764..a55121aaa12c 100644
--- a/core/java/android/app/GrammaticalInflectionManager.java
+++ b/core/java/android/app/GrammaticalInflectionManager.java
@@ -100,7 +100,7 @@ public class GrammaticalInflectionManager {
/**
* Sets the current grammatical gender for all privileged applications. The value will be
- * stored in an encrypted file at {@link android.os.Environment#getDataSystemCeDirectory(int)
+ * stored in an encrypted file at {@link android.os.Environment#getDataSystemCeDirectory(int)}
*
* @param grammaticalGender the terms of address the user preferred in system.
*
@@ -121,8 +121,7 @@ public class GrammaticalInflectionManager {
}
/**
- * Get the current grammatical gender of privileged application from the encrypted file,
- * which is stored under {@link android.os.Environment#getDataSystemCeDirectory(int)}.
+ * Get the current grammatical gender of privileged application from the encrypted file.
*
* @return the value of grammatical gender
*
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 93c2b5ad4d86..dd7db23d668b 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -9195,6 +9195,12 @@ public class Notification implements Parcelable
* You can opt-out of this behavior by using {@link Notification.Builder#setColorized(boolean)}.
* <p>
*
+ * <p>
+ * Starting at {@link android.os.Build.VERSION_CODES#VANILLA_ICE_CREAM Android V} the
+ * {@link Notification#FLAG_NO_CLEAR NO_CLEAR flag} will be set for valid MediaStyle
+ * notifications.
+ * <p>
+ *
* To use this style with your Notification, feed it to
* {@link Notification.Builder#setStyle(android.app.Notification.Style)} like so:
* <pre class="prettyprint">
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index d09f0a831f30..b414ed4faea2 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -5664,6 +5664,37 @@ public final class Settings {
public static final String SHOW_ROTARY_INPUT = "show_rotary_input";
/**
+ * The screen backlight brightness for automatic mode.
+ *
+ * <p>Value should be one of:
+ * <ul>
+ * <li>SCREEN_BRIGHTNESS_AUTOMATIC_BRIGHT
+ * <li>SCREEN_BRIGHTNESS_AUTOMATIC_NORMAL
+ * <li>SCREEN_BRIGHTNESS_AUTOMATIC_DIM
+ * </ul>
+ * @hide
+ */
+ public static final String SCREEN_BRIGHTNESS_FOR_ALS = "screen_brightness_for_als";
+
+ /**
+ * SCREEN_BRIGHTNESS_FOR_ALS value for automatic bright.
+ * @hide
+ */
+ public static final int SCREEN_BRIGHTNESS_AUTOMATIC_BRIGHT = 1;
+
+ /**
+ * SCREEN_BRIGHTNESS_FOR_ALS value for automatic normal.
+ * @hide
+ */
+ public static final int SCREEN_BRIGHTNESS_AUTOMATIC_NORMAL = 2;
+
+ /**
+ * SCREEN_BRIGHTNESS_FOR_ALS value for automatic dim.
+ * @hide
+ */
+ public static final int SCREEN_BRIGHTNESS_AUTOMATIC_DIM = 3;
+
+ /**
* Log raw orientation data from
* {@link com.android.server.policy.WindowOrientationListener} for use with the
* orientationplot.py tool.
diff --git a/core/java/android/service/voice/flags/flags.aconfig b/core/java/android/service/voice/flags/flags.aconfig
new file mode 100644
index 000000000000..c414ef8a6826
--- /dev/null
+++ b/core/java/android/service/voice/flags/flags.aconfig
@@ -0,0 +1,8 @@
+package: "android.service.voice.flags"
+
+flag {
+ name: "allow_training_data_egress_from_hds"
+ namespace: "machine_learning"
+ description: "This flag allows the hotword detection service to egress training data to the default assistant."
+ bug: "296074924"
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipAspectRatioChangeTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipAspectRatioChangeTest.kt
new file mode 100644
index 000000000000..4f27ceddd705
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipAspectRatioChangeTest.kt
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2023 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.flicker.pip
+
+import android.platform.test.annotations.Presubmit
+import android.tools.common.Rotation
+import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
+import android.tools.device.flicker.legacy.FlickerBuilder
+import android.tools.device.flicker.legacy.LegacyFlickerTest
+import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
+import com.android.wm.shell.flicker.pip.common.PipTransition
+import org.junit.FixMethodOrder
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/** Test changing aspect ratio of pip. */
+@RunWith(Parameterized::class)
+@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+class PipAspectRatioChangeTest(flicker: LegacyFlickerTest) : PipTransition(flicker) {
+ override val thisTransition: FlickerBuilder.() -> Unit = {
+ transitions {
+ pipApp.changeAspectRatio()
+ }
+ }
+
+ @Presubmit
+ @Test
+ fun pipAspectRatioChangesProperly() {
+ flicker.assertLayersStart { this.visibleRegion(pipApp).isSameAspectRatio(16, 9) }
+ flicker.assertLayersEnd { this.visibleRegion(pipApp).isSameAspectRatio(1, 2) }
+ }
+
+ companion object {
+ /**
+ * Creates the test configurations.
+ *
+ * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and
+ * navigation modes.
+ */
+ @Parameterized.Parameters(name = "{0}")
+ @JvmStatic
+ fun getParams() =
+ LegacyFlickerTestFactory.nonRotationTests(
+ supportedRotations = listOf(Rotation.ROTATION_0)
+ )
+ }
+}
diff --git a/libs/hwui/OWNERS b/libs/hwui/OWNERS
index 6ca991d8b294..bc174599a4d3 100644
--- a/libs/hwui/OWNERS
+++ b/libs/hwui/OWNERS
@@ -4,9 +4,8 @@ alecmouri@google.com
djsollen@google.com
jreck@google.com
njawad@google.com
-reed@google.com
scroggo@google.com
-stani@google.com
+sumir@google.com
# For text, e.g. Typeface, Font, Minikin, etc.
nona@google.com
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java
index 17ce7c7cc435..29f27f74bca4 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java
@@ -120,6 +120,11 @@ public class SystemSettingsValidators {
VALIDATORS.put(System.DISPLAY_COLOR_MODE_VENDOR_HINT, ANY_STRING_VALIDATOR);
VALIDATORS.put(System.SCREEN_OFF_TIMEOUT, NON_NEGATIVE_INTEGER_VALIDATOR);
VALIDATORS.put(System.SCREEN_BRIGHTNESS_MODE, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(
+ System.SCREEN_BRIGHTNESS_FOR_ALS,
+ new InclusiveIntegerRangeValidator(
+ System.SCREEN_BRIGHTNESS_AUTOMATIC_BRIGHT,
+ System.SCREEN_BRIGHTNESS_AUTOMATIC_DIM));
VALIDATORS.put(System.ADAPTIVE_SLEEP, BOOLEAN_VALIDATOR);
VALIDATORS.put(System.MODE_RINGER_STREAMS_AFFECTED, NON_NEGATIVE_INTEGER_VALIDATOR);
VALIDATORS.put(System.MUTE_STREAMS_AFFECTED, NON_NEGATIVE_INTEGER_VALIDATOR);
diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
index c0f62313cb39..9ddc976af7e2 100644
--- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
+++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
@@ -101,6 +101,7 @@ public class SettingsBackupTest {
Settings.System.MIN_REFRESH_RATE, // depends on hardware capabilities
Settings.System.PEAK_REFRESH_RATE, // depends on hardware capabilities
Settings.System.SCREEN_BRIGHTNESS_FLOAT,
+ Settings.System.SCREEN_BRIGHTNESS_FOR_ALS,
Settings.System.WEAR_ACCESSIBILITY_GESTURE_ENABLED_DURING_OOBE,
Settings.System.WEAR_TTS_PREWARM_ENABLED,
Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ,
diff --git a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
index a81069a1f7db..9b00b5f2aaf2 100644
--- a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
@@ -25,6 +25,7 @@ import static com.android.keyguard.LockIconView.ICON_UNLOCK;
import static com.android.systemui.doze.util.BurnInHelperKt.getBurnInOffset;
import static com.android.systemui.flags.Flags.DOZING_MIGRATION_1;
import static com.android.systemui.flags.Flags.LOCKSCREEN_WALLPAPER_DREAM_ENABLED;
+import static com.android.systemui.flags.Flags.NEW_AOD_TRANSITION;
import static com.android.systemui.flags.Flags.ONE_WAY_HAPTICS_API_MIGRATION;
import static com.android.systemui.util.kotlin.JavaAdapterKt.collectFlow;
@@ -99,6 +100,8 @@ public class LockIconViewController implements Dumpable {
private static final VibrationAttributes TOUCH_VIBRATION_ATTRIBUTES =
VibrationAttributes.createForUsage(VibrationAttributes.USAGE_TOUCH);
+ private static final long FADE_OUT_DURATION_MS = 250L;
+
private final long mLongPressTimeout;
@NonNull private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
@NonNull private final KeyguardViewController mKeyguardViewController;
@@ -388,6 +391,16 @@ public class LockIconViewController implements Dumpable {
mView.updateIcon(ICON_LOCK, true);
mView.setContentDescription(mLockedLabel);
mView.setVisibility(View.VISIBLE);
+ } else if (mIsDozing && mFeatureFlags.isEnabled(NEW_AOD_TRANSITION)) {
+ mView.animate()
+ .alpha(0f)
+ .setDuration(FADE_OUT_DURATION_MS)
+ .withEndAction(() -> {
+ mView.clearIcon();
+ mView.setVisibility(View.INVISIBLE);
+ mView.setContentDescription(null);
+ })
+ .start();
} else {
mView.clearIcon();
mView.setVisibility(View.INVISIBLE);
diff --git a/packages/SystemUI/src/com/android/systemui/flags/FlagCommand.java b/packages/SystemUI/src/com/android/systemui/flags/FlagCommand.java
index e3cc2b02177c..bf9018a1f99c 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/FlagCommand.java
+++ b/packages/SystemUI/src/com/android/systemui/flags/FlagCommand.java
@@ -177,6 +177,13 @@ public class FlagCommand implements Command {
|| (flag instanceof SysPropFlag);
}
+ private Boolean isTeamfoodFlag(Flag<?> flag) {
+ if (!(flag instanceof BooleanFlag)) {
+ return null;
+ }
+ return flag.getTeamfood();
+ }
+
private boolean isBooleanFlagEnabled(Flag<?> flag) {
if (flag instanceof ReleasedFlag) {
return mFeatureFlags.isEnabled((ReleasedFlag) flag);
@@ -232,11 +239,13 @@ public class FlagCommand implements Command {
for (int i = 0; i < longestFieldName - "Flag Name".length() + 1; i++) {
pw.print(" ");
}
- pw.println(" Value");
+ pw.print(" Value ");
+ pw.println(" Teamfood?");
for (int i = 0; i < longestFieldName; i++) {
pw.print("=");
}
- pw.println(" ========");
+ pw.println(" ======= ===========");
+
for (String fieldName : fields.keySet()) {
Flag<?> flag = fields.get(fieldName);
if (!mAllFlags.containsKey(flag.getName())) {
@@ -249,7 +258,19 @@ public class FlagCommand implements Command {
}
pw.print(" ");
if (isBooleanFlag(flag)) {
- pw.println(isBooleanFlagEnabled(flag));
+ boolean enabled = isBooleanFlagEnabled(flag);
+ pw.print(enabled);
+ if (enabled) {
+ pw.print(" ");
+ } else {
+ pw.print(" ");
+ }
+ Boolean teamfood = isTeamfoodFlag(flag);
+ if (teamfood != null) {
+ pw.print(teamfood);
+ }
+ pw.println();
+
} else if (isStringFlag(flag)) {
pw.println(getStringFlag(flag));
} else if (isIntFlag(flag)) {
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
index e33878e8c62d..bdd245ed7b7f 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
@@ -176,7 +176,11 @@ object Flags {
*/
// TODO(b/281655028): Tracking bug
@JvmField
- val LIGHT_REVEAL_MIGRATION = unreleasedFlag("light_reveal_migration", teamfood = false)
+ val LIGHT_REVEAL_MIGRATION = unreleasedFlag("light_reveal_migration", teamfood = true)
+
+ // TODO(b/301915812): Tracking Bug
+ @JvmField
+ val NEW_AOD_TRANSITION = unreleasedFlag("new_aod_transition", teamfood = true)
/** Flag to control the migration of face auth to modern architecture. */
// TODO(b/262838215): Tracking bug
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt
index 1c43609aa551..fbe26de4e9ba 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt
@@ -34,16 +34,17 @@ import com.android.systemui.keyguard.shared.model.KeyguardState.OFF
import com.android.systemui.keyguard.shared.model.KeyguardState.PRIMARY_BOUNCER
import com.android.systemui.keyguard.shared.model.TransitionState
import com.android.systemui.keyguard.shared.model.TransitionStep
+import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.merge
import kotlinx.coroutines.flow.stateIn
-import javax.inject.Inject
/** Encapsulates business-logic related to the keyguard transitions. */
@SysUISingleton
@@ -176,18 +177,17 @@ constructor(
.map { step -> step.to }
.stateIn(scope, SharingStarted.Eagerly, LOCKSCREEN)
-
/**
* Whether we're currently in a transition to a new [KeyguardState] and haven't yet completed
* it.
*/
val isInTransitionToAnyState =
- combine(
- startedKeyguardTransitionStep,
- finishedKeyguardState,
- ) { startedStep, finishedState ->
- startedStep.to != finishedState
- }
+ combine(
+ startedKeyguardTransitionStep,
+ finishedKeyguardState,
+ ) { startedStep, finishedState ->
+ startedStep.to != finishedState
+ }
/**
* The amount of transition into or out of the given [KeyguardState].
@@ -236,14 +236,9 @@ constructor(
/** Whether we're in a transition to the given [KeyguardState], but haven't yet completed it. */
fun isInTransitionToState(
- state: KeyguardState,
+ state: KeyguardState,
): Flow<Boolean> {
- return combine(
- startedKeyguardTransitionStep,
- finishedKeyguardState,
- ) { startedStep, finishedState ->
- startedStep.to == state && finishedState != state
- }
+ return isInTransitionToStateWhere { it == state }
}
/**
@@ -251,28 +246,18 @@ constructor(
* haven't yet completed it.
*/
fun isInTransitionToStateWhere(
- stateMatcher: (KeyguardState) -> Boolean,
+ stateMatcher: (KeyguardState) -> Boolean,
): Flow<Boolean> {
- return combine(
- startedKeyguardTransitionStep,
- finishedKeyguardState,
- ) { startedStep, finishedState ->
- stateMatcher(startedStep.to) && finishedState != startedStep.from
- }
+ return isInTransitionWhere(fromStatePredicate = { true }, toStatePredicate = stateMatcher)
}
/**
* Whether we're in a transition out of the given [KeyguardState], but haven't yet completed it.
*/
fun isInTransitionFromState(
- state: KeyguardState,
+ state: KeyguardState,
): Flow<Boolean> {
- return combine(
- startedKeyguardTransitionStep,
- finishedKeyguardState,
- ) { startedStep, finishedState ->
- startedStep.from == state && finishedState != state
- }
+ return isInTransitionFromStateWhere { it == state }
}
/**
@@ -280,14 +265,9 @@ constructor(
* haven't yet completed it.
*/
fun isInTransitionFromStateWhere(
- stateMatcher: (KeyguardState) -> Boolean,
+ stateMatcher: (KeyguardState) -> Boolean,
): Flow<Boolean> {
- return combine(
- startedKeyguardTransitionStep,
- finishedKeyguardState,
- ) { startedStep, finishedState ->
- stateMatcher(startedStep.from) && finishedState != startedStep.from
- }
+ return isInTransitionWhere(fromStatePredicate = stateMatcher, toStatePredicate = { true })
}
/**
@@ -299,26 +279,23 @@ constructor(
toStatePredicate: (KeyguardState) -> Boolean,
): Flow<Boolean> {
return combine(
- startedKeyguardTransitionStep,
- finishedKeyguardState,
- ) { startedStep, finishedState ->
- fromStatePredicate(startedStep.from)
- && toStatePredicate(startedStep.to)
- && finishedState != startedStep.from
- }
+ startedKeyguardTransitionStep,
+ finishedKeyguardState,
+ ) { startedStep, finishedState ->
+ fromStatePredicate(startedStep.from) &&
+ toStatePredicate(startedStep.to) &&
+ finishedState != startedStep.to
+ }
+ .distinctUntilChanged()
}
- /**
- * Whether we've FINISHED a transition to a state that matches the given predicate.
- */
+ /** Whether we've FINISHED a transition to a state that matches the given predicate. */
fun isFinishedInStateWhere(stateMatcher: (KeyguardState) -> Boolean): Flow<Boolean> {
- return finishedKeyguardState.map { stateMatcher(it) }
+ return finishedKeyguardState.map { stateMatcher(it) }.distinctUntilChanged()
}
- /**
- * Whether we've FINISHED a transition to a state that matches the given predicate.
- */
- fun isFinishedInState(state: KeyguardState) : Flow<Boolean> {
- return finishedKeyguardState.map { it == state }
+ /** Whether we've FINISHED a transition to a state that matches the given predicate. */
+ fun isFinishedInState(state: KeyguardState): Flow<Boolean> {
+ return finishedKeyguardState.map { it == state }.distinctUntilChanged()
}
-} \ No newline at end of file
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceViewBinder.kt
index aa76702dc3d4..f0d118cbe20f 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceViewBinder.kt
@@ -134,7 +134,14 @@ object KeyguardQuickAffordanceViewBinder {
vibratorHelper: VibratorHelper?,
) {
if (!viewModel.isVisible) {
- view.isInvisible = true
+ view.alpha = 1f
+ view
+ .animate()
+ .alpha(0f)
+ .setInterpolator(Interpolators.FAST_OUT_LINEAR_IN)
+ .setDuration(EXIT_DOZE_BUTTON_REVEAL_ANIMATION_DURATION_MS)
+ .withEndAction { view.isInvisible = true }
+ .start()
return
}
@@ -142,11 +149,9 @@ object KeyguardQuickAffordanceViewBinder {
view.isVisible = true
if (viewModel.animateReveal) {
view.alpha = 0f
- view.translationY = view.height / 2f
view
.animate()
.alpha(1f)
- .translationY(0f)
.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN)
.setDuration(EXIT_DOZE_BUTTON_REVEAL_ANIMATION_DURATION_MS)
.start()
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconAreaControllerViewBinderWrapperImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconAreaControllerViewBinderWrapperImpl.kt
index 20241c323ab6..5cc5e751ca8e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconAreaControllerViewBinderWrapperImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconAreaControllerViewBinderWrapperImpl.kt
@@ -35,6 +35,7 @@ import com.android.systemui.demomode.DemoMode
import com.android.systemui.demomode.DemoModeController
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags
+import com.android.systemui.flags.Flags.NEW_AOD_TRANSITION
import com.android.systemui.flags.ViewRefactorFlag
import com.android.systemui.plugins.DarkIconDispatcher
import com.android.systemui.plugins.statusbar.StatusBarStateController
@@ -88,7 +89,7 @@ constructor(
private val bubblesOptional: Optional<Bubbles>,
demoModeController: DemoModeController,
darkIconDispatcher: DarkIconDispatcher,
- featureFlags: FeatureFlags,
+ private val featureFlags: FeatureFlags,
private val statusBarWindowController: StatusBarWindowController,
private val screenOffAnimationController: ScreenOffAnimationController,
private val shelfIconsViewModel: NotificationIconContainerShelfViewModel,
@@ -299,9 +300,12 @@ constructor(
var animate = true
if (!bypassController.bypassEnabled) {
animate = dozeParameters.alwaysOn && !dozeParameters.displayNeedsBlanking
- // We only want the appear animations to happen when the notifications get fully hidden,
- // since otherwise the unhide animation overlaps
- animate = animate and isFullyHidden
+ if (!featureFlags.isEnabled(NEW_AOD_TRANSITION)) {
+ // We only want the appear animations to happen when the notifications get fully
+ // hidden,
+ // since otherwise the unhide animation overlaps
+ animate = animate and isFullyHidden
+ }
}
updateAodIconsVisibility(animate, false /* force */)
updateAodNotificationIcons()
@@ -657,23 +661,34 @@ constructor(
aodIconsVisible = visible
aodIcons!!.animate().cancel()
if (animate) {
- val wasFullyInvisible = aodIcons!!.visibility != View.VISIBLE
- if (aodIconsVisible) {
- if (wasFullyInvisible) {
- // No fading here, let's just appear the icons instead!
- aodIcons!!.visibility = View.VISIBLE
- aodIcons!!.alpha = 1.0f
- appearAodIcons()
+ if (featureFlags.isEnabled(NEW_AOD_TRANSITION)) {
+ // Let's make sure the icon are translated to 0, since we cancelled it above
+ animateInAodIconTranslation()
+ if (aodIconsVisible) {
+ CrossFadeHelper.fadeIn(aodIcons)
+ } else {
+ CrossFadeHelper.fadeOut(aodIcons)
+ }
+ } else {
+ val wasFullyInvisible = aodIcons!!.visibility != View.VISIBLE
+ if (aodIconsVisible) {
+ if (wasFullyInvisible) {
+ // No fading here, let's just appear the icons instead!
+ aodIcons!!.visibility = View.VISIBLE
+ aodIcons!!.alpha = 1.0f
+ appearAodIcons()
+ } else {
+ // Let's make sure the icon are translated to 0, since we cancelled it
+ // above
+ animateInAodIconTranslation()
+ // We were fading out, let's fade in instead
+ CrossFadeHelper.fadeIn(aodIcons)
+ }
} else {
// Let's make sure the icon are translated to 0, since we cancelled it above
animateInAodIconTranslation()
- // We were fading out, let's fade in instead
- CrossFadeHelper.fadeIn(aodIcons)
+ CrossFadeHelper.fadeOut(aodIcons)
}
- } else {
- // Let's make sure the icon are translated to 0, since we cancelled it above
- animateInAodIconTranslation()
- CrossFadeHelper.fadeOut(aodIcons)
}
} else {
aodIcons!!.alpha = 1.0f
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 d18f9919604d..061132ff4f19 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
@@ -772,6 +772,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
/**
* @return if the view is in heads up state, i.e either still heads upped or it's disappearing.
*/
+ @Override
public boolean isHeadsUpState() {
return mIsHeadsUp || mHeadsupDisappearRunning;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
index 5aae48899bc9..f2f55a87ba3f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
@@ -621,6 +621,10 @@ public abstract class ExpandableView extends FrameLayout implements Dumpable, Ro
return false;
}
+ public boolean isHeadsUpState() {
+ return false;
+ }
+
public boolean isChildInGroup() {
return false;
}
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 28f0a0c5fd78..9f95c0924c64 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
@@ -203,6 +203,8 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
private final ViewRefactorFlag mAnimatedInsets;
private final ViewRefactorFlag mShelfRefactor;
+ private final boolean mNewAodTransition;
+
private int mContentHeight;
private float mIntrinsicContentHeight;
private int mPaddingBetweenElements;
@@ -632,6 +634,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
mIsSmallLandscapeLockscreenEnabled = featureFlags.isEnabled(
Flags.LOCKSCREEN_ENABLE_LANDSCAPE);
mDebugLines = featureFlags.isEnabled(Flags.NSSL_DEBUG_LINES);
+ mNewAodTransition = featureFlags.isEnabled(Flags.NEW_AOD_TRANSITION);
mDebugRemoveAnimation = featureFlags.isEnabled(Flags.NSSL_DEBUG_REMOVE_ANIMATION);
mSensitiveRevealAnimEndabled = featureFlags.isEnabled(Flags.SENSITIVE_REVEAL_ANIM);
mAnimatedInsets =
@@ -1432,12 +1435,14 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
@VisibleForTesting
public void updateStackHeight(float endHeight, float fraction) {
- // During the (AOD<=>LS) transition where dozeAmount is changing,
- // apply dozeAmount to stack height instead of expansionFraction
- // to unfurl notifications on AOD=>LS wakeup (and furl up on LS=>AOD sleep)
- final float dozeAmount = mAmbientState.getDozeAmount();
- if (0f < dozeAmount && dozeAmount < 1f) {
- fraction = 1f - dozeAmount;
+ if (!mNewAodTransition) {
+ // During the (AOD<=>LS) transition where dozeAmount is changing,
+ // apply dozeAmount to stack height instead of expansionFraction
+ // to unfurl notifications on AOD=>LS wakeup (and furl up on LS=>AOD sleep)
+ final float dozeAmount = mAmbientState.getDozeAmount();
+ if (0f < dozeAmount && dozeAmount < 1f) {
+ fraction = 1f - dozeAmount;
+ }
}
mAmbientState.setStackHeight(
MathUtils.lerp(endHeight * StackScrollAlgorithm.START_FRACTION,
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 f2d5394e0aee..8ca18521de63 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
@@ -142,7 +142,15 @@ public class StackScrollAlgorithm {
viewState.setAlpha(1f);
} else if (ambientState.isOnKeyguard()) {
// Adjust alpha for wakeup to lockscreen.
- viewState.setAlpha(1f - ambientState.getHideAmount());
+ if (view.isHeadsUpState()) {
+ // Pulsing HUN should be visible on AOD and stay visible during
+ // AOD=>lockscreen transition
+ viewState.setAlpha(1f - ambientState.getHideAmount());
+ } else {
+ // Normal notifications are hidden on AOD and should fade in during
+ // AOD=>lockscreen transition
+ viewState.setAlpha(1f - ambientState.getDozeAmount());
+ }
} else if (ambientState.isExpansionChanging()) {
// Adjust alpha for shade open & close.
float expansion = ambientState.getExpansionFraction();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyNotificationIconAreaControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyNotificationIconAreaControllerImpl.java
index 660aa3f641c4..1b9e5b304635 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyNotificationIconAreaControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyNotificationIconAreaControllerImpl.java
@@ -15,6 +15,8 @@
*/
package com.android.systemui.statusbar.phone;
+import static com.android.systemui.flags.Flags.NEW_AOD_TRANSITION;
+
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Color;
@@ -109,6 +111,8 @@ public class LegacyNotificationIconAreaControllerImpl implements
private final ViewRefactorFlag mShelfRefactor;
+ private final boolean mNewAodTransition;
+
private int mAodIconAppearTranslation;
private boolean mAnimationsEnabled;
@@ -147,6 +151,7 @@ public class LegacyNotificationIconAreaControllerImpl implements
mContext = context;
mStatusBarStateController = statusBarStateController;
mShelfRefactor = new ViewRefactorFlag(featureFlags, Flags.NOTIFICATION_SHELF_REFACTOR);
+ mNewAodTransition = featureFlags.isEnabled(NEW_AOD_TRANSITION);
mStatusBarStateController.addCallback(this);
mMediaManager = notificationMediaManager;
mDozeParameters = dozeParameters;
@@ -609,9 +614,11 @@ public class LegacyNotificationIconAreaControllerImpl implements
boolean animate = true;
if (!mBypassController.getBypassEnabled()) {
animate = mDozeParameters.getAlwaysOn() && !mDozeParameters.getDisplayNeedsBlanking();
- // We only want the appear animations to happen when the notifications get fully hidden,
- // since otherwise the unhide animation overlaps
- animate &= fullyHidden;
+ if (!mNewAodTransition) {
+ // We only want the appear animations to happen when the notifications get fully
+ // hidden, since otherwise the unhide animation overlaps
+ animate &= fullyHidden;
+ }
}
updateAodIconsVisibility(animate, false /* force */);
updateAodNotificationIcons();
@@ -647,23 +654,34 @@ public class LegacyNotificationIconAreaControllerImpl implements
mAodIconsVisible = visible;
mAodIcons.animate().cancel();
if (animate) {
- boolean wasFullyInvisible = mAodIcons.getVisibility() != View.VISIBLE;
- if (mAodIconsVisible) {
- if (wasFullyInvisible) {
- // No fading here, let's just appear the icons instead!
- mAodIcons.setVisibility(View.VISIBLE);
- mAodIcons.setAlpha(1.0f);
- appearAodIcons();
+ if (mNewAodTransition) {
+ // Let's make sure the icon are translated to 0, since we cancelled it above
+ animateInAodIconTranslation();
+ if (mAodIconsVisible) {
+ CrossFadeHelper.fadeIn(mAodIcons);
+ } else {
+ CrossFadeHelper.fadeOut(mAodIcons);
+ }
+ } else {
+ boolean wasFullyInvisible = mAodIcons.getVisibility() != View.VISIBLE;
+ if (mAodIconsVisible) {
+ if (wasFullyInvisible) {
+ // No fading here, let's just appear the icons instead!
+ mAodIcons.setVisibility(View.VISIBLE);
+ mAodIcons.setAlpha(1.0f);
+ appearAodIcons();
+ } else {
+ // Let's make sure the icon are translated to 0, since we cancelled it
+ // above
+ animateInAodIconTranslation();
+ // We were fading out, let's fade in instead
+ CrossFadeHelper.fadeIn(mAodIcons);
+ }
} else {
// Let's make sure the icon are translated to 0, since we cancelled it above
animateInAodIconTranslation();
- // We were fading out, let's fade in instead
- CrossFadeHelper.fadeIn(mAodIcons);
+ CrossFadeHelper.fadeOut(mAodIcons);
}
- } else {
- // Let's make sure the icon are translated to 0, since we cancelled it above
- animateInAodIconTranslation();
- CrossFadeHelper.fadeOut(mAodIcons);
}
} else {
mAodIcons.setAlpha(1.0f);
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerTest.java
index a2dc7763d0ea..7b920939263e 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerTest.java
@@ -17,9 +17,11 @@
package com.android.keyguard;
import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT;
+
import static com.android.keyguard.LockIconView.ICON_LOCK;
import static com.android.keyguard.LockIconView.ICON_UNLOCK;
import static com.android.systemui.flags.Flags.ONE_WAY_HAPTICS_API_MIGRATION;
+
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.anyBoolean;
import static org.mockito.Mockito.anyInt;
@@ -41,6 +43,7 @@ import androidx.test.filters.SmallTest;
import com.android.systemui.biometrics.UdfpsController;
import com.android.systemui.biometrics.shared.model.UdfpsOverlayParams;
import com.android.systemui.doze.util.BurnInHelperKt;
+import com.android.systemui.statusbar.StatusBarState;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -180,13 +183,14 @@ public class LockIconViewControllerTest extends LockIconViewControllerBaseTest {
}
@Test
- public void testLockIcon_clearsIconOnAod_whenUdfpsNotEnrolled() {
+ public void testLockIcon_clearsIconWhenUnlocked() {
// GIVEN udfps not enrolled
setupUdfps();
when(mKeyguardUpdateMonitor.isUdfpsEnrolled()).thenReturn(false);
// GIVEN starting state for the lock icon
setupShowLockIcon();
+ when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE);
// GIVEN lock icon controller is initialized and view is attached
init(/* useMigrationFlag= */false);
@@ -194,7 +198,7 @@ public class LockIconViewControllerTest extends LockIconViewControllerBaseTest {
reset(mLockIconView);
// WHEN the dozing state changes
- mStatusBarStateListener.onDozingChanged(true /* isDozing */);
+ mStatusBarStateListener.onDozingChanged(false /* isDozing */);
// THEN the icon is cleared
verify(mLockIconView).clearIcon();
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerWithCoroutinesTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerWithCoroutinesTest.kt
index c372f4555f61..12135182ac15 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerWithCoroutinesTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerWithCoroutinesTest.kt
@@ -26,6 +26,7 @@ import com.android.systemui.keyguard.shared.model.KeyguardState.AOD
import com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN
import com.android.systemui.keyguard.shared.model.TransitionState.FINISHED
import com.android.systemui.keyguard.shared.model.TransitionStep
+import com.android.systemui.statusbar.StatusBarState
import com.android.systemui.util.mockito.whenever
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
@@ -42,7 +43,7 @@ class LockIconViewControllerWithCoroutinesTest : LockIconViewControllerBaseTest(
/** After migration, replaces LockIconViewControllerTest version */
@Test
- fun testLockIcon_clearsIconOnAod_whenUdfpsNotEnrolled() =
+ fun testLockIcon_clearsIconWhenUnlocked() =
runBlocking(IMMEDIATE) {
// GIVEN udfps not enrolled
setupUdfps()
@@ -50,14 +51,14 @@ class LockIconViewControllerWithCoroutinesTest : LockIconViewControllerBaseTest(
// GIVEN starting state for the lock icon
setupShowLockIcon()
+ whenever(mStatusBarStateController.state).thenReturn(StatusBarState.SHADE)
// GIVEN lock icon controller is initialized and view is attached
init(/* useMigrationFlag= */ true)
reset(mLockIconView)
// WHEN the dozing state changes
- mUnderTest.mIsDozingCallback.accept(true)
-
+ mUnderTest.mIsDozingCallback.accept(false)
// THEN the icon is cleared
verify(mLockIconView).clearIcon()
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt
index 9e9c25eafa33..fa93253642e3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt
@@ -230,4 +230,432 @@ class KeyguardTransitionInteractorTest : SysuiTestCase() {
assertThat(startedSteps).isEqualTo(listOf(0f, 0.5f, 1f, 1f, 0.5f, 0f))
}
+
+ @Test
+ fun isInTransitionToState() = testScope.runTest {
+ val results by collectValues(underTest.isInTransitionToState(GONE))
+
+ sendSteps(
+ TransitionStep(AOD, DOZING, 0f, STARTED),
+ TransitionStep(AOD, DOZING, 0.5f, RUNNING),
+ TransitionStep(AOD, DOZING, 1f, FINISHED),
+ )
+
+
+ assertThat(results).isEqualTo(listOf(
+ false,
+ ))
+
+ sendSteps(
+ TransitionStep(DOZING, GONE, 0f, STARTED),
+ )
+
+ assertThat(results).isEqualTo(listOf(
+ false,
+ true,
+ ))
+
+ sendSteps(
+ TransitionStep(DOZING, GONE, 0f, RUNNING),
+ )
+
+ assertThat(results).isEqualTo(listOf(
+ false,
+ true,
+ ))
+
+ sendSteps(
+ TransitionStep(DOZING, GONE, 0f, FINISHED),
+ )
+
+ assertThat(results).isEqualTo(listOf(
+ false,
+ true,
+ false,
+ ))
+
+ sendSteps(
+ TransitionStep(GONE, DOZING, 0f, STARTED),
+ TransitionStep(GONE, DOZING, 0f, RUNNING),
+ TransitionStep(GONE, DOZING, 1f, FINISHED),
+ )
+
+ assertThat(results).isEqualTo(listOf(
+ false,
+ true,
+ false,
+ ))
+
+ sendSteps(
+ TransitionStep(DOZING, GONE, 0f, STARTED),
+ TransitionStep(DOZING, GONE, 0f, RUNNING),
+ )
+
+ assertThat(results).isEqualTo(listOf(
+ false,
+ true,
+ false,
+ true,
+ ))
+ }
+
+ @Test
+ fun isInTransitionFromState() = testScope.runTest {
+ val results by collectValues(underTest.isInTransitionFromState(DOZING))
+
+ sendSteps(
+ TransitionStep(AOD, DOZING, 0f, STARTED),
+ TransitionStep(AOD, DOZING, 0.5f, RUNNING),
+ TransitionStep(AOD, DOZING, 1f, FINISHED),
+ )
+
+
+ assertThat(results).isEqualTo(listOf(
+ false,
+ ))
+
+ sendSteps(
+ TransitionStep(DOZING, GONE, 0f, STARTED),
+ )
+
+ assertThat(results).isEqualTo(listOf(
+ false,
+ true,
+ ))
+
+ sendSteps(
+ TransitionStep(DOZING, GONE, 0f, RUNNING),
+ )
+
+ assertThat(results).isEqualTo(listOf(
+ false,
+ true,
+ ))
+
+ sendSteps(
+ TransitionStep(DOZING, GONE, 0f, FINISHED),
+ )
+
+ assertThat(results).isEqualTo(listOf(
+ false,
+ true,
+ false,
+ ))
+
+ sendSteps(
+ TransitionStep(GONE, DOZING, 0f, STARTED),
+ TransitionStep(GONE, DOZING, 0f, RUNNING),
+ TransitionStep(GONE, DOZING, 1f, FINISHED),
+ )
+
+ assertThat(results).isEqualTo(listOf(
+ false,
+ true,
+ false,
+ ))
+
+ sendSteps(
+ TransitionStep(DOZING, GONE, 0f, STARTED),
+ TransitionStep(DOZING, GONE, 0f, RUNNING),
+ )
+
+ assertThat(results).isEqualTo(listOf(
+ false,
+ true,
+ false,
+ true,
+ ))
+ }
+
+ @Test
+ fun isInTransitionFromStateWhere() = testScope.runTest {
+ val results by collectValues(underTest.isInTransitionFromStateWhere {
+ it == DOZING
+ })
+
+ sendSteps(
+ TransitionStep(AOD, DOZING, 0f, STARTED),
+ TransitionStep(AOD, DOZING, 0.5f, RUNNING),
+ TransitionStep(AOD, DOZING, 1f, FINISHED),
+ )
+
+
+ assertThat(results).isEqualTo(listOf(
+ false,
+ ))
+
+ sendSteps(
+ TransitionStep(DOZING, GONE, 0f, STARTED),
+ )
+
+ assertThat(results).isEqualTo(listOf(
+ false,
+ true,
+ ))
+
+ sendSteps(
+ TransitionStep(DOZING, GONE, 0f, RUNNING),
+ )
+
+ assertThat(results).isEqualTo(listOf(
+ false,
+ true,
+ ))
+
+ sendSteps(
+ TransitionStep(DOZING, GONE, 0f, FINISHED),
+ )
+
+ assertThat(results).isEqualTo(listOf(
+ false,
+ true,
+ false,
+ ))
+
+ sendSteps(
+ TransitionStep(GONE, DOZING, 0f, STARTED),
+ TransitionStep(GONE, DOZING, 0f, RUNNING),
+ TransitionStep(GONE, DOZING, 1f, FINISHED),
+ )
+
+ assertThat(results).isEqualTo(listOf(
+ false,
+ true,
+ false,
+ ))
+
+ sendSteps(
+ TransitionStep(DOZING, GONE, 0f, STARTED),
+ TransitionStep(DOZING, GONE, 0f, RUNNING),
+ )
+
+ assertThat(results).isEqualTo(listOf(
+ false,
+ true,
+ false,
+ true,
+ ))
+ }
+
+ @Test
+ fun isInTransitionWhere() = testScope.runTest {
+ val results by collectValues(underTest.isInTransitionWhere(
+ fromStatePredicate = { it == DOZING },
+ toStatePredicate = { it == GONE },
+ ))
+
+ sendSteps(
+ TransitionStep(AOD, DOZING, 0f, STARTED),
+ TransitionStep(AOD, DOZING, 0.5f, RUNNING),
+ TransitionStep(AOD, DOZING, 1f, FINISHED),
+ )
+
+
+ assertThat(results).isEqualTo(listOf(
+ false,
+ ))
+
+ sendSteps(
+ TransitionStep(DOZING, GONE, 0f, STARTED),
+ )
+
+ assertThat(results).isEqualTo(listOf(
+ false,
+ true,
+ ))
+
+ sendSteps(
+ TransitionStep(DOZING, GONE, 0f, RUNNING),
+ )
+
+ assertThat(results).isEqualTo(listOf(
+ false,
+ true,
+ ))
+
+ sendSteps(
+ TransitionStep(DOZING, GONE, 0f, FINISHED),
+ )
+
+ assertThat(results).isEqualTo(listOf(
+ false,
+ true,
+ false,
+ ))
+
+ sendSteps(
+ TransitionStep(GONE, DOZING, 0f, STARTED),
+ TransitionStep(GONE, DOZING, 0f, RUNNING),
+ TransitionStep(GONE, DOZING, 1f, FINISHED),
+ )
+
+ assertThat(results).isEqualTo(listOf(
+ false,
+ true,
+ false,
+ ))
+
+ sendSteps(
+ TransitionStep(DOZING, GONE, 0f, STARTED),
+ TransitionStep(DOZING, GONE, 0f, RUNNING),
+ )
+
+ assertThat(results).isEqualTo(listOf(
+ false,
+ true,
+ false,
+ true,
+ ))
+ }
+
+ @Test
+ fun isFinishedInStateWhere() = testScope.runTest {
+ val results by collectValues(underTest.isFinishedInStateWhere { it == GONE } )
+
+ sendSteps(
+ TransitionStep(AOD, DOZING, 0f, STARTED),
+ TransitionStep(AOD, DOZING, 0.5f, RUNNING),
+ TransitionStep(AOD, DOZING, 1f, FINISHED),
+ )
+
+ assertThat(results).isEqualTo(listOf(
+ false, // Finished in DOZING, not GONE.
+ ))
+
+ sendSteps(TransitionStep(DOZING, GONE, 0f, STARTED))
+
+ assertThat(results).isEqualTo(listOf(
+ false,
+ ))
+
+ sendSteps(TransitionStep(DOZING, GONE, 0f, RUNNING))
+
+ assertThat(results).isEqualTo(listOf(
+ false,
+ ))
+
+ sendSteps(TransitionStep(DOZING, GONE, 1f, FINISHED))
+
+ assertThat(results).isEqualTo(listOf(
+ false,
+ true,
+ ))
+
+ sendSteps(
+ TransitionStep(GONE, DOZING, 0f, STARTED),
+ TransitionStep(GONE, DOZING, 0f, RUNNING),
+ )
+
+ assertThat(results).isEqualTo(listOf(
+ false,
+ true,
+ ))
+
+ sendSteps(TransitionStep(GONE, DOZING, 1f, FINISHED))
+
+ assertThat(results).isEqualTo(listOf(
+ false,
+ true,
+ false,
+ ))
+
+ sendSteps(
+ TransitionStep(DOZING, GONE, 0f, STARTED),
+ TransitionStep(DOZING, GONE, 0f, RUNNING),
+ )
+
+ assertThat(results).isEqualTo(listOf(
+ false,
+ true,
+ false,
+ ))
+
+ sendSteps(TransitionStep(DOZING, GONE, 1f, FINISHED))
+
+ assertThat(results).isEqualTo(listOf(
+ false,
+ true,
+ false,
+ true,
+ ))
+ }
+
+ @Test
+ fun isFinishedInState() = testScope.runTest {
+ val results by collectValues(underTest.isFinishedInState(GONE))
+
+ sendSteps(
+ TransitionStep(AOD, DOZING, 0f, STARTED),
+ TransitionStep(AOD, DOZING, 0.5f, RUNNING),
+ TransitionStep(AOD, DOZING, 1f, FINISHED),
+ )
+
+ assertThat(results).isEqualTo(listOf(
+ false, // Finished in DOZING, not GONE.
+ ))
+
+ sendSteps(TransitionStep(DOZING, GONE, 0f, STARTED))
+
+ assertThat(results).isEqualTo(listOf(
+ false,
+ ))
+
+ sendSteps(TransitionStep(DOZING, GONE, 0f, RUNNING))
+
+ assertThat(results).isEqualTo(listOf(
+ false,
+ ))
+
+ sendSteps(TransitionStep(DOZING, GONE, 1f, FINISHED))
+
+ assertThat(results).isEqualTo(listOf(
+ false,
+ true,
+ ))
+
+ sendSteps(
+ TransitionStep(GONE, DOZING, 0f, STARTED),
+ TransitionStep(GONE, DOZING, 0f, RUNNING),
+ )
+
+ assertThat(results).isEqualTo(listOf(
+ false,
+ true,
+ ))
+
+ sendSteps(TransitionStep(GONE, DOZING, 1f, FINISHED))
+
+ assertThat(results).isEqualTo(listOf(
+ false,
+ true,
+ false,
+ ))
+
+ sendSteps(
+ TransitionStep(DOZING, GONE, 0f, STARTED),
+ TransitionStep(DOZING, GONE, 0f, RUNNING),
+ )
+
+ assertThat(results).isEqualTo(listOf(
+ false,
+ true,
+ false,
+ ))
+
+ sendSteps(TransitionStep(DOZING, GONE, 1f, FINISHED))
+
+ assertThat(results).isEqualTo(listOf(
+ false,
+ true,
+ false,
+ true,
+ ))
+ }
+
+ private suspend fun sendSteps(vararg steps: TransitionStep) {
+ steps.forEach {
+ repository.sendTransitionStep(it)
+ testScope.runCurrent()
+ }
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
index 3a820e8087a8..236bcb416573 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
@@ -163,6 +163,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
mFeatureFlags.setDefault(Flags.SENSITIVE_REVEAL_ANIM);
mFeatureFlags.setDefault(Flags.ANIMATED_NOTIFICATION_SHADE_INSETS);
mFeatureFlags.setDefault(Flags.NOTIFICATION_SHELF_REFACTOR);
+ mFeatureFlags.setDefault(Flags.NEW_AOD_TRANSITION);
// Inject dependencies before initializing the layout
mDependency.injectTestDependency(FeatureFlags.class, mFeatureFlags);
@@ -247,25 +248,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
}
@Test
- public void testUpdateStackHeight_withDozeAmount_whenDozeChanging() {
- final float dozeAmount = 0.5f;
- mAmbientState.setDozeAmount(dozeAmount);
-
- final float endHeight = 8f;
- final float expansionFraction = 1f;
- float expected = MathUtils.lerp(
- endHeight * StackScrollAlgorithm.START_FRACTION,
- endHeight, dozeAmount);
-
- mStackScroller.updateStackHeight(endHeight, expansionFraction);
- assertThat(mAmbientState.getStackHeight()).isEqualTo(expected);
- }
-
- @Test
public void testUpdateStackHeight_withExpansionAmount_whenDozeNotChanging() {
- final float dozeAmount = 1f;
- mAmbientState.setDozeAmount(dozeAmount);
-
final float endHeight = 8f;
final float expansionFraction = 0.5f;
final float expected = MathUtils.lerp(
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 a52466d2fa41..93faa77bef5c 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
@@ -241,6 +241,8 @@ class StackScrollAlgorithmTest : SysuiTestCase() {
fun resetViewStates_isOnKeyguard_viewBecomesTransparent() {
ambientState.setStatusBarState(StatusBarState.KEYGUARD)
ambientState.hideAmount = 0.25f
+ whenever(notificationRow.isHeadsUpState).thenReturn(true)
+
stackScrollAlgorithm.initView(context)
stackScrollAlgorithm.resetViewStates(ambientState, /* speedBumpIndex= */ 0)
@@ -283,17 +285,20 @@ class StackScrollAlgorithmTest : SysuiTestCase() {
val row2 = mockExpandableNotificationRow()
hostView.addView(row2)
+ whenever(row1.isHeadsUpState).thenReturn(true)
+ whenever(row2.isHeadsUpState).thenReturn(false)
+
ambientState.setStatusBarState(StatusBarState.KEYGUARD)
ambientState.hideAmount = 0.25f
+ ambientState.dozeAmount = 0.33f
notificationShelf.viewState.hidden = true
ambientState.shelf = notificationShelf
stackScrollAlgorithm.initView(context)
stackScrollAlgorithm.resetViewStates(ambientState, /* speedBumpIndex= */ 0)
- val expected = 1f - ambientState.hideAmount
- assertThat(row1.viewState.alpha).isEqualTo(expected)
- assertThat(row2.viewState.alpha).isEqualTo(expected)
+ assertThat(row1.viewState.alpha).isEqualTo(1f - ambientState.hideAmount)
+ assertThat(row2.viewState.alpha).isEqualTo(1f - ambientState.dozeAmount)
}
@Test
diff --git a/services/core/java/com/android/server/OWNERS b/services/core/java/com/android/server/OWNERS
index 55130e4cbbe6..987507fe7f03 100644
--- a/services/core/java/com/android/server/OWNERS
+++ b/services/core/java/com/android/server/OWNERS
@@ -16,9 +16,6 @@ per-file UserspaceRebootLogger.java = ioffe@google.com, dvander@google.com
# ServiceWatcher
per-file ServiceWatcher.java = sooniln@google.com
-# Health
-per-file BatteryService.java = file:platform/hardware/interfaces:/health/aidl/OWNERS
-
per-file *Accessibility* = file:/services/accessibility/OWNERS
per-file *Alarm* = file:/apex/jobscheduler/OWNERS
per-file *AppOp* = file:/core/java/android/permission/OWNERS
@@ -39,7 +36,7 @@ per-file MmsServiceBroker.java = file:/telephony/OWNERS
per-file NetIdManager.java = file:/services/core/java/com/android/server/net/OWNERS
per-file PackageWatchdog.java, RescueParty.java = file:/services/core/java/com/android/server/rollback/OWNERS
per-file PinnerService.java = file:/apct-tests/perftests/OWNERS
-per-file RescueParty.java = fdunlap@google.com, shuc@google.com, ancr@google.com, harshitmahajan@google.com
+per-file RescueParty.java = shuc@google.com, ancr@google.com, harshitmahajan@google.com
per-file SystemClockTime.java = file:/services/core/java/com/android/server/timedetector/OWNERS
per-file SystemTimeZone.java = file:/services/core/java/com/android/server/timezonedetector/OWNERS
per-file TelephonyRegistry.java = file:/telephony/OWNERS
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index a3c71c2e0218..db69d93583d4 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -541,6 +541,13 @@ public class NotificationManagerService extends SystemService {
@EnabledAfter(targetSdkVersion = Build.VERSION_CODES.S_V2)
private static final long NOTIFICATION_LOG_ASSISTANT_CANCEL = 195579280L;
+ /**
+ * NO_CLEAR flag will be set for any media notification.
+ */
+ @ChangeId
+ @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ static final long ENFORCE_NO_CLEAR_FLAG_ON_MEDIA_NOTIFICATION = 264179692L;
+
private static final Duration POST_WAKE_LOCK_TIMEOUT = Duration.ofSeconds(30);
private IActivityManager mAm;
@@ -7189,6 +7196,12 @@ public class NotificationManagerService extends SystemService {
+ "MEDIA_CONTENT_CONTROL permission");
}
}
+
+ // Enforce NO_CLEAR flag on MediaStyle notification for apps with targetSdk >= V.
+ if (CompatChanges.isChangeEnabled(ENFORCE_NO_CLEAR_FLAG_ON_MEDIA_NOTIFICATION,
+ notificationUid)) {
+ notification.flags |= Notification.FLAG_NO_CLEAR;
+ }
}
// Ensure only allowed packages have a substitute app name
diff --git a/services/tests/uiservicestests/Android.bp b/services/tests/uiservicestests/Android.bp
index 2dacda0af7f4..1d37f9da8d7a 100644
--- a/services/tests/uiservicestests/Android.bp
+++ b/services/tests/uiservicestests/Android.bp
@@ -31,6 +31,7 @@ android_test {
"androidx.test.rules",
"hamcrest-library",
"mockito-target-inline-minus-junit4",
+ "platform-compat-test-rules",
"platform-test-annotations",
"platformprotosnano",
"statsdprotolite",
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index 9543a2de1e13..c98d2359b2f9 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -164,6 +164,7 @@ import android.app.admin.DevicePolicyManagerInternal;
import android.app.usage.UsageStatsManagerInternal;
import android.companion.AssociationInfo;
import android.companion.ICompanionDeviceManager;
+import android.compat.testing.PlatformCompatChangeRule;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentUris;
@@ -270,11 +271,15 @@ import com.android.server.wm.WindowManagerInternal;
import com.google.android.collect.Lists;
import com.google.common.collect.ImmutableList;
+import libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges;
+import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges;
+
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.TestRule;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.ArgumentMatcher;
@@ -317,6 +322,9 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
private final int mUid = Binder.getCallingUid();
private final @UserIdInt int mUserId = UserHandle.getUserId(mUid);
+ @Rule
+ public TestRule compatChangeRule = new PlatformCompatChangeRule();
+
private TestableNotificationManagerService mService;
private INotificationManager mBinderService;
private NotificationManagerInternal mInternalService;
@@ -4828,6 +4836,62 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
}
@Test
+ @EnableCompatChanges({NotificationManagerService.ENFORCE_NO_CLEAR_FLAG_ON_MEDIA_NOTIFICATION})
+ public void testMediaStyle_enforceNoClearFlagEnabled() throws RemoteException {
+ Notification.MediaStyle style = new Notification.MediaStyle();
+ Notification.Builder nb = new Notification.Builder(mContext,
+ mTestNotificationChannel.getId())
+ .setStyle(style);
+
+ NotificationRecord posted = createAndPostNotification(nb, "testMediaStyleSetNoClearFlag");
+
+ assertThat(posted.getFlags() & FLAG_NO_CLEAR).isEqualTo(FLAG_NO_CLEAR);
+ }
+
+ @Test
+ @EnableCompatChanges({NotificationManagerService.ENFORCE_NO_CLEAR_FLAG_ON_MEDIA_NOTIFICATION})
+ public void testCustomMediaStyle_enforceNoClearFlagEnabled() throws RemoteException {
+ Notification.DecoratedMediaCustomViewStyle style =
+ new Notification.DecoratedMediaCustomViewStyle();
+ Notification.Builder nb = new Notification.Builder(mContext,
+ mTestNotificationChannel.getId())
+ .setStyle(style);
+
+ NotificationRecord posted = createAndPostNotification(nb,
+ "testCustomMediaStyleSetNoClearFlag");
+
+ assertThat(posted.getFlags() & FLAG_NO_CLEAR).isEqualTo(FLAG_NO_CLEAR);
+ }
+
+ @Test
+ @DisableCompatChanges(NotificationManagerService.ENFORCE_NO_CLEAR_FLAG_ON_MEDIA_NOTIFICATION)
+ public void testMediaStyle_enforceNoClearFlagDisabled() throws RemoteException {
+ Notification.MediaStyle style = new Notification.MediaStyle();
+ Notification.Builder nb = new Notification.Builder(mContext,
+ mTestNotificationChannel.getId())
+ .setStyle(style);
+
+ NotificationRecord posted = createAndPostNotification(nb, "testMediaStyleSetNoClearFlag");
+
+ assertThat(posted.getFlags() & FLAG_NO_CLEAR).isNotEqualTo(FLAG_NO_CLEAR);
+ }
+
+ @Test
+ @DisableCompatChanges(NotificationManagerService.ENFORCE_NO_CLEAR_FLAG_ON_MEDIA_NOTIFICATION)
+ public void testCustomMediaStyle_enforceNoClearFlagDisabled() throws RemoteException {
+ Notification.DecoratedMediaCustomViewStyle style =
+ new Notification.DecoratedMediaCustomViewStyle();
+ Notification.Builder nb = new Notification.Builder(mContext,
+ mTestNotificationChannel.getId())
+ .setStyle(style);
+
+ NotificationRecord posted = createAndPostNotification(nb,
+ "testCustomMediaStyleSetNoClearFlag");
+
+ assertThat(posted.getFlags() & FLAG_NO_CLEAR).isNotEqualTo(FLAG_NO_CLEAR);
+ }
+
+ @Test
public void testMediaStyleRemote_hasPermission() throws RemoteException {
String deviceName = "device";
mContext.getTestablePermissions().setPermission(
@@ -4838,17 +4902,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
mTestNotificationChannel.getId())
.setStyle(style);
- StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1,
- "testMediaStyleRemoteHasPermission", mUid, 0,
- nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
- NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
-
- mBinderService.enqueueNotificationWithTag(PKG, PKG, sbn.getTag(),
- nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
- waitForIdle();
-
- NotificationRecord posted = mService.findNotificationLocked(
- PKG, nr.getSbn().getTag(), nr.getSbn().getId(), nr.getSbn().getUserId());
+ NotificationRecord posted = createAndPostNotification(nb,
+ "testMediaStyleRemoteHasPermission");
Bundle extras = posted.getNotification().extras;
assertTrue(extras.containsKey(Notification.EXTRA_MEDIA_REMOTE_DEVICE));
@@ -4866,17 +4921,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
mTestNotificationChannel.getId())
.setStyle(style);
- StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1,
- "testMediaStyleRemoteNoPermission", mUid, 0,
- nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
- NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
-
- mBinderService.enqueueNotificationWithTag(PKG, PKG, sbn.getTag(),
- nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
- waitForIdle();
-
- NotificationRecord posted = mService.findNotificationLocked(
- PKG, nr.getSbn().getTag(), nr.getSbn().getId(), nr.getSbn().getUserId());
+ NotificationRecord posted = createAndPostNotification(nb,
+ "testMediaStyleRemoteNoPermission");
assertFalse(posted.getNotification().extras
.containsKey(Notification.EXTRA_MEDIA_REMOTE_DEVICE));
@@ -4899,17 +4945,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
mTestNotificationChannel.getId())
.setStyle(style);
- StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1,
- "testCustomMediaStyleRemoteNoPermission", mUid, 0,
- nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
- NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
-
- mBinderService.enqueueNotificationWithTag(PKG, PKG, sbn.getTag(),
- nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
- waitForIdle();
-
- NotificationRecord posted = mService.findNotificationLocked(
- PKG, nr.getSbn().getTag(), nr.getSbn().getId(), nr.getSbn().getUserId());
+ NotificationRecord posted = createAndPostNotification(nb,
+ "testCustomMediaStyleRemoteNoPermission");
assertFalse(posted.getNotification().extras
.containsKey(Notification.EXTRA_MEDIA_REMOTE_DEVICE));
@@ -4929,16 +4966,9 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
Notification.Builder nb = new Notification.Builder(mContext,
mTestNotificationChannel.getId())
.addExtras(extras);
- StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1,
- "testSubstituteAppNamePermission", mUid, 0,
- nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
- NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
- mBinderService.enqueueNotificationWithTag(PKG, PKG, sbn.getTag(),
- nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
- waitForIdle();
- NotificationRecord posted = mService.findNotificationLocked(
- PKG, nr.getSbn().getTag(), nr.getSbn().getId(), nr.getSbn().getUserId());
+ NotificationRecord posted = createAndPostNotification(nb,
+ "testSubstituteAppNameHasPermission");
assertTrue(posted.getNotification().extras
.containsKey(Notification.EXTRA_SUBSTITUTE_APP_NAME));
@@ -4955,16 +4985,9 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
Notification.Builder nb = new Notification.Builder(mContext,
mTestNotificationChannel.getId())
.addExtras(extras);
- StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1,
- "testSubstituteAppNamePermission", mUid, 0,
- nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
- NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
- mBinderService.enqueueNotificationWithTag(PKG, PKG, sbn.getTag(),
- nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
- waitForIdle();
- NotificationRecord posted = mService.findNotificationLocked(
- PKG, nr.getSbn().getTag(), nr.getSbn().getId(), nr.getSbn().getUserId());
+ NotificationRecord posted = createAndPostNotification(nb,
+ "testSubstituteAppNameNoPermission");
assertFalse(posted.getNotification().extras
.containsKey(Notification.EXTRA_SUBSTITUTE_APP_NAME));
@@ -12656,6 +12679,20 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
verify(service, times(1)).setDNDMigrationDone(user.id);
}
+ private NotificationRecord createAndPostNotification(Notification.Builder nb, String testName)
+ throws RemoteException {
+ StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1, testName, mUid, 0,
+ nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
+ NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
+
+ mBinderService.enqueueNotificationWithTag(PKG, PKG, sbn.getTag(),
+ nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
+ waitForIdle();
+
+ return mService.findNotificationLocked(
+ PKG, nr.getSbn().getTag(), nr.getSbn().getId(), nr.getSbn().getUserId());
+ }
+
private static <T extends Parcelable> T parcelAndUnparcel(T source,
Parcelable.Creator<T> creator) {
Parcel parcel = Parcel.obtain();
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index a5e0638fec95..98bbb40282c9 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -519,8 +519,6 @@ public class CarrierConfigManager {
/**
* Used in the Preferred Network Types menu to determine if the 2G option is displayed.
* Value defaults to false as of Android T to discourage the use of insecure 2G protocols.
- *
- * @see #KEY_HIDE_ENABLE_2G
*/
public static final String KEY_PREFER_2G_BOOL = "prefer_2g_bool";
@@ -9541,9 +9539,9 @@ public class CarrierConfigManager {
* Used to trade privacy/security against potentially reduced carrier coverage for some
* carriers.
*
- * @deprecated Future versions of Android will disallow carriers from hiding this toggle
- * because disabling 2g is a security feature that users should always have access to at
- * their discretion.
+ * @removed This config option is no longer supported as it was hiding a security feature
+ * from users. Setting this option will not change the behavior of the Settings menu starting
+ * in Android V.
*/
@Deprecated
public static final String KEY_HIDE_ENABLE_2G = "hide_enable_2g_bool";
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/PipAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/PipAppHelper.kt
index c30786f4e1c4..da51eff24dc1 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/PipAppHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/PipAppHelper.kt
@@ -17,6 +17,7 @@
package com.android.server.wm.flicker.helpers
import android.app.Instrumentation
+import android.content.Intent
import android.media.session.MediaController
import android.media.session.MediaSessionManager
import android.tools.common.datatypes.Rect
@@ -267,6 +268,11 @@ open class PipAppHelper(instrumentation: Instrumentation) :
fun exitPipToFullScreenViaIntent(wmHelper: WindowManagerStateHelper) =
launchViaIntent(wmHelper)
+ fun changeAspectRatio() {
+ val intent = Intent("com.android.wm.shell.flicker.testapp.ASPECT_RATIO")
+ context.sendBroadcast(intent)
+ }
+
fun clickEnterPipButton(wmHelper: WindowManagerStateHelper) {
clickObject(ENTER_PIP_BUTTON_ID)
diff --git a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/PipActivity.java b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/PipActivity.java
index cdb1d42bd4f2..12eaad108fc6 100644
--- a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/PipActivity.java
+++ b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/PipActivity.java
@@ -82,6 +82,8 @@ public class PipActivity extends Activity {
"com.android.wm.shell.flicker.testapp.SWITCH_OFF";
private static final String ACTION_SWITCH_ON = "com.android.wm.shell.flicker.testapp.SWITCH_ON";
private static final String ACTION_CLEAR = "com.android.wm.shell.flicker.testapp.CLEAR";
+ private static final String ACTION_ASPECT_RATIO =
+ "com.android.wm.shell.flicker.testapp.ASPECT_RATIO";
private final PictureInPictureParams.Builder mPipParamsBuilder =
new PictureInPictureParams.Builder()
@@ -109,6 +111,9 @@ public class PipActivity extends Activity {
case ACTION_CLEAR:
mPipParamsBuilder.setActions(Collections.emptyList());
break;
+ case ACTION_ASPECT_RATIO:
+ mPipParamsBuilder.setAspectRatio(RATIO_TALL);
+ break;
case ACTION_NO_OP:
return;
default:
@@ -190,6 +195,7 @@ public class PipActivity extends Activity {
filter.addAction(ACTION_CLEAR);
filter.addAction(ACTION_SET_REQUESTED_ORIENTATION);
filter.addAction(ACTION_ENTER_PIP);
+ filter.addAction(ACTION_ASPECT_RATIO);
registerReceiver(mBroadcastReceiver, filter);
handleIntentExtra(getIntent());