summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/content/pm/TEST_MAPPING28
-rw-r--r--core/java/android/hardware/usb/UsbConfiguration.java3
-rw-r--r--core/jni/com_android_internal_os_LongArrayMultiStateCounter.cpp12
-rw-r--r--core/jni/com_android_internal_os_LongMultiStateCounter.cpp12
-rw-r--r--core/tests/coretests/src/com/android/internal/os/LongArrayMultiStateCounterTest.java40
-rw-r--r--core/tests/coretests/src/com/android/internal/os/LongMultiStateCounterTest.java39
-rw-r--r--packages/SystemUI/res/values/flags.xml3
-rw-r--r--packages/SystemUI/src/com/android/systemui/FaceScanningOverlay.kt12
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/Utils.kt7
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt29
-rw-r--r--packages/SystemUI/src/com/android/systemui/decor/FaceScanningProviderFactory.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/flags/Flags.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt44
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java24
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java1
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/FaceScanningProviderFactoryTest.kt7
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java7
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java13
-rw-r--r--services/core/java/com/android/server/PendingIntentUtils.java1
-rw-r--r--services/core/java/com/android/server/pm/TEST_MAPPING6
20 files changed, 226 insertions, 73 deletions
diff --git a/core/java/android/content/pm/TEST_MAPPING b/core/java/android/content/pm/TEST_MAPPING
index 3ffbe1d1c71b..2ea6513c4d77 100644
--- a/core/java/android/content/pm/TEST_MAPPING
+++ b/core/java/android/content/pm/TEST_MAPPING
@@ -101,20 +101,6 @@
],
"presubmit-large":[
{
- "name":"CtsContentTestCases",
- "options":[
- {
- "exclude-annotation":"androidx.test.filters.FlakyTest"
- },
- {
- "exclude-annotation":"org.junit.Ignore"
- },
- {
- "include-filter":"android.content.pm.cts"
- }
- ]
- },
- {
"name":"CtsUsesNativeLibraryTest",
"options":[
{
@@ -156,6 +142,20 @@
],
"postsubmit":[
{
+ "name":"CtsContentTestCases",
+ "options":[
+ {
+ "exclude-annotation":"androidx.test.filters.FlakyTest"
+ },
+ {
+ "exclude-annotation":"org.junit.Ignore"
+ },
+ {
+ "include-filter":"android.content.pm.cts"
+ }
+ ]
+ },
+ {
"name":"CtsAppSecurityHostTestCases",
"options":[
{
diff --git a/core/java/android/hardware/usb/UsbConfiguration.java b/core/java/android/hardware/usb/UsbConfiguration.java
index 66269cb772f8..b25f47b11532 100644
--- a/core/java/android/hardware/usb/UsbConfiguration.java
+++ b/core/java/android/hardware/usb/UsbConfiguration.java
@@ -172,7 +172,8 @@ public class UsbConfiguration implements Parcelable {
String name = in.readString();
int attributes = in.readInt();
int maxPower = in.readInt();
- Parcelable[] interfaces = in.readParcelableArray(UsbInterface.class.getClassLoader());
+ Parcelable[] interfaces = in.readParcelableArray(
+ UsbInterface.class.getClassLoader(), UsbInterface.class);
UsbConfiguration configuration = new UsbConfiguration(id, name, attributes, maxPower);
configuration.setInterfaces(interfaces);
return configuration;
diff --git a/core/jni/com_android_internal_os_LongArrayMultiStateCounter.cpp b/core/jni/com_android_internal_os_LongArrayMultiStateCounter.cpp
index a95b6e37f5de..76f5c107c970 100644
--- a/core/jni/com_android_internal_os_LongArrayMultiStateCounter.cpp
+++ b/core/jni/com_android_internal_os_LongArrayMultiStateCounter.cpp
@@ -127,16 +127,17 @@ static void native_writeToParcel(JNIEnv *env, jobject self, jlong nativePtr, job
}
}
-static void throwReadRE(JNIEnv *env, binder_status_t status) {
+static void throwReadException(JNIEnv *env, binder_status_t status) {
ALOGE("Could not read LongArrayMultiStateCounter from Parcel, status = %d", status);
- jniThrowRuntimeException(env, "Could not read LongArrayMultiStateCounter from Parcel");
+ jniThrowException(env, "android.os.BadParcelableException",
+ "Could not read LongArrayMultiStateCounter from Parcel");
}
#define THROW_AND_RETURN_ON_READ_ERROR(expr) \
{ \
binder_status_t status = expr; \
if (status != STATUS_OK) { \
- throwReadRE(env, status); \
+ throwReadException(env, status); \
return 0L; \
} \
}
@@ -147,6 +148,11 @@ static jlong native_initFromParcel(JNIEnv *env, jclass theClass, jobject jParcel
int32_t stateCount;
THROW_AND_RETURN_ON_READ_ERROR(AParcel_readInt32(parcel.get(), &stateCount));
+ if (stateCount < 0 || stateCount > 0xEFFF) {
+ throwReadException(env, STATUS_INVALID_OPERATION);
+ return 0L;
+ }
+
int32_t arrayLength;
THROW_AND_RETURN_ON_READ_ERROR(AParcel_readInt32(parcel.get(), &arrayLength));
diff --git a/core/jni/com_android_internal_os_LongMultiStateCounter.cpp b/core/jni/com_android_internal_os_LongMultiStateCounter.cpp
index 1712b3a8512b..ddf7a67e00ce 100644
--- a/core/jni/com_android_internal_os_LongMultiStateCounter.cpp
+++ b/core/jni/com_android_internal_os_LongMultiStateCounter.cpp
@@ -131,16 +131,17 @@ static void native_writeToParcel(JNIEnv *env, jobject self, jlong nativePtr, job
}
}
-static void throwReadRE(JNIEnv *env, binder_status_t status) {
+static void throwReadException(JNIEnv *env, binder_status_t status) {
ALOGE("Could not read LongMultiStateCounter from Parcel, status = %d", status);
- jniThrowRuntimeException(env, "Could not read LongMultiStateCounter from Parcel");
+ jniThrowException(env, "android.os.BadParcelableException",
+ "Could not read LongMultiStateCounter from Parcel");
}
#define THROW_AND_RETURN_ON_READ_ERROR(expr) \
{ \
binder_status_t status = expr; \
if (status != STATUS_OK) { \
- throwReadRE(env, status); \
+ throwReadException(env, status); \
return 0L; \
} \
}
@@ -151,6 +152,11 @@ static jlong native_initFromParcel(JNIEnv *env, jclass theClass, jobject jParcel
int32_t stateCount;
THROW_AND_RETURN_ON_READ_ERROR(AParcel_readInt32(parcel.get(), &stateCount));
+ if (stateCount < 0 || stateCount > 0xEFFF) {
+ throwReadException(env, STATUS_INVALID_OPERATION);
+ return 0L;
+ }
+
auto counter = std::make_unique<battery::LongMultiStateCounter>(stateCount, 0);
for (battery::state_t state = 0; state < stateCount; state++) {
diff --git a/core/tests/coretests/src/com/android/internal/os/LongArrayMultiStateCounterTest.java b/core/tests/coretests/src/com/android/internal/os/LongArrayMultiStateCounterTest.java
index 516dee7dc9aa..faccf1ad19a1 100644
--- a/core/tests/coretests/src/com/android/internal/os/LongArrayMultiStateCounterTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/LongArrayMultiStateCounterTest.java
@@ -20,6 +20,7 @@ import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertThrows;
+import android.os.BadParcelableException;
import android.os.Parcel;
import androidx.test.filters.SmallTest;
@@ -163,6 +164,45 @@ public class LongArrayMultiStateCounterTest {
}
@Test
+ public void createFromBadBundle() {
+ Parcel data = Parcel.obtain();
+ int bundleLenPos = data.dataPosition();
+ data.writeInt(0);
+ data.writeInt(0x4C444E42); // BaseBundle.BUNDLE_MAGIC
+
+ int bundleStart = data.dataPosition();
+
+ data.writeInt(1);
+ data.writeString("key");
+ data.writeInt(4);
+ int lazyValueLenPos = data.dataPosition();
+ data.writeInt(0);
+ int lazyValueStart = data.dataPosition();
+ data.writeString("com.android.internal.os.LongArrayMultiStateCounter");
+
+ // Invalid int16 value
+ data.writeInt(0x10000); // stateCount
+ data.writeInt(10); // arrayLength
+ for (int i = 0; i < 0x10000; ++i) {
+ data.writeLong(0);
+ }
+
+ backPatchLength(data, lazyValueLenPos, lazyValueStart);
+ backPatchLength(data, bundleLenPos, bundleStart);
+ data.setDataPosition(0);
+
+ assertThrows(BadParcelableException.class,
+ () -> data.readBundle().getParcelable("key", LongArrayMultiStateCounter.class));
+ }
+
+ private static void backPatchLength(Parcel parcel, int lengthPos, int startPos) {
+ int endPos = parcel.dataPosition();
+ parcel.setDataPosition(lengthPos);
+ parcel.writeInt(endPos - startPos);
+ parcel.setDataPosition(endPos);
+ }
+
+ @Test
public void combineValues() {
long[] values = new long[] {0, 1, 2, 3, 42};
LongArrayMultiStateCounter.LongArrayContainer container =
diff --git a/core/tests/coretests/src/com/android/internal/os/LongMultiStateCounterTest.java b/core/tests/coretests/src/com/android/internal/os/LongMultiStateCounterTest.java
index fc86ebe1c10e..341375357902 100644
--- a/core/tests/coretests/src/com/android/internal/os/LongMultiStateCounterTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/LongMultiStateCounterTest.java
@@ -20,6 +20,7 @@ import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertThrows;
+import android.os.BadParcelableException;
import android.os.Parcel;
import androidx.test.filters.SmallTest;
@@ -210,4 +211,42 @@ public class LongMultiStateCounterTest {
assertThrows(RuntimeException.class,
() -> LongMultiStateCounter.CREATOR.createFromParcel(parcel));
}
+
+ @Test
+ public void createFromBadBundle() {
+ Parcel data = Parcel.obtain();
+ int bundleLenPos = data.dataPosition();
+ data.writeInt(0);
+ data.writeInt(0x4C444E42); // BaseBundle.BUNDLE_MAGIC
+
+ int bundleStart = data.dataPosition();
+
+ data.writeInt(1);
+ data.writeString("key");
+ data.writeInt(4);
+ int lazyValueLenPos = data.dataPosition();
+ data.writeInt(0);
+ int lazyValueStart = data.dataPosition();
+ data.writeString("com.android.internal.os.LongMultiStateCounter");
+
+ // Invalid int16 value
+ data.writeInt(0x10000); // stateCount
+ for (int i = 0; i < 0x10000; ++i) {
+ data.writeLong(0);
+ }
+
+ backPatchLength(data, lazyValueLenPos, lazyValueStart);
+ backPatchLength(data, bundleLenPos, bundleStart);
+ data.setDataPosition(0);
+
+ assertThrows(BadParcelableException.class,
+ () -> data.readBundle().getParcelable("key", LongMultiStateCounter.class));
+ }
+
+ private static void backPatchLength(Parcel parcel, int lengthPos, int startPos) {
+ int endPos = parcel.dataPosition();
+ parcel.setDataPosition(lengthPos);
+ parcel.writeInt(endPos - startPos);
+ parcel.setDataPosition(endPos);
+ }
}
diff --git a/packages/SystemUI/res/values/flags.xml b/packages/SystemUI/res/values/flags.xml
index c2dba6c41d12..261b08d4356f 100644
--- a/packages/SystemUI/res/values/flags.xml
+++ b/packages/SystemUI/res/values/flags.xml
@@ -40,4 +40,7 @@
<!-- Whether face auth will immediately stop when the display state is OFF -->
<bool name="flag_stop_face_auth_on_display_off">false</bool>
+
+ <!-- Whether we want to stop pulsing while running the face scanning animation -->
+ <bool name="flag_stop_pulsing_face_scanning_animation">true</bool>
</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/FaceScanningOverlay.kt b/packages/SystemUI/src/com/android/systemui/FaceScanningOverlay.kt
index 403c80985377..95e2dba88b90 100644
--- a/packages/SystemUI/src/com/android/systemui/FaceScanningOverlay.kt
+++ b/packages/SystemUI/src/com/android/systemui/FaceScanningOverlay.kt
@@ -36,6 +36,8 @@ import com.android.keyguard.KeyguardUpdateMonitor
import com.android.keyguard.KeyguardUpdateMonitorCallback
import com.android.settingslib.Utils
import com.android.systemui.biometrics.AuthController
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags
import com.android.systemui.log.ScreenDecorationsLogger
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.util.asIndenting
@@ -54,6 +56,7 @@ class FaceScanningOverlay(
val mainExecutor: Executor,
val logger: ScreenDecorationsLogger,
val authController: AuthController,
+ val featureFlags: FeatureFlags,
) : ScreenDecorations.DisplayCutoutView(context, pos) {
private var showScanningAnim = false
private val rimPaint = Paint()
@@ -294,6 +297,15 @@ class FaceScanningOverlay(
}
private fun createFaceScanningRimAnimator(): AnimatorSet {
+ val dontPulse = featureFlags.isEnabled(Flags.STOP_PULSING_FACE_SCANNING_ANIMATION)
+ if (dontPulse) {
+ return AnimatorSet().apply {
+ playSequentially(
+ cameraProtectionAnimator,
+ createRimAppearAnimator(),
+ )
+ }
+ }
return AnimatorSet().apply {
playSequentially(
cameraProtectionAnimator,
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/Utils.kt b/packages/SystemUI/src/com/android/systemui/biometrics/Utils.kt
index b538085fa40d..1ca57e77034c 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/Utils.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/Utils.kt
@@ -60,6 +60,13 @@ object Utils {
return dp * (density / DisplayMetrics.DENSITY_DEFAULT)
}
+ /**
+ * Note: Talkback 14.0 has new rate-limitation design to reduce frequency
+ * of TYPE_WINDOW_CONTENT_CHANGED events to once every 30 seconds.
+ * (context: b/281765653#comment18)
+ * Using {@link View#announceForAccessibility} instead as workaround when sending events
+ * exceeding this frequency is required.
+ */
@JvmStatic
fun notifyAccessibilityContentChanged(am: AccessibilityManager, view: ViewGroup) {
if (!am.isEnabled) {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt
index 40bb8715f8c5..1bf7ffa8cff6 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt
@@ -47,7 +47,6 @@ import com.android.systemui.biometrics.AuthBiometricView.Callback
import com.android.systemui.biometrics.AuthBiometricViewAdapter
import com.android.systemui.biometrics.AuthIconController
import com.android.systemui.biometrics.AuthPanelController
-import com.android.systemui.biometrics.Utils
import com.android.systemui.biometrics.domain.model.BiometricModalities
import com.android.systemui.biometrics.shared.model.BiometricModality
import com.android.systemui.biometrics.shared.model.PromptKind
@@ -83,9 +82,6 @@ object BiometricViewBinder {
applicationScope: CoroutineScope,
): AuthBiometricViewAdapter {
val accessibilityManager = view.context.getSystemService(AccessibilityManager::class.java)!!
- fun notifyAccessibilityChanged() {
- Utils.notifyAccessibilityContentChanged(accessibilityManager, view)
- }
val textColorError =
view.resources.getColor(R.color.biometric_dialog_error, view.context.theme)
@@ -327,21 +323,14 @@ object BiometricViewBinder {
}
}
- // not sure why this is here, but the legacy code did it probably needed?
- launch {
- viewModel.isAuthenticating.collect { isAuthenticating ->
- if (isAuthenticating) {
- notifyAccessibilityChanged()
- }
- }
- }
-
// dismiss prompt when authenticated and confirmed
launch {
viewModel.isAuthenticated.collect { authState ->
// Disable background view for cancelling authentication once authenticated,
// and remove from talkback
if (authState.isAuthenticated) {
+ // Prevents Talkback from speaking subtitle after already authenticated
+ subtitleView.importantForAccessibility = IMPORTANT_FOR_ACCESSIBILITY_NO
backgroundView.setOnClickListener(null)
backgroundView.importantForAccessibility =
IMPORTANT_FOR_ACCESSIBILITY_NO
@@ -358,7 +347,6 @@ object BiometricViewBinder {
view.announceForAccessibility(
view.resources.getString(R.string.biometric_dialog_authenticated)
)
- notifyAccessibilityChanged()
launch {
delay(authState.delay)
@@ -390,7 +378,18 @@ object BiometricViewBinder {
!accessibilityManager.isEnabled ||
!accessibilityManager.isTouchExplorationEnabled
- notifyAccessibilityChanged()
+ /**
+ * Note: Talkback 14.0 has new rate-limitation design to reduce frequency of
+ * TYPE_WINDOW_CONTENT_CHANGED events to once every 30 seconds. (context:
+ * b/281765653#comment18) Using {@link View#announceForAccessibility}
+ * instead as workaround since sending events exceeding this frequency is
+ * required.
+ */
+ indicatorMessageView?.text?.let {
+ if (it.isNotBlank()) {
+ view.announceForAccessibility(it)
+ }
+ }
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/decor/FaceScanningProviderFactory.kt b/packages/SystemUI/src/com/android/systemui/decor/FaceScanningProviderFactory.kt
index 4e62104034ee..ac0d3c8f3d36 100644
--- a/packages/SystemUI/src/com/android/systemui/decor/FaceScanningProviderFactory.kt
+++ b/packages/SystemUI/src/com/android/systemui/decor/FaceScanningProviderFactory.kt
@@ -34,6 +34,7 @@ import com.android.systemui.FaceScanningOverlay
import com.android.systemui.biometrics.AuthController
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.flags.FeatureFlags
import com.android.systemui.log.ScreenDecorationsLogger
import com.android.systemui.plugins.statusbar.StatusBarStateController
import java.util.concurrent.Executor
@@ -47,6 +48,7 @@ class FaceScanningProviderFactory @Inject constructor(
private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
@Main private val mainExecutor: Executor,
private val logger: ScreenDecorationsLogger,
+ private val featureFlags: FeatureFlags,
) : DecorProviderFactory() {
private val display = context.display
private val displayInfo = DisplayInfo()
@@ -86,6 +88,7 @@ class FaceScanningProviderFactory @Inject constructor(
keyguardUpdateMonitor,
mainExecutor,
logger,
+ featureFlags,
)
)
}
@@ -110,6 +113,7 @@ class FaceScanningOverlayProviderImpl(
private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
private val mainExecutor: Executor,
private val logger: ScreenDecorationsLogger,
+ private val featureFlags: FeatureFlags,
) : BoundDecorProvider() {
override val viewId: Int = com.android.systemui.R.id.face_scanning_anim
@@ -144,6 +148,7 @@ class FaceScanningOverlayProviderImpl(
mainExecutor,
logger,
authController,
+ featureFlags
)
view.id = viewId
view.setColor(tintColor)
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
index ee9482c730af..ee8fae599d41 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
@@ -273,6 +273,12 @@ object Flags {
@JvmField val STOP_FACE_AUTH_ON_DISPLAY_OFF = resourceBooleanFlag(245,
R.bool.flag_stop_face_auth_on_display_off, "stop_face_auth_on_display_off")
+ /** Flag to disable the face scanning animation pulsing. */
+ // TODO(b/295245791): Tracking bug.
+ @JvmField val STOP_PULSING_FACE_SCANNING_ANIMATION = resourceBooleanFlag(246,
+ R.bool.flag_stop_pulsing_face_scanning_animation,
+ "stop_pulsing_face_scanning_animation")
+
// 300 - power menu
// TODO(b/254512600): Tracking Bug
@JvmField val POWER_MENU_LITE = releasedFlag(300, "power_menu_lite")
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
index 68e72c58972b..4418740e545f 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
@@ -934,28 +934,41 @@ class KeyguardUnlockAnimationController @Inject constructor(
/**
* Called by [KeyguardViewMediator] to let us know that the remote animation has finished, and
- * we should clean up all of our state.
+ * we should clean up all of our state. [showKeyguard] will tell us which surface should be
+ * visible after the animation has been completed or canceled.
*
* This is generally triggered by us, calling
* [KeyguardViewMediator.finishSurfaceBehindRemoteAnimation].
*/
- fun notifyFinishedKeyguardExitAnimation(cancelled: Boolean) {
+ fun notifyFinishedKeyguardExitAnimation(showKeyguard: Boolean) {
// Cancel any pending actions.
handler.removeCallbacksAndMessages(null)
- // Make sure we made the surface behind fully visible, just in case. It should already be
- // fully visible. The exit animation is finished, and we should not hold the leash anymore,
- // so forcing it to 1f.
- surfaceBehindAlpha = 1f
- setSurfaceBehindAppearAmount(1f)
+ // The lockscreen surface is gone, so it is now safe to re-show the smartspace.
+ if (lockscreenSmartspace?.visibility == View.INVISIBLE) {
+ lockscreenSmartspace?.visibility = View.VISIBLE
+ }
+
+ if (!showKeyguard) {
+ // Make sure we made the surface behind fully visible, just in case. It should already be
+ // fully visible. The exit animation is finished, and we should not hold the leash anymore,
+ // so forcing it to 1f.
+ surfaceBehindAlpha = 1f
+ setSurfaceBehindAppearAmount(1f)
+
+ try {
+ launcherUnlockController?.setUnlockAmount(1f, false /* forceIfAnimating */)
+ } catch (e: RemoteException) {
+ Log.e(TAG, "Remote exception in notifyFinishedKeyguardExitAnimation", e)
+ }
+ }
+
+ listeners.forEach { it.onUnlockAnimationFinished() }
+
+ // Reset all state
surfaceBehindAlphaAnimator.cancel()
surfaceBehindEntryAnimator.cancel()
wallpaperCannedUnlockAnimator.cancel()
- try {
- launcherUnlockController?.setUnlockAmount(1f, false /* forceIfAnimating */)
- } catch (e: RemoteException) {
- Log.e(TAG, "Remote exception in notifyFinishedKeyguardExitAnimation", e)
- }
// That target is no longer valid since the animation finished, null it out.
surfaceBehindRemoteAnimationTargets = null
@@ -965,13 +978,6 @@ class KeyguardUnlockAnimationController @Inject constructor(
dismissAmountThresholdsReached = false
willUnlockWithInWindowLauncherAnimations = false
willUnlockWithSmartspaceTransition = false
-
- // The lockscreen surface is gone, so it is now safe to re-show the smartspace.
- if (lockscreenSmartspace?.visibility == View.INVISIBLE) {
- lockscreenSmartspace?.visibility = View.VISIBLE
- }
-
- listeners.forEach { it.onUnlockAnimationFinished() }
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 1a06b0184bc5..49ae876b677e 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -2520,7 +2520,7 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
} else if (mSurfaceBehindRemoteAnimationRunning) {
// We're already running the keyguard exit animation, likely due to an in-progress swipe
// to unlock.
- exitKeyguardAndFinishSurfaceBehindRemoteAnimation(false /* cancelled */);
+ exitKeyguardAndFinishSurfaceBehindRemoteAnimation(false /* showKeyguard */);
} else if (!mHideAnimationRun) {
if (DEBUG) Log.d(TAG, "tryKeyguardDone: starting pre-hide animation");
mHideAnimationRun = true;
@@ -2966,7 +2966,7 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
mContext.getMainExecutor().execute(() -> {
if (finishedCallback == null) {
mKeyguardUnlockAnimationControllerLazy.get()
- .notifyFinishedKeyguardExitAnimation(false /* cancelled */);
+ .notifyFinishedKeyguardExitAnimation(false /* showKeyguard */);
mInteractionJankMonitor.end(CUJ_LOCKSCREEN_UNLOCK_ANIMATION);
return;
}
@@ -3083,7 +3083,7 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
// A lock is pending, meaning the keyguard exit animation was cancelled because we're
// re-locking. We should just end the surface-behind animation without exiting the
// keyguard. The pending lock will be handled by onFinishedGoingToSleep().
- finishSurfaceBehindRemoteAnimation(true);
+ finishSurfaceBehindRemoteAnimation(true /* showKeyguard */);
maybeHandlePendingLock();
} else {
Log.d(TAG, "#handleCancelKeyguardExitAnimation: keyguard exit animation cancelled. "
@@ -3092,7 +3092,7 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
// No lock is pending, so the animation was cancelled during the unlock sequence, but
// we should end up unlocked. Show the surface and exit the keyguard.
showSurfaceBehindKeyguard();
- exitKeyguardAndFinishSurfaceBehindRemoteAnimation(true /* cancelled */);
+ exitKeyguardAndFinishSurfaceBehindRemoteAnimation(false /* showKeyguard */);
}
}
@@ -3103,12 +3103,13 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
* with the RemoteAnimation, actually hide the keyguard, and clean up state related to the
* keyguard exit animation.
*
- * @param cancelled {@code true} if the animation was cancelled before it finishes.
+ * @param showKeyguard {@code true} if the animation was cancelled and keyguard should remain
+ * visible
*/
- public void exitKeyguardAndFinishSurfaceBehindRemoteAnimation(boolean cancelled) {
+ public void exitKeyguardAndFinishSurfaceBehindRemoteAnimation(boolean showKeyguard) {
Log.d(TAG, "onKeyguardExitRemoteAnimationFinished");
if (!mSurfaceBehindRemoteAnimationRunning && !mSurfaceBehindRemoteAnimationRequested) {
- Log.d(TAG, "skip onKeyguardExitRemoteAnimationFinished cancelled=" + cancelled
+ Log.d(TAG, "skip onKeyguardExitRemoteAnimationFinished showKeyguard=" + showKeyguard
+ " surfaceAnimationRunning=" + mSurfaceBehindRemoteAnimationRunning
+ " surfaceAnimationRequested=" + mSurfaceBehindRemoteAnimationRequested);
return;
@@ -3133,9 +3134,7 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
+ " wasShowing=" + wasShowing);
}
- mKeyguardUnlockAnimationControllerLazy.get()
- .notifyFinishedKeyguardExitAnimation(cancelled);
- finishSurfaceBehindRemoteAnimation(cancelled);
+ finishSurfaceBehindRemoteAnimation(showKeyguard);
// Dispatch the callback on animation finishes.
mUpdateMonitor.dispatchKeyguardDismissAnimationFinished();
@@ -3199,7 +3198,10 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
* This does not set keyguard state to either locked or unlocked, it simply ends the remote
* animation on the surface behind the keyguard. This can be called by
*/
- void finishSurfaceBehindRemoteAnimation(boolean cancelled) {
+ void finishSurfaceBehindRemoteAnimation(boolean showKeyguard) {
+ mKeyguardUnlockAnimationControllerLazy.get()
+ .notifyFinishedKeyguardExitAnimation(showKeyguard);
+
mSurfaceBehindRemoteAnimationRequested = false;
mSurfaceBehindRemoteAnimationRunning = false;
mKeyguardStateController.notifyKeyguardGoingAway(false);
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
index 2f7644eb5c82..c7a7d97aff4f 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
@@ -499,6 +499,7 @@ public class NotificationShadeWindowViewController {
MotionEvent.ACTION_CANCEL, 0.0f, 0.0f, 0);
event.setSource(InputDevice.SOURCE_TOUCHSCREEN);
}
+ Log.w(TAG, "Canceling current touch event (should be very rare)");
mView.dispatchTouchEvent(event);
event.recycle();
mTouchCancelled = true;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/FaceScanningProviderFactoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/FaceScanningProviderFactoryTest.kt
index 01d3a3931052..ea7cc3dcd119 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/FaceScanningProviderFactoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/FaceScanningProviderFactoryTest.kt
@@ -27,6 +27,8 @@ import com.android.keyguard.KeyguardUpdateMonitor
import com.android.systemui.biometrics.AuthController
import com.android.systemui.decor.FaceScanningProviderFactory
import com.android.systemui.dump.logcatLogBuffer
+import com.android.systemui.flags.FakeFeatureFlags
+import com.android.systemui.flags.Flags
import com.android.systemui.log.ScreenDecorationsLogger
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.util.mockito.whenever
@@ -80,6 +82,8 @@ class FaceScanningProviderFactoryTest : SysuiTestCase() {
R.bool.config_fillMainBuiltInDisplayCutout,
true
)
+ val featureFlags = FakeFeatureFlags()
+ featureFlags.set(Flags.STOP_PULSING_FACE_SCANNING_ANIMATION, true)
underTest =
FaceScanningProviderFactory(
authController,
@@ -87,7 +91,8 @@ class FaceScanningProviderFactoryTest : SysuiTestCase() {
statusBarStateController,
keyguardUpdateMonitor,
mock(Executor::class.java),
- ScreenDecorationsLogger(logcatLogBuffer("FaceScanningProviderFactoryTest"))
+ ScreenDecorationsLogger(logcatLogBuffer("FaceScanningProviderFactoryTest")),
+ featureFlags,
)
whenever(authController.faceSensorLocation).thenReturn(Point(10, 10))
diff --git a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java
index 4cf5a4be0b60..13a1fe969ac8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java
@@ -91,6 +91,8 @@ import com.android.systemui.decor.OverlayWindow;
import com.android.systemui.decor.PrivacyDotCornerDecorProviderImpl;
import com.android.systemui.decor.PrivacyDotDecorProviderFactory;
import com.android.systemui.decor.RoundedCornerResDelegate;
+import com.android.systemui.flags.FakeFeatureFlags;
+import com.android.systemui.flags.Flags;
import com.android.systemui.log.ScreenDecorationsLogger;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.settings.FakeDisplayTracker;
@@ -225,13 +227,16 @@ public class ScreenDecorationsTest extends SysuiTestCase {
doAnswer(it -> !(mMockCutoutList.isEmpty())).when(mCutoutFactory).getHasProviders();
doReturn(mMockCutoutList).when(mCutoutFactory).getProviders();
+ FakeFeatureFlags featureFlags = new FakeFeatureFlags();
+ featureFlags.set(Flags.STOP_PULSING_FACE_SCANNING_ANIMATION, true);
mFaceScanningDecorProvider = spy(new FaceScanningOverlayProviderImpl(
BOUNDS_POSITION_TOP,
mAuthController,
mStatusBarStateController,
mKeyguardUpdateMonitor,
mExecutor,
- new ScreenDecorationsLogger(logcatLogBuffer("TestLogBuffer"))));
+ new ScreenDecorationsLogger(logcatLogBuffer("TestLogBuffer")),
+ featureFlags));
mScreenDecorations = spy(new ScreenDecorations(mContext, mExecutor, mSecureSettings,
mTunerService, mUserTracker, mDisplayTracker, mDotViewController, mThreadFactory,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
index 34ea91b94414..cb2daca1fe97 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
@@ -480,6 +480,7 @@ public class KeyguardViewMediatorTest extends SysuiTestCase {
TestableLooper.get(this).processAllMessages();
assertFalse(mViewMediator.isShowingAndNotOccluded());
+ verify(mKeyguardUnlockAnimationController).notifyFinishedKeyguardExitAnimation(false);
}
@Test
@@ -496,6 +497,7 @@ public class KeyguardViewMediatorTest extends SysuiTestCase {
TestableLooper.get(this).processAllMessages();
assertTrue(mViewMediator.isShowingAndNotOccluded());
+ verify(mKeyguardUnlockAnimationController).notifyFinishedKeyguardExitAnimation(true);
}
@Test
@@ -504,6 +506,9 @@ public class KeyguardViewMediatorTest extends SysuiTestCase {
startMockKeyguardExitAnimation();
cancelMockKeyguardExitAnimation();
+ // Calling cancel above results in keyguard not visible, as there is no pending lock
+ verify(mKeyguardUnlockAnimationController).notifyFinishedKeyguardExitAnimation(false);
+
mViewMediator.maybeHandlePendingLock();
TestableLooper.get(this).processAllMessages();
@@ -518,9 +523,15 @@ public class KeyguardViewMediatorTest extends SysuiTestCase {
@Test
@TestableLooper.RunWithLooper(setAsMainLooper = true)
- public void testStartKeyguardExitAnimation_expectSurfaceBehindRemoteAnimation() {
+ public void testStartKeyguardExitAnimation_expectSurfaceBehindRemoteAnimationAndExits() {
startMockKeyguardExitAnimation();
assertTrue(mViewMediator.isAnimatingBetweenKeyguardAndSurfaceBehind());
+
+ mViewMediator.mViewMediatorCallback.keyguardDonePending(true,
+ mUpdateMonitor.getCurrentUser());
+ mViewMediator.mViewMediatorCallback.readyForKeyguardDone();
+ TestableLooper.get(this).processAllMessages();
+ verify(mKeyguardUnlockAnimationController).notifyFinishedKeyguardExitAnimation(false);
}
/**
diff --git a/services/core/java/com/android/server/PendingIntentUtils.java b/services/core/java/com/android/server/PendingIntentUtils.java
index 1600101b20f4..a72a4d254a2a 100644
--- a/services/core/java/com/android/server/PendingIntentUtils.java
+++ b/services/core/java/com/android/server/PendingIntentUtils.java
@@ -34,6 +34,7 @@ public class PendingIntentUtils {
public static Bundle createDontSendToRestrictedAppsBundle(@Nullable Bundle bundle) {
final BroadcastOptions options = BroadcastOptions.makeBasic();
options.setDontSendToRestrictedApps(true);
+ options.setPendingIntentBackgroundActivityLaunchAllowed(false);
if (bundle == null) {
return options.toBundle();
}
diff --git a/services/core/java/com/android/server/pm/TEST_MAPPING b/services/core/java/com/android/server/pm/TEST_MAPPING
index a622d0743bbb..bb6e11dcf8d4 100644
--- a/services/core/java/com/android/server/pm/TEST_MAPPING
+++ b/services/core/java/com/android/server/pm/TEST_MAPPING
@@ -90,7 +90,7 @@
]
}
],
- "presubmit-large": [
+ "postsubmit": [
{
"name": "CtsContentTestCases",
"options": [
@@ -104,9 +104,7 @@
"include-filter": "android.content.pm.cts"
}
]
- }
- ],
- "postsubmit": [
+ },
{
"name": "CtsPermissionTestCases",
"options": [