Merge "Force unparcel values when collecting intent keys on server side." into main
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index a988acf..a352d9d 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -3415,6 +3415,10 @@
method public void onBindClient(@Nullable android.content.Intent);
}
+ public class TelecomManager {
+ method @FlaggedApi("com.android.server.telecom.flags.voip_call_monitor_refactor") public boolean hasForegroundServiceDelegation(@Nullable android.telecom.PhoneAccountHandle);
+ }
+
}
package android.telephony {
diff --git a/core/java/android/content/res/ApkAssets.java b/core/java/android/content/res/ApkAssets.java
index b938aac..f538e9f 100644
--- a/core/java/android/content/res/ApkAssets.java
+++ b/core/java/android/content/res/ApkAssets.java
@@ -367,7 +367,7 @@
/** @hide */
public @NonNull String getDebugName() {
synchronized (this) {
- return nativeGetDebugName(mNativePtr);
+ return mNativePtr == 0 ? "<destroyed>" : nativeGetDebugName(mNativePtr);
}
}
diff --git a/core/java/android/hardware/input/InputGestureData.java b/core/java/android/hardware/input/InputGestureData.java
index f41550f..75c652c 100644
--- a/core/java/android/hardware/input/InputGestureData.java
+++ b/core/java/android/hardware/input/InputGestureData.java
@@ -48,27 +48,7 @@
/** Returns the trigger information for this input gesture */
public Trigger getTrigger() {
- switch (mInputGestureData.trigger.getTag()) {
- case AidlInputGestureData.Trigger.Tag.key: {
- AidlInputGestureData.KeyTrigger trigger = mInputGestureData.trigger.getKey();
- if (trigger == null) {
- throw new RuntimeException("InputGestureData is corrupted, null key trigger!");
- }
- return createKeyTrigger(trigger.keycode, trigger.modifierState);
- }
- case AidlInputGestureData.Trigger.Tag.touchpadGesture: {
- AidlInputGestureData.TouchpadGestureTrigger trigger =
- mInputGestureData.trigger.getTouchpadGesture();
- if (trigger == null) {
- throw new RuntimeException(
- "InputGestureData is corrupted, null touchpad trigger!");
- }
- return createTouchpadTrigger(trigger.gestureType);
- }
- default:
- throw new RuntimeException("InputGestureData is corrupted, invalid trigger type!");
-
- }
+ return createTriggerFromAidlTrigger(mInputGestureData.trigger);
}
/** Returns the action to perform for this input gesture */
@@ -147,18 +127,7 @@
"No app launch data for system action launch application");
}
AidlInputGestureData data = new AidlInputGestureData();
- data.trigger = new AidlInputGestureData.Trigger();
- if (mTrigger instanceof KeyTrigger keyTrigger) {
- data.trigger.setKey(new AidlInputGestureData.KeyTrigger());
- data.trigger.getKey().keycode = keyTrigger.getKeycode();
- data.trigger.getKey().modifierState = keyTrigger.getModifierState();
- } else if (mTrigger instanceof TouchpadTrigger touchpadTrigger) {
- data.trigger.setTouchpadGesture(new AidlInputGestureData.TouchpadGestureTrigger());
- data.trigger.getTouchpadGesture().gestureType =
- touchpadTrigger.getTouchpadGestureType();
- } else {
- throw new IllegalArgumentException("Invalid trigger type!");
- }
+ data.trigger = mTrigger.getAidlTrigger();
data.gestureType = mKeyGestureType;
if (mAppLaunchData != null) {
if (mAppLaunchData instanceof AppLaunchData.CategoryData categoryData) {
@@ -198,6 +167,7 @@
}
public interface Trigger {
+ AidlInputGestureData.Trigger getAidlTrigger();
}
/** Creates a input gesture trigger based on a key press */
@@ -210,85 +180,128 @@
return new TouchpadTrigger(touchpadGestureType);
}
+ public static Trigger createTriggerFromAidlTrigger(AidlInputGestureData.Trigger aidlTrigger) {
+ switch (aidlTrigger.getTag()) {
+ case AidlInputGestureData.Trigger.Tag.key: {
+ AidlInputGestureData.KeyTrigger trigger = aidlTrigger.getKey();
+ if (trigger == null) {
+ throw new RuntimeException("aidlTrigger is corrupted, null key trigger!");
+ }
+ return new KeyTrigger(trigger);
+ }
+ case AidlInputGestureData.Trigger.Tag.touchpadGesture: {
+ AidlInputGestureData.TouchpadGestureTrigger trigger =
+ aidlTrigger.getTouchpadGesture();
+ if (trigger == null) {
+ throw new RuntimeException(
+ "aidlTrigger is corrupted, null touchpad trigger!");
+ }
+ return new TouchpadTrigger(trigger);
+ }
+ default:
+ throw new RuntimeException("aidlTrigger is corrupted, invalid trigger type!");
+
+ }
+ }
+
/** Key based input gesture trigger */
public static class KeyTrigger implements Trigger {
- private static final int SHORTCUT_META_MASK =
- KeyEvent.META_META_ON | KeyEvent.META_CTRL_ON | KeyEvent.META_ALT_ON
- | KeyEvent.META_SHIFT_ON;
- private final int mKeycode;
- private final int mModifierState;
+
+ AidlInputGestureData.KeyTrigger mAidlKeyTrigger;
+
+ private KeyTrigger(@NonNull AidlInputGestureData.KeyTrigger aidlKeyTrigger) {
+ mAidlKeyTrigger = aidlKeyTrigger;
+ }
private KeyTrigger(int keycode, int modifierState) {
if (keycode <= KeyEvent.KEYCODE_UNKNOWN || keycode > KeyEvent.getMaxKeyCode()) {
throw new IllegalArgumentException("Invalid keycode = " + keycode);
}
- mKeycode = keycode;
- mModifierState = modifierState;
+ mAidlKeyTrigger = new AidlInputGestureData.KeyTrigger();
+ mAidlKeyTrigger.keycode = keycode;
+ mAidlKeyTrigger.modifierState = modifierState;
}
public int getKeycode() {
- return mKeycode;
+ return mAidlKeyTrigger.keycode;
}
public int getModifierState() {
- return mModifierState;
+ return mAidlKeyTrigger.modifierState;
+ }
+
+ public AidlInputGestureData.Trigger getAidlTrigger() {
+ AidlInputGestureData.Trigger trigger = new AidlInputGestureData.Trigger();
+ trigger.setKey(mAidlKeyTrigger);
+ return trigger;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof KeyTrigger that)) return false;
- return mKeycode == that.mKeycode && mModifierState == that.mModifierState;
+ return Objects.equals(mAidlKeyTrigger, that.mAidlKeyTrigger);
}
@Override
public int hashCode() {
- return Objects.hash(mKeycode, mModifierState);
+ return mAidlKeyTrigger.hashCode();
}
@Override
public String toString() {
return "KeyTrigger{" +
- "mKeycode=" + KeyEvent.keyCodeToString(mKeycode) +
- ", mModifierState=" + mModifierState +
+ "mKeycode=" + KeyEvent.keyCodeToString(mAidlKeyTrigger.keycode) +
+ ", mModifierState=" + mAidlKeyTrigger.modifierState +
'}';
}
}
/** Touchpad based input gesture trigger */
public static class TouchpadTrigger implements Trigger {
- private final int mTouchpadGestureType;
+ AidlInputGestureData.TouchpadGestureTrigger mAidlTouchpadTrigger;
+
+ private TouchpadTrigger(
+ @NonNull AidlInputGestureData.TouchpadGestureTrigger aidlTouchpadTrigger) {
+ mAidlTouchpadTrigger = aidlTouchpadTrigger;
+ }
private TouchpadTrigger(int touchpadGestureType) {
if (touchpadGestureType != TOUCHPAD_GESTURE_TYPE_THREE_FINGER_TAP) {
throw new IllegalArgumentException(
"Invalid touchpadGestureType = " + touchpadGestureType);
}
- mTouchpadGestureType = touchpadGestureType;
+ mAidlTouchpadTrigger = new AidlInputGestureData.TouchpadGestureTrigger();
+ mAidlTouchpadTrigger.gestureType = touchpadGestureType;
}
public int getTouchpadGestureType() {
- return mTouchpadGestureType;
+ return mAidlTouchpadTrigger.gestureType;
+ }
+
+ public AidlInputGestureData.Trigger getAidlTrigger() {
+ AidlInputGestureData.Trigger trigger = new AidlInputGestureData.Trigger();
+ trigger.setTouchpadGesture(mAidlTouchpadTrigger);
+ return trigger;
}
@Override
public String toString() {
return "TouchpadTrigger{" +
- "mTouchpadGestureType=" + mTouchpadGestureType +
+ "mTouchpadGestureType=" + mAidlTouchpadTrigger.gestureType +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
- TouchpadTrigger that = (TouchpadTrigger) o;
- return mTouchpadGestureType == that.mTouchpadGestureType;
+ if (!(o instanceof TouchpadTrigger that)) return false;
+ return Objects.equals(mAidlTouchpadTrigger, that.mAidlTouchpadTrigger);
}
@Override
public int hashCode() {
- return Objects.hashCode(mTouchpadGestureType);
+ return mAidlTouchpadTrigger.hashCode();
}
}
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index 1801df0..2a5666c 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -615,6 +615,7 @@
WAKE_REASON_WAKE_KEY,
WAKE_REASON_WAKE_MOTION,
WAKE_REASON_HDMI,
+ WAKE_REASON_LID,
WAKE_REASON_DISPLAY_GROUP_ADDED,
WAKE_REASON_DISPLAY_GROUP_TURNED_ON,
WAKE_REASON_UNFOLD_DEVICE,
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt
index 636549f..a6f8150 100644
--- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt
@@ -176,7 +176,6 @@
* transition
*/
@Ignore("TODO(b/356277166): enable the tablet test")
- @Postsubmit
@Test
open fun pipAppLayerPlusLetterboxCoversFullScreenOnStartTablet() {
assumeTrue(tapl.isTablet)
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/nonmatchparent/BottomHalfEnterPipToOtherOrientation.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/nonmatchparent/BottomHalfEnterPipToOtherOrientation.kt
index 4987ab7..d65f158 100644
--- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/nonmatchparent/BottomHalfEnterPipToOtherOrientation.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/nonmatchparent/BottomHalfEnterPipToOtherOrientation.kt
@@ -78,7 +78,6 @@
}
@Ignore("TODO(b/356277166): enable the tablet test")
- @Presubmit
@Test
override fun pipAppLayerPlusLetterboxCoversFullScreenOnStartTablet() {
// Test app and pip app should covers the entire screen on start.
diff --git a/libs/appfunctions/api/current.txt b/libs/appfunctions/api/current.txt
index f8fb6b7..139ccfd 100644
--- a/libs/appfunctions/api/current.txt
+++ b/libs/appfunctions/api/current.txt
@@ -36,8 +36,7 @@
public abstract class AppFunctionService extends android.app.Service {
ctor public AppFunctionService();
method @NonNull public final android.os.IBinder onBind(@Nullable android.content.Intent);
- method @MainThread public void onExecuteFunction(@NonNull com.android.extensions.appfunctions.ExecuteAppFunctionRequest, @NonNull String, @NonNull android.content.pm.SigningInfo, @NonNull android.os.CancellationSignal, @NonNull android.os.OutcomeReceiver<com.android.extensions.appfunctions.ExecuteAppFunctionResponse,com.android.extensions.appfunctions.AppFunctionException>);
- method @Deprecated @MainThread public abstract void onExecuteFunction(@NonNull com.android.extensions.appfunctions.ExecuteAppFunctionRequest, @NonNull String, @NonNull android.os.CancellationSignal, @NonNull android.os.OutcomeReceiver<com.android.extensions.appfunctions.ExecuteAppFunctionResponse,com.android.extensions.appfunctions.AppFunctionException>);
+ method @MainThread public abstract void onExecuteFunction(@NonNull com.android.extensions.appfunctions.ExecuteAppFunctionRequest, @NonNull String, @NonNull android.os.CancellationSignal, @NonNull android.os.OutcomeReceiver<com.android.extensions.appfunctions.ExecuteAppFunctionResponse,com.android.extensions.appfunctions.AppFunctionException>);
field @NonNull public static final String BIND_APP_FUNCTION_SERVICE = "android.permission.BIND_APP_FUNCTION_SERVICE";
field @NonNull public static final String SERVICE_INTERFACE = "android.app.appfunctions.AppFunctionService";
}
diff --git a/libs/appfunctions/java/com/android/extensions/appfunctions/AppFunctionService.java b/libs/appfunctions/java/com/android/extensions/appfunctions/AppFunctionService.java
index a09451e..81d9d81 100644
--- a/libs/appfunctions/java/com/android/extensions/appfunctions/AppFunctionService.java
+++ b/libs/appfunctions/java/com/android/extensions/appfunctions/AppFunctionService.java
@@ -25,7 +25,6 @@
import android.annotation.SdkConstant;
import android.app.Service;
import android.content.Intent;
-import android.content.pm.SigningInfo;
import android.os.Binder;
import android.os.CancellationSignal;
import android.os.IBinder;
@@ -82,7 +81,6 @@
SidecarConverter.getSidecarExecuteAppFunctionRequest(
platformRequest),
callingPackage,
- callingPackageSigningInfo,
cancellationSignal,
new OutcomeReceiver<>() {
@Override
@@ -129,52 +127,10 @@
*
* @param request The function execution request.
* @param callingPackage The package name of the app that is requesting the execution.
- * @param callingPackageSigningInfo The signing information of the app that is requesting the
- * execution.
* @param cancellationSignal A signal to cancel the execution.
* @param callback A callback to report back the result or error.
*/
@MainThread
- public void onExecuteFunction(
- @NonNull ExecuteAppFunctionRequest request,
- @NonNull String callingPackage,
- @NonNull SigningInfo callingPackageSigningInfo,
- @NonNull CancellationSignal cancellationSignal,
- @NonNull OutcomeReceiver<ExecuteAppFunctionResponse, AppFunctionException> callback) {
- onExecuteFunction(request, callingPackage, cancellationSignal, callback);
- }
-
- /**
- * Called by the system to execute a specific app function.
- *
- * <p>This method is the entry point for handling all app function requests in an app. When the
- * system needs your AppFunctionService to perform a function, it will invoke this method.
- *
- * <p>Each function you've registered is identified by a unique identifier. This identifier
- * doesn't need to be globally unique, but it must be unique within your app. For example, a
- * function to order food could be identified as "orderFood". In most cases, this identifier is
- * automatically generated by the AppFunctions SDK.
- *
- * <p>You can determine which function to execute by calling {@link
- * ExecuteAppFunctionRequest#getFunctionIdentifier()}. This allows your service to route the
- * incoming request to the appropriate logic for handling the specific function.
- *
- * <p>This method is always triggered in the main thread. You should run heavy tasks on a worker
- * thread and dispatch the result with the given callback. You should always report back the
- * result using the callback, no matter if the execution was successful or not.
- *
- * <p>This method also accepts a {@link CancellationSignal} that the app should listen to cancel
- * the execution of function if requested by the system.
- *
- * @param request The function execution request.
- * @param callingPackage The package name of the app that is requesting the execution.
- * @param cancellationSignal A signal to cancel the execution.
- * @param callback A callback to report back the result or error.
- * @deprecated Use {@link #onExecuteFunction(ExecuteAppFunctionRequest, String, SigningInfo,
- * CancellationSignal, OutcomeReceiver)} instead.
- */
- @MainThread
- @Deprecated
public abstract void onExecuteFunction(
@NonNull ExecuteAppFunctionRequest request,
@NonNull String callingPackage,
diff --git a/media/TEST_MAPPING b/media/TEST_MAPPING
index e52e0b1..6a21496 100644
--- a/media/TEST_MAPPING
+++ b/media/TEST_MAPPING
@@ -1,7 +1,10 @@
{
"presubmit": [
{
- "name": "CtsMediaBetterTogetherTestCases"
+ "name": "CtsMediaRouterTestCases"
+ },
+ {
+ "name": "CtsMediaSessionTestCases"
},
{
"name": "mediaroutertest"
diff --git a/packages/SettingsLib/src/com/android/settingslib/enterprise/ActionDisabledByAdminControllerFactory.java b/packages/SettingsLib/src/com/android/settingslib/enterprise/ActionDisabledByAdminControllerFactory.java
index 7516d2e..e3d7902 100644
--- a/packages/SettingsLib/src/com/android/settingslib/enterprise/ActionDisabledByAdminControllerFactory.java
+++ b/packages/SettingsLib/src/com/android/settingslib/enterprise/ActionDisabledByAdminControllerFactory.java
@@ -22,6 +22,7 @@
import static com.android.settingslib.enterprise.ManagedDeviceActionDisabledByAdminController.DEFAULT_FOREGROUND_USER_CHECKER;
import android.app.admin.DevicePolicyManager;
+import android.app.supervision.SupervisionManager;
import android.content.ComponentName;
import android.content.Context;
import android.hardware.biometrics.BiometricAuthenticator;
@@ -59,12 +60,18 @@
}
private static boolean isSupervisedDevice(Context context) {
- DevicePolicyManager devicePolicyManager =
- context.getSystemService(DevicePolicyManager.class);
- ComponentName supervisionComponent =
- devicePolicyManager.getProfileOwnerOrDeviceOwnerSupervisionComponent(
- new UserHandle(UserHandle.myUserId()));
- return supervisionComponent != null;
+ if (android.app.supervision.flags.Flags.deprecateDpmSupervisionApis()) {
+ SupervisionManager supervisionManager =
+ context.getSystemService(SupervisionManager.class);
+ return supervisionManager.isSupervisionEnabledForUser(UserHandle.myUserId());
+ } else {
+ DevicePolicyManager devicePolicyManager =
+ context.getSystemService(DevicePolicyManager.class);
+ ComponentName supervisionComponent =
+ devicePolicyManager.getProfileOwnerOrDeviceOwnerSupervisionComponent(
+ new UserHandle(UserHandle.myUserId()));
+ return supervisionComponent != null;
+ }
}
/**
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
index f79a60f..c1c3e04 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
@@ -212,6 +212,8 @@
private static final String ERROR_IO_EXCEPTION = "io_exception";
private static final String ERROR_FAILED_TO_RESTORE_SOFTAP_CONFIG =
"failed_to_restore_softap_config";
+ private static final String ERROR_FAILED_TO_RESTORE_WIFI_CONFIG =
+ "failed_to_restore_wifi_config";
// Name of the temporary file we use during full backup/restore. This is
@@ -1455,8 +1457,14 @@
return baos.toByteArray();
}
- private byte[] getNewWifiConfigData() {
- return mWifiManager.retrieveBackupData();
+ @VisibleForTesting
+ byte[] getNewWifiConfigData() {
+ byte[] data = mWifiManager.retrieveBackupData();
+ if (areAgentMetricsEnabled) {
+ // We're unable to determine how many settings this includes, so we'll just log 1.
+ numberOfSettingsPerKey.put(KEY_WIFI_NEW_CONFIG, 1);
+ }
+ return data;
}
private byte[] getLocaleSettings() {
@@ -1468,11 +1476,22 @@
return localeList.toLanguageTags().getBytes();
}
- private void restoreNewWifiConfigData(byte[] bytes) {
+ @VisibleForTesting
+ void restoreNewWifiConfigData(byte[] bytes) {
if (DEBUG_BACKUP) {
Log.v(TAG, "Applying restored wifi data");
}
- mWifiManager.restoreBackupData(bytes);
+ if (areAgentMetricsEnabled) {
+ try {
+ mWifiManager.restoreBackupData(bytes);
+ mBackupRestoreEventLogger.logItemsRestored(KEY_WIFI_NEW_CONFIG, /* count= */ 1);
+ } catch (Exception e) {
+ mBackupRestoreEventLogger.logItemsRestoreFailed(
+ KEY_WIFI_NEW_CONFIG, /* count= */ 1, ERROR_FAILED_TO_RESTORE_WIFI_CONFIG);
+ }
+ } else {
+ mWifiManager.restoreBackupData(bytes);
+ }
}
private void restoreNetworkPolicies(byte[] data) {
diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsBackupAgentTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsBackupAgentTest.java
index 95dd0db..6e5b602c 100644
--- a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsBackupAgentTest.java
+++ b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsBackupAgentTest.java
@@ -16,6 +16,7 @@
package com.android.providers.settings;
+import static com.android.providers.settings.SettingsBackupRestoreKeys.KEY_WIFI_NEW_CONFIG;
import static com.android.providers.settings.SettingsBackupRestoreKeys.KEY_SOFTAP_CONFIG;
import static junit.framework.Assert.assertEquals;
@@ -28,6 +29,8 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.when;
import android.annotation.Nullable;
@@ -69,6 +72,7 @@
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
+import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
@@ -834,6 +838,74 @@
assertNull(getLoggingResultForDatatype(KEY_SOFTAP_CONFIG, mAgentUnderTest));
}
+ @Test
+ @EnableFlags(com.android.server.backup.Flags.FLAG_ENABLE_METRICS_SETTINGS_BACKUP_AGENTS)
+ public void getNewWifiConfigData_flagIsEnabled_numberOfSettingsInKeyAreRecorded() {
+ mAgentUnderTest.onCreate(
+ UserHandle.SYSTEM, BackupDestination.CLOUD, OperationType.BACKUP);
+ when(mWifiManager.retrieveBackupData()).thenReturn(null);
+
+ mAgentUnderTest.getNewWifiConfigData();
+
+ assertEquals(mAgentUnderTest.getNumberOfSettingsPerKey(KEY_WIFI_NEW_CONFIG), 1);
+ }
+
+ @Test
+ @DisableFlags(com.android.server.backup.Flags.FLAG_ENABLE_METRICS_SETTINGS_BACKUP_AGENTS)
+ public void getNewWifiConfigData_flagIsNotEnabled_numberOfSettingsInKeyAreNotRecorded() {
+ mAgentUnderTest.onCreate(
+ UserHandle.SYSTEM, BackupDestination.CLOUD, OperationType.BACKUP);
+ when(mWifiManager.retrieveBackupData()).thenReturn(null);
+
+ mAgentUnderTest.getNewWifiConfigData();
+
+ assertEquals(mAgentUnderTest.getNumberOfSettingsPerKey(KEY_WIFI_NEW_CONFIG), 0);
+ }
+
+ @Test
+ @EnableFlags(com.android.server.backup.Flags.FLAG_ENABLE_METRICS_SETTINGS_BACKUP_AGENTS)
+ public void
+ restoreNewWifiConfigData_flagIsEnabled_restoreIsSuccessful_successMetricsAreLogged() {
+ mAgentUnderTest.onCreate(
+ UserHandle.SYSTEM, BackupDestination.CLOUD, OperationType.RESTORE);
+ doNothing().when(mWifiManager).restoreBackupData(any());
+
+ mAgentUnderTest.restoreNewWifiConfigData(new byte[] {});
+
+ DataTypeResult loggingResult =
+ getLoggingResultForDatatype(KEY_WIFI_NEW_CONFIG, mAgentUnderTest);
+ assertNotNull(loggingResult);
+ assertEquals(loggingResult.getSuccessCount(), 1);
+ }
+
+ @Test
+ @EnableFlags(com.android.server.backup.Flags.FLAG_ENABLE_METRICS_SETTINGS_BACKUP_AGENTS)
+ public void
+ restoreNewWifiConfigData_flagIsEnabled_restoreIsNotSuccessful_failureMetricsAreLogged() {
+ mAgentUnderTest.onCreate(
+ UserHandle.SYSTEM, BackupDestination.CLOUD, OperationType.RESTORE);
+ doThrow(new RuntimeException()).when(mWifiManager).restoreBackupData(any());
+
+ mAgentUnderTest.restoreNewWifiConfigData(new byte[] {});
+
+ DataTypeResult loggingResult =
+ getLoggingResultForDatatype(KEY_WIFI_NEW_CONFIG, mAgentUnderTest);
+ assertNotNull(loggingResult);
+ assertEquals(loggingResult.getFailCount(), 1);
+ }
+
+ @Test
+ @DisableFlags(com.android.server.backup.Flags.FLAG_ENABLE_METRICS_SETTINGS_BACKUP_AGENTS)
+ public void restoreNewWifiConfigData_flagIsNotEnabled_metricsAreNotLogged() {
+ mAgentUnderTest.onCreate(
+ UserHandle.SYSTEM, BackupDestination.CLOUD, OperationType.RESTORE);
+ doNothing().when(mWifiManager).restoreBackupData(any());
+
+ mAgentUnderTest.restoreNewWifiConfigData(new byte[] {});
+
+ assertNull(getLoggingResultForDatatype(KEY_WIFI_NEW_CONFIG, mAgentUnderTest));
+ }
+
private byte[] generateBackupData(Map<String, String> keyValueData) {
int totalBytes = 0;
for (String key : keyValueData.keySet()) {
diff --git a/packages/SystemUI/compose/core/tests/AndroidManifest.xml b/packages/SystemUI/compose/core/tests/AndroidManifest.xml
index 28f80d4..7c721b9 100644
--- a/packages/SystemUI/compose/core/tests/AndroidManifest.xml
+++ b/packages/SystemUI/compose/core/tests/AndroidManifest.xml
@@ -15,6 +15,7 @@
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
package="com.android.compose.core.tests" >
<application>
@@ -23,7 +24,8 @@
<activity
android:name="androidx.activity.ComponentActivity"
android:theme="@android:style/Theme.DeviceDefault.DayNight"
- android:exported="true" />
+ android:exported="true"
+ tools:replace="android:theme" />
</application>
<instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/source/TestShortcuts.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/source/TestShortcuts.kt
index 7c88d76..183e4d6 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/source/TestShortcuts.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/data/source/TestShortcuts.kt
@@ -24,6 +24,7 @@
import android.os.SystemClock
import android.view.KeyEvent
import android.view.KeyEvent.ACTION_DOWN
+import android.view.KeyEvent.ACTION_UP
import android.view.KeyEvent.KEYCODE_A
import android.view.KeyEvent.META_ALT_ON
import android.view.KeyEvent.META_CTRL_ON
@@ -540,11 +541,7 @@
simpleShortcutCategory(System, "System apps", "Take a note"),
simpleShortcutCategory(System, "System controls", "Take screenshot"),
simpleShortcutCategory(System, "System controls", "Go back"),
- simpleShortcutCategory(
- MultiTasking,
- "Split screen",
- "Switch to full screen",
- ),
+ simpleShortcutCategory(MultiTasking, "Split screen", "Switch to full screen"),
simpleShortcutCategory(
MultiTasking,
"Split screen",
@@ -704,7 +701,7 @@
android.view.KeyEvent(
/* downTime = */ SystemClock.uptimeMillis(),
/* eventTime = */ SystemClock.uptimeMillis(),
- /* action = */ ACTION_DOWN,
+ /* action = */ ACTION_UP,
/* code = */ KEYCODE_A,
/* repeat = */ 0,
/* metaState = */ 0,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutCustomizationViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutCustomizationViewModelTest.kt
index 755c218..d9d34f5 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutCustomizationViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutCustomizationViewModelTest.kt
@@ -92,13 +92,14 @@
viewModel.onShortcutCustomizationRequested(standardAddShortcutRequest)
val uiState by collectLastValue(viewModel.shortcutCustomizationUiState)
- assertThat(uiState).isEqualTo(
- AddShortcutDialog(
- shortcutLabel = "Standard shortcut",
- defaultCustomShortcutModifierKey =
- ShortcutKey.Icon.ResIdIcon(R.drawable.ic_ksh_key_meta),
+ assertThat(uiState)
+ .isEqualTo(
+ AddShortcutDialog(
+ shortcutLabel = "Standard shortcut",
+ defaultCustomShortcutModifierKey =
+ ShortcutKey.Icon.ResIdIcon(R.drawable.ic_ksh_key_meta),
+ )
)
- )
}
}
@@ -137,8 +138,7 @@
testScope.runTest {
val uiState by collectLastValue(viewModel.shortcutCustomizationUiState)
viewModel.onShortcutCustomizationRequested(standardAddShortcutRequest)
- assertThat((uiState as AddShortcutDialog).pressedKeys)
- .isEmpty()
+ assertThat((uiState as AddShortcutDialog).pressedKeys).isEmpty()
}
}
@@ -161,8 +161,7 @@
val uiState by collectLastValue(viewModel.shortcutCustomizationUiState)
viewModel.onShortcutCustomizationRequested(allAppsShortcutAddRequest)
- assertThat((uiState as AddShortcutDialog).errorMessage)
- .isEmpty()
+ assertThat((uiState as AddShortcutDialog).errorMessage).isEmpty()
}
}
@@ -244,32 +243,34 @@
}
@Test
- fun onKeyPressed_handlesKeyEvents_whereActionKeyIsAlsoPressed() {
+ fun onShortcutKeyCombinationSelected_handlesKeyEvents_whereActionKeyIsAlsoPressed() {
testScope.runTest {
viewModel.onShortcutCustomizationRequested(standardAddShortcutRequest)
- val isHandled = viewModel.onKeyPressed(keyDownEventWithActionKeyPressed)
+ val isHandled =
+ viewModel.onShortcutKeyCombinationSelected(keyDownEventWithActionKeyPressed)
assertThat(isHandled).isTrue()
}
}
@Test
- fun onKeyPressed_doesNotHandleKeyEvents_whenActionKeyIsNotAlsoPressed() {
+ fun onShortcutKeyCombinationSelected_doesNotHandleKeyEvents_whenActionKeyIsNotAlsoPressed() {
testScope.runTest {
viewModel.onShortcutCustomizationRequested(standardAddShortcutRequest)
- val isHandled = viewModel.onKeyPressed(keyDownEventWithoutActionKeyPressed)
+ val isHandled =
+ viewModel.onShortcutKeyCombinationSelected(keyDownEventWithoutActionKeyPressed)
assertThat(isHandled).isFalse()
}
}
@Test
- fun onKeyPressed_convertsKeyEventsAndUpdatesUiStatesPressedKey() {
+ fun onShortcutKeyCombinationSelected_convertsKeyEventsAndUpdatesUiStatesPressedKey() {
testScope.runTest {
val uiState by collectLastValue(viewModel.shortcutCustomizationUiState)
viewModel.onShortcutCustomizationRequested(standardAddShortcutRequest)
- viewModel.onKeyPressed(keyDownEventWithActionKeyPressed)
- viewModel.onKeyPressed(keyUpEventWithActionKeyPressed)
+ viewModel.onShortcutKeyCombinationSelected(keyDownEventWithActionKeyPressed)
+ viewModel.onShortcutKeyCombinationSelected(keyUpEventWithActionKeyPressed)
// Note that Action Key is excluded as it's already displayed on the UI
assertThat((uiState as AddShortcutDialog).pressedKeys)
@@ -282,8 +283,8 @@
testScope.runTest {
val uiState by collectLastValue(viewModel.shortcutCustomizationUiState)
viewModel.onShortcutCustomizationRequested(standardAddShortcutRequest)
- viewModel.onKeyPressed(keyDownEventWithActionKeyPressed)
- viewModel.onKeyPressed(keyUpEventWithActionKeyPressed)
+ viewModel.onShortcutKeyCombinationSelected(keyDownEventWithActionKeyPressed)
+ viewModel.onShortcutKeyCombinationSelected(keyUpEventWithActionKeyPressed)
// Note that Action Key is excluded as it's already displayed on the UI
assertThat((uiState as AddShortcutDialog).pressedKeys)
@@ -292,16 +293,15 @@
// Close the dialog and show it again
viewModel.onDialogDismissed()
viewModel.onShortcutCustomizationRequested(standardAddShortcutRequest)
- assertThat((uiState as AddShortcutDialog).pressedKeys)
- .isEmpty()
+ assertThat((uiState as AddShortcutDialog).pressedKeys).isEmpty()
}
}
private suspend fun openAddShortcutDialogAndSetShortcut() {
viewModel.onShortcutCustomizationRequested(allAppsShortcutAddRequest)
- viewModel.onKeyPressed(keyDownEventWithActionKeyPressed)
- viewModel.onKeyPressed(keyUpEventWithActionKeyPressed)
+ viewModel.onShortcutKeyCombinationSelected(keyDownEventWithActionKeyPressed)
+ viewModel.onShortcutKeyCombinationSelected(keyUpEventWithActionKeyPressed)
viewModel.onSetShortcut()
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt
index b3417b9..c44f27e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt
@@ -46,8 +46,6 @@
import com.android.systemui.keyguard.shared.model.TransitionState.STARTED
import com.android.systemui.keyguard.shared.model.TransitionStep
import com.android.systemui.kosmos.testScope
-import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAwakeForTest
-import com.android.systemui.power.domain.interactor.powerInteractor
import com.android.systemui.res.R
import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.scene.shared.model.Scenes
@@ -76,7 +74,6 @@
private val configRepository by lazy { kosmos.fakeConfigurationRepository }
private val bouncerRepository by lazy { kosmos.keyguardBouncerRepository }
private val shadeRepository by lazy { kosmos.shadeRepository }
- private val powerInteractor by lazy { kosmos.powerInteractor }
private val keyguardRepository by lazy { kosmos.keyguardRepository }
private val keyguardTransitionRepository by lazy { kosmos.fakeKeyguardTransitionRepository }
@@ -444,7 +441,6 @@
repository.setDozeTransitionModel(
DozeTransitionModel(from = DozeStateModel.DOZE, to = DozeStateModel.FINISH)
)
- powerInteractor.setAwakeForTest()
advanceTimeBy(1000L)
assertThat(isAbleToDream).isEqualTo(false)
@@ -460,9 +456,6 @@
repository.setDozeTransitionModel(
DozeTransitionModel(from = DozeStateModel.DOZE, to = DozeStateModel.FINISH)
)
- powerInteractor.setAwakeForTest()
- runCurrent()
-
// After some delay, still false
advanceTimeBy(300L)
assertThat(isAbleToDream).isEqualTo(false)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToPrimaryBouncerTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToPrimaryBouncerTransitionViewModelTest.kt
index feaf06a..ade7614 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToPrimaryBouncerTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToPrimaryBouncerTransitionViewModelTest.kt
@@ -16,10 +16,13 @@
package com.android.systemui.keyguard.ui.viewmodel
+import android.platform.test.annotations.EnableFlags
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
+import com.android.systemui.Flags.FLAG_BOUNCER_UI_REVAMP
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectValues
+import com.android.systemui.flags.BrokenWithSceneContainer
import com.android.systemui.flags.Flags
import com.android.systemui.flags.fakeFeatureFlagsClassic
import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
@@ -72,6 +75,28 @@
}
@Test
+ @EnableFlags(FLAG_BOUNCER_UI_REVAMP)
+ @BrokenWithSceneContainer(388068805)
+ fun notifications_areFullyVisible_whenShadeIsOpen() =
+ testScope.runTest {
+ val values by collectValues(underTest.notificationAlpha)
+ kosmos.bouncerWindowBlurTestUtil.shadeExpanded(true)
+
+ keyguardTransitionRepository.sendTransitionSteps(
+ listOf(
+ step(0f, TransitionState.STARTED),
+ step(0.1f),
+ step(0.2f),
+ step(0.3f),
+ step(1f),
+ ),
+ testScope,
+ )
+
+ values.forEach { assertThat(it).isEqualTo(1f) }
+ }
+
+ @Test
fun blurRadiusGoesToMaximumWhenShadeIsExpanded() =
testScope.runTest {
val values by collectValues(underTest.windowBlurRadius)
@@ -88,6 +113,25 @@
}
@Test
+ @EnableFlags(FLAG_BOUNCER_UI_REVAMP)
+ @BrokenWithSceneContainer(388068805)
+ fun notificationBlur_isNonZero_whenShadeIsExpanded() =
+ testScope.runTest {
+ val values by collectValues(underTest.notificationBlurRadius)
+
+ kosmos.bouncerWindowBlurTestUtil.shadeExpanded(true)
+
+ kosmos.bouncerWindowBlurTestUtil.assertTransitionToBlurRadius(
+ transitionProgress = listOf(0f, 0f, 0.1f, 0.2f, 0.3f, 1f),
+ startValue = kosmos.blurConfig.maxBlurRadiusPx / 3.0f,
+ endValue = kosmos.blurConfig.maxBlurRadiusPx / 3.0f,
+ transitionFactory = ::step,
+ actualValuesProvider = { values },
+ checkInterpolatedValues = false,
+ )
+ }
+
+ @Test
fun blurRadiusGoesFromMinToMaxWhenShadeIsNotExpanded() =
testScope.runTest {
val values by collectValues(underTest.windowBlurRadius)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToPrimaryBouncerTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToPrimaryBouncerTransitionViewModelTest.kt
index d909c5a..914094f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToPrimaryBouncerTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToPrimaryBouncerTransitionViewModelTest.kt
@@ -16,9 +16,11 @@
package com.android.systemui.keyguard.ui.viewmodel
+import android.platform.test.annotations.EnableFlags
import android.platform.test.flag.junit.FlagsParameterization
import androidx.test.filters.SmallTest
import com.android.compose.animation.scene.ObservableTransitionState
+import com.android.systemui.Flags.FLAG_BOUNCER_UI_REVAMP
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.coroutines.collectValues
@@ -153,7 +155,7 @@
}
@Test
- @BrokenWithSceneContainer(330311871)
+ @BrokenWithSceneContainer(388068805)
fun blurRadiusIsMaxWhenShadeIsExpanded() =
testScope.runTest {
val values by collectValues(underTest.windowBlurRadius)
@@ -170,7 +172,7 @@
}
@Test
- @BrokenWithSceneContainer(330311871)
+ @BrokenWithSceneContainer(388068805)
fun blurRadiusGoesFromMinToMaxWhenShadeIsNotExpanded() =
testScope.runTest {
val values by collectValues(underTest.windowBlurRadius)
@@ -185,6 +187,44 @@
)
}
+ @Test
+ @EnableFlags(FLAG_BOUNCER_UI_REVAMP)
+ @BrokenWithSceneContainer(388068805)
+ fun notificationBlur_isNonZero_whenShadeIsExpanded() =
+ testScope.runTest {
+ val values by collectValues(underTest.notificationBlurRadius)
+ kosmos.bouncerWindowBlurTestUtil.shadeExpanded(true)
+ runCurrent()
+
+ kosmos.bouncerWindowBlurTestUtil.assertTransitionToBlurRadius(
+ transitionProgress = listOf(0f, 0f, 0.1f, 0.2f, 0.3f, 1f),
+ startValue = kosmos.blurConfig.maxBlurRadiusPx / 3.0f,
+ endValue = kosmos.blurConfig.maxBlurRadiusPx / 3.0f,
+ transitionFactory = ::step,
+ actualValuesProvider = { values },
+ checkInterpolatedValues = false,
+ )
+ }
+
+ @Test
+ @EnableFlags(FLAG_BOUNCER_UI_REVAMP)
+ @BrokenWithSceneContainer(388068805)
+ fun notifications_areFullyVisible_whenShadeIsExpanded() =
+ testScope.runTest {
+ val values by collectValues(underTest.notificationAlpha)
+ kosmos.bouncerWindowBlurTestUtil.shadeExpanded(true)
+ runCurrent()
+
+ kosmos.bouncerWindowBlurTestUtil.assertTransitionToBlurRadius(
+ transitionProgress = listOf(0f, 0f, 0.1f, 0.2f, 0.3f, 1f),
+ startValue = 1.0f,
+ endValue = 1.0f,
+ transitionFactory = ::step,
+ actualValuesProvider = { values },
+ checkInterpolatedValues = false,
+ )
+ }
+
private fun step(
value: Float,
state: TransitionState = TransitionState.RUNNING,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java
index fc1d73b..3a3f537 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java
@@ -35,6 +35,7 @@
import android.app.Dialog;
import android.media.projection.StopReason;
import android.os.Handler;
+import android.platform.test.annotations.EnableFlags;
import android.platform.test.flag.junit.FlagsParameterization;
import android.service.quicksettings.Tile;
import android.testing.TestableLooper;
@@ -52,6 +53,7 @@
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.qs.QSHost;
import com.android.systemui.qs.QsEventLogger;
+import com.android.systemui.qs.flags.QsDetailedView;
import com.android.systemui.qs.flags.QsInCompose;
import com.android.systemui.qs.logging.QSLogger;
import com.android.systemui.qs.pipeline.domain.interactor.PanelInteractor;
@@ -63,6 +65,7 @@
import com.android.systemui.statusbar.policy.KeyguardStateController;
import org.junit.After;
+import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -70,11 +73,11 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-import java.util.List;
-
import platform.test.runner.parameterized.ParameterizedAndroidJunit4;
import platform.test.runner.parameterized.Parameters;
+import java.util.List;
+
@RunWith(ParameterizedAndroidJunit4.class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
@SmallTest
@@ -82,7 +85,8 @@
@Parameters(name = "{0}")
public static List<FlagsParameterization> getParams() {
- return allCombinationsOf(FLAG_QS_CUSTOM_TILE_CLICK_GUARANTEED_BUG_FIX);
+ return allCombinationsOf(FLAG_QS_CUSTOM_TILE_CLICK_GUARANTEED_BUG_FIX,
+ QsDetailedView.FLAG_NAME);
}
@Mock
@@ -336,6 +340,30 @@
.notifyPermissionRequestDisplayed(mContext.getUserId());
}
+ @Test
+ @EnableFlags(QsDetailedView.FLAG_NAME)
+ public void testNotStartingAndRecording_returnDetailsViewModel() {
+ when(mController.isStarting()).thenReturn(false);
+ when(mController.isRecording()).thenReturn(false);
+ mTile.getDetailsViewModel(Assert::assertNotNull);
+ }
+
+ @Test
+ @EnableFlags(QsDetailedView.FLAG_NAME)
+ public void testStarting_notReturnDetailsViewModel() {
+ when(mController.isStarting()).thenReturn(true);
+ when(mController.isRecording()).thenReturn(false);
+ mTile.getDetailsViewModel(Assert::assertNull);
+ }
+
+ @Test
+ @EnableFlags(QsDetailedView.FLAG_NAME)
+ public void testRecording_notReturnDetailsViewModel() {
+ when(mController.isStarting()).thenReturn(false);
+ when(mController.isRecording()).thenReturn(true);
+ mTile.getDetailsViewModel(Assert::assertNull);
+ }
+
private QSTile.Icon createExpectedIcon(int resId) {
if (QsInCompose.isEnabled()) {
return new QSTileImpl.DrawableIconWithRes(mContext.getDrawable(resId), resId);
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
index 789ca51..62c3604 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
@@ -85,7 +85,6 @@
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository;
import com.android.systemui.keyguard.domain.interactor.KeyguardClockInteractor;
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor;
-import com.android.systemui.keyguard.domain.interactor.KeyguardInteractorFactory;
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor;
import com.android.systemui.keyguard.domain.interactor.NaturalScrollingSettingObserver;
import com.android.systemui.keyguard.ui.viewmodel.DreamingToLockscreenTransitionViewModel;
@@ -335,16 +334,14 @@
mFeatureFlags.set(Flags.QS_USER_DETAIL_SHORTCUT, false);
mMainDispatcher = getMainDispatcher();
- KeyguardInteractorFactory.WithDependencies keyguardInteractorDeps =
- KeyguardInteractorFactory.create();
- mFakeKeyguardRepository = keyguardInteractorDeps.getRepository();
+ mFakeKeyguardRepository = mKosmos.getKeyguardRepository();
mFakeKeyguardClockRepository = new FakeKeyguardClockRepository();
mKeyguardClockInteractor = mKosmos.getKeyguardClockInteractor();
- mKeyguardInteractor = keyguardInteractorDeps.getKeyguardInteractor();
+ mKeyguardInteractor = mKosmos.getKeyguardInteractor();
mShadeRepository = new FakeShadeRepository();
mShadeAnimationInteractor = new ShadeAnimationInteractorLegacyImpl(
new ShadeAnimationRepository(), mShadeRepository);
- mPowerInteractor = keyguardInteractorDeps.getPowerInteractor();
+ mPowerInteractor = mKosmos.getPowerInteractor();
when(mKeyguardTransitionInteractor.isInTransitionWhere(any(), any())).thenReturn(
MutableStateFlow(false));
when(mKeyguardTransitionInteractor.isInTransition(any(), any()))
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt
index 45977886..a045b37 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt
@@ -70,6 +70,7 @@
import com.android.systemui.statusbar.notification.stack.domain.interactor.sharedNotificationContainerInteractor
import com.android.systemui.statusbar.notification.stack.ui.viewmodel.SharedNotificationContainerViewModel.HorizontalPosition
import com.android.systemui.testKosmos
+import com.android.systemui.window.ui.viewmodel.fakeBouncerTransitions
import com.google.common.collect.Range
import com.google.common.truth.Truth.assertThat
import kotlin.test.assertIs
@@ -1395,6 +1396,19 @@
assertThat(stackAbsoluteBottom).isEqualTo(100F)
}
+ @Test
+ fun blurRadius_emitsValues_fromPrimaryBouncerTransitions() =
+ testScope.runTest {
+ val blurRadius by collectLastValue(underTest.blurRadius)
+ assertThat(blurRadius).isEqualTo(0.0f)
+
+ kosmos.fakeBouncerTransitions.first().notificationBlurRadius.value = 30.0f
+ assertThat(blurRadius).isEqualTo(30.0f)
+
+ kosmos.fakeBouncerTransitions.last().notificationBlurRadius.value = 40.0f
+ assertThat(blurRadius).isEqualTo(40.0f)
+ }
+
private suspend fun TestScope.showLockscreen() {
shadeTestUtil.setQsExpansion(0f)
shadeTestUtil.setLockscreenShadeExpansion(0f)
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/ShortcutCustomizationDialogStarter.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/ShortcutCustomizationDialogStarter.kt
index 274fa59..a16b4a6 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/ShortcutCustomizationDialogStarter.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/ShortcutCustomizationDialogStarter.kt
@@ -53,11 +53,11 @@
override suspend fun onActivated(): Nothing {
viewModel.shortcutCustomizationUiState.collect { uiState ->
- when(uiState){
+ when (uiState) {
is AddShortcutDialog,
is DeleteShortcutDialog,
is ResetShortcutDialog -> {
- if (dialog == null){
+ if (dialog == null) {
dialog = createDialog().also { it.show() }
}
}
@@ -85,7 +85,9 @@
ShortcutCustomizationDialog(
uiState = uiState,
modifier = Modifier.width(364.dp).wrapContentHeight().padding(vertical = 24.dp),
- onKeyPress = { viewModel.onKeyPressed(it) },
+ onShortcutKeyCombinationSelected = {
+ viewModel.onShortcutKeyCombinationSelected(it)
+ },
onCancel = { dialog.dismiss() },
onConfirmSetShortcut = { coroutineScope.launch { viewModel.onSetShortcut() } },
onConfirmDeleteShortcut = {
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutCustomizer.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutCustomizer.kt
index 3819f6d..d9e55f8 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutCustomizer.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutCustomizer.kt
@@ -49,8 +49,12 @@
import androidx.compose.ui.focus.focusProperties
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.input.key.Key
import androidx.compose.ui.input.key.KeyEvent
-import androidx.compose.ui.input.key.onKeyEvent
+import androidx.compose.ui.input.key.KeyEventType
+import androidx.compose.ui.input.key.key
+import androidx.compose.ui.input.key.onPreviewKeyEvent
+import androidx.compose.ui.input.key.type
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
@@ -65,7 +69,7 @@
fun ShortcutCustomizationDialog(
uiState: ShortcutCustomizationUiState,
modifier: Modifier = Modifier,
- onKeyPress: (KeyEvent) -> Boolean,
+ onShortcutKeyCombinationSelected: (KeyEvent) -> Boolean,
onCancel: () -> Unit,
onConfirmSetShortcut: () -> Unit,
onConfirmDeleteShortcut: () -> Unit,
@@ -73,7 +77,13 @@
) {
when (uiState) {
is ShortcutCustomizationUiState.AddShortcutDialog -> {
- AddShortcutDialog(modifier, uiState, onKeyPress, onCancel, onConfirmSetShortcut)
+ AddShortcutDialog(
+ modifier,
+ uiState,
+ onShortcutKeyCombinationSelected,
+ onCancel,
+ onConfirmSetShortcut,
+ )
}
is ShortcutCustomizationUiState.DeleteShortcutDialog -> {
DeleteShortcutDialog(modifier, onCancel, onConfirmDeleteShortcut)
@@ -91,29 +101,27 @@
private fun AddShortcutDialog(
modifier: Modifier,
uiState: ShortcutCustomizationUiState.AddShortcutDialog,
- onKeyPress: (KeyEvent) -> Boolean,
+ onShortcutKeyCombinationSelected: (KeyEvent) -> Boolean,
onCancel: () -> Unit,
- onConfirmSetShortcut: () -> Unit
-){
+ onConfirmSetShortcut: () -> Unit,
+) {
Column(modifier = modifier) {
Title(uiState.shortcutLabel)
Description(
- text =
- stringResource(
- id = R.string.shortcut_customize_mode_add_shortcut_description
- )
+ text = stringResource(id = R.string.shortcut_customize_mode_add_shortcut_description)
)
PromptShortcutModifier(
modifier =
- Modifier.padding(top = 24.dp, start = 116.5.dp, end = 116.5.dp)
- .width(131.dp)
- .height(48.dp),
+ Modifier.padding(top = 24.dp, start = 116.5.dp, end = 116.5.dp)
+ .width(131.dp)
+ .height(48.dp),
defaultModifierKey = uiState.defaultCustomShortcutModifierKey,
)
SelectedKeyCombinationContainer(
shouldShowError = uiState.errorMessage.isNotEmpty(),
- onKeyPress = onKeyPress,
+ onShortcutKeyCombinationSelected = onShortcutKeyCombinationSelected,
pressedKeys = uiState.pressedKeys,
+ onConfirmSetShortcut = onConfirmSetShortcut,
)
ErrorMessageContainer(uiState.errorMessage)
DialogButtons(
@@ -121,9 +129,7 @@
isConfirmButtonEnabled = uiState.pressedKeys.isNotEmpty(),
onConfirm = onConfirmSetShortcut,
confirmButtonText =
- stringResource(
- R.string.shortcut_helper_customize_dialog_set_shortcut_button_label
- ),
+ stringResource(R.string.shortcut_helper_customize_dialog_set_shortcut_button_label),
)
}
}
@@ -132,20 +138,15 @@
private fun DeleteShortcutDialog(
modifier: Modifier,
onCancel: () -> Unit,
- onConfirmDeleteShortcut: () -> Unit
-){
+ onConfirmDeleteShortcut: () -> Unit,
+) {
ConfirmationDialog(
modifier = modifier,
- title =
- stringResource(
- id = R.string.shortcut_customize_mode_remove_shortcut_dialog_title
- ),
+ title = stringResource(id = R.string.shortcut_customize_mode_remove_shortcut_dialog_title),
description =
- stringResource(
- id = R.string.shortcut_customize_mode_remove_shortcut_description
- ),
+ stringResource(id = R.string.shortcut_customize_mode_remove_shortcut_description),
confirmButtonText =
- stringResource(R.string.shortcut_helper_customize_dialog_remove_button_label),
+ stringResource(R.string.shortcut_helper_customize_dialog_remove_button_label),
onCancel = onCancel,
onConfirm = onConfirmDeleteShortcut,
)
@@ -155,20 +156,15 @@
private fun ResetShortcutDialog(
modifier: Modifier,
onCancel: () -> Unit,
- onConfirmResetShortcut: () -> Unit
-){
+ onConfirmResetShortcut: () -> Unit,
+) {
ConfirmationDialog(
modifier = modifier,
- title =
- stringResource(
- id = R.string.shortcut_customize_mode_reset_shortcut_dialog_title
- ),
+ title = stringResource(id = R.string.shortcut_customize_mode_reset_shortcut_dialog_title),
description =
- stringResource(
- id = R.string.shortcut_customize_mode_reset_shortcut_description
- ),
+ stringResource(id = R.string.shortcut_customize_mode_reset_shortcut_description),
confirmButtonText =
- stringResource(R.string.shortcut_helper_customize_dialog_reset_button_label),
+ stringResource(R.string.shortcut_helper_customize_dialog_reset_button_label),
onCancel = onCancel,
onConfirm = onConfirmResetShortcut,
)
@@ -201,6 +197,9 @@
onConfirm: () -> Unit,
confirmButtonText: String,
) {
+ val focusRequester = remember { FocusRequester() }
+ LaunchedEffect(Unit) { focusRequester.requestFocus() }
+
Row(
modifier =
Modifier.padding(top = 24.dp, start = 24.dp, end = 24.dp)
@@ -218,6 +217,10 @@
)
Spacer(modifier = Modifier.width(8.dp))
ShortcutHelperButton(
+ modifier =
+ Modifier.focusRequester(focusRequester).focusProperties {
+ canFocus = true
+ }, // enable focus on touch/click mode
onClick = onConfirm,
color = MaterialTheme.colorScheme.primary,
width = 116.dp,
@@ -248,8 +251,9 @@
@Composable
private fun SelectedKeyCombinationContainer(
shouldShowError: Boolean,
- onKeyPress: (KeyEvent) -> Boolean,
+ onShortcutKeyCombinationSelected: (KeyEvent) -> Boolean,
pressedKeys: List<ShortcutKey>,
+ onConfirmSetShortcut: () -> Unit,
) {
val interactionSource = remember { MutableInteractionSource() }
val isFocused by interactionSource.collectIsFocusedAsState()
@@ -269,7 +273,17 @@
Modifier.padding(all = 16.dp)
.sizeIn(minWidth = 332.dp, minHeight = 56.dp)
.border(width = 2.dp, color = outlineColor, shape = RoundedCornerShape(50.dp))
- .onKeyEvent { onKeyPress(it) }
+ .onPreviewKeyEvent { keyEvent ->
+ val keyEventProcessed = onShortcutKeyCombinationSelected(keyEvent)
+ if (
+ !keyEventProcessed &&
+ keyEvent.key == Key.Enter &&
+ keyEvent.type == KeyEventType.KeyUp
+ ) {
+ onConfirmSetShortcut()
+ true
+ } else keyEventProcessed
+ }
.focusProperties { canFocus = true } // enables keyboard focus when in touch mode
.focusRequester(focusRequester),
interactionSource = interactionSource,
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutCustomizationViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutCustomizationViewModel.kt
index 373eb25..915a66c 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutCustomizationViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutCustomizationViewModel.kt
@@ -46,6 +46,7 @@
private val context: Context,
private val shortcutCustomizationInteractor: ShortcutCustomizationInteractor,
) {
+ private var keyDownEventCache: KeyEvent? = null
private val _shortcutCustomizationUiState =
MutableStateFlow<ShortcutCustomizationUiState>(ShortcutCustomizationUiState.Inactive)
@@ -94,9 +95,16 @@
shortcutCustomizationInteractor.updateUserSelectedKeyCombination(null)
}
- fun onKeyPressed(keyEvent: KeyEvent): Boolean {
- if ((keyEvent.isMetaPressed && keyEvent.type == KeyEventType.KeyDown)) {
- updatePressedKeys(keyEvent)
+ fun onShortcutKeyCombinationSelected(keyEvent: KeyEvent): Boolean {
+ if (isModifier(keyEvent)) {
+ return false
+ }
+ if (keyEvent.isMetaPressed && keyEvent.type == KeyEventType.KeyDown) {
+ keyDownEventCache = keyEvent
+ return true
+ } else if (keyEvent.type == KeyEventType.KeyUp && keyEvent.key == keyDownEventCache?.key) {
+ updatePressedKeys(keyDownEventCache!!)
+ clearKeyDownEventCache()
return true
}
return false
@@ -157,16 +165,21 @@
return (uiState as? AddShortcutDialog)?.copy(errorMessage = errorMessage) ?: uiState
}
+ private fun isModifier(keyEvent: KeyEvent) = SUPPORTED_MODIFIERS.contains(keyEvent.key)
+
private fun updatePressedKeys(keyEvent: KeyEvent) {
- val isModifier = SUPPORTED_MODIFIERS.contains(keyEvent.key)
val keyCombination =
KeyCombination(
modifiers = keyEvent.nativeKeyEvent.modifiers,
- keyCode = if (!isModifier) keyEvent.key.nativeKeyCode else null,
+ keyCode = if (!isModifier(keyEvent)) keyEvent.key.nativeKeyCode else null,
)
shortcutCustomizationInteractor.updateUserSelectedKeyCombination(keyCombination)
}
+ private fun clearKeyDownEventCache() {
+ keyDownEventCache = null
+ }
+
@AssistedFactory
interface Factory {
fun create(): ShortcutCustomizationViewModel
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt
index fbe31bb..8f7f2a0 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt
@@ -44,7 +44,6 @@
import com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN
import com.android.systemui.keyguard.shared.model.KeyguardState.OCCLUDED
import com.android.systemui.keyguard.shared.model.StatusBarState
-import com.android.systemui.power.domain.interactor.PowerInteractor
import com.android.systemui.res.R
import com.android.systemui.scene.domain.interactor.SceneInteractor
import com.android.systemui.scene.shared.flag.SceneContainerFlag
@@ -84,7 +83,6 @@
@Inject
constructor(
private val repository: KeyguardRepository,
- powerInteractor: PowerInteractor,
bouncerRepository: KeyguardBouncerRepository,
@ShadeDisplayAware configurationInteractor: ConfigurationInteractor,
shadeRepository: ShadeRepository,
@@ -216,11 +214,7 @@
// should actually be quite strange to leave AOD and then go straight to
// DREAMING so this should be fine.
delay(IS_ABLE_TO_DREAM_DELAY_MS)
- isDreaming
- .sample(powerInteractor.isAwake) { isDreaming, isAwake ->
- isDreaming && isAwake
- }
- .debounce(50L)
+ isDreaming.debounce(50L)
} else {
flowOf(false)
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/transitions/BlurConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/transitions/BlurConfig.kt
index 542fb9b..3eb8522 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/transitions/BlurConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/transitions/BlurConfig.kt
@@ -23,4 +23,10 @@
// No-op config that will be used by dagger of other SysUI variants which don't blur the
// background surface.
@Inject constructor() : this(0.0f, 0.0f)
+
+ companion object {
+ // Blur the shade much lesser than the background surface so that the surface is
+ // distinguishable from the background.
+ @JvmStatic fun Float.maxBlurRadiusToNotificationPanelBlurRadius(): Float = this / 3.0f
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/transitions/PrimaryBouncerTransition.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/transitions/PrimaryBouncerTransition.kt
index e77e9dd..eb1afb4 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/transitions/PrimaryBouncerTransition.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/transitions/PrimaryBouncerTransition.kt
@@ -30,6 +30,9 @@
/** Radius of blur applied to the window's root view. */
val windowBlurRadius: Flow<Float>
+ /** Radius of blur applied to the notifications on expanded shade */
+ val notificationBlurRadius: Flow<Float>
+
fun transitionProgressToBlurRadius(
starBlurRadius: Float,
endBlurRadius: Float,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToPrimaryBouncerTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToPrimaryBouncerTransitionViewModel.kt
index f174557..92bb5e6 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToPrimaryBouncerTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToPrimaryBouncerTransitionViewModel.kt
@@ -16,6 +16,7 @@
package com.android.systemui.keyguard.ui.viewmodel
+import com.android.systemui.Flags
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.keyguard.domain.interactor.FromAlternateBouncerTransitionInteractor
import com.android.systemui.keyguard.shared.model.Edge
@@ -23,6 +24,7 @@
import com.android.systemui.keyguard.shared.model.KeyguardState.PRIMARY_BOUNCER
import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
import com.android.systemui.keyguard.ui.transitions.BlurConfig
+import com.android.systemui.keyguard.ui.transitions.BlurConfig.Companion.maxBlurRadiusToNotificationPanelBlurRadius
import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransition
import com.android.systemui.keyguard.ui.transitions.PrimaryBouncerTransition
import com.android.systemui.scene.shared.flag.SceneContainerFlag
@@ -73,7 +75,28 @@
val lockscreenAlpha: Flow<Float> = if (WindowBlurFlag.isEnabled) alphaFlow else emptyFlow()
- val notificationAlpha: Flow<Float> = alphaFlow
+ val notificationAlpha: Flow<Float> =
+ if (Flags.bouncerUiRevamp()) {
+ shadeDependentFlows.transitionFlow(
+ flowWhenShadeIsNotExpanded = lockscreenAlpha,
+ flowWhenShadeIsExpanded = transitionAnimation.immediatelyTransitionTo(1f),
+ )
+ } else {
+ alphaFlow
+ }
+
+ override val notificationBlurRadius: Flow<Float> =
+ if (Flags.bouncerUiRevamp()) {
+ shadeDependentFlows.transitionFlow(
+ flowWhenShadeIsNotExpanded = emptyFlow(),
+ flowWhenShadeIsExpanded =
+ transitionAnimation.immediatelyTransitionTo(
+ blurConfig.maxBlurRadiusPx.maxBlurRadiusToNotificationPanelBlurRadius()
+ ),
+ )
+ } else {
+ emptyFlow<Float>()
+ }
override val deviceEntryParentViewAlpha: Flow<Float> =
transitionAnimation.immediatelyTransitionTo(0f)
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodToPrimaryBouncerTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodToPrimaryBouncerTransitionViewModel.kt
index dbb6a49..e3b5587 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodToPrimaryBouncerTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodToPrimaryBouncerTransitionViewModel.kt
@@ -53,4 +53,7 @@
override val windowBlurRadius: Flow<Float> =
transitionAnimation.immediatelyTransitionTo(blurConfig.maxBlurRadiusPx)
+
+ override val notificationBlurRadius: Flow<Float> =
+ transitionAnimation.immediatelyTransitionTo(0.0f)
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DozingToPrimaryBouncerTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DozingToPrimaryBouncerTransitionViewModel.kt
index d8b617a..c937d5c 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DozingToPrimaryBouncerTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DozingToPrimaryBouncerTransitionViewModel.kt
@@ -64,4 +64,6 @@
},
onFinish = { blurConfig.maxBlurRadiusPx },
)
+ override val notificationBlurRadius: Flow<Float> =
+ transitionAnimation.immediatelyTransitionTo(0f)
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GlanceableHubToPrimaryBouncerTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GlanceableHubToPrimaryBouncerTransitionViewModel.kt
index 597df15..5ab4583 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GlanceableHubToPrimaryBouncerTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GlanceableHubToPrimaryBouncerTransitionViewModel.kt
@@ -42,4 +42,7 @@
override val windowBlurRadius: Flow<Float> =
transitionAnimation.immediatelyTransitionTo(blurConfig.maxBlurRadiusPx)
+
+ override val notificationBlurRadius: Flow<Float> =
+ transitionAnimation.immediatelyTransitionTo(0.0f)
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToPrimaryBouncerTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToPrimaryBouncerTransitionViewModel.kt
index c373fd0..44c4c87 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToPrimaryBouncerTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToPrimaryBouncerTransitionViewModel.kt
@@ -16,6 +16,7 @@
package com.android.systemui.keyguard.ui.viewmodel
+import com.android.systemui.Flags
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.keyguard.domain.interactor.FromLockscreenTransitionInteractor
import com.android.systemui.keyguard.shared.model.Edge
@@ -23,6 +24,7 @@
import com.android.systemui.keyguard.shared.model.KeyguardState.PRIMARY_BOUNCER
import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
import com.android.systemui.keyguard.ui.transitions.BlurConfig
+import com.android.systemui.keyguard.ui.transitions.BlurConfig.Companion.maxBlurRadiusToNotificationPanelBlurRadius
import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransition
import com.android.systemui.keyguard.ui.transitions.PrimaryBouncerTransition
import com.android.systemui.scene.shared.flag.SceneContainerFlag
@@ -32,6 +34,7 @@
import kotlin.time.Duration.Companion.milliseconds
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.emptyFlow
/**
* Breaks down LOCKSCREEN->PRIMARY BOUNCER transition into discrete steps for corresponding views to
@@ -70,6 +73,29 @@
val lockscreenAlpha: Flow<Float> = shortcutsAlpha
+ val notificationAlpha: Flow<Float> =
+ if (Flags.bouncerUiRevamp()) {
+ shadeDependentFlows.transitionFlow(
+ flowWhenShadeIsNotExpanded = lockscreenAlpha,
+ flowWhenShadeIsExpanded = transitionAnimation.immediatelyTransitionTo(1f),
+ )
+ } else {
+ lockscreenAlpha
+ }
+
+ override val notificationBlurRadius: Flow<Float> =
+ if (Flags.bouncerUiRevamp()) {
+ shadeDependentFlows.transitionFlow(
+ flowWhenShadeIsNotExpanded = emptyFlow(),
+ flowWhenShadeIsExpanded =
+ transitionAnimation.immediatelyTransitionTo(
+ blurConfig.maxBlurRadiusPx.maxBlurRadiusToNotificationPanelBlurRadius()
+ ),
+ )
+ } else {
+ emptyFlow()
+ }
+
override val deviceEntryParentViewAlpha: Flow<Float> =
shadeDependentFlows.transitionFlow(
flowWhenShadeIsNotExpanded =
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToPrimaryBouncerTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToPrimaryBouncerTransitionViewModel.kt
index 4459810..4d3e272 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToPrimaryBouncerTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToPrimaryBouncerTransitionViewModel.kt
@@ -42,4 +42,7 @@
override val windowBlurRadius: Flow<Float> =
transitionAnimation.immediatelyTransitionTo(blurConfig.maxBlurRadiusPx)
+
+ override val notificationBlurRadius: Flow<Float> =
+ transitionAnimation.immediatelyTransitionTo(0.0f)
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToAodTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToAodTransitionViewModel.kt
index fab8008..224191b 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToAodTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToAodTransitionViewModel.kt
@@ -91,4 +91,7 @@
},
onFinish = { blurConfig.minBlurRadiusPx },
)
+
+ override val notificationBlurRadius: Flow<Float> =
+ transitionAnimation.immediatelyTransitionTo(0.0f)
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToDozingTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToDozingTransitionViewModel.kt
index eebdf2e..0f8495f 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToDozingTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToDozingTransitionViewModel.kt
@@ -80,4 +80,6 @@
},
onFinish = { blurConfig.minBlurRadiusPx },
)
+ override val notificationBlurRadius: Flow<Float> =
+ transitionAnimation.immediatelyTransitionTo(0.0f)
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGlanceableHubTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGlanceableHubTransitionViewModel.kt
index 3636b74..a13eef2 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGlanceableHubTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGlanceableHubTransitionViewModel.kt
@@ -43,4 +43,7 @@
override val windowBlurRadius: Flow<Float> =
transitionAnimation.immediatelyTransitionTo(blurConfig.minBlurRadiusPx)
+
+ override val notificationBlurRadius: Flow<Float> =
+ transitionAnimation.immediatelyTransitionTo(0.0f)
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModel.kt
index 4ed3e6c..d1233f2 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModel.kt
@@ -166,6 +166,9 @@
createBouncerWindowBlurFlow(primaryBouncerInteractor::willRunDismissFromKeyguard)
}
+ override val notificationBlurRadius: Flow<Float> =
+ transitionAnimation.immediatelyTransitionTo(0.0f)
+
val scrimAlpha: Flow<ScrimAlpha> =
bouncerToGoneFlows.scrimAlpha(TO_GONE_DURATION, PRIMARY_BOUNCER)
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToLockscreenTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToLockscreenTransitionViewModel.kt
index 2edc93cb..c53a408 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToLockscreenTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToLockscreenTransitionViewModel.kt
@@ -91,4 +91,7 @@
},
),
)
+
+ override val notificationBlurRadius: Flow<Float> =
+ transitionAnimation.immediatelyTransitionTo(0.0f)
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToOccludedTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToOccludedTransitionViewModel.kt
index 3a54a26..fe1708e 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToOccludedTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToOccludedTransitionViewModel.kt
@@ -42,4 +42,7 @@
override val windowBlurRadius: Flow<Float> =
transitionAnimation.immediatelyTransitionTo(blurConfig.minBlurRadiusPx)
+
+ override val notificationBlurRadius: Flow<Float> =
+ transitionAnimation.immediatelyTransitionTo(0.0f)
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java
index ec8d30b..e93cec8 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java
@@ -41,12 +41,14 @@
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.qs.QSTile;
+import com.android.systemui.plugins.qs.TileDetailsViewModel;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.qs.QSHost;
import com.android.systemui.qs.QsEventLogger;
import com.android.systemui.qs.logging.QSLogger;
import com.android.systemui.qs.pipeline.domain.interactor.PanelInteractor;
import com.android.systemui.qs.tileimpl.QSTileImpl;
+import com.android.systemui.qs.tiles.dialog.ScreenRecordDetailsViewModel;
import com.android.systemui.res.R;
import com.android.systemui.screenrecord.RecordingController;
import com.android.systemui.screenrecord.data.model.ScreenRecordModel;
@@ -54,6 +56,8 @@
import com.android.systemui.statusbar.phone.KeyguardDismissUtil;
import com.android.systemui.statusbar.policy.KeyguardStateController;
+import java.util.function.Consumer;
+
import javax.inject.Inject;
/**
@@ -122,17 +126,78 @@
@Override
protected void handleClick(@Nullable Expandable expandable) {
+ handleClick(() -> showDialog(expandable));
+ }
+
+ private void showDialog(@Nullable Expandable expandable) {
+ final Dialog dialog = mController.createScreenRecordDialog(
+ this::onStartRecordingClicked);
+
+ executeWhenUnlockedKeyguard(() -> {
+ // We animate from the touched view only if we are not on the keyguard, given that if we
+ // are we will dismiss it which will also collapse the shade.
+ boolean shouldAnimateFromExpandable =
+ expandable != null && !mKeyguardStateController.isShowing();
+
+ if (shouldAnimateFromExpandable) {
+ DialogTransitionAnimator.Controller controller =
+ expandable.dialogTransitionController(new DialogCuj(
+ InteractionJankMonitor.CUJ_SHADE_DIALOG_OPEN,
+ INTERACTION_JANK_TAG));
+ if (controller != null) {
+ mDialogTransitionAnimator.show(dialog,
+ controller, /* animateBackgroundBoundsChange= */ true);
+ } else {
+ dialog.show();
+ }
+ } else {
+ dialog.show();
+ }
+ });
+ }
+
+ private void onStartRecordingClicked() {
+ // We dismiss the shade. Since starting the recording will also dismiss the dialog (if
+ // there is one showing), we disable the exit animation which looks weird when it happens
+ // at the same time as the shade collapsing.
+ mDialogTransitionAnimator.disableAllCurrentDialogsExitAnimations();
+ mPanelInteractor.collapsePanels();
+ }
+
+ private void executeWhenUnlockedKeyguard(Runnable dismissActionCallback) {
+ ActivityStarter.OnDismissAction dismissAction = () -> {
+ dismissActionCallback.run();
+
+ int uid = mUserContextProvider.getUserContext().getUserId();
+ mMediaProjectionMetricsLogger.notifyPermissionRequestDisplayed(uid);
+
+ return false;
+ };
+
+ mKeyguardDismissUtil.executeWhenUnlocked(dismissAction, false /* requiresShadeOpen */,
+ true /* afterKeyguardDone */);
+ }
+
+ private void handleClick(Runnable showPromptCallback) {
if (mController.isStarting()) {
cancelCountdown();
} else if (mController.isRecording()) {
stopRecording();
} else {
- mUiHandler.post(() -> showPrompt(expandable));
+ mUiHandler.post(showPromptCallback);
}
refreshState();
}
@Override
+ public boolean getDetailsViewModel(Consumer<TileDetailsViewModel> callback) {
+ handleClick(() ->
+ callback.accept(new ScreenRecordDetailsViewModel())
+ );
+ return true;
+ }
+
+ @Override
protected void handleUpdateState(BooleanState state, Object arg) {
boolean isStarting = mController.isStarting();
boolean isRecording = mController.isRecording();
@@ -178,49 +243,6 @@
return mContext.getString(R.string.quick_settings_screen_record_label);
}
- private void showPrompt(@Nullable Expandable expandable) {
- // We animate from the touched view only if we are not on the keyguard, given that if we
- // are we will dismiss it which will also collapse the shade.
- boolean shouldAnimateFromExpandable =
- expandable != null && !mKeyguardStateController.isShowing();
-
- // Create the recording dialog that will collapse the shade only if we start the recording.
- Runnable onStartRecordingClicked = () -> {
- // We dismiss the shade. Since starting the recording will also dismiss the dialog, we
- // disable the exit animation which looks weird when it happens at the same time as the
- // shade collapsing.
- mDialogTransitionAnimator.disableAllCurrentDialogsExitAnimations();
- mPanelInteractor.collapsePanels();
- };
-
- final Dialog dialog = mController.createScreenRecordDialog(onStartRecordingClicked);
-
- ActivityStarter.OnDismissAction dismissAction = () -> {
- if (shouldAnimateFromExpandable) {
- DialogTransitionAnimator.Controller controller =
- expandable.dialogTransitionController(new DialogCuj(
- InteractionJankMonitor.CUJ_SHADE_DIALOG_OPEN,
- INTERACTION_JANK_TAG));
- if (controller != null) {
- mDialogTransitionAnimator.show(dialog,
- controller, /* animateBackgroundBoundsChange= */ true);
- } else {
- dialog.show();
- }
- } else {
- dialog.show();
- }
-
- int uid = mUserContextProvider.getUserContext().getUserId();
- mMediaProjectionMetricsLogger.notifyPermissionRequestDisplayed(uid);
-
- return false;
- };
-
- mKeyguardDismissUtil.executeWhenUnlocked(dismissAction, false /* requiresShadeOpen */,
- true /* afterKeyguardDone */);
- }
-
private void cancelCountdown() {
Log.d(TAG, "Cancelling countdown");
mController.cancelCountdown();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/ScreenRecordDetailsViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/ScreenRecordDetailsViewModel.kt
new file mode 100644
index 0000000..42cb124
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/ScreenRecordDetailsViewModel.kt
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2025 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.systemui.qs.tiles.dialog
+
+import android.view.LayoutInflater
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.heightIn
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.unit.Dp
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.viewinterop.AndroidView
+import com.android.systemui.plugins.qs.TileDetailsViewModel
+import com.android.systemui.res.R
+
+/** The view model used for the screen record details view in the Quick Settings */
+class ScreenRecordDetailsViewModel() : TileDetailsViewModel() {
+ @Composable
+ override fun GetContentView() {
+ // TODO(b/378514312): Finish implementing this function.
+ AndroidView(
+ modifier = Modifier.fillMaxWidth().heightIn(max = VIEW_MAX_HEIGHT),
+ factory = { context ->
+ // Inflate with the existing dialog xml layout
+ LayoutInflater.from(context).inflate(R.layout.screen_share_dialog, null)
+ },
+ )
+ }
+
+ override fun clickOnSettingsButton() {
+ // No settings button in this tile.
+ }
+
+ override fun getTitle(): String {
+ // TODO(b/388321032): Replace this string with a string in a translatable xml file,
+ return "Screen recording"
+ }
+
+ override fun getSubTitle(): String {
+ // No sub-title in this tile.
+ return ""
+ }
+
+ companion object {
+ private val VIEW_MAX_HEIGHT: Dp = 320.dp
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
index 1915217..c4306d3 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
@@ -109,6 +109,7 @@
import com.android.systemui.keyguard.shared.model.TransitionState;
import com.android.systemui.keyguard.shared.model.TransitionStep;
import com.android.systemui.keyguard.ui.binder.KeyguardLongPressViewBinder;
+import com.android.systemui.keyguard.ui.transitions.BlurConfig;
import com.android.systemui.keyguard.ui.viewmodel.DreamingToLockscreenTransitionViewModel;
import com.android.systemui.keyguard.ui.viewmodel.KeyguardTouchHandlingViewModel;
import com.android.systemui.media.controls.domain.pipeline.MediaDataManager;
@@ -914,13 +915,12 @@
if (!com.android.systemui.Flags.bouncerUiRevamp()) return;
if (isBouncerShowing && isExpanded()) {
- // Blur the shade much lesser than the background surface so that the surface is
- // distinguishable from the background.
- float shadeBlurEffect = mDepthController.getMaxBlurRadiusPx() / 3;
+ float shadeBlurEffect = BlurConfig.maxBlurRadiusToNotificationPanelBlurRadius(
+ mDepthController.getMaxBlurRadiusPx());
mView.setRenderEffect(RenderEffect.createBlurEffect(
shadeBlurEffect,
shadeBlurEffect,
- Shader.TileMode.MIRROR));
+ Shader.TileMode.CLAMP));
} else {
mView.setRenderEffect(null);
}
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 3866f79..95604c1 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
@@ -1267,6 +1267,9 @@
}
if (mExpandedWhenPinned) {
return Math.max(getMaxExpandHeight(), getHeadsUpHeight());
+ } else if (android.app.Flags.compactHeadsUpNotification()
+ && getShowingLayout().isHUNCompact()) {
+ return getHeadsUpHeight();
} else if (atLeastMinHeight) {
return Math.max(getCollapsedHeight(), getHeadsUpHeight());
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
index 786d7d9..0d29981 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
@@ -207,6 +207,8 @@
private boolean mContentAnimating;
private UiEventLogger mUiEventLogger;
+ private boolean mIsHUNCompact;
+
public NotificationContentView(Context context, AttributeSet attrs) {
super(context, attrs);
mHybridGroupManager = new HybridGroupManager(getContext());
@@ -543,6 +545,7 @@
if (child == null) {
mHeadsUpChild = null;
mHeadsUpWrapper = null;
+ mIsHUNCompact = false;
if (mTransformationStartVisibleType == VISIBLE_TYPE_HEADSUP) {
mTransformationStartVisibleType = VISIBLE_TYPE_NONE;
}
@@ -556,8 +559,9 @@
mHeadsUpWrapper = NotificationViewWrapper.wrap(getContext(), child,
mContainingNotification);
- if (Flags.compactHeadsUpNotification()
- && mHeadsUpWrapper instanceof NotificationCompactHeadsUpTemplateViewWrapper) {
+ mIsHUNCompact = Flags.compactHeadsUpNotification()
+ && mHeadsUpWrapper instanceof NotificationCompactHeadsUpTemplateViewWrapper;
+ if (mIsHUNCompact) {
logCompactHUNShownEvent();
}
@@ -902,6 +906,10 @@
}
}
+ public boolean isHUNCompact() {
+ return mIsHUNCompact;
+ }
+
private boolean isGroupExpanded() {
return mContainingNotification.isGroupExpanded();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
index e752e65..c717e3b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
@@ -35,6 +35,8 @@
import android.animation.ObjectAnimator;
import android.content.res.Configuration;
import android.graphics.Point;
+import android.graphics.RenderEffect;
+import android.graphics.Shader;
import android.os.Trace;
import android.os.UserHandle;
import android.provider.Settings;
@@ -1237,6 +1239,22 @@
updateAlpha();
}
+ /**
+ * Applies a blur effect to the view.
+ *
+ * @param blurRadius Radius of blur
+ */
+ public void setBlurRadius(float blurRadius) {
+ if (blurRadius > 0.0f) {
+ mView.setRenderEffect(RenderEffect.createBlurEffect(
+ blurRadius,
+ blurRadius,
+ Shader.TileMode.CLAMP));
+ } else {
+ mView.setRenderEffect(null);
+ }
+ }
+
private void updateAlpha() {
if (mView != null) {
mView.setAlpha(Math.min(Math.min(mMaxAlphaFromView, mMaxAlphaForKeyguard),
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/SharedNotificationContainerBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/SharedNotificationContainerBinder.kt
index 0b2b84e..3ea4d48 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/SharedNotificationContainerBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/SharedNotificationContainerBinder.kt
@@ -179,6 +179,10 @@
}
}
+ if (Flags.bouncerUiRevamp()) {
+ launch { viewModel.blurRadius.collect { controller.setBlurRadius(it) } }
+ }
+
if (communalSettingsInteractor.isCommunalFlagEnabled()) {
launch {
viewModel.glanceableHubAlpha.collect {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt
index fc8c70f..f0455fc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt
@@ -42,6 +42,7 @@
import com.android.systemui.keyguard.shared.model.KeyguardState.PRIMARY_BOUNCER
import com.android.systemui.keyguard.shared.model.StatusBarState.SHADE
import com.android.systemui.keyguard.shared.model.StatusBarState.SHADE_LOCKED
+import com.android.systemui.keyguard.ui.transitions.PrimaryBouncerTransition
import com.android.systemui.keyguard.ui.viewmodel.AlternateBouncerToGoneTransitionViewModel
import com.android.systemui.keyguard.ui.viewmodel.AlternateBouncerToPrimaryBouncerTransitionViewModel
import com.android.systemui.keyguard.ui.viewmodel.AodBurnInViewModel
@@ -154,6 +155,7 @@
private val primaryBouncerToGoneTransitionViewModel: PrimaryBouncerToGoneTransitionViewModel,
private val primaryBouncerToLockscreenTransitionViewModel:
PrimaryBouncerToLockscreenTransitionViewModel,
+ private val primaryBouncerTransitions: Set<@JvmSuppressWildcards PrimaryBouncerTransition>,
aodBurnInViewModel: AodBurnInViewModel,
private val communalSceneInteractor: CommunalSceneInteractor,
// Lazy because it's only used in the SceneContainer + Dual Shade configuration.
@@ -562,7 +564,7 @@
lockscreenToDreamingTransitionViewModel.lockscreenAlpha,
lockscreenToGoneTransitionViewModel.notificationAlpha(viewState),
lockscreenToOccludedTransitionViewModel.lockscreenAlpha,
- lockscreenToPrimaryBouncerTransitionViewModel.lockscreenAlpha,
+ lockscreenToPrimaryBouncerTransitionViewModel.notificationAlpha,
alternateBouncerToPrimaryBouncerTransitionViewModel.notificationAlpha,
occludedToAodTransitionViewModel.lockscreenAlpha,
occludedToGoneTransitionViewModel.notificationAlpha(viewState),
@@ -626,6 +628,12 @@
.dumpWhileCollecting("keyguardAlpha")
}
+ val blurRadius =
+ primaryBouncerTransitions
+ .map { transition -> transition.notificationBlurRadius }
+ .merge()
+ .dumpWhileCollecting("blurRadius")
+
/**
* Returns a flow of the expected alpha while running a LOCKSCREEN<->GLANCEABLE_HUB or
* DREAMING<->GLANCEABLE_HUB transition or idle on the hub.
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt
index 4abbbac..047b78e 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt
@@ -28,9 +28,11 @@
import com.android.systemui.SysuiTestCase
import com.android.systemui.broadcast.BroadcastDispatcher
import com.android.systemui.flags.Flags
+import com.android.systemui.flags.fakeFeatureFlagsClassic
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
-import com.android.systemui.keyguard.domain.interactor.KeyguardInteractorFactory
+import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
+import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
import com.android.systemui.keyguard.shared.model.Edge
import com.android.systemui.keyguard.shared.model.KeyguardState.AOD
import com.android.systemui.keyguard.shared.model.KeyguardState.DOZING
@@ -159,14 +161,12 @@
dndModeId = MANUAL_DND_INACTIVE.id
zenModeRepository.addMode(MANUAL_DND_INACTIVE)
- repository = FakeKeyguardRepository()
+ repository = kosmos.fakeKeyguardRepository
- val withDeps = KeyguardInteractorFactory.create(repository = repository)
-
- withDeps.featureFlags.apply { set(Flags.REGION_SAMPLING, false) }
+ kosmos.fakeFeatureFlagsClassic.set(Flags.REGION_SAMPLING, false)
underTest =
ClockEventController(
- withDeps.keyguardInteractor,
+ kosmos.keyguardInteractor,
keyguardTransitionInteractor,
broadcastDispatcher,
batteryController,
@@ -177,7 +177,7 @@
mainExecutor,
bgExecutor,
clockBuffers,
- withDeps.featureFlags,
+ kosmos.fakeFeatureFlagsClassic,
zenModeController,
kosmos.zenModeInteractor,
userTracker,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorFactory.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorFactory.kt
index 3de8093..ee21bdc 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorFactory.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorFactory.kt
@@ -24,8 +24,6 @@
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.TransitionStep
-import com.android.systemui.power.domain.interactor.PowerInteractor
-import com.android.systemui.power.domain.interactor.PowerInteractorFactory
import com.android.systemui.scene.domain.interactor.SceneInteractor
import com.android.systemui.shade.data.repository.FakeShadeRepository
import com.android.systemui.util.mockito.mock
@@ -55,7 +53,6 @@
fromLockscreenTransitionInteractor: FromLockscreenTransitionInteractor = mock(),
fromOccludedTransitionInteractor: FromOccludedTransitionInteractor = mock(),
fromAlternateBouncerTransitionInteractor: FromAlternateBouncerTransitionInteractor = mock(),
- powerInteractor: PowerInteractor = PowerInteractorFactory.create().powerInteractor,
testScope: CoroutineScope = TestScope(),
): WithDependencies {
// Mock these until they are replaced by kosmos
@@ -73,10 +70,8 @@
bouncerRepository = bouncerRepository,
configurationRepository = configurationRepository,
shadeRepository = shadeRepository,
- powerInteractor = powerInteractor,
KeyguardInteractor(
repository = repository,
- powerInteractor = powerInteractor,
bouncerRepository = bouncerRepository,
configurationInteractor = ConfigurationInteractorImpl(configurationRepository),
shadeRepository = shadeRepository,
@@ -99,7 +94,6 @@
val bouncerRepository: FakeKeyguardBouncerRepository,
val configurationRepository: FakeConfigurationRepository,
val shadeRepository: FakeShadeRepository,
- val powerInteractor: PowerInteractor,
val keyguardInteractor: KeyguardInteractor,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorKosmos.kt
index f5f8ef7..869bae2 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorKosmos.kt
@@ -21,7 +21,6 @@
import com.android.systemui.keyguard.data.repository.keyguardRepository
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.testScope
-import com.android.systemui.power.domain.interactor.powerInteractor
import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.shade.data.repository.shadeRepository
@@ -29,7 +28,6 @@
Kosmos.Fixture {
KeyguardInteractor(
repository = keyguardRepository,
- powerInteractor = powerInteractor,
bouncerRepository = keyguardBouncerRepository,
configurationInteractor = configurationInteractor,
shadeRepository = shadeRepository,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/transitions/FakeBouncerTransition.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/transitions/FakeBouncerTransition.kt
index 15d00d9..edc1cce 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/transitions/FakeBouncerTransition.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/transitions/FakeBouncerTransition.kt
@@ -20,4 +20,5 @@
class FakeBouncerTransition : PrimaryBouncerTransition {
override val windowBlurRadius: MutableStateFlow<Float> = MutableStateFlow(0.0f)
+ override val notificationBlurRadius: MutableStateFlow<Float> = MutableStateFlow(0.0f)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelKosmos.kt
index d1619b7..60e092c 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelKosmos.kt
@@ -57,6 +57,7 @@
import com.android.systemui.statusbar.notification.stack.domain.interactor.notificationStackAppearanceInteractor
import com.android.systemui.statusbar.notification.stack.domain.interactor.sharedNotificationContainerInteractor
import com.android.systemui.unfold.domain.interactor.unfoldTransitionInteractor
+import com.android.systemui.window.ui.viewmodel.fakeBouncerTransitions
import kotlinx.coroutines.ExperimentalCoroutinesApi
@OptIn(ExperimentalCoroutinesApi::class)
@@ -99,6 +100,7 @@
primaryBouncerToGoneTransitionViewModel = primaryBouncerToGoneTransitionViewModel,
primaryBouncerToLockscreenTransitionViewModel =
primaryBouncerToLockscreenTransitionViewModel,
+ primaryBouncerTransitions = fakeBouncerTransitions,
aodBurnInViewModel = aodBurnInViewModel,
communalSceneInteractor = communalSceneInteractor,
headsUpNotificationInteractor = { headsUpNotificationInteractor },
diff --git a/services/core/java/com/android/server/media/TEST_MAPPING b/services/core/java/com/android/server/media/TEST_MAPPING
index 43e2afd..dbf9915 100644
--- a/services/core/java/com/android/server/media/TEST_MAPPING
+++ b/services/core/java/com/android/server/media/TEST_MAPPING
@@ -1,7 +1,10 @@
{
"presubmit": [
{
- "name": "CtsMediaBetterTogetherTestCases"
+ "name": "CtsMediaRouterTestCases"
+ },
+ {
+ "name": "CtsMediaSessionTestCases"
},
{
"name": "MediaRouterServiceTests"
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index 93f512b..0bb3c6a 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -36,10 +36,7 @@
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.Person;
-import android.content.ContentProvider;
-import android.content.ContentResolver;
import android.content.Context;
-import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.content.pm.ShortcutInfo;
@@ -48,7 +45,6 @@
import android.media.AudioSystem;
import android.metrics.LogMaker;
import android.net.Uri;
-import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
@@ -1493,23 +1489,14 @@
final Notification notification = getNotification();
notification.visitUris((uri) -> {
- if (com.android.server.notification.Flags.notificationVerifyChannelSoundUri()) {
- visitGrantableUri(uri, false, false);
- } else {
- oldVisitGrantableUri(uri, false, false);
- }
+ visitGrantableUri(uri, false, false);
});
if (notification.getChannelId() != null) {
NotificationChannel channel = getChannel();
if (channel != null) {
- if (com.android.server.notification.Flags.notificationVerifyChannelSoundUri()) {
- visitGrantableUri(channel.getSound(), (channel.getUserLockedFields()
- & NotificationChannel.USER_LOCKED_SOUND) != 0, true);
- } else {
- oldVisitGrantableUri(channel.getSound(), (channel.getUserLockedFields()
- & NotificationChannel.USER_LOCKED_SOUND) != 0, true);
- }
+ visitGrantableUri(channel.getSound(), (channel.getUserLockedFields()
+ & NotificationChannel.USER_LOCKED_SOUND) != 0, true);
}
}
} finally {
@@ -1525,53 +1512,6 @@
* {@link #mGrantableUris}. Otherwise, this will either log or throw
* {@link SecurityException} depending on target SDK of enqueuing app.
*/
- private void oldVisitGrantableUri(Uri uri, boolean userOverriddenUri, boolean isSound) {
- if (uri == null || !ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) return;
-
- if (mGrantableUris != null && mGrantableUris.contains(uri)) {
- return; // already verified this URI
- }
-
- final int sourceUid = getSbn().getUid();
- final long ident = Binder.clearCallingIdentity();
- try {
- // This will throw a SecurityException if the caller can't grant.
- mUgmInternal.checkGrantUriPermission(sourceUid, null,
- ContentProvider.getUriWithoutUserId(uri),
- Intent.FLAG_GRANT_READ_URI_PERMISSION,
- ContentProvider.getUserIdFromUri(uri, UserHandle.getUserId(sourceUid)));
-
- if (mGrantableUris == null) {
- mGrantableUris = new ArraySet<>();
- }
- mGrantableUris.add(uri);
- } catch (SecurityException e) {
- if (!userOverriddenUri) {
- if (isSound) {
- mSound = Settings.System.DEFAULT_NOTIFICATION_URI;
- Log.w(TAG, "Replacing " + uri + " from " + sourceUid + ": " + e.getMessage());
- } else {
- if (mTargetSdkVersion >= Build.VERSION_CODES.P) {
- throw e;
- } else {
- Log.w(TAG,
- "Ignoring " + uri + " from " + sourceUid + ": " + e.getMessage());
- }
- }
- }
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
-
- /**
- * Note the presence of a {@link Uri} that should have permission granted to
- * whoever will be rendering it.
- * <p>
- * If the enqueuing app has the ability to grant access, it will be added to
- * {@link #mGrantableUris}. Otherwise, this will either log or throw
- * {@link SecurityException} depending on target SDK of enqueuing app.
- */
private void visitGrantableUri(Uri uri, boolean userOverriddenUri,
boolean isSound) {
if (mGrantableUris != null && mGrantableUris.contains(uri)) {
diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java
index 9d25d18..36eabae 100644
--- a/services/core/java/com/android/server/notification/PreferencesHelper.java
+++ b/services/core/java/com/android/server/notification/PreferencesHelper.java
@@ -1187,9 +1187,7 @@
// Verify that the app has permission to read the sound Uri
// Only check for new channels, as regular apps can only set sound
// before creating. See: {@link NotificationChannel#setSound}
- if (Flags.notificationVerifyChannelSoundUri()) {
- PermissionHelper.grantUriPermission(mUgmInternal, channel.getSound(), uid);
- }
+ PermissionHelper.grantUriPermission(mUgmInternal, channel.getSound(), uid);
channel.setImportanceLockedByCriticalDeviceFunction(
r.defaultAppLockedImportance || r.fixedImportance);
diff --git a/services/core/java/com/android/server/notification/flags.aconfig b/services/core/java/com/android/server/notification/flags.aconfig
index 2b4d71e..c1ca9c2 100644
--- a/services/core/java/com/android/server/notification/flags.aconfig
+++ b/services/core/java/com/android/server/notification/flags.aconfig
@@ -172,16 +172,6 @@
}
flag {
- name: "notification_verify_channel_sound_uri"
- namespace: "systemui"
- description: "Verify Uri permission for sound when creating a notification channel"
- bug: "337775777"
- metadata {
- purpose: PURPOSE_BUGFIX
- }
-}
-
-flag {
name: "notification_vibration_in_sound_uri_for_channel"
namespace: "systemui"
description: "Enables sound uri with vibration source in notification channel"
diff --git a/services/core/java/com/android/server/rollback/RollbackStore.java b/services/core/java/com/android/server/rollback/RollbackStore.java
index 14539d5..50db1e4 100644
--- a/services/core/java/com/android/server/rollback/RollbackStore.java
+++ b/services/core/java/com/android/server/rollback/RollbackStore.java
@@ -84,8 +84,12 @@
*/
private static List<Rollback> loadRollbacks(File rollbackDataDir) {
List<Rollback> rollbacks = new ArrayList<>();
- rollbackDataDir.mkdirs();
- for (File rollbackDir : rollbackDataDir.listFiles()) {
+ File[] rollbackDirs = rollbackDataDir.listFiles();
+ if (rollbackDirs == null) {
+ Slog.e(TAG, "Folder doesn't exist: " + rollbackDataDir);
+ return rollbacks;
+ }
+ for (File rollbackDir : rollbackDirs) {
if (rollbackDir.isDirectory()) {
try {
rollbacks.add(loadRollback(rollbackDir));
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 3e63156..3d53078 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -4261,7 +4261,7 @@
}
void finishRelaunching() {
- mAppCompatController.getAppCompatOrientationOverrides()
+ mAppCompatController.getOrientationOverrides()
.setRelaunchingAfterRequestedOrientationChanged(false);
mTaskSupervisor.getActivityMetricsLogger().notifyActivityRelaunched(this);
@@ -8222,7 +8222,7 @@
mLastReportedConfiguration.getMergedConfiguration())) {
ensureActivityConfiguration(false /* ignoreVisibility */);
if (mPendingRelaunchCount > originalRelaunchingCount) {
- mAppCompatController.getAppCompatOrientationOverrides()
+ mAppCompatController.getOrientationOverrides()
.setRelaunchingAfterRequestedOrientationChanged(true);
}
if (mTransitionController.inPlayingTransition(this)) {
@@ -10217,7 +10217,7 @@
mAppCompatController.getAppCompatAspectRatioOverrides()
.shouldOverrideMinAspectRatio());
proto.write(SHOULD_IGNORE_ORIENTATION_REQUEST_LOOP,
- mAppCompatController.getAppCompatOrientationOverrides()
+ mAppCompatController.getOrientationOverrides()
.shouldIgnoreOrientationRequestLoop());
proto.write(SHOULD_OVERRIDE_FORCE_RESIZE_APP,
mAppCompatController.getResizeOverrides().shouldOverrideForceResizeApp());
diff --git a/services/core/java/com/android/server/wm/AppCompatController.java b/services/core/java/com/android/server/wm/AppCompatController.java
index c748264..6d0e8ea 100644
--- a/services/core/java/com/android/server/wm/AppCompatController.java
+++ b/services/core/java/com/android/server/wm/AppCompatController.java
@@ -89,8 +89,8 @@
}
@NonNull
- AppCompatOrientationOverrides getAppCompatOrientationOverrides() {
- return mAppCompatOverrides.getAppCompatOrientationOverrides();
+ AppCompatOrientationOverrides getOrientationOverrides() {
+ return mAppCompatOverrides.getOrientationOverrides();
}
@NonNull
diff --git a/services/core/java/com/android/server/wm/AppCompatLetterboxPolicy.java b/services/core/java/com/android/server/wm/AppCompatLetterboxPolicy.java
index 8866e39..4494586 100644
--- a/services/core/java/com/android/server/wm/AppCompatLetterboxPolicy.java
+++ b/services/core/java/com/android/server/wm/AppCompatLetterboxPolicy.java
@@ -154,7 +154,7 @@
@VisibleForTesting
boolean shouldShowLetterboxUi(@NonNull WindowState mainWindow) {
- if (mActivityRecord.mAppCompatController.getAppCompatOrientationOverrides()
+ if (mActivityRecord.mAppCompatController.getOrientationOverrides()
.getIsRelaunchingAfterRequestedOrientationChanged()) {
return mLastShouldShowLetterboxUi;
}
diff --git a/services/core/java/com/android/server/wm/AppCompatOrientationOverrides.java b/services/core/java/com/android/server/wm/AppCompatOrientationOverrides.java
index c84711d..af83668 100644
--- a/services/core/java/com/android/server/wm/AppCompatOrientationOverrides.java
+++ b/services/core/java/com/android/server/wm/AppCompatOrientationOverrides.java
@@ -113,7 +113,7 @@
// Task to ensure that Activity Embedding is excluded.
return mActivityRecord.isVisibleRequested() && mActivityRecord.getTaskFragment() != null
&& mActivityRecord.getTaskFragment().getWindowingMode() == WINDOWING_MODE_FULLSCREEN
- && mActivityRecord.mAppCompatController.getAppCompatOrientationOverrides()
+ && mActivityRecord.mAppCompatController.getOrientationOverrides()
.isOverrideRespectRequestedOrientationEnabled();
}
diff --git a/services/core/java/com/android/server/wm/AppCompatOrientationPolicy.java b/services/core/java/com/android/server/wm/AppCompatOrientationPolicy.java
index 16e2029..fc758ef 100644
--- a/services/core/java/com/android/server/wm/AppCompatOrientationPolicy.java
+++ b/services/core/java/com/android/server/wm/AppCompatOrientationPolicy.java
@@ -94,7 +94,7 @@
return SCREEN_ORIENTATION_PORTRAIT;
}
- if (mAppCompatOverrides.getAppCompatOrientationOverrides()
+ if (mAppCompatOverrides.getOrientationOverrides()
.isAllowOrientationOverrideOptOut()) {
return candidate;
}
@@ -108,7 +108,7 @@
}
final AppCompatOrientationOverrides.OrientationOverridesState capabilityState =
- mAppCompatOverrides.getAppCompatOrientationOverrides()
+ mAppCompatOverrides.getOrientationOverrides()
.mOrientationOverridesState;
if (capabilityState.mIsOverrideToReverseLandscapeOrientationEnabled
@@ -170,7 +170,7 @@
boolean shouldIgnoreRequestedOrientation(
@ActivityInfo.ScreenOrientation int requestedOrientation) {
final AppCompatOrientationOverrides orientationOverrides =
- mAppCompatOverrides.getAppCompatOrientationOverrides();
+ mAppCompatOverrides.getOrientationOverrides();
if (orientationOverrides.shouldEnableIgnoreOrientationRequest()) {
if (orientationOverrides.getIsRelaunchingAfterRequestedOrientationChanged()) {
Slog.w(TAG, "Ignoring orientation update to "
diff --git a/services/core/java/com/android/server/wm/AppCompatOverrides.java b/services/core/java/com/android/server/wm/AppCompatOverrides.java
index 9effae6..9fb54db 100644
--- a/services/core/java/com/android/server/wm/AppCompatOverrides.java
+++ b/services/core/java/com/android/server/wm/AppCompatOverrides.java
@@ -27,7 +27,7 @@
public class AppCompatOverrides {
@NonNull
- private final AppCompatOrientationOverrides mAppCompatOrientationOverrides;
+ private final AppCompatOrientationOverrides mOrientationOverrides;
@NonNull
private final AppCompatCameraOverrides mAppCompatCameraOverrides;
@NonNull
@@ -48,7 +48,7 @@
@NonNull AppCompatDeviceStateQuery appCompatDeviceStateQuery) {
mAppCompatCameraOverrides = new AppCompatCameraOverrides(activityRecord,
appCompatConfiguration, optPropBuilder);
- mAppCompatOrientationOverrides = new AppCompatOrientationOverrides(activityRecord,
+ mOrientationOverrides = new AppCompatOrientationOverrides(activityRecord,
appCompatConfiguration, optPropBuilder, mAppCompatCameraOverrides);
mReachabilityOverrides = new AppCompatReachabilityOverrides(activityRecord,
appCompatConfiguration, appCompatDeviceStateQuery);
@@ -64,8 +64,8 @@
}
@NonNull
- AppCompatOrientationOverrides getAppCompatOrientationOverrides() {
- return mAppCompatOrientationOverrides;
+ AppCompatOrientationOverrides getOrientationOverrides() {
+ return mOrientationOverrides;
}
@NonNull
diff --git a/services/core/java/com/android/server/wm/DisplayArea.java b/services/core/java/com/android/server/wm/DisplayArea.java
index f40d636..b932ef3 100644
--- a/services/core/java/com/android/server/wm/DisplayArea.java
+++ b/services/core/java/com/android/server/wm/DisplayArea.java
@@ -264,7 +264,7 @@
// that should be respected, Check all activities in display to make sure any eligible
// activity should be respected.
final ActivityRecord activity = mDisplayContent.getActivity((r) ->
- r.mAppCompatController.getAppCompatOrientationOverrides()
+ r.mAppCompatController.getOrientationOverrides()
.shouldRespectRequestedOrientationDueToOverride());
return activity != null;
}
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 145c7b3..dd23f57 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -2964,7 +2964,7 @@
if (!handlesOrientationChangeFromDescendant(orientation)) {
ActivityRecord topActivity = topRunningActivity(/* considerKeyguardState= */ true);
if (topActivity != null && topActivity.mAppCompatController
- .getAppCompatOrientationOverrides()
+ .getOrientationOverrides()
.shouldUseDisplayLandscapeNaturalOrientation()) {
ProtoLog.v(WM_DEBUG_ORIENTATION,
"Display id=%d is ignoring orientation request for %d, return %d"
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index b43e334..3a2a1ea 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -5424,7 +5424,7 @@
// change then delay the position update until it has redrawn to avoid any flickers.
final boolean isLetterboxedAndRelaunching = activityRecord != null
&& activityRecord.areBoundsLetterboxed()
- && activityRecord.mAppCompatController.getAppCompatOrientationOverrides()
+ && activityRecord.mAppCompatController.getOrientationOverrides()
.getIsRelaunchingAfterRequestedOrientationChanged();
if (surfaceResizedWithoutMoveAnimation || isLetterboxedAndRelaunching) {
applyWithNextDraw(mSetSurfacePositionConsumer);
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
index 0d86d4c..60a4b9a 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
@@ -402,6 +402,7 @@
});
}
+ /**
public void testPushDynamicShortcut() {
// Change the max number of shortcuts.
mService.updateConfigurationLocked(ConfigConstants.KEY_MAX_SHORTCUTS + "=5,"
@@ -543,6 +544,7 @@
verify(mMockUsageStatsManagerInternal, times(1)).reportShortcutUsage(
eq(CALLING_PACKAGE_1), eq("s9"), eq(USER_10));
}
+ */
public void testPushDynamicShortcut_CallsToUsageStatsManagerAreThrottled()
throws InterruptedException {
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
index 8cc233b..f41805d 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
@@ -66,7 +66,6 @@
import static com.android.internal.util.FrameworkStatsLog.PACKAGE_NOTIFICATION_PREFERENCES__FSI_STATE__DENIED;
import static com.android.internal.util.FrameworkStatsLog.PACKAGE_NOTIFICATION_PREFERENCES__FSI_STATE__GRANTED;
import static com.android.internal.util.FrameworkStatsLog.PACKAGE_NOTIFICATION_PREFERENCES__FSI_STATE__NOT_REQUESTED;
-import static com.android.server.notification.Flags.FLAG_NOTIFICATION_VERIFY_CHANNEL_SOUND_URI;
import static com.android.server.notification.Flags.FLAG_PERSIST_INCOMPLETE_RESTORE_DATA;
import static com.android.server.notification.NotificationChannelLogger.NotificationChannelEvent.NOTIFICATION_CHANNEL_UPDATED_BY_USER;
import static com.android.server.notification.PreferencesHelper.DEFAULT_BUBBLE_PREFERENCE;
@@ -3192,7 +3191,6 @@
}
@Test
- @EnableFlags(FLAG_NOTIFICATION_VERIFY_CHANNEL_SOUND_URI)
public void testCreateChannel_noSoundUriPermission_contentSchemeVerified() {
final Uri sound = Uri.parse(SCHEME_CONTENT + "://media/test/sound/uri");
@@ -3212,7 +3210,6 @@
}
@Test
- @EnableFlags(FLAG_NOTIFICATION_VERIFY_CHANNEL_SOUND_URI)
public void testCreateChannel_noSoundUriPermission_fileSchemaIgnored() {
final Uri sound = Uri.parse(SCHEME_FILE + "://path/sound");
@@ -3231,7 +3228,6 @@
}
@Test
- @EnableFlags(FLAG_NOTIFICATION_VERIFY_CHANNEL_SOUND_URI)
public void testCreateChannel_noSoundUriPermission_resourceSchemaIgnored() {
final Uri sound = Uri.parse(SCHEME_ANDROID_RESOURCE + "://resId/sound");
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppCompatOrientationOverridesTest.java b/services/tests/wmtests/src/com/android/server/wm/AppCompatOrientationOverridesTest.java
index 9d191ce..a0727a7 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppCompatOrientationOverridesTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppCompatOrientationOverridesTest.java
@@ -335,7 +335,7 @@
}
private AppCompatOrientationOverrides getTopOrientationOverrides() {
- return activity().top().mAppCompatController.getAppCompatOrientationOverrides();
+ return activity().top().mAppCompatController.getOrientationOverrides();
}
}
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppCompatOrientationPolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/AppCompatOrientationPolicyTest.java
index a21ab5d..4faa714 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppCompatOrientationPolicyTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppCompatOrientationPolicyTest.java
@@ -601,7 +601,7 @@
}
private AppCompatOrientationOverrides getTopOrientationOverrides() {
- return activity().top().mAppCompatController.getAppCompatOrientationOverrides();
+ return activity().top().mAppCompatController.getOrientationOverrides();
}
private AppCompatOrientationPolicy getTopAppCompatOrientationPolicy() {
diff --git a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
index d6080e0..96b11a8 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
@@ -834,7 +834,7 @@
// Change the fixed orientation.
mActivity.setRequestedOrientation(SCREEN_ORIENTATION_LANDSCAPE);
assertTrue(mActivity.isRelaunching());
- assertTrue(mActivity.mAppCompatController.getAppCompatOrientationOverrides()
+ assertTrue(mActivity.mAppCompatController.getOrientationOverrides()
.getIsRelaunchingAfterRequestedOrientationChanged());
assertFitted();
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index 7082f00..e65e4b0 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -29,6 +29,7 @@
import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.annotation.SystemService;
+import android.annotation.TestApi;
import android.compat.annotation.ChangeId;
import android.compat.annotation.EnabledSince;
import android.compat.annotation.UnsupportedAppUsage;
@@ -1886,6 +1887,34 @@
}
/**
+ * This test API determines the foreground service delegation state for a VoIP app that adds
+ * calls via {@link TelecomManager#addCall(CallAttributes, Executor, OutcomeReceiver,
+ * CallControlCallback, CallEventCallback)}. Foreground Service Delegation allows applications
+ * to operate in the background starting in Android 14 and is granted by Telecom via a request
+ * to the ActivityManager.
+ *
+ * @param handle of the voip app that is being checked
+ * @return true if the app has foreground service delegation. Otherwise, false.
+ *
+ * @hide
+ */
+ @FlaggedApi(Flags.FLAG_VOIP_CALL_MONITOR_REFACTOR)
+ @TestApi
+ public boolean hasForegroundServiceDelegation(@Nullable PhoneAccountHandle handle) {
+ ITelecomService service = getTelecomService();
+ if (service != null) {
+ try {
+ return service.hasForegroundServiceDelegation(handle, mContext.getOpPackageName());
+ } catch (RemoteException e) {
+ Log.e(TAG,
+ "RemoteException calling ITelecomService#hasForegroundServiceDelegation.",
+ e);
+ }
+ }
+ return false;
+ }
+
+ /**
* Return the line 1 phone number for given phone account.
*
* <p>Requires Permission:
diff --git a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
index c85374e..b32379a 100644
--- a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
+++ b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
@@ -409,4 +409,10 @@
*/
void addCall(in CallAttributes callAttributes, in ICallEventCallback callback, String callId,
String callingPackage);
+
+ /**
+ * @see TelecomServiceImpl#hasForegroundServiceDelegation
+ */
+ boolean hasForegroundServiceDelegation(in PhoneAccountHandle phoneAccountHandle,
+ String callingPackage);
}
diff --git a/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/open/MainActivityStartsSecondaryWithAlwaysExpandTest.kt b/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/open/MainActivityStartsSecondaryWithAlwaysExpandTest.kt
index 08b5f38..75bd5d1 100644
--- a/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/open/MainActivityStartsSecondaryWithAlwaysExpandTest.kt
+++ b/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/open/MainActivityStartsSecondaryWithAlwaysExpandTest.kt
@@ -17,7 +17,6 @@
package com.android.server.wm.flicker.activityembedding.open
import android.graphics.Rect
-import android.platform.test.annotations.Presubmit
import android.tools.flicker.junit.FlickerParametersRunnerFactory
import android.tools.flicker.legacy.FlickerBuilder
import android.tools.flicker.legacy.LegacyFlickerTest
@@ -68,13 +67,21 @@
}
}
- @Ignore("Not applicable to this CUJ.") override fun navBarWindowIsVisibleAtStartAndEnd() {}
+ @Ignore("Not applicable to this CUJ.")
+ @Test
+ override fun navBarWindowIsVisibleAtStartAndEnd() {}
- @FlakyTest(bugId = 291575593) override fun entireScreenCovered() {}
+ @FlakyTest(bugId = 291575593)
+ @Test
+ override fun entireScreenCovered() {}
- @Ignore("Not applicable to this CUJ.") override fun statusBarWindowIsAlwaysVisible() {}
+ @Ignore("Not applicable to this CUJ.")
+ @Test
+ override fun statusBarWindowIsAlwaysVisible() {}
- @Ignore("Not applicable to this CUJ.") override fun statusBarLayerPositionAtStartAndEnd() {}
+ @Ignore("Not applicable to this CUJ.")
+ @Test
+ override fun statusBarLayerPositionAtStartAndEnd() {}
/** Transition begins with a split. */
@FlakyTest(bugId = 286952194)
@@ -122,7 +129,6 @@
/** Always expand activity is on top of the split. */
@FlakyTest(bugId = 286952194)
- @Presubmit
@Test
fun endsWithAlwaysExpandActivityOnTop() {
flicker.assertWmEnd {
diff --git a/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/splitscreen/EnterSystemSplitTest.kt b/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/splitscreen/EnterSystemSplitTest.kt
index 0ca8f37..e413645 100644
--- a/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/splitscreen/EnterSystemSplitTest.kt
+++ b/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/splitscreen/EnterSystemSplitTest.kt
@@ -176,12 +176,15 @@
}
@Ignore("Not applicable to this CUJ.")
+ @Test
override fun visibleLayersShownMoreThanOneConsecutiveEntry() {}
@FlakyTest(bugId = 342596801)
+ @Test
override fun entireScreenCovered() = super.entireScreenCovered()
@FlakyTest(bugId = 342596801)
+ @Test
override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
super.visibleWindowsShownMoreThanOneConsecutiveEntry()
diff --git a/tests/FlickerTests/IME/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromFixedOrientationTest.kt b/tests/FlickerTests/IME/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromFixedOrientationTest.kt
index b8f11dc..ad083fa 100644
--- a/tests/FlickerTests/IME/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromFixedOrientationTest.kt
+++ b/tests/FlickerTests/IME/src/com/android/server/wm/flicker/ime/ShowImeOnAppStartWhenLaunchingAppFromFixedOrientationTest.kt
@@ -16,7 +16,6 @@
package com.android.server.wm.flicker.ime
-import android.platform.test.annotations.Postsubmit
import android.platform.test.annotations.Presubmit
import android.tools.Rotation
import android.tools.flicker.junit.FlickerParametersRunnerFactory
@@ -81,7 +80,6 @@
}
@FlakyTest(bugId = 290767483)
- @Postsubmit
@Test
fun imeLayerAlphaOneAfterSnapshotStartingWindowRemoval() {
val layerTrace = flicker.reader.readLayersTrace() ?: error("Unable to read layers trace")