summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/api/current.txt2
-rw-r--r--core/api/module-lib-current.txt4
-rw-r--r--core/java/android/app/SystemServiceRegistry.java12
-rw-r--r--core/java/android/hardware/display/DisplayManager.java16
-rw-r--r--core/java/android/net/metrics/DnsEvent.java6
-rw-r--r--core/java/android/os/OWNERS3
-rw-r--r--core/java/android/os/SELinux.java27
-rw-r--r--core/java/android/os/ServiceManager.java6
-rw-r--r--core/java/android/os/ServiceManagerNative.java2
-rw-r--r--core/java/android/os/UpdateEngine.java20
-rw-r--r--core/java/android/provider/Settings.java114
-rw-r--r--core/java/android/security/net/config/CertificatesEntryRef.java10
-rw-r--r--core/java/android/security/net/config/KeyStoreConfigSource.java4
-rw-r--r--core/java/android/security/net/config/NetworkSecurityConfig.java22
-rw-r--r--core/java/android/security/net/config/XmlConfigSource.java5
-rw-r--r--core/java/com/android/internal/os/TEST_MAPPING2
-rw-r--r--core/java/com/android/internal/pm/pkg/component/AconfigFlags.java8
-rw-r--r--core/jni/Android.bp1
-rw-r--r--core/jni/android_os_SELinux.cpp30
-rw-r--r--core/tests/coretests/Android.bp15
-rw-r--r--core/tests/coretests/src/android/content/res/FontScaleConverterFactoryTest.kt13
-rw-r--r--core/tests/coretests/src/android/content/res/ResourcesManagerTest.java10
-rw-r--r--core/tests/coretests/src/android/os/BinderThreadPriorityTest.java4
-rw-r--r--keystore/java/Android.bp8
-rw-r--r--keystore/java/android/security/KeyStore2.java14
-rw-r--r--keystore/java/android/security/KeyStore2HalCurrent.java30
-rw-r--r--keystore/java/android/security/KeyStore2HalLatest.java31
-rw-r--r--keystore/java/android/security/keystore/KeyStoreManager.java35
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/transition/MixedTransitionHelper.java5
-rw-r--r--libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/FromSplitScreenEnterPipOnUserLeaveHintTest.kt6
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java8
-rw-r--r--packages/SystemUI/aconfig/systemui.aconfig10
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayCallbackControllerTest.kt14
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayServiceTest.kt3
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryBackgroundViewModelTest.kt90
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt26
-rw-r--r--packages/SystemUI/res/layout/super_notification_shade.xml16
-rw-r--r--packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractor.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayCallbackController.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt12
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardPreviewClockViewBinder.kt15
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryBackgroundViewModel.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDozingTransitionViewModel.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaProcessingHelper.kt18
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/SingleLineViewInflater.kt24
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ui/viewbinder/SingleLineViewBinder.kt12
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java11
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java14
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/SingleLineViewBinderTest.kt65
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java54
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryBackgroundViewModelKosmos.kt52
-rw-r--r--ravenwood/Android.bp16
-rw-r--r--ravenwood/junit-flag-src/android/platform/test/flag/junit/RavenwoodFlagsValueProvider.java54
-rw-r--r--ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodAwareTestRunner.java12
-rw-r--r--ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRunnerState.java14
-rw-r--r--ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java4
-rw-r--r--ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java4
-rw-r--r--ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodAwareTestRunnerBase.java6
-rw-r--r--ravenwood/runtime-jni/ravenwood_initializer.cpp4
-rw-r--r--ravenwood/runtime-jni/ravenwood_runtime.cpp2
-rw-r--r--services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java6
-rw-r--r--services/accessibility/java/com/android/server/accessibility/magnification/MagnificationConnectionManager.java10
-rw-r--r--services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java11
-rw-r--r--services/core/java/com/android/server/UiModeManagerService.java33
-rw-r--r--services/core/java/com/android/server/accounts/AccountManagerService.java88
-rw-r--r--services/core/java/com/android/server/am/ActiveServices.java5
-rw-r--r--services/core/java/com/android/server/audio/AudioService.java23
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java27
-rw-r--r--services/core/java/com/android/server/pm/permission/PermissionManagerService.java3
-rw-r--r--services/core/java/com/android/server/policy/PhoneWindowManager.java115
-rw-r--r--services/core/java/com/android/server/search/SearchManagerService.java12
-rw-r--r--services/core/java/com/android/server/vibrator/VibrationSettings.java137
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java9
-rw-r--r--services/core/java/com/android/server/wm/ConfigurationContainer.java12
-rw-r--r--services/core/java/com/android/server/wm/InsetsSourceProvider.java3
-rw-r--r--services/core/java/com/android/server/wm/Transition.java11
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationConnectionManagerTest.java7
-rw-r--r--services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java62
-rw-r--r--services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java3
-rw-r--r--services/tests/vibrator/src/com/android/server/vibrator/VibrationSettingsTest.java134
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java22
-rw-r--r--tests/NetworkSecurityConfigTest/res/xml/ct_domains.xml38
-rw-r--r--tests/NetworkSecurityConfigTest/res/xml/ct_users.xml15
-rw-r--r--tests/NetworkSecurityConfigTest/src/android/security/net/config/NetworkSecurityConfigTests.java15
-rw-r--r--tests/NetworkSecurityConfigTest/src/android/security/net/config/XmlConfigTests.java43
92 files changed, 1306 insertions, 621 deletions
diff --git a/core/api/current.txt b/core/api/current.txt
index 3335375238c9..832a68fd1e8f 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -39990,8 +39990,10 @@ package android.security.keystore {
method @NonNull public java.util.List<java.security.cert.X509Certificate> getGrantedCertificateChainFromId(long) throws android.security.keystore.KeyPermanentlyInvalidatedException, java.security.UnrecoverableKeyException;
method @NonNull public java.security.Key getGrantedKeyFromId(long) throws android.security.keystore.KeyPermanentlyInvalidatedException, java.security.UnrecoverableKeyException;
method @NonNull public java.security.KeyPair getGrantedKeyPairFromId(long) throws android.security.keystore.KeyPermanentlyInvalidatedException, java.security.UnrecoverableKeyException;
+ method @FlaggedApi("android.security.keystore2.attest_modules") @NonNull public byte[] getSupplementaryAttestationInfo(int) throws android.security.KeyStoreException;
method public long grantKeyAccess(@NonNull String, int) throws android.security.KeyStoreException, java.security.UnrecoverableKeyException;
method public void revokeKeyAccess(@NonNull String, int) throws android.security.KeyStoreException, java.security.UnrecoverableKeyException;
+ field public static final int MODULE_HASH = -1879047468; // 0x900002d4
}
public class SecureKeyImportUnavailableException extends java.security.ProviderException {
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt
index 340d9cba1eac..6446f07937d4 100644
--- a/core/api/module-lib-current.txt
+++ b/core/api/module-lib-current.txt
@@ -483,6 +483,10 @@ package android.os {
field public static final long TRACE_TAG_NETWORK = 2097152L; // 0x200000L
}
+ public class UpdateEngine {
+ method @FlaggedApi("android.os.update_engine_api") public void triggerPostinstall(@NonNull String);
+ }
+
}
package android.os.storage {
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 8f84ee879b1a..79dd22fb3df5 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -78,8 +78,6 @@ import android.content.ContentCaptureOptions;
import android.content.Context;
import android.content.IRestrictionsManager;
import android.content.RestrictionsManager;
-import android.content.integrity.AppIntegrityManager;
-import android.content.integrity.IAppIntegrityManager;
import android.content.om.IOverlayManager;
import android.content.om.OverlayManager;
import android.content.pm.ApplicationInfo;
@@ -1536,16 +1534,6 @@ public final class SystemServiceRegistry {
return new AttestationVerificationManager(ctx.getOuterContext(),
IAttestationVerificationManagerService.Stub.asInterface(b));
}});
-
- //CHECKSTYLE:ON IndentationCheck
- registerService(Context.APP_INTEGRITY_SERVICE, AppIntegrityManager.class,
- new CachedServiceFetcher<AppIntegrityManager>() {
- @Override
- public AppIntegrityManager createService(ContextImpl ctx)
- throws ServiceNotFoundException {
- IBinder b = ServiceManager.getServiceOrThrow(Context.APP_INTEGRITY_SERVICE);
- return new AppIntegrityManager(IAppIntegrityManager.Stub.asInterface(b));
- }});
registerService(Context.APP_HIBERNATION_SERVICE, AppHibernationManager.class,
new CachedServiceFetcher<AppHibernationManager>() {
@Override
diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java
index 97f6899ff141..b0ea92d140a5 100644
--- a/core/java/android/hardware/display/DisplayManager.java
+++ b/core/java/android/hardware/display/DisplayManager.java
@@ -18,6 +18,7 @@ package android.hardware.display;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.HdrCapabilities.HdrType;
+import static android.view.Display.INVALID_DISPLAY;
import android.Manifest;
import android.annotation.FlaggedApi;
@@ -47,6 +48,7 @@ import android.os.Looper;
import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.os.UserManager;
import android.util.Log;
import android.util.Pair;
import android.util.Slog;
@@ -96,6 +98,8 @@ public final class DisplayManager {
@GuardedBy("mLock")
private final WeakDisplayCache mDisplayCache = new WeakDisplayCache();
+ private int mDisplayIdToMirror = INVALID_DISPLAY;
+
/**
* Broadcast receiver that indicates when the Wifi display status changes.
* <p>
@@ -1086,6 +1090,7 @@ public final class DisplayManager {
if (surface != null) {
builder.setSurface(surface);
}
+ builder.setDisplayIdToMirror(getDisplayIdToMirror());
return createVirtualDisplay(builder.build(), handler, callback);
}
@@ -1163,6 +1168,7 @@ public final class DisplayManager {
if (surface != null) {
builder.setSurface(surface);
}
+ builder.setDisplayIdToMirror(getDisplayIdToMirror());
return createVirtualDisplay(projection, builder.build(), callback, handler);
}
@@ -1708,6 +1714,16 @@ public final class DisplayManager {
return mGlobal.getDefaultDozeBrightness(displayId);
}
+ private int getDisplayIdToMirror() {
+ if (mDisplayIdToMirror == INVALID_DISPLAY) {
+ final UserManager userManager = mContext.getSystemService(UserManager.class);
+ mDisplayIdToMirror = userManager.isVisibleBackgroundUsersSupported()
+ ? userManager.getMainDisplayIdAssignedToUser()
+ : DEFAULT_DISPLAY;
+ }
+ return mDisplayIdToMirror;
+ }
+
/**
* Listens for changes in available display devices.
*/
diff --git a/core/java/android/net/metrics/DnsEvent.java b/core/java/android/net/metrics/DnsEvent.java
index bf351ce07fe8..f53d1c4d191d 100644
--- a/core/java/android/net/metrics/DnsEvent.java
+++ b/core/java/android/net/metrics/DnsEvent.java
@@ -62,7 +62,11 @@ final public class DnsEvent {
return isSuccess;
}
if (eventCount == eventTypes.length) {
- resize((int) (1.4 * eventCount));
+ int resizeLength = (int) (1.4 * eventCount);
+ if (eventCount == resizeLength) {
+ resizeLength++;
+ }
+ resize(resizeLength);
}
eventTypes[eventCount] = eventType;
returnCodes[eventCount] = returnCode;
diff --git a/core/java/android/os/OWNERS b/core/java/android/os/OWNERS
index bfcc5cc6f18e..8d353384f1e2 100644
--- a/core/java/android/os/OWNERS
+++ b/core/java/android/os/OWNERS
@@ -118,9 +118,10 @@ per-file IpcDataCache.java = file:/PERFORMANCE_OWNERS
# Memory
per-file OomKillRecord.java = file:/MEMORY_OWNERS
-# MessageQueue
+# MessageQueue and related classes
per-file MessageQueue.java = mfasheh@google.com, shayba@google.com
per-file Message.java = mfasheh@google.com, shayba@google.com
+per-file TestLooperManager.java = mfasheh@google.com, shayba@google.com
# Stats
per-file IStatsBootstrapAtomService.aidl = file:/services/core/java/com/android/server/stats/OWNERS
diff --git a/core/java/android/os/SELinux.java b/core/java/android/os/SELinux.java
index f64a81177ce2..11c54ef802fe 100644
--- a/core/java/android/os/SELinux.java
+++ b/core/java/android/os/SELinux.java
@@ -193,4 +193,31 @@ public class SELinux {
return false;
}
}
+
+ /**
+ * Gets the genfs labels version of the vendor. The genfs labels version is
+ * specified in {@code /vendor/etc/selinux/genfs_labels_version.txt}. The
+ * version follows the VINTF version format "YYYYMM" and affects how {@code
+ * genfs_contexts} entries are applied.
+ *
+ * <p>The genfs labels version indicates changes in the SELinux labeling
+ * scheme over time. For example:
+ * <ul>
+ * <li>For version 202504 and later, {@code /sys/class/udc} is labeled as
+ * {@code sysfs_udc}.
+ * <li>For version 202404 and earlier, {@code /sys/class/udc} is labeled
+ * as {@code sysfs}.
+ * </ul>
+ * Check {@code /system/etc/selinux/plat_sepolicy_genfs_{version}.cil} to
+ * see which labels are new in {version}.
+ *
+ * <p>Older vendors may override {@code genfs_contexts} with vendor-specific
+ * extensions. The framework must not break such labellings to maintain
+ * compatibility with such vendors, by checking the genfs labels version and
+ * implementing a fallback mechanism.
+ *
+ * @return an integer representing the genfs labels version of /vendor, in
+ * the format YYYYMM.
+ */
+ public static final native int getGenfsLabelsVersion();
}
diff --git a/core/java/android/os/ServiceManager.java b/core/java/android/os/ServiceManager.java
index 8aec7eb59e91..9085fe09bdaa 100644
--- a/core/java/android/os/ServiceManager.java
+++ b/core/java/android/os/ServiceManager.java
@@ -277,7 +277,8 @@ public final class ServiceManager {
if (service != null) {
return service;
} else {
- return Binder.allowBlocking(getIServiceManager().checkService(name).getBinder());
+ return Binder.allowBlocking(
+ getIServiceManager().checkService(name).getServiceWithMetadata().service);
}
} catch (RemoteException e) {
Log.e(TAG, "error in checkService", e);
@@ -425,7 +426,8 @@ public final class ServiceManager {
private static IBinder rawGetService(String name) throws RemoteException {
final long start = sStatLogger.getTime();
- final IBinder binder = getIServiceManager().getService2(name).getBinder();
+ final IBinder binder =
+ getIServiceManager().getService2(name).getServiceWithMetadata().service;
final int time = (int) sStatLogger.logDurationStat(Stats.GET_SERVICE, start);
diff --git a/core/java/android/os/ServiceManagerNative.java b/core/java/android/os/ServiceManagerNative.java
index 5a9c8787ee3b..49b696d95723 100644
--- a/core/java/android/os/ServiceManagerNative.java
+++ b/core/java/android/os/ServiceManagerNative.java
@@ -61,7 +61,7 @@ class ServiceManagerProxy implements IServiceManager {
@UnsupportedAppUsage
public IBinder getService(String name) throws RemoteException {
// Same as checkService (old versions of servicemanager had both methods).
- return checkService(name).getBinder();
+ return checkService(name).getServiceWithMetadata().service;
}
public Service getService2(String name) throws RemoteException {
diff --git a/core/java/android/os/UpdateEngine.java b/core/java/android/os/UpdateEngine.java
index 0a8f62fd56d8..81e4549c78d1 100644
--- a/core/java/android/os/UpdateEngine.java
+++ b/core/java/android/os/UpdateEngine.java
@@ -16,6 +16,7 @@
package android.os;
+import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.SystemApi;
@@ -667,4 +668,23 @@ public class UpdateEngine {
throw e.rethrowFromSystemServer();
}
}
+
+ /**
+ * Run postinstall script for specified partition |partition|
+ *
+ * @param partition The partition to trigger postinstall runs
+ *
+ * @throws ServiceSpecificException error code of this exception would be one of
+ * https://cs.android.com/android/platform/superproject/main/+/main:system/update_engine/common/error_code.h
+ * @hide
+ */
+ @FlaggedApi(Flags.FLAG_UPDATE_ENGINE_API)
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+ public void triggerPostinstall(@NonNull String partition) {
+ try {
+ mUpdateEngine.triggerPostinstall(partition);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index b8a8be159d12..ef8b3d738154 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -19338,14 +19338,14 @@ public final class Settings {
* If hotword detection should be enabled.
* @hide
*/
- @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ @Readable
public static final String HOTWORD_DETECTION_ENABLED = "hotword_detection_enabled";
/**
* Whether Smart Replies are enabled within Wear.
* @hide
*/
- @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ @Readable
public static final String SMART_REPLIES_ENABLED = "smart_replies_enabled";
/**
@@ -19359,7 +19359,7 @@ public final class Settings {
* If FLP should obtain location data from the paired device.
* @hide
*/
- @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ @Readable
public static final String OBTAIN_PAIRED_DEVICE_LOCATION =
"obtain_paired_device_location";
@@ -19367,7 +19367,7 @@ public final class Settings {
* The play store availability on companion phone.
* @hide
*/
- @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ @Readable
public static final String PHONE_PLAY_STORE_AVAILABILITY =
"phone_play_store_availability";
@@ -19383,7 +19383,7 @@ public final class Settings {
* Whether the bug report is enabled.
* @hide
*/
- @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ @Readable
public static final String BUG_REPORT = "bug_report";
// Possible bug report states
@@ -19396,14 +19396,14 @@ public final class Settings {
* The enabled/disabled state of the SmartIlluminate.
* @hide
*/
- @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ @Readable
public static final String SMART_ILLUMINATE_ENABLED = "smart_illuminate_enabled";
/**
* Whether automatic time is enabled on the watch.
* @hide
*/
- @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ @Readable
public static final String CLOCKWORK_AUTO_TIME = "clockwork_auto_time";
// Possible clockwork auto time states
@@ -19421,7 +19421,7 @@ public final class Settings {
* Whether automatic time zone is enabled on the watch.
* @hide
*/
- @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ @Readable
public static final String CLOCKWORK_AUTO_TIME_ZONE = "clockwork_auto_time_zone";
// Possible clockwork auto time zone states
@@ -19438,14 +19438,14 @@ public final class Settings {
* Whether 24 hour time format is enabled on the watch.
* @hide
*/
- @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ @Readable
public static final String CLOCKWORK_24HR_TIME = "clockwork_24hr_time";
/**
* Whether the auto wifi toggle setting is enabled.
* @hide
*/
- @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ @Readable
public static final String AUTO_WIFI = "auto_wifi";
// Possible force wifi on states
@@ -19465,7 +19465,7 @@ public final class Settings {
* wifi requirement until this time). The time is in millis since epoch.
* @hide
*/
- @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ @Readable
public static final String ALT_BYPASS_WIFI_REQUIREMENT_TIME_MILLIS =
"alt_bypass_wifi_requirement_time_millis";
@@ -19473,7 +19473,7 @@ public final class Settings {
* Whether the setup was skipped.
* @hide
*/
- @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ @Readable
public static final String SETUP_SKIPPED = "setup_skipped";
// Possible setup_skipped states
@@ -19488,7 +19488,7 @@ public final class Settings {
* The last requested call forwarding action.
* @hide
*/
- @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ @Readable
public static final String LAST_CALL_FORWARD_ACTION = "last_call_forward_action";
// Possible call forwarding actions
@@ -19501,31 +19501,31 @@ public final class Settings {
// Stem button settings.
/** @hide */
- @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ @Readable
public static final String STEM_1_TYPE = "STEM_1_TYPE";
/** @hide */
- @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ @Readable
public static final String STEM_1_DATA = "STEM_1_DATA";
/** @hide */
- @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ @Readable
public static final String STEM_1_DEFAULT_DATA = "STEM_1_DEFAULT_DATA";
/** @hide */
- @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ @Readable
public static final String STEM_2_TYPE = "STEM_2_TYPE";
/** @hide */
- @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ @Readable
public static final String STEM_2_DATA = "STEM_2_DATA";
/** @hide */
- @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ @Readable
public static final String STEM_2_DEFAULT_DATA = "STEM_2_DEFAULT_DATA";
/** @hide */
- @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ @Readable
public static final String STEM_3_TYPE = "STEM_3_TYPE";
/** @hide */
- @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ @Readable
public static final String STEM_3_DATA = "STEM_3_DATA";
/** @hide */
- @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ @Readable
public static final String STEM_3_DEFAULT_DATA = "STEM_3_DEFAULT_DATA";
// Stem types
@@ -19540,14 +19540,14 @@ public final class Settings {
* If the device should be muted when off body.
* @hide
*/
- @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ @Readable
public static final String MUTE_WHEN_OFF_BODY_ENABLED = "obtain_mute_when_off_body";
/**
* Wear OS version string.
* @hide
*/
- @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ @Readable
public static final String WEAR_OS_VERSION_STRING = "wear_os_version_string";
/**
@@ -19560,28 +19560,28 @@ public final class Settings {
* The android wear system version.
* @hide
*/
- @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ @Readable
public static final String ANDROID_WEAR_VERSION = "android_wear_version";
/**
* The wear system capabiltiies.
* @hide
*/
- @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ @Readable
public static final String SYSTEM_CAPABILITIES = "system_capabilities";
/**
* The android wear system edition.
* @hide
*/
- @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ @Readable
public static final String SYSTEM_EDITION = "android_wear_system_edition";
/**
* The Wear platform MR number.
* @hide
*/
- @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ @Readable
public static final String WEAR_PLATFORM_MR_NUMBER = "wear_platform_mr_number";
/**
@@ -19595,42 +19595,42 @@ public final class Settings {
* Whether ambient is currently enabled.
* @hide
*/
- @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ @Readable
public static final String AMBIENT_ENABLED = "ambient_enabled";
/**
* Whether ambient tilt to wake is enabled.
* @hide
*/
- @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ @Readable
public static final String AMBIENT_TILT_TO_WAKE = "ambient_tilt_to_wake";
/**
* Whether ambient low bit mode is enabled by developer options.
* @hide
*/
- @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ @Readable
public static final String AMBIENT_LOW_BIT_ENABLED_DEV = "ambient_low_bit_enabled_dev";
/**
* Whether ambient touch to wake is enabled.
* @hide
*/
- @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ @Readable
public static final String AMBIENT_TOUCH_TO_WAKE = "ambient_touch_to_wake";
/**
* Whether ambient tilt to bright is enabled.
* @hide
*/
- @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ @Readable
public static final String AMBIENT_TILT_TO_BRIGHT = "ambient_tilt_to_bright";
/**
* Whether touch and hold to edit WF is enabled
* @hide
*/
- @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ @Readable
public static final String GESTURE_TOUCH_AND_HOLD_WATCH_FACE_ENABLED =
"gesture_touch_and_hold_watchface_enabled";
@@ -19644,7 +19644,7 @@ public final class Settings {
* Whether bedtime mode is enabled.
* @hide
*/
- @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ @Readable
public static final String BEDTIME_MODE = "bedtime_mode";
/**
@@ -19656,35 +19656,35 @@ public final class Settings {
* Whether the current watchface is decomposable.
* @hide
*/
- @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ @Readable
public static final String DECOMPOSABLE_WATCHFACE = "current_watchface_decomposable";
/**
* Whether to force ambient when docked.
* @hide
*/
- @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ @Readable
public static final String AMBIENT_FORCE_WHEN_DOCKED = "ambient_force_when_docked";
/**
* Whether the ambient low bit mode is enabled.
* @hide
*/
- @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ @Readable
public static final String AMBIENT_LOW_BIT_ENABLED = "ambient_low_bit_enabled";
/**
* The timeout duration in minutes of ambient mode when plugged in.
* @hide
*/
- @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ @Readable
public static final String AMBIENT_PLUGGED_TIMEOUT_MIN = "ambient_plugged_timeout_min";
/**
* What OS does paired device has.
* @hide
*/
- @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ @Readable
public static final String PAIRED_DEVICE_OS_TYPE = "paired_device_os_type";
// Possible values of PAIRED_DEVICE_OS_TYPE
@@ -19719,7 +19719,7 @@ public final class Settings {
* The user's last setting for hfp client.
* @hide
*/
- @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ @Readable
public static final String USER_HFP_CLIENT_SETTING = "user_hfp_client_setting";
// Possible hfp client user setting values
@@ -19744,7 +19744,7 @@ public final class Settings {
* The companion App name.
* @hide
*/
- @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ @Readable
public static final String COMPANION_APP_NAME = "wear_companion_app_name";
/**
@@ -19752,21 +19752,21 @@ public final class Settings {
* wear. 1 for supporting, 0 for not supporting.
* @hide
*/
- @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ @Readable
public static final String ENABLE_ALL_LANGUAGES = "enable_all_languages";
/**
* The Locale (as language tag) the user chose at startup.
* @hide
*/
- @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ @Readable
public static final String SETUP_LOCALE = "setup_locale";
/**
* The version of oem setup present.
* @hide
*/
- @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ @Readable
public static final String OEM_SETUP_VERSION = "oem_setup_version";
/**
@@ -19812,7 +19812,7 @@ public final class Settings {
* -{@link BATTERY_SAVER_MODE_CUSTOM}
* @hide
*/
- @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ @Readable
public static final String BATTERY_SAVER_MODE = "battery_saver_mode";
/**
@@ -19869,7 +19869,7 @@ public final class Settings {
* If burn in protection is enabled.
* @hide
*/
- @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ @Readable
public static final String BURN_IN_PROTECTION_ENABLED = "burn_in_protection";
/**
@@ -19888,7 +19888,7 @@ public final class Settings {
* RIGHT_WRIST_ROTATION_0 = "2", RIGHT_WRIST_ROTATION_180 = "3"
* @hide
*/
- @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ @Readable
public static final String WRIST_ORIENTATION_MODE = "wear_wrist_orientation_mode";
/**
@@ -19927,7 +19927,7 @@ public final class Settings {
*
* @hide
*/
- @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ @Readable
public static final String CLOCKWORK_SYSUI_PACKAGE = "clockwork_sysui_package";
/**
@@ -19957,7 +19957,7 @@ public final class Settings {
* Whether the device has Wet Mode/ Touch Lock Mode enabled.
* @hide
*/
- @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ @Readable
public static final String WET_MODE_ON = "wet_mode_on";
/**
@@ -19976,7 +19976,7 @@ public final class Settings {
* Whether charging sounds are enabled.
* @hide
*/
- @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ @Readable
public static final String CHARGING_SOUNDS_ENABLED = "wear_charging_sounds_enabled";
/**
@@ -19985,7 +19985,7 @@ public final class Settings {
*
* @hide
*/
- @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ @Readable
public static final String DYNAMIC_COLOR_THEME_ENABLED = "dynamic_color_theme_enabled";
/**
@@ -20077,7 +20077,7 @@ public final class Settings {
* The key to indicate the data migration status on device upgrade in Wear Services.
* @hide
*/
- @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ @Readable
public static final String UPGRADE_DATA_MIGRATION_STATUS =
"upgrade_data_migration_status";
@@ -20134,20 +20134,20 @@ public final class Settings {
* The custom foreground color.
* @hide
*/
- @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ @Readable
public static final String CUSTOM_COLOR_FOREGROUND = "custom_foreground_color";
/**
* The custom background color.
* @hide
*/
- @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ @Readable
public static final String CUSTOM_COLOR_BACKGROUND = "custom_background_color";
/** The status of the phone switching process.
* @hide
*/
- @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ @Readable
public static final String PHONE_SWITCHING_STATUS = "phone_switching_status";
/**
@@ -20318,7 +20318,7 @@ public final class Settings {
* Controls the launcher ui mode on wearable devices.
* @hide
*/
- @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ @Readable
public static final String WEAR_LAUNCHER_UI_MODE = "wear_launcher_ui_mode";
/** Whether Wear Power Anomaly Service is enabled.
diff --git a/core/java/android/security/net/config/CertificatesEntryRef.java b/core/java/android/security/net/config/CertificatesEntryRef.java
index 45cd0f011299..a46049fb2f6d 100644
--- a/core/java/android/security/net/config/CertificatesEntryRef.java
+++ b/core/java/android/security/net/config/CertificatesEntryRef.java
@@ -17,6 +17,7 @@
package android.security.net.config;
import android.util.ArraySet;
+
import java.security.cert.X509Certificate;
import java.util.Set;
@@ -24,16 +25,23 @@ import java.util.Set;
public final class CertificatesEntryRef {
private final CertificateSource mSource;
private final boolean mOverridesPins;
+ private final boolean mDisableCT;
- public CertificatesEntryRef(CertificateSource source, boolean overridesPins) {
+ public CertificatesEntryRef(CertificateSource source, boolean overridesPins,
+ boolean disableCT) {
mSource = source;
mOverridesPins = overridesPins;
+ mDisableCT = disableCT;
}
boolean overridesPins() {
return mOverridesPins;
}
+ boolean disableCT() {
+ return mDisableCT;
+ }
+
public Set<TrustAnchor> getTrustAnchors() {
// TODO: cache this [but handle mutable sources]
Set<TrustAnchor> anchors = new ArraySet<TrustAnchor>();
diff --git a/core/java/android/security/net/config/KeyStoreConfigSource.java b/core/java/android/security/net/config/KeyStoreConfigSource.java
index 8d4f098bcb37..a54d8d0499cb 100644
--- a/core/java/android/security/net/config/KeyStoreConfigSource.java
+++ b/core/java/android/security/net/config/KeyStoreConfigSource.java
@@ -17,8 +17,8 @@
package android.security.net.config;
import android.util.Pair;
+
import java.security.KeyStore;
-import java.security.KeyStoreException;
import java.util.Set;
/**
@@ -32,7 +32,7 @@ class KeyStoreConfigSource implements ConfigSource {
mConfig = new NetworkSecurityConfig.Builder()
.addCertificatesEntryRef(
// Use the KeyStore and do not override pins (of which there are none).
- new CertificatesEntryRef(new KeyStoreCertificateSource(ks), false))
+ new CertificatesEntryRef(new KeyStoreCertificateSource(ks), false, false))
.build();
}
diff --git a/core/java/android/security/net/config/NetworkSecurityConfig.java b/core/java/android/security/net/config/NetworkSecurityConfig.java
index 129ae63ec9c0..410c68b8d04d 100644
--- a/core/java/android/security/net/config/NetworkSecurityConfig.java
+++ b/core/java/android/security/net/config/NetworkSecurityConfig.java
@@ -112,7 +112,6 @@ public final class NetworkSecurityConfig {
return mHstsEnforced;
}
- // TODO(b/28746284): add exceptions for user-added certificates and enterprise overrides.
public boolean isCertificateTransparencyVerificationRequired() {
return mCertificateTransparencyVerificationRequired;
}
@@ -192,20 +191,21 @@ public final class NetworkSecurityConfig {
* @hide
*/
public static Builder getDefaultBuilder(ApplicationInfo info) {
+ // System certificate store, does not bypass static pins, does not disable CT.
+ CertificatesEntryRef systemRef = new CertificatesEntryRef(
+ SystemCertificateSource.getInstance(), false, false);
Builder builder = new Builder()
.setHstsEnforced(DEFAULT_HSTS_ENFORCED)
- // System certificate store, does not bypass static pins.
- .addCertificatesEntryRef(
- new CertificatesEntryRef(SystemCertificateSource.getInstance(), false));
+ .addCertificatesEntryRef(systemRef);
final boolean cleartextTrafficPermitted = info.targetSdkVersion < Build.VERSION_CODES.P
&& !info.isInstantApp();
builder.setCleartextTrafficPermitted(cleartextTrafficPermitted);
// Applications targeting N and above must opt in into trusting the user added certificate
// store.
if (info.targetSdkVersion <= Build.VERSION_CODES.M && !info.isPrivilegedApp()) {
- // User certificate store, does not bypass static pins.
+ // User certificate store, does not bypass static pins. CT is disabled.
builder.addCertificatesEntryRef(
- new CertificatesEntryRef(UserCertificateSource.getInstance(), false));
+ new CertificatesEntryRef(UserCertificateSource.getInstance(), false, true));
}
return builder;
}
@@ -339,6 +339,16 @@ public final class NetworkSecurityConfig {
if (mCertificateTransparencyVerificationRequiredSet) {
return mCertificateTransparencyVerificationRequired;
}
+ // CT verification has not been set explicitly. Before deferring to
+ // the parent, check if any of the CertificatesEntryRef requires it
+ // to be disabled (i.e., user store or inline certificate).
+ if (hasCertificatesEntryRefs()) {
+ for (CertificatesEntryRef ref : getCertificatesEntryRefs()) {
+ if (ref.disableCT()) {
+ return false;
+ }
+ }
+ }
if (mParentBuilder != null) {
return mParentBuilder.getCertificateTransparencyVerificationRequired();
}
diff --git a/core/java/android/security/net/config/XmlConfigSource.java b/core/java/android/security/net/config/XmlConfigSource.java
index b1c14793bbbd..95e579fc538b 100644
--- a/core/java/android/security/net/config/XmlConfigSource.java
+++ b/core/java/android/security/net/config/XmlConfigSource.java
@@ -182,6 +182,7 @@ public class XmlConfigSource implements ConfigSource {
boolean overridePins =
parser.getAttributeBooleanValue(null, "overridePins", defaultOverridePins);
int sourceId = parser.getAttributeResourceValue(null, "src", -1);
+ boolean disableCT = false;
String sourceString = parser.getAttributeValue(null, "src");
CertificateSource source = null;
if (sourceString == null) {
@@ -190,10 +191,12 @@ public class XmlConfigSource implements ConfigSource {
if (sourceId != -1) {
// TODO: Cache ResourceCertificateSources by sourceId
source = new ResourceCertificateSource(sourceId, mContext);
+ disableCT = true;
} else if ("system".equals(sourceString)) {
source = SystemCertificateSource.getInstance();
} else if ("user".equals(sourceString)) {
source = UserCertificateSource.getInstance();
+ disableCT = true;
} else if ("wfa".equals(sourceString)) {
source = WfaCertificateSource.getInstance();
} else {
@@ -201,7 +204,7 @@ public class XmlConfigSource implements ConfigSource {
+ "Should be one of system|user|@resourceVal");
}
XmlUtils.skipCurrentTag(parser);
- return new CertificatesEntryRef(source, overridePins);
+ return new CertificatesEntryRef(source, overridePins, disableCT);
}
private Collection<CertificatesEntryRef> parseTrustAnchors(XmlResourceParser parser,
diff --git a/core/java/com/android/internal/os/TEST_MAPPING b/core/java/com/android/internal/os/TEST_MAPPING
index 4400ed117721..1923c5fb9186 100644
--- a/core/java/com/android/internal/os/TEST_MAPPING
+++ b/core/java/com/android/internal/os/TEST_MAPPING
@@ -20,7 +20,7 @@
"file_patterns": [
"BinderDeathDispatcher\\.java"
],
- "name": "FrameworksCoreTests_internal_os_binder"
+ "name": "FrameworksCoreTests_all_binder"
},
{
"file_patterns": [
diff --git a/core/java/com/android/internal/pm/pkg/component/AconfigFlags.java b/core/java/com/android/internal/pm/pkg/component/AconfigFlags.java
index 39aadfb24b0c..f0c8f0ac2bad 100644
--- a/core/java/com/android/internal/pm/pkg/component/AconfigFlags.java
+++ b/core/java/com/android/internal/pm/pkg/component/AconfigFlags.java
@@ -239,16 +239,12 @@ public class AconfigFlags {
negated = true;
featureFlag = featureFlag.substring(1).strip();
}
- final Boolean flagValue = getFlagValue(featureFlag);
+ Boolean flagValue = getFlagValue(featureFlag);
if (flagValue == null) {
- Slog.w(LOG_TAG, "Skipping element " + parser.getName()
- + " due to unknown feature flag " + featureFlag);
- return true;
+ flagValue = false;
}
// Skip if flag==false && attr=="flag" OR flag==true && attr=="!flag" (negated)
if (flagValue == negated) {
- Slog.v(LOG_TAG, "Skipping element " + parser.getName()
- + " behind feature flag " + featureFlag + " = " + flagValue);
return true;
}
return false;
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index 9a4ff8fc264f..37c84ce76e61 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -290,6 +290,7 @@ cc_library_shared_for_libandroid_runtime {
"libasync_safe",
"libbinderthreadstateutils",
"libdmabufinfo",
+ "libgenfslabelsversion.ffi",
"libgui_window_info_static",
"libkernelconfigs",
"libnativehelper_lazy",
diff --git a/core/jni/android_os_SELinux.cpp b/core/jni/android_os_SELinux.cpp
index 7a4670f4e49d..805d5ad41e83 100644
--- a/core/jni/android_os_SELinux.cpp
+++ b/core/jni/android_os_SELinux.cpp
@@ -18,18 +18,19 @@
#include <errno.h>
#include <fcntl.h>
-
+#include <genfslabelsversion.h>
+#include <nativehelper/JNIPlatformHelp.h>
+#include <nativehelper/ScopedLocalRef.h>
+#include <nativehelper/ScopedUtfChars.h>
#include <utils/Log.h>
-#include <nativehelper/JNIPlatformHelp.h>
-#include "jni.h"
+#include <atomic>
+#include <memory>
+
#include "core_jni_helpers.h"
-#include "selinux/selinux.h"
+#include "jni.h"
#include "selinux/android.h"
-#include <memory>
-#include <atomic>
-#include <nativehelper/ScopedLocalRef.h>
-#include <nativehelper/ScopedUtfChars.h>
+#include "selinux/selinux.h"
namespace android {
namespace {
@@ -404,8 +405,19 @@ static jboolean native_restorecon(JNIEnv *env, jobject, jstring pathnameStr, jin
}
/*
+ * Function: getGenfsLabelsVersion
+ * Purpose: get which genfs labels version /vendor uses
+ * Returns: int: genfs labels version of /vendor
+ * Exceptions: none
+ */
+static jint getGenfsLabelsVersion(JNIEnv *, jclass) {
+ return get_genfs_labels_version();
+}
+
+/*
* JNI registration.
*/
+// clang-format off
static const JNINativeMethod method_table[] = {
/* name, signature, funcPtr */
{ "checkSELinuxAccess" , "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z" , (void*)checkSELinuxAccess },
@@ -420,7 +432,9 @@ static const JNINativeMethod method_table[] = {
{ "setFileContext" , "(Ljava/lang/String;Ljava/lang/String;)Z" , (void*)setFileCon },
{ "setFSCreateContext" , "(Ljava/lang/String;)Z" , (void*)setFSCreateCon },
{ "fileSelabelLookup" , "(Ljava/lang/String;)Ljava/lang/String;" , (void*)fileSelabelLookup},
+ { "getGenfsLabelsVersion" , "()I" , (void *)getGenfsLabelsVersion},
};
+// clang-format on
static int log_callback(int type, const char *fmt, ...) {
va_list ap;
diff --git a/core/tests/coretests/Android.bp b/core/tests/coretests/Android.bp
index 6a191c601846..0a33a80830e3 100644
--- a/core/tests/coretests/Android.bp
+++ b/core/tests/coretests/Android.bp
@@ -523,14 +523,25 @@ test_module_config {
}
test_module_config {
- name: "FrameworksCoreTests_internal_os_binder",
+ name: "FrameworksCoreTests_all_binder",
base: "FrameworksCoreTests",
test_suites: [
"automotive-tests",
"device-tests",
"device-platinum-tests",
],
- include_filters: ["com.android.internal.os.BinderDeathDispatcherTest"],
+ include_filters: [
+ "android.os.BinderProxyTest",
+ "android.os.BinderDeathRecipientTest",
+ "android.os.BinderFrozenStateChangeNotificationTest",
+ "android.os.BinderProxyCountingTest",
+ "android.os.BinderUncaughtExceptionHandlerTest",
+ "android.os.BinderThreadPriorityTest",
+ "android.os.BinderWorkSourceTest",
+ "android.os.ParcelNullabilityTest",
+ "android.os.ParcelTest",
+ "com.android.internal.os.BinderDeathDispatcherTest",
+ ],
exclude_annotations: ["com.android.internal.os.SkipPresubmit"],
}
diff --git a/core/tests/coretests/src/android/content/res/FontScaleConverterFactoryTest.kt b/core/tests/coretests/src/android/content/res/FontScaleConverterFactoryTest.kt
index c0a9bc2cdd24..f9d449cd3b10 100644
--- a/core/tests/coretests/src/android/content/res/FontScaleConverterFactoryTest.kt
+++ b/core/tests/coretests/src/android/content/res/FontScaleConverterFactoryTest.kt
@@ -18,10 +18,7 @@ package android.content.res
import android.platform.test.annotations.Presubmit
import android.platform.test.annotations.RequiresFlagsEnabled
-import android.platform.test.flag.junit.CheckFlagsRule
import android.platform.test.flag.junit.DeviceFlagsValueProvider
-import android.platform.test.flag.junit.RavenwoodFlagsValueProvider
-import android.platform.test.ravenwood.RavenwoodRule
import android.util.SparseArray
import androidx.core.util.forEach
import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -47,15 +44,7 @@ import org.junit.runner.RunWith
class FontScaleConverterFactoryTest {
@get:Rule
- val ravenwoodRule: RavenwoodRule = RavenwoodRule.Builder().build()
-
- @get:Rule
- val checkFlagsRule: CheckFlagsRule =
- if (RavenwoodRule.isOnRavenwood()) {
- RavenwoodFlagsValueProvider.createAllOnCheckFlagsRule()
- } else {
- DeviceFlagsValueProvider.createCheckFlagsRule()
- }
+ val checkFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule()
private var defaultLookupTables: SparseArray<FontScaleConverter>? = null
diff --git a/core/tests/coretests/src/android/content/res/ResourcesManagerTest.java b/core/tests/coretests/src/android/content/res/ResourcesManagerTest.java
index 3eefe044de90..9dc4ca19f60c 100644
--- a/core/tests/coretests/src/android/content/res/ResourcesManagerTest.java
+++ b/core/tests/coretests/src/android/content/res/ResourcesManagerTest.java
@@ -33,8 +33,6 @@ import android.platform.test.annotations.Postsubmit;
import android.platform.test.annotations.RequiresFlagsEnabled;
import android.platform.test.flag.junit.CheckFlagsRule;
import android.platform.test.flag.junit.DeviceFlagsValueProvider;
-import android.platform.test.flag.junit.RavenwoodFlagsValueProvider;
-import android.platform.test.ravenwood.RavenwoodRule;
import android.util.ArraySet;
import android.util.DisplayMetrics;
import android.util.TypedValue;
@@ -65,13 +63,7 @@ public class ResourcesManagerTest {
private static final String TEST_LIB = "com.android.frameworks.coretests.bdr_helper_app1";
@Rule
- public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder().build();
-
- @Rule
- public final CheckFlagsRule mCheckFlagsRule =
- RavenwoodRule.isOnRavenwood()
- ? RavenwoodFlagsValueProvider.createAllOnCheckFlagsRule()
- : DeviceFlagsValueProvider.createCheckFlagsRule();
+ public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
private ResourcesManager mResourcesManager;
private Map<Integer, DisplayMetrics> mDisplayMetricsMap;
diff --git a/core/tests/coretests/src/android/os/BinderThreadPriorityTest.java b/core/tests/coretests/src/android/os/BinderThreadPriorityTest.java
index 4172bffe100c..9a679d8e8a96 100644
--- a/core/tests/coretests/src/android/os/BinderThreadPriorityTest.java
+++ b/core/tests/coretests/src/android/os/BinderThreadPriorityTest.java
@@ -31,6 +31,8 @@ import android.util.Log;
import androidx.test.InstrumentationRegistry;
import androidx.test.ext.junit.runners.AndroidJUnit4;
+import com.android.internal.os.SkipPresubmit;
+
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
@@ -131,6 +133,7 @@ public class BinderThreadPriorityTest {
}
@Test
+ @SkipPresubmit("b/381950874: bitrot and failed")
public void testPassPriorityToService() throws Exception {
for (int prio = 19; prio >= -20; prio--) {
Process.setThreadPriority(prio);
@@ -146,6 +149,7 @@ public class BinderThreadPriorityTest {
}
@Test
+ @SkipPresubmit("b/381950874: bitrot and failed")
public void testCallBackFromServiceWithPriority() throws Exception {
for (int prio = -20; prio <= 19; prio++) {
final int expected = prio;
diff --git a/keystore/java/Android.bp b/keystore/java/Android.bp
index 21edff1e1c96..264ac5ff1d92 100644
--- a/keystore/java/Android.bp
+++ b/keystore/java/Android.bp
@@ -13,5 +13,13 @@ filegroup {
"**/*.java",
"**/*.aidl",
],
+ exclude_srcs: select(release_flag("RELEASE_ATTEST_MODULES"), {
+ true: [
+ "android/security/KeyStore2HalCurrent.java",
+ ],
+ default: [
+ "android/security/KeyStore2HalLatest.java",
+ ],
+ }),
visibility: ["//frameworks/base"],
}
diff --git a/keystore/java/android/security/KeyStore2.java b/keystore/java/android/security/KeyStore2.java
index dd703f5eefb9..f5cf571ad955 100644
--- a/keystore/java/android/security/KeyStore2.java
+++ b/keystore/java/android/security/KeyStore2.java
@@ -101,7 +101,7 @@ public class KeyStore2 {
R execute(IKeystoreService service) throws RemoteException;
}
- private <R> R handleRemoteExceptionWithRetry(@NonNull CheckedRemoteRequest<R> request)
+ <R> R handleRemoteExceptionWithRetry(@NonNull CheckedRemoteRequest<R> request)
throws KeyStoreException {
IKeystoreService service = getService(false /* retryLookup */);
boolean firstTry = true;
@@ -369,6 +369,18 @@ public class KeyStore2 {
}
}
+ /**
+ * Returns tag-specific info required to interpret a tag's attested value.
+ * @see IKeystoreService#getSupplementaryAttestationInfo(Tag) for more details.
+ * @param tag
+ * @return
+ * @throws KeyStoreException
+ * @hide
+ */
+ public byte[] getSupplementaryAttestationInfo(int tag) throws KeyStoreException {
+ return KeyStore2HalVersion.getSupplementaryAttestationInfoHelper(tag, this);
+ }
+
static KeyStoreException getKeyStoreException(int errorCode, String serviceErrorMessage) {
if (errorCode > 0) {
// KeyStore layer error
diff --git a/keystore/java/android/security/KeyStore2HalCurrent.java b/keystore/java/android/security/KeyStore2HalCurrent.java
new file mode 100644
index 000000000000..f4d8fe65c995
--- /dev/null
+++ b/keystore/java/android/security/KeyStore2HalCurrent.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2024 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 android.security;
+
+/**
+ * @hide This class is necessary to allow the version of the AIDL interface for Keystore and
+* KeyMint used in KeyStore2.java to differ by BUILD flag `RELEASE_ATTEST_MODULES`. When
+* `RELEASE_ATTEST_MODULES` is not set, this file is included, and the current HALs for Keystore
+* (V4) and KeyMint (V3) are used.
+*/
+class KeyStore2HalVersion {
+ public static byte[] getSupplementaryAttestationInfoHelper(int tag, KeyStore2 ks)
+ throws KeyStoreException {
+ return new byte[0];
+ }
+}
diff --git a/keystore/java/android/security/KeyStore2HalLatest.java b/keystore/java/android/security/KeyStore2HalLatest.java
new file mode 100644
index 000000000000..123f1c0b8f39
--- /dev/null
+++ b/keystore/java/android/security/KeyStore2HalLatest.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2024 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 android.security;
+
+/**
+ * @hide This class is necessary to allow the version of the AIDL interface for Keystore and
+* KeyMint used in KeyStore2.java to differ by BUILD flag `RELEASE_ATTEST_MODULES`. When
+* `RELEASE_ATTEST_MODULES` is set, this file is included, and the latest HALs for Keystore (V5)
+* and KeyMint (V4) are used.
+*/
+class KeyStore2HalVersion {
+ public static byte[] getSupplementaryAttestationInfoHelper(int tag, KeyStore2 ks)
+ throws KeyStoreException {
+ return ks.handleRemoteExceptionWithRetry(
+ (service) -> service.getSupplementaryAttestationInfo(tag));
+ }
+}
diff --git a/keystore/java/android/security/keystore/KeyStoreManager.java b/keystore/java/android/security/keystore/KeyStoreManager.java
index e6091c1da8a5..740ccb53a691 100644
--- a/keystore/java/android/security/keystore/KeyStoreManager.java
+++ b/keystore/java/android/security/keystore/KeyStoreManager.java
@@ -17,9 +17,11 @@
package android.security.keystore;
import android.annotation.FlaggedApi;
+import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.SystemService;
import android.content.Context;
+import android.hardware.security.keymint.TagType;
import android.security.KeyStore2;
import android.security.KeyStoreException;
import android.security.keystore2.AndroidKeyStoreProvider;
@@ -32,6 +34,8 @@ import android.util.Log;
import com.android.internal.annotations.GuardedBy;
import java.io.ByteArrayInputStream;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.security.Key;
import java.security.KeyPair;
import java.security.PublicKey;
@@ -299,6 +303,37 @@ public final class KeyStoreManager {
return Collections.emptyList();
}
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(value = {MODULE_HASH})
+ public @interface SupplementaryAttestationInfoTagEnum {}
+
+ /**
+ * When passed into getSupplementaryAttestationInfo, getSupplementaryAttestationInfo returns the
+ * DER-encoded structure corresponding to the `Modules` schema described in the KeyMint HAL's
+ * KeyCreationResult.aidl. The SHA-256 hash of this encoded structure is what's included with
+ * the tag in attestations.
+ */
+ // TODO(b/369375199): Replace with Tag.MODULE_HASH when flagging is removed.
+ public static final int MODULE_HASH = TagType.BYTES | 724;
+
+ /**
+ * Returns tag-specific data required to interpret a tag's attested value.
+ *
+ * When performing key attestation, the obtained attestation certificate contains a list of tags
+ * and their corresponding attested values. For some tags, additional information about the
+ * attested value can be queried via this API. See individual tags for specifics.
+ *
+ * @param tag tag for which info is being requested
+ * @return tag-specific info
+ * @throws KeyStoreException if the requested info is not available
+ */
+ @FlaggedApi(android.security.keystore2.Flags.FLAG_ATTEST_MODULES)
+ public @NonNull byte[] getSupplementaryAttestationInfo(
+ @SupplementaryAttestationInfoTagEnum int tag) throws KeyStoreException {
+ return mKeyStore2.getSupplementaryAttestationInfo(tag);
+ }
+
/**
* Returns a new {@link KeyDescriptor} instance in the app domain / namespace with the {@code
* alias} set to the provided value.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
index 3e5adf395cdd..5836085e0ddc 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
@@ -1501,10 +1501,6 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
int rootIdx = -1;
for (int i = info.getChanges().size() - 1; i >= 0; --i) {
final TransitionInfo.Change c = info.getChanges().get(i);
- if (c.hasFlags(FLAG_IS_WALLPAPER)) {
- st.setAlpha(c.getLeash(), 1.0f);
- continue;
- }
if (TransitionUtil.isOpeningMode(c.getMode())) {
final Point offset = c.getEndRelOffset();
st.setPosition(c.getLeash(), offset.x, offset.y);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/MixedTransitionHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/MixedTransitionHelper.java
index 30d7245436be..e61929fef312 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/MixedTransitionHelper.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/MixedTransitionHelper.java
@@ -141,10 +141,13 @@ public class MixedTransitionHelper {
pipHandler.setEnterAnimationType(ANIM_TYPE_ALPHA);
pipHandler.startEnterAnimation(pipChange, startTransaction, finishTransaction,
finishCB);
+ // make a new finishTransaction because pip's startEnterAnimation "consumes" it so
+ // we need a separate one to send over to launcher.
+ SurfaceControl.Transaction otherFinishT = new SurfaceControl.Transaction();
// Dispatch the rest of the transition normally. This will most-likely be taken by
// recents or default handler.
mixed.mLeftoversHandler = player.dispatchTransition(mixed.mTransition, everythingElse,
- otherStartT, finishTransaction, finishCB, mixedHandler);
+ otherStartT, otherFinishT, finishCB, mixedHandler);
} else {
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " Not leaving split, so just "
+ "forward animation to Pip-Handler.");
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/FromSplitScreenEnterPipOnUserLeaveHintTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/FromSplitScreenEnterPipOnUserLeaveHintTest.kt
index d03d7799d675..d1bf6acf785d 100644
--- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/FromSplitScreenEnterPipOnUserLeaveHintTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/FromSplitScreenEnterPipOnUserLeaveHintTest.kt
@@ -183,12 +183,6 @@ class FromSplitScreenEnterPipOnUserLeaveHintTest(flicker: LegacyFlickerTest) :
}
/** {@inheritDoc} */
- @FlakyTest(bugId = 312446524)
- @Test
- override fun visibleLayersShownMoreThanOneConsecutiveEntry() =
- super.visibleLayersShownMoreThanOneConsecutiveEntry()
-
- /** {@inheritDoc} */
@Test
@FlakyTest(bugId = 336510055)
override fun entireScreenCovered() {
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 749ad0a993b3..6f8947c9bea1 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -2479,10 +2479,10 @@ public class SettingsProvider extends ContentProvider {
final long identity = Binder.clearCallingIdentity();
try {
int currentUser = ActivityManager.getCurrentUser();
- if (callingUser == currentUser) {
- // enforce the deny list only if the caller is not current user. Currently only auto
- // uses background visible user, and auto doesn't support profiles so profiles of
- // current users is not checked here.
+ if (callingUser == currentUser || callingUser == UserHandle.USER_SYSTEM) {
+ // enforce the deny list only if the caller is not current user or not a system
+ // user. Currently only auto uses background visible user, and auto doesn't
+ // support profiles so profiles of current users is not checked here.
return;
}
} finally {
diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig
index f8383d94b1ab..554ad8ba64e6 100644
--- a/packages/SystemUI/aconfig/systemui.aconfig
+++ b/packages/SystemUI/aconfig/systemui.aconfig
@@ -1431,4 +1431,14 @@ flag {
metadata {
purpose: PURPOSE_BUGFIX
}
+}
+
+flag {
+ name: "ignore_touches_next_to_notification_shelf"
+ namespace: "systemui"
+ description: "The shelf can vertically overlap the unlock icon. Ignore touches if so."
+ bug: "358424256"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
} \ No newline at end of file
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayCallbackControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayCallbackControllerTest.kt
index d9dcfdc7becb..9c6fd4bf71b4 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayCallbackControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayCallbackControllerTest.kt
@@ -56,6 +56,7 @@ class DreamOverlayCallbackControllerTest : SysuiTestCase() {
// Adding twice should not invoke twice
reset(callback)
+ underTest.onStartDream()
underTest.addCallback(callback)
underTest.onWakeUp()
verify(callback, times(1)).onWakeUp()
@@ -68,6 +69,19 @@ class DreamOverlayCallbackControllerTest : SysuiTestCase() {
}
@Test
+ fun onWakeUp_multipleCalls() {
+ underTest.onStartDream()
+ assertThat(underTest.isDreaming).isEqualTo(true)
+
+ underTest.addCallback(callback)
+ underTest.onWakeUp()
+ underTest.onWakeUp()
+ underTest.onWakeUp()
+ verify(callback, times(1)).onWakeUp()
+ assertThat(underTest.isDreaming).isEqualTo(false)
+ }
+
+ @Test
fun onStartDreamInvokesCallback() {
underTest.addCallback(callback)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayServiceTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayServiceTest.kt
index 7dd717470153..30b0aef90489 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayServiceTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayServiceTest.kt
@@ -712,6 +712,9 @@ class DreamOverlayServiceTest : SysuiTestCase() {
// Verify DreamOverlayContainerViewController is destroyed.
verify(mDreamOverlayContainerViewController).destroy()
+
+ // DreamOverlay callback receives onWakeUp.
+ verify(mDreamOverlayCallbackController).onWakeUp()
}
@Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryBackgroundViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryBackgroundViewModelTest.kt
new file mode 100644
index 000000000000..22677b2f8e3e
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryBackgroundViewModelTest.kt
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2024 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.keyguard.ui.viewmodel
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.biometrics.data.repository.fingerprintPropertyRepository
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
+import com.android.systemui.keyguard.shared.model.KeyguardState
+import com.android.systemui.keyguard.shared.model.TransitionState
+import com.android.systemui.keyguard.shared.model.TransitionState.RUNNING
+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.testKosmos
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@ExperimentalCoroutinesApi
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class DeviceEntryBackgroundViewModelTest : SysuiTestCase() {
+ private val kosmos = testKosmos()
+ private val testScope = kosmos.testScope
+ private val underTest: DeviceEntryBackgroundViewModel by lazy {
+ kosmos.deviceEntryBackgroundViewModel
+ }
+
+ @Test
+ fun lockscreenToDozingTransitionChangesBackgroundViewAlphaToZero() =
+ testScope.runTest {
+ kosmos.fingerprintPropertyRepository.supportsUdfps()
+ val alpha by collectLastValue(underTest.alpha)
+
+ kosmos.fakeKeyguardTransitionRepository.sendTransitionSteps(
+ listOf(dozingToLockscreen(0f, STARTED), dozingToLockscreen(0.1f)),
+ testScope,
+ )
+ runCurrent()
+ assertThat(alpha).isEqualTo(1.0f)
+
+ kosmos.fakeKeyguardTransitionRepository.sendTransitionSteps(
+ listOf(lockscreenToDozing(0f, STARTED)),
+ testScope,
+ )
+ runCurrent()
+
+ assertThat(alpha).isEqualTo(0.0f)
+ }
+
+ private fun lockscreenToDozing(value: Float, state: TransitionState = RUNNING): TransitionStep {
+ return TransitionStep(
+ from = KeyguardState.LOCKSCREEN,
+ to = KeyguardState.DOZING,
+ value = value,
+ transitionState = state,
+ ownerName = "DeviceEntryBackgroundViewModelTest",
+ )
+ }
+
+ private fun dozingToLockscreen(value: Float, state: TransitionState = RUNNING): TransitionStep {
+ return TransitionStep(
+ from = KeyguardState.DOZING,
+ to = KeyguardState.LOCKSCREEN,
+ value = value,
+ transitionState = state,
+ ownerName = "DeviceEntryBackgroundViewModelTest",
+ )
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt
index 5d606c67a4d7..4b1ed3b2354a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt
@@ -189,17 +189,6 @@ class KeyguardRootViewModelTest(flags: FlagsParameterization) : SysuiTestCase()
}
@Test
- fun iconContainer_isVisible_bypassEnabled() =
- testScope.runTest {
- val isVisible by collectLastValue(underTest.isNotifIconContainerVisible)
- runCurrent()
- deviceEntryRepository.setBypassEnabled(true)
- runCurrent()
-
- assertThat(isVisible?.value).isTrue()
- }
-
- @Test
fun iconContainer_isNotVisible_pulseExpanding_notBypassing() =
testScope.runTest {
val isVisible by collectLastValue(underTest.isNotifIconContainerVisible)
@@ -288,22 +277,23 @@ class KeyguardRootViewModelTest(flags: FlagsParameterization) : SysuiTestCase()
}
@Test
- fun iconContainer_isNotVisible_bypassDisabled_onLockscreen() =
+ fun iconContainer_isNotVisible_notifsFullyHiddenThenVisible_bypassEnabled() =
testScope.runTest {
val isVisible by collectLastValue(underTest.isNotifIconContainerVisible)
runCurrent()
- keyguardTransitionRepository.sendTransitionSteps(
- from = KeyguardState.AOD,
- to = KeyguardState.LOCKSCREEN,
- testScope,
- )
notificationsKeyguardInteractor.setPulseExpanding(false)
- deviceEntryRepository.setBypassEnabled(false)
+ deviceEntryRepository.setBypassEnabled(true)
whenever(dozeParameters.alwaysOn).thenReturn(true)
whenever(dozeParameters.displayNeedsBlanking).thenReturn(false)
notificationsKeyguardInteractor.setNotificationsFullyHidden(true)
runCurrent()
+ assertThat(isVisible?.value).isTrue()
+ assertThat(isVisible?.isAnimating).isTrue()
+
+ notificationsKeyguardInteractor.setNotificationsFullyHidden(false)
+ runCurrent()
+
assertThat(isVisible?.value).isFalse()
assertThat(isVisible?.isAnimating).isTrue()
}
diff --git a/packages/SystemUI/res/layout/super_notification_shade.xml b/packages/SystemUI/res/layout/super_notification_shade.xml
index 22d34eb7b115..fbb07bed4b50 100644
--- a/packages/SystemUI/res/layout/super_notification_shade.xml
+++ b/packages/SystemUI/res/layout/super_notification_shade.xml
@@ -58,22 +58,22 @@
android:layout_height="match_parent"
android:visibility="invisible" />
- <!-- Shared container for the notification stack. Can be positioned by either
- the keyguard_root_view or notification_panel -->
- <com.android.systemui.statusbar.notification.stack.ui.view.SharedNotificationContainer
- android:id="@+id/shared_notification_container"
+ <!-- Root for all keyguard content. It was previously located within the shade. -->
+ <com.android.systemui.keyguard.ui.view.KeyguardRootView
+ android:id="@id/keyguard_root_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false"
- android:clipToPadding="false"
/>
- <!-- Root for all keyguard content. It was previously located within the shade. -->
- <com.android.systemui.keyguard.ui.view.KeyguardRootView
- android:id="@id/keyguard_root_view"
+ <!-- Shared container for the notification stack. Can be positioned by either
+ the keyguard_root_view or notification_panel -->
+ <com.android.systemui.statusbar.notification.stack.ui.view.SharedNotificationContainer
+ android:id="@+id/shared_notification_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false"
+ android:clipToPadding="false"
/>
<include layout="@layout/brightness_mirror_container" />
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractor.kt b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractor.kt
index 373671d01395..0949ea4d7797 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractor.kt
@@ -16,6 +16,7 @@
package com.android.systemui.bouncer.domain.interactor
+import android.util.Log
import com.android.keyguard.KeyguardUpdateMonitor
import com.android.systemui.biometrics.data.repository.FingerprintPropertyRepository
import com.android.systemui.bouncer.data.repository.KeyguardBouncerRepository
@@ -46,6 +47,7 @@ import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.stateIn
/** Encapsulates business logic for interacting with the lock-screen alternate bouncer. */
@@ -137,6 +139,8 @@ constructor(
flowOf(false)
}
}
+ .distinctUntilChanged()
+ .onEach { Log.d(TAG, "canShowAlternateBouncer changed to $it") }
.stateIn(
scope = scope,
started = WhileSubscribed(),
@@ -234,5 +238,7 @@ constructor(
companion object {
private const val MIN_VISIBILITY_DURATION_UNTIL_TOUCHES_DISMISS_ALTERNATE_BOUNCER_MS = 200L
+
+ private const val TAG = "AlternateBouncerInteractor"
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayCallbackController.kt b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayCallbackController.kt
index d5ff8f21abb2..2b617525fbcc 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayCallbackController.kt
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayCallbackController.kt
@@ -39,8 +39,10 @@ class DreamOverlayCallbackController @Inject constructor() :
}
fun onWakeUp() {
- isDreaming = false
- callbacks.forEach { it.onWakeUp() }
+ if (isDreaming) {
+ isDreaming = false
+ callbacks.forEach { it.onWakeUp() }
+ }
}
fun onStartDream() {
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java
index 113e0011f5bd..0b465e9ce6db 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java
@@ -296,6 +296,8 @@ public class DreamOverlayService extends android.service.dreams.DreamOverlayServ
mStateController.setLowLightActive(false);
mStateController.setEntryAnimationsFinished(false);
+ mDreamOverlayCallbackController.onWakeUp();
+
if (mDreamOverlayContainerViewController != null) {
mDreamOverlayContainerViewController.destroy();
mDreamOverlayContainerViewController = null;
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt
index afe3481677c3..4d3727657f3e 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt
@@ -189,6 +189,7 @@ constructor(
internalTransitionInteractor.currentTransitionInfoInternal,
keyguardInteractor.statusBarState,
keyguardInteractor.isKeyguardDismissible,
+ keyguardInteractor.isKeyguardOccluded,
)
.collect {
(
@@ -196,7 +197,8 @@ constructor(
startedStep,
currentTransitionInfo,
statusBarState,
- isKeyguardUnlocked) ->
+ isKeyguardUnlocked,
+ isKeyguardOccluded) ->
val id = transitionId
if (id != null) {
if (startedStep.to == KeyguardState.PRIMARY_BOUNCER) {
@@ -236,9 +238,13 @@ constructor(
if (nextState == TransitionState.CANCELED) {
transitionRepository.startTransition(
TransitionInfo(
- ownerName = name,
+ ownerName =
+ "$name " +
+ "(on behalf of FromPrimaryBouncerInteractor)",
from = KeyguardState.PRIMARY_BOUNCER,
- to = KeyguardState.LOCKSCREEN,
+ to =
+ if (isKeyguardOccluded) KeyguardState.OCCLUDED
+ else KeyguardState.LOCKSCREEN,
modeOnCanceled = TransitionModeOnCanceled.REVERSE,
animator =
getDefaultAnimatorForTransitionsToState(
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardPreviewClockViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardPreviewClockViewBinder.kt
index 86dae0cbc6aa..69fc012e007a 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardPreviewClockViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardPreviewClockViewBinder.kt
@@ -121,7 +121,10 @@ object KeyguardPreviewClockViewBinder {
private fun applyClockDefaultConstraints(context: Context, constraints: ConstraintSet) {
constraints.apply {
constrainWidth(R.id.lockscreen_clock_view_large, ConstraintSet.WRAP_CONTENT)
- constrainHeight(R.id.lockscreen_clock_view_large, ConstraintSet.MATCH_CONSTRAINT)
+ // The following two lines make lockscreen_clock_view_large is constrained to available
+ // height when it goes beyond constraints; otherwise, it use WRAP_CONTENT
+ constrainHeight(R.id.lockscreen_clock_view_large, WRAP_CONTENT)
+ constrainMaxHeight(R.id.lockscreen_clock_view_large, 0)
val largeClockTopMargin =
SystemBarUtils.getStatusBarHeight(context) +
context.resources.getDimensionPixelSize(
@@ -138,7 +141,7 @@ object KeyguardPreviewClockViewBinder {
R.id.lockscreen_clock_view_large,
ConstraintSet.END,
PARENT_ID,
- ConstraintSet.END
+ ConstraintSet.END,
)
// In preview, we'll show UDFPS icon for UDFPS devices
@@ -160,14 +163,14 @@ object KeyguardPreviewClockViewBinder {
BOTTOM,
PARENT_ID,
BOTTOM,
- clockBottomMargin
+ clockBottomMargin,
)
}
constrainWidth(R.id.lockscreen_clock_view, WRAP_CONTENT)
constrainHeight(
R.id.lockscreen_clock_view,
- context.resources.getDimensionPixelSize(customizationR.dimen.small_clock_height)
+ context.resources.getDimensionPixelSize(customizationR.dimen.small_clock_height),
)
connect(
R.id.lockscreen_clock_view,
@@ -175,7 +178,7 @@ object KeyguardPreviewClockViewBinder {
PARENT_ID,
START,
context.resources.getDimensionPixelSize(customizationR.dimen.clock_padding_start) +
- context.resources.getDimensionPixelSize(R.dimen.status_view_margin_horizontal)
+ context.resources.getDimensionPixelSize(R.dimen.status_view_margin_horizontal),
)
val smallClockTopMargin =
context.resources.getDimensionPixelSize(R.dimen.keyguard_clock_top_margin) +
@@ -188,7 +191,7 @@ object KeyguardPreviewClockViewBinder {
context: Context,
rootView: ConstraintLayout,
previewClock: ClockController,
- viewModel: KeyguardPreviewClockViewModel
+ viewModel: KeyguardPreviewClockViewModel,
) {
val cs = ConstraintSet().apply { clone(rootView) }
applyClockDefaultConstraints(context, cs)
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryBackgroundViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryBackgroundViewModel.kt
index a021de446911..546b32073aca 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryBackgroundViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryBackgroundViewModel.kt
@@ -59,6 +59,7 @@ constructor(
primaryBouncerToAodTransitionViewModel: PrimaryBouncerToAodTransitionViewModel,
primaryBouncerToDozingTransitionViewModel: PrimaryBouncerToDozingTransitionViewModel,
primaryBouncerToLockscreenTransitionViewModel: PrimaryBouncerToLockscreenTransitionViewModel,
+ lockscreenToDozingTransitionViewModel: LockscreenToDozingTransitionViewModel,
) {
val color: Flow<Int> =
deviceEntryIconViewModel.useBackgroundProtection.flatMapLatest { useBackground ->
@@ -103,6 +104,7 @@ constructor(
primaryBouncerToLockscreenTransitionViewModel
.deviceEntryBackgroundViewAlpha,
occludedToDozingTransitionViewModel.deviceEntryBackgroundViewAlpha,
+ lockscreenToDozingTransitionViewModel.deviceEntryBackgroundViewAlpha,
)
.merge()
.onStart {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt
index 0b023d9bfead..630fb99bc70a 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt
@@ -341,12 +341,8 @@ constructor(
when {
// If there are no notification icons to show, then it can be hidden
!hasAodIcons -> false
- // If we're bypassing, then we're visible
- isBypassEnabled -> true
// If we are pulsing (and not bypassing), then we are hidden
isPulseExpanding -> false
- // Besides bypass above, they should not be visible on lockscreen
- isOnLockscreen -> false
// If notifs are fully gone, then we're visible
areNotifsFullyHidden -> true
// Otherwise, we're hidden
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDozingTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDozingTransitionViewModel.kt
index d3eefca67037..7abf35de5dae 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDozingTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDozingTransitionViewModel.kt
@@ -55,16 +55,16 @@ constructor(
onCancel = { 1f },
)
+ val deviceEntryBackgroundViewAlpha: Flow<Float> =
+ transitionAnimation.immediatelyTransitionTo(0f)
+
override val deviceEntryParentViewAlpha: Flow<Float> =
deviceEntryUdfpsInteractor.isUdfpsEnrolledAndEnabled.flatMapLatest {
isUdfpsEnrolledAndEnabled ->
if (isUdfpsEnrolledAndEnabled) {
transitionAnimation.immediatelyTransitionTo(1f)
} else {
- transitionAnimation.sharedFlow(
- duration = 250.milliseconds,
- onStep = { 1f - it },
- )
+ transitionAnimation.sharedFlow(duration = 250.milliseconds, onStep = { 1f - it })
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaProcessingHelper.kt b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaProcessingHelper.kt
index 55d7b1d498e0..2bdee67dd57a 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaProcessingHelper.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaProcessingHelper.kt
@@ -42,7 +42,7 @@ fun isSameMediaData(
context: Context,
newController: MediaController,
new: MediaData,
- old: MediaData?
+ old: MediaData?,
): Boolean {
if (old == null || !mediaControlsPostsOptimization()) return false
@@ -71,7 +71,7 @@ fun isSameMediaData(
/** Returns whether actions lists are equal. */
fun areCustomActionListsEqual(
first: List<PlaybackState.CustomAction>?,
- second: List<PlaybackState.CustomAction>?
+ second: List<PlaybackState.CustomAction>?,
): Boolean {
// Same object, or both null
if (first === second) {
@@ -94,7 +94,7 @@ fun areCustomActionListsEqual(
private fun areCustomActionsEqual(
firstAction: PlaybackState.CustomAction,
- secondAction: PlaybackState.CustomAction
+ secondAction: PlaybackState.CustomAction,
): Boolean {
if (
firstAction.action != secondAction.action ||
@@ -139,7 +139,7 @@ private fun areActionsEqual(
context: Context,
newController: MediaController,
new: MediaData,
- old: MediaData
+ old: MediaData,
): Boolean {
val oldState = MediaController(context, old.token!!).playbackState
return if (
@@ -150,8 +150,7 @@ private fun areActionsEqual(
var same = true
new.actions.asSequence().zip(old.actions.asSequence()).forEach {
if (
- it.first.actionIntent?.intent?.filterEquals(it.second.actionIntent?.intent) !=
- true ||
+ it.first.actionIntent?.intent != it.second.actionIntent?.intent ||
it.first.icon != it.second.icon ||
it.first.contentDescription != it.second.contentDescription
) {
@@ -164,7 +163,7 @@ private fun areActionsEqual(
oldState?.actions == newController.playbackState?.actions &&
areCustomActionListsEqual(
oldState?.customActions,
- newController.playbackState?.customActions
+ newController.playbackState?.customActions,
)
} else {
false
@@ -172,8 +171,5 @@ private fun areActionsEqual(
}
private fun areClickIntentsEqual(newIntent: PendingIntent?, oldIntent: PendingIntent?): Boolean {
- if ((newIntent == null && oldIntent == null) || newIntent === oldIntent) return true
- if (newIntent == null || oldIntent == null) return false
-
- return newIntent.intent?.filterEquals(oldIntent.intent) == true
+ return newIntent == oldIntent
}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
index 0c05dbde6117..e197f03b5575 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
@@ -2710,6 +2710,11 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
}
private int calculatePanelHeightShade() {
+ // Bypass should always occupy the full height
+ if (mBarState == KEYGUARD && mKeyguardBypassController.getBypassEnabled()) {
+ return mNotificationStackScrollLayoutController.getHeight();
+ }
+
int emptyBottomMargin = mNotificationStackScrollLayoutController.getEmptyBottomMargin();
int maxHeight = mNotificationStackScrollLayoutController.getHeight() - emptyBottomMargin;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
index 7b6a2cb62b14..560028cb5640 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
@@ -444,9 +444,11 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
if (onFinishedRunnable != null) {
onFinishedRunnable.run();
}
+ if (mRunWithoutInterruptions) {
+ enableAppearDrawing(false);
+ }
// We need to reset the View state, even if the animation was cancelled
- enableAppearDrawing(false);
onAppearAnimationFinished(isAppearing);
if (mRunWithoutInterruptions) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java
index 8c80fd400360..36e3e92e4063 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java
@@ -203,13 +203,16 @@ public class NotificationContentInflater implements NotificationRowContentBinder
messagingStyle = mConversationProcessor
.processNotification(entry, builder, mLogger);
}
- result.mInflatedSingleLineViewModel = SingleLineViewInflater
+ SingleLineViewModel viewModel = SingleLineViewInflater
.inflateSingleLineViewModel(
entry.getSbn().getNotification(),
messagingStyle,
builder,
row.getContext()
);
+ // If the messagingStyle is null, we want to inflate the normal view
+ isConversation = viewModel.isConversation();
+ result.mInflatedSingleLineViewModel = viewModel;
result.mInflatedSingleLineView =
SingleLineViewInflater.inflatePrivateSingleLineView(
isConversation,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/SingleLineViewInflater.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/SingleLineViewInflater.kt
index d67947d1fda8..4e26ae85100c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/SingleLineViewInflater.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/SingleLineViewInflater.kt
@@ -90,7 +90,7 @@ internal object SingleLineViewInflater {
notification = notification,
isGroupConversation = isGroupConversation,
builder = builder,
- systemUiContext = systemUiContext
+ systemUiContext = systemUiContext,
)
val conversationData =
@@ -98,7 +98,7 @@ internal object SingleLineViewInflater {
// We don't show the sender's name for one-to-one conversation
conversationSenderName =
if (isGroupConversation) conversationTextData?.senderName else null,
- avatar = conversationAvatar
+ avatar = conversationAvatar,
)
return SingleLineViewModel(
@@ -111,7 +111,7 @@ internal object SingleLineViewInflater {
@JvmStatic
fun inflateRedactedSingleLineViewModel(
context: Context,
- isConversation: Boolean = false
+ isConversation: Boolean = false,
): SingleLineViewModel {
val conversationData =
if (isConversation) {
@@ -122,7 +122,7 @@ internal object SingleLineViewInflater {
com.android.systemui.res.R.drawable
.ic_redacted_notification_single_line_icon
)
- )
+ ),
)
} else {
null
@@ -134,7 +134,7 @@ internal object SingleLineViewInflater {
context.getString(
com.android.systemui.res.R.string.redacted_notification_single_line_text
),
- conversationData
+ conversationData,
)
}
@@ -159,11 +159,13 @@ internal object SingleLineViewInflater {
}
// load the sender's name to display
- val name = lastMessage.senderPerson?.name
+ // null senderPerson means the current user.
+ val name = lastMessage.senderPerson?.name ?: user.name
+
val senderName =
systemUiContext.resources.getString(
R.string.conversation_single_line_name_display,
- if (Flags.cleanUpSpansAndNewLines()) name?.toString() else name
+ if (Flags.cleanUpSpansAndNewLines()) name?.toString() else name,
)
// We need to find back-up values for those texts if they are needed and empty
@@ -333,7 +335,7 @@ internal object SingleLineViewInflater {
sender.icon
?: builder.getDefaultAvatar(
name = sender.name,
- uniqueNames = uniqueNames
+ uniqueNames = uniqueNames,
)
lastKey = senderKey
} else {
@@ -341,7 +343,7 @@ internal object SingleLineViewInflater {
sender.icon
?: builder.getDefaultAvatar(
name = sender.name,
- uniqueNames = uniqueNames
+ uniqueNames = uniqueNames,
)
break
}
@@ -424,7 +426,7 @@ internal object SingleLineViewInflater {
private fun Notification.Builder.getDefaultAvatar(
name: CharSequence?,
- uniqueNames: PeopleHelper.NameToPrefixMap? = null
+ uniqueNames: PeopleHelper.NameToPrefixMap? = null,
): Icon {
val layoutColor = getSmallIconColor(/* isHeader= */ false)
if (!name.isNullOrEmpty()) {
@@ -432,7 +434,7 @@ internal object SingleLineViewInflater {
return peopleHelper.createAvatarSymbol(
/* name = */ name,
/* symbol = */ symbol,
- /* layoutColor = */ layoutColor
+ /* layoutColor = */ layoutColor,
)
}
// If name is null, create default avatar with background color
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ui/viewbinder/SingleLineViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ui/viewbinder/SingleLineViewBinder.kt
index 3b0f1ee22be3..a17197c1f8ea 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ui/viewbinder/SingleLineViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ui/viewbinder/SingleLineViewBinder.kt
@@ -24,14 +24,14 @@ import com.android.systemui.statusbar.notification.row.ui.viewmodel.SingleLineVi
object SingleLineViewBinder {
@JvmStatic
fun bind(viewModel: SingleLineViewModel?, view: HybridNotificationView?) {
- if (viewModel?.isConversation() == true && view is HybridConversationNotificationView) {
+ if (view is HybridConversationNotificationView) {
if (AsyncHybridViewInflation.isUnexpectedlyInLegacyMode()) return
- viewModel.conversationData?.avatar?.let { view.setAvatar(it) }
+ viewModel?.conversationData?.avatar?.let { view.setAvatar(it) }
view.setText(
- viewModel.titleText,
- viewModel.contentText,
- viewModel.conversationData?.conversationSenderName
+ viewModel?.titleText,
+ viewModel?.contentText,
+ viewModel?.conversationData?.conversationSenderName,
)
} else {
// bind the title and content text views
@@ -39,7 +39,7 @@ object SingleLineViewBinder {
bind(
/* title = */ viewModel?.titleText,
/* text = */ viewModel?.contentText,
- /* contentView = */ null
+ /* contentView = */ null,
)
}
}
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 dad6894a43ce..ae71ca443236 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
@@ -24,6 +24,7 @@ import static com.android.internal.jank.InteractionJankMonitor.CUJ_NOTIFICATION_
import static com.android.server.notification.Flags.screenshareNotificationHiding;
import static com.android.systemui.Dependency.ALLOW_NOTIFICATION_LONG_PRESS_NAME;
import static com.android.systemui.Flags.confineNotificationTouchToViewWidth;
+import static com.android.systemui.Flags.ignoreTouchesNextToNotificationShelf;
import static com.android.systemui.statusbar.StatusBarState.KEYGUARD;
import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.OnEmptySpaceClickListener;
import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.OnOverscrollTopChangedListener;
@@ -604,6 +605,16 @@ public class NotificationStackScrollLayoutController implements Dumpable {
true /* requireMinHeight */,
false /* ignoreDecors */,
!confineNotificationTouchToViewWidth() /* ignoreWidth */);
+
+ // Verify the MotionEvent x,y are actually inside the touch area of the shelf,
+ // since the shelf may be animated down to a collapsed size on keyguard.
+ if (ignoreTouchesNextToNotificationShelf()) {
+ if (child instanceof NotificationShelf shelf) {
+ if (!NotificationSwipeHelper.isTouchInView(ev, shelf)) {
+ return null;
+ }
+ }
+ }
if (child instanceof ExpandableNotificationRow row) {
ExpandableNotificationRow parent = row.getNotificationParent();
if (parent != null && parent.areChildrenExpanded()
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java
index 7e327e66982c..0e94ca351835 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java
@@ -18,6 +18,7 @@
package com.android.systemui.statusbar.notification.stack;
import static com.android.internal.jank.InteractionJankMonitor.CUJ_NOTIFICATION_SHADE_ROW_SWIPE;
+import static com.android.systemui.Flags.ignoreTouchesNextToNotificationShelf;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -39,6 +40,7 @@ import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper;
+import com.android.systemui.statusbar.NotificationShelf;
import com.android.systemui.statusbar.notification.SourceType;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.ExpandableView;
@@ -503,13 +505,21 @@ class NotificationSwipeHelper extends SwipeHelper implements NotificationSwipeAc
final int height = (view instanceof ExpandableView)
? ((ExpandableView) view).getActualHeight()
: view.getHeight();
+ final int width;
+ if (ignoreTouchesNextToNotificationShelf()) {
+ width = (view instanceof NotificationShelf)
+ ? ((NotificationShelf) view).getActualWidth()
+ : view.getWidth();
+ } else {
+ width = view.getWidth();
+ }
final int rx = (int) ev.getRawX();
final int ry = (int) ev.getRawY();
int[] temp = new int[2];
view.getLocationOnScreen(temp);
final int x = temp[0];
final int y = temp[1];
- Rect rect = new Rect(x, y, x + view.getWidth(), y + height);
+ Rect rect = new Rect(x, y, x + width, y + height);
boolean ret = rect.contains(rx, ry);
return ret;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index 1ea26e5727ac..6fde603af4c6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -528,6 +528,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
this::consumeKeyguardAuthenticatedBiometricsHandled
);
} else {
+ // Collector that keeps the AlternateBouncerInteractor#canShowAlternateBouncer flow hot.
mListenForCanShowAlternateBouncer = mJavaAdapter.alwaysCollectFlow(
mAlternateBouncerInteractor.getCanShowAlternateBouncer(),
this::consumeCanShowAlternateBouncer
@@ -576,8 +577,17 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
}
private void consumeCanShowAlternateBouncer(boolean canShow) {
- // do nothing, we only are registering for the flow to ensure that there's at least
- // one subscriber that will update AlternateBouncerInteractor.canShowAlternateBouncer.value
+ // Hack: this is required to fix issues where
+ // KeyguardBouncerRepository#alternateBouncerVisible state is incorrectly set and then never
+ // reset. This is caused by usages of show()/forceShow() that only read this flow to set the
+ // alternate bouncer visible state, if there is a race condition between when that flow
+ // changes to false and when the read happens, the flow will be set to an incorrect value
+ // and not reset on time.
+ if (!canShow) {
+ Log.d(TAG, "canShowAlternateBouncer turned false, maybe try hiding the alternate "
+ + "bouncer if it is already visible");
+ mAlternateBouncerInteractor.maybeHide();
+ }
}
/** Register a callback, to be invoked by the Predictive Back system. */
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/SingleLineViewBinderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/SingleLineViewBinderTest.kt
index 6b3fb5b4a2eb..503fa789cb80 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/SingleLineViewBinderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/SingleLineViewBinderTest.kt
@@ -29,12 +29,13 @@ import com.android.systemui.statusbar.notification.row.SingleLineViewInflater.in
import com.android.systemui.statusbar.notification.row.SingleLineViewInflater.inflatePublicSingleLineView
import com.android.systemui.statusbar.notification.row.shared.AsyncHybridViewInflation
import com.android.systemui.statusbar.notification.row.ui.viewbinder.SingleLineViewBinder
-import com.android.systemui.util.mockito.mock
import kotlin.test.assertEquals
import kotlin.test.assertNotNull
+import kotlin.test.assertNull
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.kotlin.mock
@SmallTest
@RunWith(AndroidJUnit4::class)
@@ -69,7 +70,7 @@ class SingleLineViewBinderTest : SysuiTestCase() {
reinflateFlags = FLAG_CONTENT_VIEW_SINGLE_LINE,
entry = row.entry,
context = context,
- logger = mock()
+ logger = mock(),
)
val publicView =
@@ -78,7 +79,7 @@ class SingleLineViewBinderTest : SysuiTestCase() {
reinflateFlags = FLAG_CONTENT_VIEW_PUBLIC_SINGLE_LINE,
entry = row.entry,
context = context,
- logger = mock()
+ logger = mock(),
)
assertNotNull(publicView)
@@ -114,7 +115,7 @@ class SingleLineViewBinderTest : SysuiTestCase() {
.addMessage(
"How about lunch?",
System.currentTimeMillis(),
- Person.Builder().setName("user2").build()
+ Person.Builder().setName("user2").build(),
)
.setGroupConversation(true)
notificationBuilder.setStyle(style).setShortcutId(SHORTCUT_ID)
@@ -127,7 +128,7 @@ class SingleLineViewBinderTest : SysuiTestCase() {
reinflateFlags = FLAG_CONTENT_VIEW_SINGLE_LINE,
entry = row.entry,
context = context,
- logger = mock()
+ logger = mock(),
)
as HybridConversationNotificationView
@@ -137,7 +138,7 @@ class SingleLineViewBinderTest : SysuiTestCase() {
reinflateFlags = FLAG_CONTENT_VIEW_PUBLIC_SINGLE_LINE,
entry = row.entry,
context = context,
- logger = mock()
+ logger = mock(),
)
as HybridConversationNotificationView
assertNotNull(publicView)
@@ -150,10 +151,7 @@ class SingleLineViewBinderTest : SysuiTestCase() {
systemUiContext = context,
)
// WHEN: binds the view
- SingleLineViewBinder.bind(
- viewModel,
- view,
- )
+ SingleLineViewBinder.bind(viewModel, view)
// THEN: the single-line conversation view should be bound with view model's corresponding
// fields
@@ -161,10 +159,55 @@ class SingleLineViewBinderTest : SysuiTestCase() {
assertEquals(viewModel.contentText, view.textView.text)
assertEquals(
viewModel.conversationData?.conversationSenderName,
- view.conversationSenderNameView.text
+ view.conversationSenderNameView.text,
)
}
+ @Test
+ @EnableFlags(AsyncHybridViewInflation.FLAG_NAME)
+ fun bindConversationSingleLineView_nonConversationViewModel() {
+ // GIVEN: a ConversationSingleLineView, and a nonConversationViewModel
+ val style = Notification.BigTextStyle().bigText(CONTENT_TEXT)
+ notificationBuilder.setStyle(style)
+ val notification = notificationBuilder.build()
+ val row: ExpandableNotificationRow = helper.createRow(notification)
+
+ val view =
+ inflatePrivateSingleLineView(
+ isConversation = true,
+ reinflateFlags = FLAG_CONTENT_VIEW_SINGLE_LINE,
+ entry = row.entry,
+ context = context,
+ logger = mock(),
+ )
+
+ val publicView =
+ inflatePublicSingleLineView(
+ isConversation = true,
+ reinflateFlags = FLAG_CONTENT_VIEW_PUBLIC_SINGLE_LINE,
+ entry = row.entry,
+ context = context,
+ logger = mock(),
+ )
+ assertNotNull(publicView)
+
+ val viewModel =
+ SingleLineViewInflater.inflateSingleLineViewModel(
+ notification = notification,
+ messagingStyle = null,
+ builder = notificationBuilder,
+ systemUiContext = context,
+ )
+ // WHEN: binds the view with the view model
+ SingleLineViewBinder.bind(viewModel, view)
+
+ // THEN: the single-line view should be bound with view model's corresponding
+ // fields as a normal non-conversation single-line view
+ assertEquals(viewModel.titleText, view?.titleView?.text)
+ assertEquals(viewModel.contentText, view?.textView?.text)
+ assertNull(viewModel.conversationData)
+ }
+
private companion object {
const val CHANNEL_ID = "CHANNEL_ID"
const val CONTENT_TITLE = "A Cool New Feature"
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java
index 95db95cd288b..789701f5e4b0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java
@@ -13,6 +13,8 @@
package com.android.systemui.statusbar.notification.stack;
+import static com.android.systemui.Flags.FLAG_IGNORE_TOUCHES_NEXT_TO_NOTIFICATION_SHELF;
+
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
@@ -36,6 +38,7 @@ import static org.mockito.Mockito.when;
import android.animation.Animator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.os.Handler;
+import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
import android.service.notification.StatusBarNotification;
import android.testing.TestableLooper;
@@ -52,6 +55,7 @@ import com.android.systemui.flags.FakeFeatureFlags;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper.SnoozeOption;
+import com.android.systemui.statusbar.NotificationShelf;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.shared.NotificationContentAlphaOptimization;
@@ -85,6 +89,7 @@ public class NotificationSwipeHelperTest extends SysuiTestCase {
private NotificationMenuRowPlugin mMenuRow;
private Handler mHandler;
private ExpandableNotificationRow mNotificationRow;
+ private NotificationShelf mShelf;
private Runnable mFalsingCheck;
private final FeatureFlags mFeatureFlags = new FakeFeatureFlags();
@@ -111,6 +116,7 @@ public class NotificationSwipeHelperTest extends SysuiTestCase {
mEvent = mock(MotionEvent.class);
mMenuRow = mock(NotificationMenuRowPlugin.class);
mNotificationRow = mock(ExpandableNotificationRow.class);
+ mShelf = mock(NotificationShelf.class);
mHandler = mock(Handler.class);
mFalsingCheck = mock(Runnable.class);
}
@@ -665,6 +671,54 @@ public class NotificationSwipeHelperTest extends SysuiTestCase {
}
@Test
+ @EnableFlags(FLAG_IGNORE_TOUCHES_NEXT_TO_NOTIFICATION_SHELF)
+ public void testIsTouchInView_notificationShelf_flagEnabled() {
+ doReturn(500).when(mShelf).getWidth();
+ doReturn(FAKE_ROW_WIDTH).when(mShelf).getActualWidth();
+ doReturn(FAKE_ROW_HEIGHT).when(mShelf).getHeight();
+ doReturn(FAKE_ROW_HEIGHT).when(mShelf).getActualHeight();
+
+ Answer answer = (Answer) invocation -> {
+ int[] arr = invocation.getArgument(0);
+ arr[0] = 0;
+ arr[1] = 0;
+ return null;
+ };
+
+ doReturn(5f).when(mEvent).getRawX();
+ doReturn(10f).when(mEvent).getRawY();
+ doAnswer(answer).when(mShelf).getLocationOnScreen(any());
+ assertTrue("Touch is within the view", mSwipeHelper.isTouchInView(mEvent, mShelf));
+
+ doReturn(50f).when(mEvent).getRawX();
+ assertFalse("Touch is not within the view", mSwipeHelper.isTouchInView(mEvent, mShelf));
+ }
+
+ @Test
+ @DisableFlags(FLAG_IGNORE_TOUCHES_NEXT_TO_NOTIFICATION_SHELF)
+ public void testIsTouchInView_notificationShelf_flagDisabled() {
+ doReturn(500).when(mShelf).getWidth();
+ doReturn(FAKE_ROW_WIDTH).when(mShelf).getActualWidth();
+ doReturn(FAKE_ROW_HEIGHT).when(mShelf).getHeight();
+ doReturn(FAKE_ROW_HEIGHT).when(mShelf).getActualHeight();
+
+ Answer answer = (Answer) invocation -> {
+ int[] arr = invocation.getArgument(0);
+ arr[0] = 0;
+ arr[1] = 0;
+ return null;
+ };
+
+ doReturn(5f).when(mEvent).getRawX();
+ doReturn(10f).when(mEvent).getRawY();
+ doAnswer(answer).when(mShelf).getLocationOnScreen(any());
+ assertTrue("Touch is within the view", mSwipeHelper.isTouchInView(mEvent, mShelf));
+
+ doReturn(50f).when(mEvent).getRawX();
+ assertTrue("Touch is within the view", mSwipeHelper.isTouchInView(mEvent, mShelf));
+ }
+
+ @Test
public void testContentAlphaRemainsUnchangedWhenNotificationIsNotDismissible() {
doReturn(FAKE_ROW_WIDTH).when(mNotificationRow).getMeasuredWidth();
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryBackgroundViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryBackgroundViewModelKosmos.kt
new file mode 100644
index 000000000000..09836ed46817
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryBackgroundViewModelKosmos.kt
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2024 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.keyguard.ui.viewmodel
+
+import android.content.applicationContext
+import com.android.systemui.common.ui.domain.interactor.configurationInteractor
+import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+
+@ExperimentalCoroutinesApi
+val Kosmos.deviceEntryBackgroundViewModel by Fixture {
+ DeviceEntryBackgroundViewModel(
+ context = applicationContext,
+ deviceEntryIconViewModel = deviceEntryIconViewModel,
+ configurationInteractor = configurationInteractor,
+ keyguardTransitionInteractor = keyguardTransitionInteractor,
+ alternateBouncerToAodTransitionViewModel = alternateBouncerToAodTransitionViewModel,
+ alternateBouncerToDozingTransitionViewModel = alternateBouncerToDozingTransitionViewModel,
+ aodToLockscreenTransitionViewModel = aodToLockscreenTransitionViewModel,
+ dozingToLockscreenTransitionViewModel = dozingToLockscreenTransitionViewModel,
+ dreamingToAodTransitionViewModel = dreamingToAodTransitionViewModel,
+ dreamingToLockscreenTransitionViewModel = dreamingToLockscreenTransitionViewModel,
+ goneToAodTransitionViewModel = goneToAodTransitionViewModel,
+ goneToDozingTransitionViewModel = goneToDozingTransitionViewModel,
+ goneToLockscreenTransitionViewModel = goneToLockscreenTransitionViewModel,
+ lockscreenToAodTransitionViewModel = lockscreenToAodTransitionViewModel,
+ occludedToAodTransitionViewModel = occludedToAodTransitionViewModel,
+ occludedToDozingTransitionViewModel = occludedToDozingTransitionViewModel,
+ occludedToLockscreenTransitionViewModel = occludedToLockscreenTransitionViewModel,
+ primaryBouncerToAodTransitionViewModel = primaryBouncerToAodTransitionViewModel,
+ primaryBouncerToDozingTransitionViewModel = primaryBouncerToDozingTransitionViewModel,
+ primaryBouncerToLockscreenTransitionViewModel =
+ primaryBouncerToLockscreenTransitionViewModel,
+ lockscreenToDozingTransitionViewModel = lockscreenToDozingTransitionViewModel,
+ )
+}
diff --git a/ravenwood/Android.bp b/ravenwood/Android.bp
index 66c8d0fa32f9..59043a8356ae 100644
--- a/ravenwood/Android.bp
+++ b/ravenwood/Android.bp
@@ -182,21 +182,6 @@ java_device_for_host {
visibility: [":__subpackages__"],
}
-// Separated out from ravenwood-junit-impl since it needs to compile
-// against `module_current`
-java_library {
- name: "ravenwood-junit-impl-flag",
- srcs: [
- "junit-flag-src/**/*.java",
- ],
- sdk_version: "module_current",
- libs: [
- "junit",
- "flag-junit",
- ],
- visibility: ["//visibility:public"],
-}
-
// Carefully compiles against only module_current to support tests that
// want to verify they're unbundled. The "impl" library above is what
// ships inside the Ravenwood environment to actually drive any API
@@ -651,7 +636,6 @@ android_ravenwood_libgroup {
"flag-junit",
"ravenwood-framework",
"ravenwood-junit-impl",
- "ravenwood-junit-impl-flag",
"mockito-ravenwood-prebuilt",
"inline-mockito-ravenwood-prebuilt",
diff --git a/ravenwood/junit-flag-src/android/platform/test/flag/junit/RavenwoodFlagsValueProvider.java b/ravenwood/junit-flag-src/android/platform/test/flag/junit/RavenwoodFlagsValueProvider.java
deleted file mode 100644
index 9d6277473298..000000000000
--- a/ravenwood/junit-flag-src/android/platform/test/flag/junit/RavenwoodFlagsValueProvider.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2024 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 android.platform.test.flag.junit;
-
-import android.platform.test.flag.junit.CheckFlagsRule;
-import android.platform.test.flag.junit.IFlagsValueProvider;
-
-/**
- * Offer to create {@link CheckFlagsRule} instances that are useful on the Ravenwood deviceless
- * testing environment.
- *
- * At the moment, default flag values are not available on Ravenwood, so the only options offered
- * here are "all-on" and "all-off" options. Tests that want to exercise specific flag states should
- * use {@link android.platform.test.flag.junit.SetFlagsRule}.
- */
-public class RavenwoodFlagsValueProvider {
- /**
- * Create a {@link CheckFlagsRule} instance where flags are in an "all-on" state.
- */
- public static CheckFlagsRule createAllOnCheckFlagsRule() {
- return new CheckFlagsRule(new IFlagsValueProvider() {
- @Override
- public boolean getBoolean(String flag) {
- return true;
- }
- });
- }
-
- /**
- * Create a {@link CheckFlagsRule} instance where flags are in an "all-off" state.
- */
- public static CheckFlagsRule createAllOffCheckFlagsRule() {
- return new CheckFlagsRule(new IFlagsValueProvider() {
- @Override
- public boolean getBoolean(String flag) {
- return false;
- }
- });
- }
-}
diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodAwareTestRunner.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodAwareTestRunner.java
index 9644a52a749e..3ebef02284d6 100644
--- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodAwareTestRunner.java
+++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodAwareTestRunner.java
@@ -129,7 +129,7 @@ public final class RavenwoodAwareTestRunner extends RavenwoodAwareTestRunnerBase
mTestClass = new TestClass(testClass);
- Log.v(TAG, "RavenwoodAwareTestRunner starting for " + testClass.getCanonicalName());
+ Log.v(TAG, "RavenwoodAwareTestRunner initializing for " + testClass.getCanonicalName());
// Hook point to allow more customization.
runAnnotatedMethodsOnRavenwood(RavenwoodTestRunnerInitializing.class, null);
@@ -146,7 +146,9 @@ public final class RavenwoodAwareTestRunner extends RavenwoodAwareTestRunnerBase
private void runAnnotatedMethodsOnRavenwood(Class<? extends Annotation> annotationClass,
Object instance) {
- Log.v(TAG, "runAnnotatedMethodsOnRavenwood() " + annotationClass.getName());
+ if (RAVENWOOD_VERBOSE_LOGGING) {
+ Log.v(TAG, "runAnnotatedMethodsOnRavenwood() " + annotationClass.getName());
+ }
for (var method : mTestClass.getAnnotatedMethods(annotationClass)) {
ensureIsPublicVoidMethod(method.getMethod(), /* isStatic=*/ instance == null);
@@ -169,12 +171,14 @@ public final class RavenwoodAwareTestRunner extends RavenwoodAwareTestRunnerBase
RavenwoodTestStats.getInstance().attachToRunNotifier(notifier);
if (mRealRunner instanceof ClassSkippingTestRunner) {
- Log.i(TAG, "onClassSkipped: description=" + description);
+ Log.v(TAG, "onClassSkipped: description=" + description);
mRealRunner.run(notifier);
return;
}
- Log.v(TAG, "Starting " + mTestJavaClass.getCanonicalName());
+ if (RAVENWOOD_VERBOSE_LOGGING) {
+ Log.v(TAG, "Running " + mTestJavaClass.getCanonicalName());
+ }
if (RAVENWOOD_VERBOSE_LOGGING) {
dumpDescription(description);
}
diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRunnerState.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRunnerState.java
index a5d0bfd51a0f..70bc52bdaa12 100644
--- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRunnerState.java
+++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRunnerState.java
@@ -15,6 +15,8 @@
*/
package android.platform.test.ravenwood;
+import static com.android.ravenwood.common.RavenwoodCommonUtils.RAVENWOOD_VERBOSE_LOGGING;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
@@ -59,16 +61,22 @@ public final class RavenwoodRunnerState {
private Description mMethodDescription;
public void enterTestRunner() {
- Log.i(TAG, "enterTestRunner: " + mRunner);
+ if (RAVENWOOD_VERBOSE_LOGGING) {
+ Log.v(TAG, "enterTestRunner: " + mRunner);
+ }
RavenwoodRuntimeEnvironmentController.initForRunner();
}
public void enterTestClass() {
- Log.i(TAG, "enterTestClass: " + mRunner.mTestJavaClass.getName());
+ if (RAVENWOOD_VERBOSE_LOGGING) {
+ Log.v(TAG, "enterTestClass: " + mRunner.mTestJavaClass.getName());
+ }
}
public void exitTestClass() {
- Log.i(TAG, "exitTestClass: " + mRunner.mTestJavaClass.getName());
+ if (RAVENWOOD_VERBOSE_LOGGING) {
+ Log.v(TAG, "exitTestClass: " + mRunner.mTestJavaClass.getName());
+ }
assertTrue(RAVENWOOD_RULE_ERROR, sActiveProperties.isEmpty());
RavenwoodRuntimeEnvironmentController.exitTestClass();
}
diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java
index 930914f586eb..3cb6c5a6bd16 100644
--- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java
+++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java
@@ -552,7 +552,7 @@ public class RavenwoodRuntimeEnvironmentController {
}
private static void dumpCommandLineArgs() {
- Log.i(TAG, "JVM arguments:");
+ Log.v(TAG, "JVM arguments:");
// Note, we use the wrapper in JUnit4, not the actual class (
// java.lang.management.ManagementFactory), because we can't see the later at the build
@@ -561,7 +561,7 @@ public class RavenwoodRuntimeEnvironmentController {
var args = ManagementFactory.getRuntimeMXBean().getInputArguments();
for (var arg : args) {
- Log.i(TAG, " " + arg);
+ Log.v(TAG, " " + arg);
}
}
}
diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java
index fac07910be11..70c161c1f19a 100644
--- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java
+++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java
@@ -84,7 +84,7 @@ public class RavenwoodSystemProperties {
var ravenwoodProps = readProperties(path + RAVENWOOD_BUILD_PROP);
var deviceProps = readProperties(path + DEVICE_BUILD_PROP);
- Log.i(TAG, "Default system properties:");
+ Log.v(TAG, "Default system properties:");
ravenwoodProps.forEach((key, origValue) -> {
final String value;
@@ -100,7 +100,7 @@ public class RavenwoodSystemProperties {
} else {
value = origValue;
}
- Log.i(TAG, key + "=" + value);
+ Log.v(TAG, key + "=" + value);
sDefaultValues.put(key, value);
});
diff --git a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodAwareTestRunnerBase.java b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodAwareTestRunnerBase.java
index f3688d664142..359210582ba5 100644
--- a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodAwareTestRunnerBase.java
+++ b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodAwareTestRunnerBase.java
@@ -15,6 +15,8 @@
*/
package android.platform.test.ravenwood;
+import static com.android.ravenwood.common.RavenwoodCommonUtils.RAVENWOOD_VERBOSE_LOGGING;
+
import android.platform.test.annotations.internal.InnerRunner;
import android.util.Log;
@@ -53,7 +55,9 @@ abstract class RavenwoodAwareTestRunnerBase extends Runner implements Filterable
}
try {
- Log.i(TAG, "Initializing the inner runner: " + runnerClass);
+ if (RAVENWOOD_VERBOSE_LOGGING) {
+ Log.v(TAG, "Initializing the inner runner: " + runnerClass);
+ }
try {
return runnerClass.getConstructor(Class.class)
.newInstance(testClass.getJavaClass());
diff --git a/ravenwood/runtime-jni/ravenwood_initializer.cpp b/ravenwood/runtime-jni/ravenwood_initializer.cpp
index dbbc3453b2f1..391c5d56b212 100644
--- a/ravenwood/runtime-jni/ravenwood_initializer.cpp
+++ b/ravenwood/runtime-jni/ravenwood_initializer.cpp
@@ -140,7 +140,7 @@ static void check_system_property_access(const char* key, bool write) {
if (gVM != nullptr && gRunnerState != nullptr) {
JNIEnv* env;
if (gVM->GetEnv((void**)&env, JNI_VERSION_1_4) >= 0) {
- ALOGI("%s access to system property '%s'", write ? "Write" : "Read", key);
+ ALOGV("%s access to system property '%s'", write ? "Write" : "Read", key);
env->CallStaticVoidMethod(gRunnerState, gCheckSystemPropertyAccess,
env->NewStringUTF(key), write ? JNI_TRUE : JNI_FALSE);
return;
@@ -208,7 +208,7 @@ static const JNINativeMethod sMethods[] = {
};
extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */) {
- ALOGI("%s: JNI_OnLoad", __FILE__);
+ ALOGV("%s: JNI_OnLoad", __FILE__);
maybeRedirectLog();
diff --git a/ravenwood/runtime-jni/ravenwood_runtime.cpp b/ravenwood/runtime-jni/ravenwood_runtime.cpp
index bab4c7e0fd14..8d8ed7119e84 100644
--- a/ravenwood/runtime-jni/ravenwood_runtime.cpp
+++ b/ravenwood/runtime-jni/ravenwood_runtime.cpp
@@ -204,7 +204,7 @@ static const JNINativeMethod sMethods[] =
};
extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */) {
- ALOGI("%s: JNI_OnLoad", __FILE__);
+ ALOGV("%s: JNI_OnLoad", __FILE__);
JNIEnv* env = GetJNIEnvOrDie(vm);
g_StructStat = FindGlobalClassOrDie(env, "android/system/StructStat");
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 7580b697b516..49f15e46894d 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -3653,6 +3653,12 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
return;
}
+ // Magnification connection should not be requested for visible background users.
+ // (b/332222893)
+ if (mUmi.isVisibleBackgroundFullUser(userState.mUserId)) {
+ return;
+ }
+
final boolean shortcutEnabled = (userState.isShortcutMagnificationEnabledLocked()
|| userState.isMagnificationSingleFingerTripleTapEnabledLocked()
|| (Flags.enableMagnificationMultipleFingerMultipleTapGesture()
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationConnectionManager.java b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationConnectionManager.java
index 19e3e690924e..fe06406e580a 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationConnectionManager.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationConnectionManager.java
@@ -19,6 +19,7 @@ package com.android.server.accessibility.magnification;
import static android.accessibilityservice.AccessibilityTrace.FLAGS_MAGNIFICATION_CONNECTION;
import static android.accessibilityservice.AccessibilityTrace.FLAGS_MAGNIFICATION_CONNECTION_CALLBACK;
import static android.os.Build.HW_TIMEOUT_MULTIPLIER;
+import static android.os.UserHandle.getCallingUserId;
import static android.view.accessibility.MagnificationAnimationCallback.STUB_ANIMATION_CALLBACK;
import static com.android.server.accessibility.AccessibilityManagerService.INVALID_SERVICE_ID;
@@ -54,6 +55,7 @@ import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.LocalServices;
import com.android.server.accessibility.AccessibilityTraceManager;
+import com.android.server.pm.UserManagerInternal;
import com.android.server.statusbar.StatusBarManagerInternal;
import com.android.server.wm.WindowManagerInternal;
@@ -209,6 +211,7 @@ public class MagnificationConnectionManager implements
private final Callback mCallback;
private final AccessibilityTraceManager mTrace;
private final MagnificationScaleProvider mScaleProvider;
+ private final UserManagerInternal mUserManagerInternal;
public MagnificationConnectionManager(Context context, Object lock, @NonNull Callback callback,
AccessibilityTraceManager trace, MagnificationScaleProvider scaleProvider) {
@@ -217,6 +220,7 @@ public class MagnificationConnectionManager implements
mCallback = callback;
mTrace = trace;
mScaleProvider = scaleProvider;
+ mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
}
/**
@@ -280,12 +284,18 @@ public class MagnificationConnectionManager implements
* Requests {@link IMagnificationConnection} through
* {@link StatusBarManagerInternal#requestMagnificationConnection(boolean)} and
* destroys all window magnifications if necessary.
+ * NOTE: Currently, this is not allowed to call from visible background users.(b/332222893)
*
* @param connect {@code true} if needs connection, otherwise set the connection to null and
* destroy all window magnifications.
* @return {@code true} if {@link IMagnificationConnection} state is going to change.
*/
public boolean requestConnection(boolean connect) {
+ final int callingUserId = getCallingUserId();
+ if (mUserManagerInternal.isVisibleBackgroundFullUser(callingUserId)) {
+ throw new SecurityException("Visible background user(u" + callingUserId
+ + " is not permitted to request magnification connection.");
+ }
if (DBG) {
Slog.d(TAG, "requestConnection :" + connect);
}
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index c9f892907b59..b52c65054e51 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -92,6 +92,7 @@ import com.android.server.autofill.ui.AutoFillUI;
import com.android.server.contentcapture.ContentCaptureManagerInternal;
import com.android.server.infra.AbstractPerUserSystemService;
import com.android.server.inputmethod.InputMethodManagerInternal;
+import com.android.server.pm.UserManagerInternal;
import com.android.server.wm.ActivityTaskManagerInternal;
import java.io.PrintWriter;
@@ -192,6 +193,8 @@ final class AutofillManagerServiceImpl
private final ContentCaptureManagerInternal mContentCaptureManagerInternal;
+ private final UserManagerInternal mUserManagerInternal;
+
private final DisabledInfoCache mDisabledInfoCache;
AutofillManagerServiceImpl(AutofillManagerService master, Object lock,
@@ -208,6 +211,7 @@ final class AutofillManagerServiceImpl
mInputMethodManagerInternal = LocalServices.getService(InputMethodManagerInternal.class);
mContentCaptureManagerInternal = LocalServices.getService(
ContentCaptureManagerInternal.class);
+ mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
mDisabledInfoCache = disableCache;
updateLocked(disabled);
}
@@ -379,6 +383,13 @@ final class AutofillManagerServiceImpl
return 0;
}
+ // TODO(b/376482880): remove this check once autofill service supports visible
+ // background users.
+ if (mUserManagerInternal.isVisibleBackgroundFullUser(mUserId)) {
+ Slog.d(TAG, "Currently, autofill service does not support visible background users.");
+ return 0;
+ }
+
if (!forAugmentedAutofillOnly && isAutofillDisabledLocked(clientActivity)) {
// Standard autofill is enabled, but service disabled autofill for this activity; that
// means no session, unless the activity is allowlisted for augmented autofill
diff --git a/services/core/java/com/android/server/UiModeManagerService.java b/services/core/java/com/android/server/UiModeManagerService.java
index f32031dec43c..f2069d011958 100644
--- a/services/core/java/com/android/server/UiModeManagerService.java
+++ b/services/core/java/com/android/server/UiModeManagerService.java
@@ -427,6 +427,11 @@ final class UiModeManagerService extends SystemService {
mDreamsDisabledByAmbientModeSuppression = disabledByAmbientModeSuppression;
}
+ @VisibleForTesting
+ void setCurrentUser(int currentUserId) {
+ mCurrentUser = currentUserId;
+ }
+
@Override
public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) {
mCurrentUser = to.getUserIdentifier();
@@ -848,9 +853,9 @@ final class UiModeManagerService extends SystemService {
throw new IllegalArgumentException("Unknown mode: " + mode);
}
- final int user = UserHandle.getCallingUserId();
- enforceCurrentUserIfVisibleBackgroundEnabled(user);
+ enforceCurrentUserIfVisibleBackgroundEnabled(mCurrentUser);
+ final int user = UserHandle.getCallingUserId();
final long ident = Binder.clearCallingIdentity();
try {
synchronized (mLock) {
@@ -913,7 +918,7 @@ final class UiModeManagerService extends SystemService {
@AttentionModeThemeOverlayType int attentionModeThemeOverlayType) {
setAttentionModeThemeOverlay_enforcePermission();
- enforceCurrentUserIfVisibleBackgroundEnabled(UserHandle.getCallingUserId());
+ enforceCurrentUserIfVisibleBackgroundEnabled(mCurrentUser);
synchronized (mLock) {
if (mAttentionModeThemeOverlay != attentionModeThemeOverlayType) {
@@ -1004,16 +1009,16 @@ final class UiModeManagerService extends SystemService {
return false;
}
final int user = Binder.getCallingUserHandle().getIdentifier();
- enforceCurrentUserIfVisibleBackgroundEnabled(user);
-
if (user != mCurrentUser && getContext().checkCallingOrSelfPermission(
android.Manifest.permission.INTERACT_ACROSS_USERS)
!= PackageManager.PERMISSION_GRANTED) {
Slog.e(TAG, "Target user is not current user,"
+ " INTERACT_ACROSS_USERS permission is required");
return false;
-
}
+
+ enforceCurrentUserIfVisibleBackgroundEnabled(mCurrentUser);
+
// Store the last requested bedtime night mode state so that we don't need to notify
// anyone if the user decides to switch to the night mode to bedtime.
if (modeCustomType == MODE_NIGHT_CUSTOM_TYPE_BEDTIME) {
@@ -1062,9 +1067,10 @@ final class UiModeManagerService extends SystemService {
Slog.e(TAG, "Set custom time start, requires MODIFY_DAY_NIGHT_MODE permission");
return;
}
- final int user = UserHandle.getCallingUserId();
- enforceCurrentUserIfVisibleBackgroundEnabled(user);
+ enforceCurrentUserIfVisibleBackgroundEnabled(mCurrentUser);
+
+ final int user = UserHandle.getCallingUserId();
final long ident = Binder.clearCallingIdentity();
try {
LocalTime newTime = LocalTime.ofNanoOfDay(time * 1000);
@@ -1092,9 +1098,10 @@ final class UiModeManagerService extends SystemService {
Slog.e(TAG, "Set custom time end, requires MODIFY_DAY_NIGHT_MODE permission");
return;
}
- final int user = UserHandle.getCallingUserId();
- enforceCurrentUserIfVisibleBackgroundEnabled(user);
+ enforceCurrentUserIfVisibleBackgroundEnabled(mCurrentUser);
+
+ final int user = UserHandle.getCallingUserId();
final long ident = Binder.clearCallingIdentity();
try {
LocalTime newTime = LocalTime.ofNanoOfDay(time * 1000);
@@ -1115,7 +1122,7 @@ final class UiModeManagerService extends SystemService {
assertLegit(callingPackage);
assertSingleProjectionType(projectionType);
enforceProjectionTypePermissions(projectionType);
- enforceCurrentUserIfVisibleBackgroundEnabled(getCallingUserId());
+ enforceCurrentUserIfVisibleBackgroundEnabled(mCurrentUser);
synchronized (mLock) {
if (mProjectionHolders == null) {
@@ -1161,7 +1168,7 @@ final class UiModeManagerService extends SystemService {
assertLegit(callingPackage);
assertSingleProjectionType(projectionType);
enforceProjectionTypePermissions(projectionType);
- enforceCurrentUserIfVisibleBackgroundEnabled(getCallingUserId());
+ enforceCurrentUserIfVisibleBackgroundEnabled(mCurrentUser);
return releaseProjectionUnchecked(projectionType, callingPackage);
}
@@ -1203,7 +1210,7 @@ final class UiModeManagerService extends SystemService {
return;
}
- enforceCurrentUserIfVisibleBackgroundEnabled(getCallingUserId());
+ enforceCurrentUserIfVisibleBackgroundEnabled(mCurrentUser);
synchronized (mLock) {
if (mProjectionListeners == null) {
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index 88edb121c0c8..3499a3a5edde 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -1773,8 +1773,7 @@ public class AccountManagerService
// Create a Session for the target user and pass in the bundle
completeCloningAccount(response, result, account, toAccounts, userFrom);
} else {
- // Bundle format is not defined.
- super.onResultSkipSanitization(result);
+ super.onResult(result);
}
}
}.bind();
@@ -1861,8 +1860,7 @@ public class AccountManagerService
// account to avoid retries?
// TODO: what we do with the visibility?
- // Bundle format is not defined.
- super.onResultSkipSanitization(result);
+ super.onResult(result);
}
@Override
@@ -2108,7 +2106,6 @@ public class AccountManagerService
@Override
public void onResult(Bundle result) {
Bundle.setDefusable(result, true);
- result = sanitizeBundle(result);
IAccountManagerResponse response = getResponseAndClose();
if (response != null) {
try {
@@ -2462,7 +2459,6 @@ public class AccountManagerService
@Override
public void onResult(Bundle result) {
Bundle.setDefusable(result, true);
- result = sanitizeBundle(result);
if (result != null && result.containsKey(AccountManager.KEY_BOOLEAN_RESULT)
&& !result.containsKey(AccountManager.KEY_INTENT)) {
final boolean removalAllowed = result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT);
@@ -2977,7 +2973,6 @@ public class AccountManagerService
@Override
public void onResult(Bundle result) {
Bundle.setDefusable(result, true);
- result = sanitizeBundle(result);
if (result != null) {
String label = result.getString(AccountManager.KEY_AUTH_TOKEN_LABEL);
Bundle bundle = new Bundle();
@@ -3155,7 +3150,6 @@ public class AccountManagerService
@Override
public void onResult(Bundle result) {
Bundle.setDefusable(result, true);
- result = sanitizeBundle(result);
if (result != null) {
if (result.containsKey(AccountManager.KEY_AUTH_TOKEN_LABEL)) {
Intent intent = newGrantCredentialsPermissionIntent(
@@ -3627,12 +3621,6 @@ public class AccountManagerService
@Override
public void onResult(Bundle result) {
Bundle.setDefusable(result, true);
- Bundle sessionBundle = null;
- if (result != null) {
- // Session bundle will be removed from result.
- sessionBundle = result.getBundle(AccountManager.KEY_ACCOUNT_SESSION_BUNDLE);
- }
- result = sanitizeBundle(result);
mNumResults++;
Intent intent = null;
if (result != null) {
@@ -3694,6 +3682,7 @@ public class AccountManagerService
// bundle contains data necessary for finishing the session
// later. The session bundle will be encrypted here and
// decrypted later when trying to finish the session.
+ Bundle sessionBundle = result.getBundle(AccountManager.KEY_ACCOUNT_SESSION_BUNDLE);
if (sessionBundle != null) {
String accountType = sessionBundle.getString(AccountManager.KEY_ACCOUNT_TYPE);
if (TextUtils.isEmpty(accountType)
@@ -4081,7 +4070,6 @@ public class AccountManagerService
@Override
public void onResult(Bundle result) {
Bundle.setDefusable(result, true);
- result = sanitizeBundle(result);
IAccountManagerResponse response = getResponseAndClose();
if (response == null) {
return;
@@ -4395,7 +4383,6 @@ public class AccountManagerService
@Override
public void onResult(Bundle result) {
Bundle.setDefusable(result, true);
- result = sanitizeBundle(result);
mNumResults++;
if (result == null) {
onError(AccountManager.ERROR_CODE_INVALID_RESPONSE, "null bundle");
@@ -4952,68 +4939,6 @@ public class AccountManagerService
callback, resultReceiver);
}
-
- // All keys for Strings passed from AbstractAccountAuthenticator using Bundle.
- private static final String[] sStringBundleKeys = new String[] {
- AccountManager.KEY_ACCOUNT_NAME,
- AccountManager.KEY_ACCOUNT_TYPE,
- AccountManager.KEY_AUTHTOKEN,
- AccountManager.KEY_AUTH_TOKEN_LABEL,
- AccountManager.KEY_ERROR_MESSAGE,
- AccountManager.KEY_PASSWORD,
- AccountManager.KEY_ACCOUNT_STATUS_TOKEN};
-
- /**
- * Keep only documented fields in a Bundle received from AbstractAccountAuthenticator.
- */
- protected static Bundle sanitizeBundle(Bundle bundle) {
- if (bundle == null) {
- return null;
- }
- Bundle sanitizedBundle = new Bundle();
- Bundle.setDefusable(sanitizedBundle, true);
- int updatedKeysCount = 0;
- for (String stringKey : sStringBundleKeys) {
- if (bundle.containsKey(stringKey)) {
- String value = bundle.getString(stringKey);
- sanitizedBundle.putString(stringKey, value);
- updatedKeysCount++;
- }
- }
- String key = AbstractAccountAuthenticator.KEY_CUSTOM_TOKEN_EXPIRY;
- if (bundle.containsKey(key)) {
- long expiryMillis = bundle.getLong(key, 0L);
- sanitizedBundle.putLong(key, expiryMillis);
- updatedKeysCount++;
- }
- key = AccountManager.KEY_BOOLEAN_RESULT;
- if (bundle.containsKey(key)) {
- boolean booleanResult = bundle.getBoolean(key, false);
- sanitizedBundle.putBoolean(key, booleanResult);
- updatedKeysCount++;
- }
- key = AccountManager.KEY_ERROR_CODE;
- if (bundle.containsKey(key)) {
- int errorCode = bundle.getInt(key, 0);
- sanitizedBundle.putInt(key, errorCode);
- updatedKeysCount++;
- }
- key = AccountManager.KEY_INTENT;
- if (bundle.containsKey(key)) {
- Intent intent = bundle.getParcelable(key, Intent.class);
- sanitizedBundle.putParcelable(key, intent);
- updatedKeysCount++;
- }
- if (bundle.containsKey(AccountManager.KEY_ACCOUNT_SESSION_BUNDLE)) {
- // The field is not copied in sanitized bundle.
- updatedKeysCount++;
- }
- if (updatedKeysCount != bundle.size()) {
- Log.w(TAG, "Size mismatch after sanitizeBundle call.");
- }
- return sanitizedBundle;
- }
-
private abstract class Session extends IAccountAuthenticatorResponse.Stub
implements IBinder.DeathRecipient, ServiceConnection {
private final Object mSessionLock = new Object();
@@ -5304,15 +5229,10 @@ public class AccountManagerService
}
}
}
+
@Override
public void onResult(Bundle result) {
Bundle.setDefusable(result, true);
- result = sanitizeBundle(result);
- onResultSkipSanitization(result);
- }
-
- public void onResultSkipSanitization(Bundle result) {
- Bundle.setDefusable(result, true);
mNumResults++;
Intent intent = null;
if (result != null) {
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 36665240c16b..f9197e3c5c42 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -5077,7 +5077,10 @@ public final class ActiveServices {
+ " requires " + r.permission);
return new ServiceLookupResult(r.permission);
} else if ((Manifest.permission.BIND_HOTWORD_DETECTION_SERVICE.equals(r.permission)
- || Manifest.permission.BIND_VISUAL_QUERY_DETECTION_SERVICE.equals(r.permission))
+ || Manifest.permission.BIND_VISUAL_QUERY_DETECTION_SERVICE.equals(r.permission)
+ || Manifest.permission.BIND_WEARABLE_SENSING_SERVICE.equals(r.permission)
+ || Manifest.permission.BIND_ON_DEVICE_SANDBOXED_INFERENCE_SERVICE.equals(
+ r.permission))
&& callingUid != Process.SYSTEM_UID) {
// Hotword detection and visual query detection must run in its own sandbox, and we
// don't even trust its enclosing application to bind to it - only the system.
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index f64a16359028..e1909d91a77d 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -1583,8 +1583,11 @@ public class AudioService extends IAudioService.Stub
synchronized (mCachedAbsVolDrivingStreamsLock) {
mCachedAbsVolDrivingStreams.forEach((dev, stream) -> {
- mAudioSystem.setDeviceAbsoluteVolumeEnabled(dev, /*address=*/"", /*enabled=*/true,
- stream);
+ boolean enabled = true;
+ if (dev == AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP) {
+ enabled = mAvrcpAbsVolSupported;
+ }
+ mAudioSystem.setDeviceAbsoluteVolumeEnabled(dev, /*address=*/"", enabled, stream);
});
}
}
@@ -4848,7 +4851,7 @@ public class AudioService extends IAudioService.Stub
if (absDev == AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP) {
enabled = mAvrcpAbsVolSupported;
}
- if (stream != streamType) {
+ if (stream != streamType || !enabled) {
mAudioSystem.setDeviceAbsoluteVolumeEnabled(absDev, /*address=*/"",
enabled, streamType);
}
@@ -10354,10 +10357,10 @@ public class AudioService extends IAudioService.Stub
}
/*package*/ void setAvrcpAbsoluteVolumeSupported(boolean support) {
- mAvrcpAbsVolSupported = support;
- if (absVolumeIndexFix()) {
- int a2dpDev = AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP;
- synchronized (mCachedAbsVolDrivingStreamsLock) {
+ synchronized (mCachedAbsVolDrivingStreamsLock) {
+ mAvrcpAbsVolSupported = support;
+ if (absVolumeIndexFix()) {
+ int a2dpDev = AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP;
mCachedAbsVolDrivingStreams.compute(a2dpDev, (dev, stream) -> {
if (!mAvrcpAbsVolSupported) {
mAudioSystem.setDeviceAbsoluteVolumeEnabled(a2dpDev, /*address=*/
@@ -12420,6 +12423,12 @@ public class AudioService extends IAudioService.Stub
pw.println("\nLoudness alignment:");
mLoudnessCodecHelper.dump(pw);
+ pw.println("\nAbsolute voume devices:");
+ synchronized (mCachedAbsVolDrivingStreamsLock) {
+ mCachedAbsVolDrivingStreams.forEach((dev, stream) -> pw.println(
+ "Device type: 0x" + Integer.toHexString(dev) + ", driving stream " + stream));
+ }
+
mAudioSystem.dump(pw);
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 8a7dabdeceda..cc41b73fb677 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -3389,18 +3389,31 @@ public class PackageManagerService implements PackageSender, TestUtilityService
return true;
}
// Does it contain a device admin for any user?
- int[] users;
+ int[] allUsers = mUserManager.getUserIds();
+ int[] targetUsers;
if (userId == UserHandle.USER_ALL) {
- users = mUserManager.getUserIds();
+ targetUsers = allUsers;
} else {
- users = new int[]{userId};
+ targetUsers = new int[]{userId};
}
- for (int i = 0; i < users.length; ++i) {
- if (dpm.packageHasActiveAdmins(packageName, users[i])) {
+
+ for (int i = 0; i < targetUsers.length; ++i) {
+ if (dpm.packageHasActiveAdmins(packageName, targetUsers[i])) {
return true;
}
- if (isDeviceManagementRoleHolder(packageName, users[i])
- && dpmi.isUserOrganizationManaged(users[i])) {
+ }
+
+ // If a package is DMRH on a managed user, it should also be treated as an admin on
+ // that user. If that package is also a system package, it should also be protected
+ // on other users otherwise "uninstall updates" on an unmanaged user may break
+ // management on other users because apk version is shared between all users.
+ var packageState = snapshotComputer().getPackageStateInternal(packageName);
+ if (packageState == null) {
+ return false;
+ }
+ for (int user : packageState.isSystem() ? allUsers : targetUsers) {
+ if (isDeviceManagementRoleHolder(packageName, user)
+ && dpmi.isUserOrganizationManaged(user)) {
return true;
}
}
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index df9f7fb3d6e5..5fc3e332b95c 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -1015,8 +1015,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
permission, attributionSource, message, forDataDelivery, startDataDelivery,
fromDatasource, attributedOp);
// Finish any started op if some step in the attribution chain failed.
- if (startDataDelivery && result != PermissionChecker.PERMISSION_GRANTED
- && result != PermissionChecker.PERMISSION_SOFT_DENIED) {
+ if (startDataDelivery && result != PermissionChecker.PERMISSION_GRANTED) {
if (attributedOp == AppOpsManager.OP_NONE) {
finishDataDelivery(AppOpsManager.permissionToOpCode(permission),
attributionSource.asState(), fromDatasource);
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 63491e8434bf..e0c4ebeb9f89 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -37,6 +37,7 @@ import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.os.Build.VERSION_CODES.M;
import static android.os.Build.VERSION_CODES.O;
import static android.os.IInputConstants.INVALID_INPUT_DEVICE_ID;
+import static android.os.UserManager.isVisibleBackgroundUsersEnabled;
import static android.provider.Settings.Secure.VOLUME_HUSH_OFF;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;
@@ -184,6 +185,7 @@ import android.service.dreams.IDreamManager;
import android.service.vr.IPersistentVrStateCallbacks;
import android.speech.RecognizerIntent;
import android.telecom.TelecomManager;
+import android.util.ArraySet;
import android.util.Log;
import android.util.MathUtils;
import android.util.MutableBoolean;
@@ -256,6 +258,7 @@ import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
+import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -718,6 +721,25 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// Timeout for showing the keyguard after the screen is on, in case no "ready" is received.
private int mKeyguardDrawnTimeout = 1000;
+ private final boolean mVisibleBackgroundUsersEnabled = isVisibleBackgroundUsersEnabled();
+
+ // Key codes that should be ignored for visible background users in MUMD environment.
+ private static final Set<Integer> KEY_CODES_IGNORED_FOR_VISIBLE_BACKGROUND_USERS =
+ new ArraySet<>(Arrays.asList(
+ KeyEvent.KEYCODE_POWER,
+ KeyEvent.KEYCODE_SLEEP,
+ KeyEvent.KEYCODE_WAKEUP,
+ KeyEvent.KEYCODE_CALL,
+ KeyEvent.KEYCODE_ENDCALL,
+ KeyEvent.KEYCODE_ASSIST,
+ KeyEvent.KEYCODE_VOICE_ASSIST,
+ KeyEvent.KEYCODE_MUTE,
+ KeyEvent.KEYCODE_VOLUME_MUTE,
+ KeyEvent.KEYCODE_RECENT_APPS,
+ KeyEvent.KEYCODE_APP_SWITCH,
+ KeyEvent.KEYCODE_NOTIFICATION
+ ));
+
private static final int MSG_DISPATCH_MEDIA_KEY_WITH_WAKE_LOCK = 3;
private static final int MSG_DISPATCH_MEDIA_KEY_REPEAT_WITH_WAKE_LOCK = 4;
private static final int MSG_KEYGUARD_DRAWN_COMPLETE = 5;
@@ -811,7 +833,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {
event.recycle();
break;
case MSG_HANDLE_ALL_APPS:
- launchAllAppsAction();
+ KeyEvent keyEvent = (KeyEvent) msg.obj;
+ if (isKeyEventForCurrentUser(keyEvent.getDisplayId(), keyEvent.getKeyCode(),
+ "launchAllAppsViaA11y")) {
+ launchAllAppsAction();
+ }
break;
case MSG_RINGER_TOGGLE_CHORD:
handleRingerChordGesture();
@@ -2054,12 +2080,21 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
switch (mDoubleTapOnHomeBehavior) {
case DOUBLE_TAP_HOME_RECENT_SYSTEM_UI:
+ if (!isKeyEventForCurrentUser(
+ event.getDisplayId(), event.getKeyCode(), "toggleRecentApps")) {
+ break;
+ }
notifyKeyGestureCompleted(event,
KeyGestureEvent.KEY_GESTURE_TYPE_APP_SWITCH);
mHomeConsumed = true;
toggleRecentApps();
break;
case DOUBLE_TAP_HOME_PIP_MENU:
+ if (!isKeyEventForCurrentUser(
+ event.getDisplayId(), event.getKeyCode(),
+ "showPictureInPictureMenu")) {
+ break;
+ }
mHomeConsumed = true;
showPictureInPictureMenuInternal();
break;
@@ -2082,15 +2117,26 @@ public class PhoneWindowManager implements WindowManagerPolicy {
switch (mLongPressOnHomeBehavior) {
case LONG_PRESS_HOME_ALL_APPS:
notifyKeyGestureCompleted(event, KeyGestureEvent.KEY_GESTURE_TYPE_ALL_APPS);
- launchAllAppsAction();
+ if (isKeyEventForCurrentUser(event.getDisplayId(), event.getKeyCode(),
+ "launchAllAppsViaA11y")) {
+ launchAllAppsAction();
+ }
break;
case LONG_PRESS_HOME_ASSIST:
+ if (!isKeyEventForCurrentUser(
+ event.getDisplayId(), event.getKeyCode(), "launchAssistAction")) {
+ break;
+ }
notifyKeyGestureCompleted(event,
KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_ASSISTANT);
launchAssistAction(null, event.getDeviceId(), event.getEventTime(),
AssistUtils.INVOCATION_TYPE_HOME_BUTTON_LONG_PRESS);
break;
case LONG_PRESS_HOME_NOTIFICATION_PANEL:
+ if (!isKeyEventForCurrentUser(
+ event.getDisplayId(), event.getKeyCode(), "toggleNotificationPanel")) {
+ break;
+ }
notifyKeyGestureCompleted(event,
KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_NOTIFICATION_PANEL);
toggleNotificationPanel();
@@ -3451,7 +3497,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {
if (isUserSetupComplete() && !keyguardOn) {
if (mModifierShortcutManager.interceptKey(event)) {
- dismissKeyboardShortcutsMenu();
+ if (isKeyEventForCurrentUser(
+ event.getDisplayId(), event.getKeyCode(),
+ "dismissKeyboardShortcutsMenu")) {
+ dismissKeyboardShortcutsMenu();
+ }
mPendingMetaAction = false;
mPendingCapsLockToggle = false;
return true;
@@ -3763,7 +3813,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {
KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_CAPS_LOCK);
} else if (mPendingMetaAction) {
if (!canceled) {
- launchAllAppsAction();
+ if (isKeyEventForCurrentUser(event.getDisplayId(), event.getKeyCode(),
+ "launchAllAppsViaA11y")) {
+ launchAllAppsAction();
+ }
notifyKeyGestureCompleted(event,
KeyGestureEvent.KEY_GESTURE_TYPE_ALL_APPS);
}
@@ -4030,7 +4083,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
return true;
case KeyGestureEvent.KEY_GESTURE_TYPE_ALL_APPS:
case KeyGestureEvent.KEY_GESTURE_TYPE_ACCESSIBILITY_ALL_APPS:
- if (complete) {
+ if (complete && isKeyEventForCurrentUser(event.getDisplayId(),
+ event.getKeycodes()[0], "launchAllAppsViaA11y")) {
launchAllAppsAction();
}
return true;
@@ -4703,7 +4757,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
// no keyguard stuff to worry about, just launch home!
- if (mRecentsVisible) {
+ // If Recents is visible and the action is not from visible background users,
+ // hide Recents and notify it to launch Home.
+ if (mRecentsVisible
+ && (!mVisibleBackgroundUsersEnabled || displayId == DEFAULT_DISPLAY)) {
try {
ActivityManager.getService().stopAppSwitches();
} catch (RemoteException e) {}
@@ -4859,6 +4916,14 @@ public class PhoneWindowManager implements WindowManagerPolicy {
boolean isWakeKey = (policyFlags & WindowManagerPolicy.FLAG_WAKE) != 0
|| event.isWakeKey();
+ // There are key events that perform the operation as the current user,
+ // and these should be ignored for visible background users.
+ if (mVisibleBackgroundUsersEnabled
+ && KEY_CODES_IGNORED_FOR_VISIBLE_BACKGROUND_USERS.contains(keyCode)
+ && !isKeyEventForCurrentUser(event.getDisplayId(), keyCode, null)) {
+ return 0;
+ }
+
if (!mSystemBooted) {
// If we have not yet booted, don't let key events do anything.
// Exception: Wake and power key events are forwarded to PowerManager to allow it to
@@ -5439,6 +5504,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
* Notify the StatusBar that a system key was pressed.
*/
private void sendSystemKeyToStatusBar(KeyEvent key) {
+ if (!isKeyEventForCurrentUser(key.getDisplayId(), key.getKeyCode(), "handleSystemKey")) {
+ return;
+ }
IStatusBarService statusBar = getStatusBarService();
if (statusBar != null) {
try {
@@ -5866,6 +5934,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
private void wakeUpFromWakeKey(KeyEvent event) {
+ if (!isKeyEventForCurrentUser(
+ event.getDisplayId(), event.getKeyCode(), "wakeUpFromWakeKey")) {
+ return;
+ }
wakeUpFromWakeKey(
event.getEventTime(),
event.getKeyCode(),
@@ -6445,6 +6517,12 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// TODO (b/113840485): Move this logic to DisplayPolicy when lockscreen supports multi-display.
@Override
public void setAllowLockscreenWhenOn(int displayId, boolean allow) {
+ // We should ignore this operation for visible background users
+ // until lockscreen supports multi-display.
+ if (mVisibleBackgroundUsersEnabled
+ && mUserManagerInternal.getUserAssignedToDisplay(displayId) != mCurrentUserId) {
+ return;
+ }
if (allow) {
mAllowLockscreenWhenOnDisplays.add(displayId);
} else {
@@ -7253,4 +7331,29 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
return DEFAULT_DISPLAY;
}
+
+ /**
+ * This method is intended to prevent key events for visible background users
+ * from interfering with the current user's experience in MUMD environment.
+ *
+ * @param displayId the displayId of the key event.
+ * @param keyCode the key code of the event.
+ *
+ * @return false if the key event is for a visible background user.
+ */
+ private boolean isKeyEventForCurrentUser(int displayId, int keyCode, @Nullable String purpose) {
+ if (!mVisibleBackgroundUsersEnabled) {
+ return true;
+ }
+ int assignedUser = mUserManagerInternal.getUserAssignedToDisplay(displayId);
+ if (assignedUser == mCurrentUserId) {
+ return true;
+ }
+ if (DEBUG_INPUT) {
+ Slog.w(TAG, "Cannot handle " + KeyEvent.keyCodeToString(keyCode)
+ + (purpose != null ? " to " + purpose : "")
+ + " for visible background user(u" + assignedUser + ")");
+ }
+ return false;
+ }
}
diff --git a/services/core/java/com/android/server/search/SearchManagerService.java b/services/core/java/com/android/server/search/SearchManagerService.java
index 9b39fa1e177c..a49a9fdf4cca 100644
--- a/services/core/java/com/android/server/search/SearchManagerService.java
+++ b/services/core/java/com/android/server/search/SearchManagerService.java
@@ -46,6 +46,7 @@ import com.android.internal.util.IndentingPrintWriter;
import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.SystemService.TargetUser;
+import com.android.server.pm.UserManagerInternal;
import com.android.server.statusbar.StatusBarManagerInternal;
import java.io.FileDescriptor;
@@ -89,6 +90,8 @@ public class SearchManagerService extends ISearchManager.Stub {
@GuardedBy("mSearchables")
private final SparseArray<Searchables> mSearchables = new SparseArray<>();
+ private final UserManagerInternal mUserManagerInternal;
+
/**
* Initializes the Search Manager service in the provided system context.
* Only one instance of this object should be created!
@@ -101,6 +104,7 @@ public class SearchManagerService extends ISearchManager.Stub {
mMyPackageMonitor.register(context, null, UserHandle.ALL, true);
new GlobalSearchProviderObserver(context.getContentResolver());
mHandler = BackgroundThread.getHandler();
+ mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
}
private Searchables getSearchables(int userId) {
@@ -336,6 +340,14 @@ public class SearchManagerService extends ISearchManager.Stub {
@Override
public void launchAssist(int userHandle, Bundle args) {
+ // Currently, visible background users are not allowed to launch assist.(b/332222893)
+ // TODO(b/368715893): Consider indirect calls from system service when checking the
+ // calling user.
+ final int callingUserId = UserHandle.getCallingUserId();
+ if (mUserManagerInternal.isVisibleBackgroundFullUser(callingUserId)) {
+ throw new SecurityException("Visible background user(u" + callingUserId
+ + ") is not permitted to launch assist.");
+ }
StatusBarManagerInternal statusBarManager =
LocalServices.getService(StatusBarManagerInternal.class);
if (statusBarManager != null) {
diff --git a/services/core/java/com/android/server/vibrator/VibrationSettings.java b/services/core/java/com/android/server/vibrator/VibrationSettings.java
index b8840790a816..102306fa3c42 100644
--- a/services/core/java/com/android/server/vibrator/VibrationSettings.java
+++ b/services/core/java/com/android/server/vibrator/VibrationSettings.java
@@ -31,6 +31,7 @@ import static android.os.VibrationAttributes.USAGE_UNKNOWN;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
+import android.app.IActivityManager;
import android.app.SynchronousUserSwitchObserver;
import android.app.UidObserver;
import android.content.BroadcastReceiver;
@@ -74,6 +75,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
+import java.util.Objects;
import java.util.Set;
/** Controls all the system settings related to vibration. */
@@ -147,9 +149,6 @@ final class VibrationSettings {
PowerManager.GO_TO_SLEEP_REASON_INATTENTIVE,
PowerManager.GO_TO_SLEEP_REASON_TIMEOUT));
- private static final IntentFilter INTERNAL_RINGER_MODE_CHANGED_INTENT_FILTER =
- new IntentFilter(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION);
-
/** Listener for changes on vibration settings. */
interface OnVibratorSettingsChanged {
/** Callback triggered when any of the vibrator settings change. */
@@ -158,15 +157,18 @@ final class VibrationSettings {
private final Object mLock = new Object();
private final Context mContext;
- private final String mSystemUiPackage;
@VisibleForTesting
final SettingsContentObserver mSettingObserver;
@VisibleForTesting
- final SettingsBroadcastReceiver mSettingChangeReceiver;
+ final RingerModeBroadcastReceiver mRingerModeBroadcastReceiver;
+ @VisibleForTesting
+ final BatteryBroadcastReceiver mBatteryBroadcastReceiver;
@VisibleForTesting
final VibrationUidObserver mUidObserver;
@VisibleForTesting
final VibrationUserSwitchObserver mUserSwitchObserver;
+ @VisibleForTesting
+ final VibrationLowPowerModeListener mLowPowerModeListener;
@GuardedBy("mLock")
private final List<OnVibratorSettingsChanged> mListeners = new ArrayList<>();
@@ -180,10 +182,13 @@ final class VibrationSettings {
@GuardedBy("mLock")
@Nullable
private PowerManagerInternal mPowerManagerInternal;
+ @GuardedBy("mLock")
@Nullable
private VirtualDeviceManagerInternal mVirtualDeviceManagerInternal;
@GuardedBy("mLock")
+ private String mSystemUiPackage;
+ @GuardedBy("mLock")
private boolean mVibrateInputDevices;
@GuardedBy("mLock")
private SparseIntArray mCurrentVibrationIntensities = new SparseIntArray();
@@ -205,11 +210,11 @@ final class VibrationSettings {
mContext = context;
mVibrationConfig = config;
mSettingObserver = new SettingsContentObserver(handler);
- mSettingChangeReceiver = new SettingsBroadcastReceiver();
+ mRingerModeBroadcastReceiver = new RingerModeBroadcastReceiver();
+ mBatteryBroadcastReceiver = new BatteryBroadcastReceiver();
mUidObserver = new VibrationUidObserver();
mUserSwitchObserver = new VibrationUserSwitchObserver();
- mSystemUiPackage = LocalServices.getService(PackageManagerInternal.class)
- .getSystemUiServiceComponent().getPackageName();
+ mLowPowerModeListener = new VibrationLowPowerModeListener();
VibrationEffect clickEffect = createEffectFromResource(
com.android.internal.R.array.config_virtualKeyVibePattern);
@@ -233,18 +238,34 @@ final class VibrationSettings {
}
public void onSystemReady() {
- PowerManagerInternal pm = LocalServices.getService(PowerManagerInternal.class);
- AudioManager am = mContext.getSystemService(AudioManager.class);
- int ringerMode = (am == null) ? mRingerMode : am.getRingerModeInternal();
+ onSystemReady(LocalServices.getService(PackageManagerInternal.class),
+ LocalServices.getService(PowerManagerInternal.class),
+ ActivityManager.getService(),
+ LocalServices.getService(VirtualDeviceManagerInternal.class),
+ mContext.getSystemService(AudioManager.class));
+ }
+
+ @VisibleForTesting
+ void onSystemReady(PackageManagerInternal packageManagerInternal,
+ PowerManagerInternal powerManagerInternal,
+ IActivityManager activityManagerInternal,
+ @Nullable VirtualDeviceManagerInternal virtualDeviceManagerInternal,
+ @Nullable AudioManager audioManager) {
+ int ringerMode = (audioManager == null)
+ ? AudioManager.RINGER_MODE_NORMAL
+ : audioManager.getRingerModeInternal();
+ String sysUiPackage = packageManagerInternal.getSystemUiServiceComponent().getPackageName();
synchronized (mLock) {
- mPowerManagerInternal = pm;
- mAudioManager = am;
+ mPowerManagerInternal = powerManagerInternal;
+ mVirtualDeviceManagerInternal = virtualDeviceManagerInternal;
+ mAudioManager = audioManager;
mRingerMode = ringerMode;
+ mSystemUiPackage = sysUiPackage;
}
try {
- ActivityManager.getService().registerUidObserver(mUidObserver,
+ activityManagerInternal.registerUidObserver(mUidObserver,
ActivityManager.UID_OBSERVER_PROCSTATE | ActivityManager.UID_OBSERVER_GONE,
ActivityManager.PROCESS_STATE_UNKNOWN, /* callingPackage= */ null);
} catch (RemoteException e) {
@@ -252,32 +273,16 @@ final class VibrationSettings {
}
try {
- ActivityManager.getService().registerUserSwitchObserver(mUserSwitchObserver, TAG);
+ activityManagerInternal.registerUserSwitchObserver(mUserSwitchObserver, TAG);
} catch (RemoteException e) {
// ignored; both services live in system_server
}
- pm.registerLowPowerModeObserver(
- new PowerManagerInternal.LowPowerModeListener() {
- @Override
- public int getServiceType() {
- return PowerManager.ServiceType.VIBRATION;
- }
-
- @Override
- public void onLowPowerModeChanged(PowerSaveState result) {
- boolean shouldNotifyListeners;
- synchronized (mLock) {
- shouldNotifyListeners = result.batterySaverEnabled != mBatterySaverMode;
- mBatterySaverMode = result.batterySaverEnabled;
- }
- if (shouldNotifyListeners) {
- notifyListeners();
- }
- }
- });
-
- registerSettingsChangeReceiver(INTERNAL_RINGER_MODE_CHANGED_INTENT_FILTER);
+ powerManagerInternal.registerLowPowerModeObserver(mLowPowerModeListener);
+
+ mContext.registerReceiver(mRingerModeBroadcastReceiver,
+ new IntentFilter(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION),
+ Context.RECEIVER_EXPORTED_UNAUDITED);
// Listen to all settings that might affect the result of Vibrator.getVibrationIntensity.
registerSettingsObserver(Settings.System.getUriFor(Settings.System.VIBRATE_INPUT_DEVICES));
@@ -301,12 +306,7 @@ final class VibrationSettings {
if (mVibrationConfig.ignoreVibrationsOnWirelessCharger()) {
Intent batteryStatus = mContext.registerReceiver(
- new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- updateBatteryInfo(intent);
- }
- },
+ mBatteryBroadcastReceiver,
new IntentFilter(Intent.ACTION_BATTERY_CHANGED),
Context.RECEIVER_NOT_EXPORTED);
// After registering the receiver for battery status, process the sticky broadcast that
@@ -476,8 +476,10 @@ final class VibrationSettings {
public boolean shouldCancelVibrationOnScreenOff(@NonNull CallerInfo callerInfo,
long vibrationStartUptimeMillis) {
PowerManagerInternal pm;
+ String sysUiPackageName;
synchronized (mLock) {
pm = mPowerManagerInternal;
+ sysUiPackageName = mSystemUiPackage;
}
if (pm != null) {
// The SleepData from PowerManager may refer to a more recent sleep than the broadcast
@@ -501,7 +503,7 @@ final class VibrationSettings {
}
// Only allow vibrations from System packages to continue vibrating when the screen goes off
return callerInfo.uid != Process.SYSTEM_UID && callerInfo.uid != 0
- && !mSystemUiPackage.equals(callerInfo.opPkg);
+ && !Objects.equals(sysUiPackageName, callerInfo.opPkg);
}
/**
@@ -782,11 +784,6 @@ final class VibrationSettings {
UserHandle.USER_ALL);
}
- private void registerSettingsChangeReceiver(IntentFilter intentFilter) {
- mContext.registerReceiver(mSettingChangeReceiver, intentFilter,
- Context.RECEIVER_EXPORTED_UNAUDITED);
- }
-
@Nullable
private VibrationEffect createEffectFromResource(int resId) {
return createEffectFromResource(mContext.getResources(), resId);
@@ -833,12 +830,11 @@ final class VibrationSettings {
}
private boolean isAppRunningOnAnyVirtualDevice(int uid) {
- if (mVirtualDeviceManagerInternal == null) {
- mVirtualDeviceManagerInternal =
- LocalServices.getService(VirtualDeviceManagerInternal.class);
+ VirtualDeviceManagerInternal vdm;
+ synchronized (mLock) {
+ vdm = mVirtualDeviceManagerInternal;
}
- return mVirtualDeviceManagerInternal != null
- && mVirtualDeviceManagerInternal.isAppRunningOnAnyVirtualDevice(uid);
+ return vdm != null && vdm.isAppRunningOnAnyVirtualDevice(uid);
}
/** Implementation of {@link ContentObserver} to be registered to a setting {@link Uri}. */
@@ -857,7 +853,7 @@ final class VibrationSettings {
/** Implementation of {@link BroadcastReceiver} to update on ringer mode change. */
@VisibleForTesting
- final class SettingsBroadcastReceiver extends BroadcastReceiver {
+ final class RingerModeBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
@@ -868,6 +864,18 @@ final class VibrationSettings {
}
}
+ /** Implementation of {@link BroadcastReceiver} to update on battery mode change. */
+ @VisibleForTesting
+ final class BatteryBroadcastReceiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ if (Intent.ACTION_BATTERY_CHANGED.equals(action)) {
+ updateBatteryInfo(intent);
+ }
+ }
+ }
+
/** Implementation of {@link ContentObserver} to be registered to a setting {@link Uri}. */
@VisibleForTesting
final class VibrationUidObserver extends UidObserver {
@@ -913,4 +921,25 @@ final class VibrationSettings {
update();
}
}
+
+ /** Implementation of {@link PowerManagerInternal.LowPowerModeListener} for low battery. */
+ @VisibleForTesting
+ final class VibrationLowPowerModeListener implements PowerManagerInternal.LowPowerModeListener {
+ @Override
+ public int getServiceType() {
+ return PowerManager.ServiceType.VIBRATION;
+ }
+
+ @Override
+ public void onLowPowerModeChanged(PowerSaveState result) {
+ boolean shouldNotifyListeners;
+ synchronized (mLock) {
+ shouldNotifyListeners = result.batterySaverEnabled != mBatterySaverMode;
+ mBatterySaverMode = result.batterySaverEnabled;
+ }
+ if (shouldNotifyListeners) {
+ notifyListeners();
+ }
+ }
+ }
}
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index de0ec30fb9e8..96b924336881 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -5863,6 +5863,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
return;
}
+ final State prevState = mState;
mState = state;
if (getTaskFragment() != null) {
@@ -5903,6 +5904,14 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
mAtmService.updateBatteryStats(this, false);
mAtmService.updateActivityUsageStats(this, Event.ACTIVITY_PAUSED);
break;
+ case STOPPING:
+ // It is possible that an Activity is scheduled to be STOPPED directly from RESUMED
+ // state. Updating the PAUSED usage state in that case, since the Activity will be
+ // STOPPED while cycled through the PAUSED state.
+ if (prevState == RESUMED) {
+ mAtmService.updateActivityUsageStats(this, Event.ACTIVITY_PAUSED);
+ }
+ break;
case STOPPED:
mAtmService.updateActivityUsageStats(this, Event.ACTIVITY_STOPPED);
if (mDisplayContent != null) {
diff --git a/services/core/java/com/android/server/wm/ConfigurationContainer.java b/services/core/java/com/android/server/wm/ConfigurationContainer.java
index 670a61dca5c8..05dcbb7f9af4 100644
--- a/services/core/java/com/android/server/wm/ConfigurationContainer.java
+++ b/services/core/java/com/android/server/wm/ConfigurationContainer.java
@@ -25,6 +25,7 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.app.WindowConfiguration.ROTATION_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.app.WindowConfiguration.activityTypeToString;
@@ -268,7 +269,16 @@ public abstract class ConfigurationContainer<E extends ConfigurationContainer> {
}
final DisplayPolicy.DecorInsets.Info decor =
displayContent.getDisplayPolicy().getDecorInsetsInfo(rotation, dw, dh);
- outAppBounds.intersectUnchecked(decor.mOverrideNonDecorFrame);
+ if (!outAppBounds.intersect(decor.mOverrideNonDecorFrame)) {
+ // TODO (b/364883053): When a split screen is requested from an app intent for a new
+ // task, the bounds is not the final bounds, and this is also not a bounds change
+ // event handled correctly with the offset. Revert back to legacy method for this
+ // case.
+ if (inOutConfig.windowConfiguration.getWindowingMode()
+ == WINDOWING_MODE_MULTI_WINDOW) {
+ outAppBounds.inset(decor.mOverrideNonDecorInsets);
+ }
+ }
if (task != null && (task.mOffsetYForInsets != 0 || task.mOffsetXForInsets != 0)) {
outAppBounds.offset(-task.mOffsetXForInsets, -task.mOffsetYForInsets);
}
diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
index 57b879277326..d3cae4c7b940 100644
--- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
@@ -400,7 +400,7 @@ class InsetsSourceProvider {
}
final Point position = getWindowFrameSurfacePosition();
if (!mPosition.equals(position)) {
- mPosition.set(position.x, position.y);
+ mPosition.set(position);
if (windowState != null && windowState.getWindowFrames().didFrameSizeChange()
&& windowState.mWinAnimator.getShown() && mWindowContainer.okToDisplay()) {
windowState.applyWithNextDraw(mSetControlPositionConsumer);
@@ -543,6 +543,7 @@ class InsetsSourceProvider {
}
boolean initiallyVisible = mClientVisible;
final Point surfacePosition = getWindowFrameSurfacePosition();
+ mPosition.set(surfacePosition);
mAdapter = new ControlAdapter(surfacePosition);
if (mSource.getType() == WindowInsets.Type.ime()) {
if (android.view.inputmethod.Flags.refactorInsetsController()) {
diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java
index d042b3859c3e..dd5f6134e2eb 100644
--- a/services/core/java/com/android/server/wm/Transition.java
+++ b/services/core/java/com/android/server/wm/Transition.java
@@ -1385,7 +1385,16 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
// Commit wallpaper visibility after activity, because usually the wallpaper target token is
// an activity, and wallpaper's visibility depends on activity's visibility.
for (int i = mParticipants.size() - 1; i >= 0; --i) {
- final WallpaperWindowToken wt = mParticipants.valueAt(i).asWallpaperToken();
+ final WindowContainer<?> wc = mParticipants.valueAt(i);
+ WallpaperWindowToken wt = wc.asWallpaperToken();
+ if (!Flags.ensureWallpaperInTransitions()) {
+ if (wt == null) {
+ final WindowState windowState = wc.asWindowState();
+ if (windowState != null) {
+ wt = windowState.mToken.asWallpaperToken();
+ }
+ }
+ }
if (wt == null) continue;
final WindowState target = wt.mDisplayContent.mWallpaperController.getWallpaperTarget();
final boolean isTargetInvisible = target == null || !target.mToken.isVisible();
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationConnectionManagerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationConnectionManagerTest.java
index 87fe6cf8f283..6d27dddfc357 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationConnectionManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationConnectionManagerTest.java
@@ -62,6 +62,7 @@ import androidx.test.filters.FlakyTest;
import com.android.internal.util.test.FakeSettingsProvider;
import com.android.server.LocalServices;
import com.android.server.accessibility.AccessibilityTraceManager;
+import com.android.server.pm.UserManagerInternal;
import com.android.server.statusbar.StatusBarManagerInternal;
import org.junit.Before;
@@ -92,12 +93,16 @@ public class MagnificationConnectionManagerTest {
private MagnificationConnectionManager.Callback mMockCallback;
private MockContentResolver mResolver;
private MagnificationConnectionManager mMagnificationConnectionManager;
+ @Mock
+ private UserManagerInternal mMockUserManagerInternal;
@Before
public void setUp() throws RemoteException {
MockitoAnnotations.initMocks(this);
LocalServices.removeServiceForTest(StatusBarManagerInternal.class);
+ LocalServices.removeServiceForTest(UserManagerInternal.class);
LocalServices.addService(StatusBarManagerInternal.class, mMockStatusBarManagerInternal);
+ LocalServices.addService(UserManagerInternal.class, mMockUserManagerInternal);
mResolver = new MockContentResolver();
mMockConnection = new MockMagnificationConnection();
mMagnificationConnectionManager = new MagnificationConnectionManager(mContext, new Object(),
@@ -110,6 +115,8 @@ public class MagnificationConnectionManagerTest {
Settings.Secure.putFloatForUser(mResolver,
Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE, 2.5f,
CURRENT_USER_ID);
+
+ when(mMockUserManagerInternal.isVisibleBackgroundFullUser(anyInt())).thenReturn(false);
}
private void stubSetConnection(boolean needDelay) {
diff --git a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
index b9ce8ad0b018..0c92abce7254 100644
--- a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
@@ -1163,6 +1163,16 @@ public class AccountManagerServiceTest extends AndroidTestCase {
verify(mMockAccountManagerResponse).onResult(mBundleCaptor.capture());
Bundle result = mBundleCaptor.getValue();
+ Bundle sessionBundle = result.getBundle(AccountManager.KEY_ACCOUNT_SESSION_BUNDLE);
+ assertNotNull(sessionBundle);
+ // Assert that session bundle is decrypted and hence data is visible.
+ assertEquals(AccountManagerServiceTestFixtures.SESSION_DATA_VALUE_1,
+ sessionBundle.getString(AccountManagerServiceTestFixtures.SESSION_DATA_NAME_1));
+ // Assert finishSessionAsUser added calling uid and pid into the sessionBundle
+ assertTrue(sessionBundle.containsKey(AccountManager.KEY_CALLER_UID));
+ assertTrue(sessionBundle.containsKey(AccountManager.KEY_CALLER_PID));
+ assertEquals(sessionBundle.getString(
+ AccountManager.KEY_ANDROID_PACKAGE_NAME), "APCT.package");
// Verify response data
assertNull(result.getString(AccountManager.KEY_AUTHTOKEN, null));
@@ -2111,6 +2121,12 @@ public class AccountManagerServiceTest extends AndroidTestCase {
result.getString(AccountManager.KEY_ACCOUNT_NAME));
assertEquals(AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1,
result.getString(AccountManager.KEY_ACCOUNT_TYPE));
+
+ Bundle optionBundle = result.getParcelable(
+ AccountManagerServiceTestFixtures.KEY_OPTIONS_BUNDLE);
+ // Assert addAccountAsUser added calling uid and pid into the option bundle
+ assertTrue(optionBundle.containsKey(AccountManager.KEY_CALLER_UID));
+ assertTrue(optionBundle.containsKey(AccountManager.KEY_CALLER_PID));
}
@SmallTest
@@ -3441,52 +3457,6 @@ public class AccountManagerServiceTest extends AndroidTestCase {
+ (readTotalTime.doubleValue() / readerCount / loopSize));
}
- @SmallTest
- public void testSanitizeBundle_expectedFields() throws Exception {
- Bundle bundle = new Bundle();
- bundle.putString(AccountManager.KEY_ACCOUNT_NAME, "name");
- bundle.putString(AccountManager.KEY_ACCOUNT_TYPE, "type");
- bundle.putString(AccountManager.KEY_AUTHTOKEN, "token");
- bundle.putString(AccountManager.KEY_AUTH_TOKEN_LABEL, "label");
- bundle.putString(AccountManager.KEY_ERROR_MESSAGE, "error message");
- bundle.putString(AccountManager.KEY_PASSWORD, "password");
- bundle.putString(AccountManager.KEY_ACCOUNT_STATUS_TOKEN, "status");
-
- bundle.putLong(AbstractAccountAuthenticator.KEY_CUSTOM_TOKEN_EXPIRY, 123L);
- bundle.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, true);
- bundle.putInt(AccountManager.KEY_ERROR_CODE, 456);
-
- Bundle sanitizedBundle = AccountManagerService.sanitizeBundle(bundle);
- assertEquals(sanitizedBundle.getString(AccountManager.KEY_ACCOUNT_NAME), "name");
- assertEquals(sanitizedBundle.getString(AccountManager.KEY_ACCOUNT_TYPE), "type");
- assertEquals(sanitizedBundle.getString(AccountManager.KEY_AUTHTOKEN), "token");
- assertEquals(sanitizedBundle.getString(AccountManager.KEY_AUTH_TOKEN_LABEL), "label");
- assertEquals(sanitizedBundle.getString(AccountManager.KEY_ERROR_MESSAGE), "error message");
- assertEquals(sanitizedBundle.getString(AccountManager.KEY_PASSWORD), "password");
- assertEquals(sanitizedBundle.getString(AccountManager.KEY_ACCOUNT_STATUS_TOKEN), "status");
-
- assertEquals(sanitizedBundle.getLong(
- AbstractAccountAuthenticator.KEY_CUSTOM_TOKEN_EXPIRY, 0), 123L);
- assertEquals(sanitizedBundle.getBoolean(AccountManager.KEY_BOOLEAN_RESULT, false), true);
- assertEquals(sanitizedBundle.getInt(AccountManager.KEY_ERROR_CODE, 0), 456);
- }
-
- @SmallTest
- public void testSanitizeBundle_filtersUnexpectedFields() throws Exception {
- Bundle bundle = new Bundle();
- bundle.putString(AccountManager.KEY_ACCOUNT_NAME, "name");
- bundle.putString("unknown_key", "value");
- Bundle sessionBundle = new Bundle();
- bundle.putBundle(AccountManager.KEY_ACCOUNT_SESSION_BUNDLE, sessionBundle);
-
- Bundle sanitizedBundle = AccountManagerService.sanitizeBundle(bundle);
-
- assertEquals(sanitizedBundle.getString(AccountManager.KEY_ACCOUNT_NAME), "name");
- assertFalse(sanitizedBundle.containsKey("unknown_key"));
- // It is a valid response from Authenticator which will be accessed using original Bundle
- assertFalse(sanitizedBundle.containsKey(AccountManager.KEY_ACCOUNT_SESSION_BUNDLE));
- }
-
private void waitForCyclicBarrier(CyclicBarrier cyclicBarrier) {
try {
cyclicBarrier.await(LATCH_TIMEOUT_MS, TimeUnit.MILLISECONDS);
diff --git a/services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java
index c247c08c8010..3b0cb4ad8779 100644
--- a/services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java
@@ -68,6 +68,7 @@ import static org.testng.Assert.assertThrows;
import android.Manifest;
import android.app.Activity;
+import android.app.ActivityManager;
import android.app.AlarmManager;
import android.app.Flags;
import android.app.IOnProjectionStateChangedListener;
@@ -247,6 +248,8 @@ public class UiModeManagerServiceTest extends UiServiceTestCase {
mInjector = spy(new TestInjector());
mUiManagerService = new UiModeManagerService(mContext, /* setupWizardComplete= */ true,
mTwilightManager, mInjector);
+ // Initialize the current user.
+ mUiManagerService.setCurrentUser(ActivityManager.getCurrentUser());
try {
mUiManagerService.onBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);
} catch (SecurityException e) {/* ignore for permission denial */}
diff --git a/services/tests/vibrator/src/com/android/server/vibrator/VibrationSettingsTest.java b/services/tests/vibrator/src/com/android/server/vibrator/VibrationSettingsTest.java
index 492f108cd79f..e4a6efdd5304 100644
--- a/services/tests/vibrator/src/com/android/server/vibrator/VibrationSettingsTest.java
+++ b/services/tests/vibrator/src/com/android/server/vibrator/VibrationSettingsTest.java
@@ -44,7 +44,8 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -52,12 +53,14 @@ import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
import android.app.ActivityManager;
+import android.app.IActivityManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
+import android.content.IntentFilter;
import android.content.pm.PackageManagerInternal;
import android.media.AudioManager;
import android.os.Handler;
@@ -79,12 +82,10 @@ import androidx.test.InstrumentationRegistry;
import com.android.internal.util.test.FakeSettingsProvider;
import com.android.internal.util.test.FakeSettingsProviderRule;
-import com.android.server.LocalServices;
import com.android.server.companion.virtual.VirtualDeviceManagerInternal;
import com.android.server.vibrator.VibrationSession.CallerInfo;
import com.android.server.vibrator.VibrationSession.Status;
-import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -101,8 +102,7 @@ public class VibrationSettingsTest {
@Rule
public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
- private static final int OLD_USER_ID = 123;
- private static final int NEW_USER_ID = 456;
+ private static final int USER_ID = 123;
private static final int UID = 1;
private static final int VIRTUAL_DEVICE_ID = 1;
private static final String SYSUI_PACKAGE_NAME = "sysui";
@@ -132,13 +132,12 @@ public class VibrationSettingsTest {
@Mock private VirtualDeviceManagerInternal mVirtualDeviceManagerInternalMock;
@Mock private PackageManagerInternal mPackageManagerInternalMock;
@Mock private AudioManager mAudioManagerMock;
+ @Mock private IActivityManager mActivityManagerMock;
@Mock private VibrationConfig mVibrationConfigMock;
private TestLooper mTestLooper;
private ContextWrapper mContextSpy;
private VibrationSettings mVibrationSettings;
- private PowerManagerInternal.LowPowerModeListener mRegisteredPowerModeListener;
- private BroadcastReceiver mRegisteredBatteryBroadcastReceiver;
@Before
public void setUp() throws Exception {
@@ -146,24 +145,20 @@ public class VibrationSettingsTest {
mContextSpy = spy(new ContextWrapper(InstrumentationRegistry.getContext()));
ContentResolver contentResolver = mSettingsProviderRule.mockContentResolver(mContextSpy);
- when(mContextSpy.getContentResolver()).thenReturn(contentResolver);
- when(mContextSpy.getSystemService(eq(Context.AUDIO_SERVICE))).thenReturn(mAudioManagerMock);
- doAnswer(invocation -> {
- mRegisteredPowerModeListener = invocation.getArgument(0);
- return null;
- }).when(mPowerManagerInternalMock).registerLowPowerModeObserver(any());
+ doReturn(contentResolver).when(mContextSpy).getContentResolver();
+
+ // Make sure broadcast receivers are not registered for this test, to avoid flakes.
+ doReturn(null).when(mContextSpy)
+ .registerReceiver(any(BroadcastReceiver.class), any(IntentFilter.class), anyInt());
when(mPackageManagerInternalMock.getSystemUiServiceComponent())
.thenReturn(new ComponentName(SYSUI_PACKAGE_NAME, ""));
- removeServicesForTest();
- addServicesForTest();
-
setDefaultIntensity(VIBRATION_INTENSITY_MEDIUM);
setIgnoreVibrationsOnWirelessCharger(false);
- createSystemReadyVibrationSettings();
mockGoToSleep(/* goToSleepTime= */ 0, PowerManager.GO_TO_SLEEP_REASON_TIMEOUT);
+ createSystemReadyVibrationSettings();
}
private void createSystemReadyVibrationSettings() {
@@ -177,38 +172,18 @@ public class VibrationSettingsTest {
setUserSetting(Settings.System.APPLY_RAMPING_RINGER, 0);
setRingerMode(AudioManager.RINGER_MODE_NORMAL);
- mVibrationSettings.onSystemReady();
- }
-
- private void removeServicesForTest() {
- LocalServices.removeServiceForTest(PowerManagerInternal.class);
- LocalServices.removeServiceForTest(PackageManagerInternal.class);
- LocalServices.removeServiceForTest(VirtualDeviceManagerInternal.class);
- }
-
- private void addServicesForTest() {
- LocalServices.addService(PowerManagerInternal.class, mPowerManagerInternalMock);
- LocalServices.addService(PackageManagerInternal.class, mPackageManagerInternalMock);
- LocalServices.addService(VirtualDeviceManagerInternal.class,
- mVirtualDeviceManagerInternalMock);
- }
-
- @After
- public void tearDown() throws Exception {
- removeServicesForTest();
+ mVibrationSettings.onSystemReady(mPackageManagerInternalMock, mPowerManagerInternalMock,
+ mActivityManagerMock, mVirtualDeviceManagerInternalMock, mAudioManagerMock);
}
@Test
public void create_withOnlyRequiredSystemServices() {
- // The only core services that we depend on are PowerManager and PackageManager
- removeServicesForTest();
- LocalServices.addService(PowerManagerInternal.class, mPowerManagerInternalMock);
- LocalServices.addService(PackageManagerInternal.class, mPackageManagerInternalMock);
- when(mContextSpy.getSystemService(eq(Context.AUDIO_SERVICE))).thenReturn(null);
-
VibrationSettings minimalVibrationSettings = new VibrationSettings(mContextSpy,
new Handler(mTestLooper.getLooper()), mVibrationConfigMock);
- minimalVibrationSettings.onSystemReady();
+
+ // The only core services that we depend on are Power, Package and Activity managers
+ minimalVibrationSettings.onSystemReady(mPackageManagerInternalMock,
+ mPowerManagerInternalMock, mActivityManagerMock, null, null);
}
@Test
@@ -216,8 +191,8 @@ public class VibrationSettingsTest {
mVibrationSettings.addListener(mListenerMock);
// Testing the broadcast flow manually.
- mVibrationSettings.mUserSwitchObserver.onUserSwitching(NEW_USER_ID);
- mVibrationSettings.mUserSwitchObserver.onUserSwitchComplete(NEW_USER_ID);
+ mVibrationSettings.mUserSwitchObserver.onUserSwitching(USER_ID);
+ mVibrationSettings.mUserSwitchObserver.onUserSwitchComplete(USER_ID);
verify(mListenerMock, times(2)).onChange();
}
@@ -227,9 +202,9 @@ public class VibrationSettingsTest {
mVibrationSettings.addListener(mListenerMock);
// Testing the broadcast flow manually.
- mVibrationSettings.mSettingChangeReceiver.onReceive(mContextSpy,
+ mVibrationSettings.mRingerModeBroadcastReceiver.onReceive(mContextSpy,
new Intent(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION));
- mVibrationSettings.mSettingChangeReceiver.onReceive(mContextSpy,
+ mVibrationSettings.mRingerModeBroadcastReceiver.onReceive(mContextSpy,
new Intent(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION));
verify(mListenerMock, times(2)).onChange();
@@ -251,9 +226,9 @@ public class VibrationSettingsTest {
mVibrationSettings.addListener(mListenerMock);
// Testing the broadcast flow manually.
- mRegisteredPowerModeListener.onLowPowerModeChanged(LOW_POWER_STATE);
- mRegisteredPowerModeListener.onLowPowerModeChanged(NORMAL_POWER_STATE);
- mRegisteredPowerModeListener.onLowPowerModeChanged(NORMAL_POWER_STATE); // No change.
+ mVibrationSettings.mLowPowerModeListener.onLowPowerModeChanged(LOW_POWER_STATE);
+ mVibrationSettings.mLowPowerModeListener.onLowPowerModeChanged(NORMAL_POWER_STATE);
+ mVibrationSettings.mLowPowerModeListener.onLowPowerModeChanged(NORMAL_POWER_STATE); // Noop.
verify(mListenerMock, times(2)).onChange();
}
@@ -268,10 +243,9 @@ public class VibrationSettingsTest {
mVibrationSettings.removeListener(mListenerMock);
// Trigger multiple observers manually.
- mVibrationSettings.mSettingObserver.onChange(false);
- mRegisteredPowerModeListener.onLowPowerModeChanged(LOW_POWER_STATE);
- mVibrationSettings.mUserSwitchObserver.onUserSwitchComplete(NEW_USER_ID);
- mVibrationSettings.mSettingChangeReceiver.onReceive(mContextSpy,
+ mVibrationSettings.mLowPowerModeListener.onLowPowerModeChanged(LOW_POWER_STATE);
+ mVibrationSettings.mUserSwitchObserver.onUserSwitchComplete(USER_ID);
+ mVibrationSettings.mRingerModeBroadcastReceiver.onReceive(mContextSpy,
new Intent(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION));
verifyNoMoreInteractions(mListenerMock);
@@ -312,11 +286,12 @@ public class VibrationSettingsTest {
@Test
public void wirelessChargingVibrationsEnabled_doesNotRegisterBatteryReceiver_allowsAnyUsage() {
- setBatteryReceiverRegistrationResult(getBatteryChangedIntent(BATTERY_PLUGGED_WIRELESS));
setIgnoreVibrationsOnWirelessCharger(false);
createSystemReadyVibrationSettings();
- assertNull(mRegisteredBatteryBroadcastReceiver);
+ verify(mContextSpy, never()).registerReceiver(any(BroadcastReceiver.class),
+ argThat(filter -> filter.matchAction(Intent.ACTION_BATTERY_CHANGED)), anyInt());
+
for (int usage : ALL_USAGES) {
assertVibrationNotIgnoredForUsage(usage);
}
@@ -324,7 +299,6 @@ public class VibrationSettingsTest {
@Test
public void shouldIgnoreVibration_noBatteryIntentWhenSystemReady_allowsAnyUsage() {
- setBatteryReceiverRegistrationResult(null);
setIgnoreVibrationsOnWirelessCharger(true);
createSystemReadyVibrationSettings();
@@ -336,7 +310,9 @@ public class VibrationSettingsTest {
@Test
public void shouldIgnoreVibration_onNonWirelessChargerWhenSystemReady_allowsAnyUsage() {
Intent nonWirelessChargingIntent = getBatteryChangedIntent(BATTERY_PLUGGED_USB);
- setBatteryReceiverRegistrationResult(nonWirelessChargingIntent);
+ doReturn(nonWirelessChargingIntent).when(mContextSpy).registerReceiver(
+ any(BroadcastReceiver.class),
+ argThat(filter -> filter.matchAction(Intent.ACTION_BATTERY_CHANGED)), anyInt());
setIgnoreVibrationsOnWirelessCharger(true);
createSystemReadyVibrationSettings();
@@ -348,7 +324,9 @@ public class VibrationSettingsTest {
@Test
public void shouldIgnoreVibration_onWirelessChargerWhenSystemReady_doesNotAllowFromAnyUsage() {
Intent wirelessChargingIntent = getBatteryChangedIntent(BATTERY_PLUGGED_WIRELESS);
- setBatteryReceiverRegistrationResult(wirelessChargingIntent);
+ doReturn(wirelessChargingIntent).when(mContextSpy).registerReceiver(
+ any(BroadcastReceiver.class),
+ argThat(filter -> filter.matchAction(Intent.ACTION_BATTERY_CHANGED)), anyInt());
setIgnoreVibrationsOnWirelessCharger(true);
createSystemReadyVibrationSettings();
@@ -359,13 +337,12 @@ public class VibrationSettingsTest {
@Test
public void shouldIgnoreVibration_receivesWirelessChargingIntent_doesNotAllowFromAnyUsage() {
- Intent nonWirelessChargingIntent = getBatteryChangedIntent(BATTERY_PLUGGED_USB);
- setBatteryReceiverRegistrationResult(nonWirelessChargingIntent);
setIgnoreVibrationsOnWirelessCharger(true);
createSystemReadyVibrationSettings();
Intent wirelessChargingIntent = getBatteryChangedIntent(BATTERY_PLUGGED_WIRELESS);
- mRegisteredBatteryBroadcastReceiver.onReceive(mContextSpy, wirelessChargingIntent);
+ mVibrationSettings.mBatteryBroadcastReceiver.onReceive(
+ mContextSpy, wirelessChargingIntent);
for (int usage : ALL_USAGES) {
assertVibrationIgnoredForUsage(usage, Status.IGNORED_ON_WIRELESS_CHARGER);
@@ -374,17 +351,21 @@ public class VibrationSettingsTest {
@Test
public void shouldIgnoreVibration_receivesNonWirelessChargingIntent_allowsAnyUsage() {
- Intent wirelessChargingIntent = getBatteryChangedIntent(BATTERY_PLUGGED_WIRELESS);
- setBatteryReceiverRegistrationResult(wirelessChargingIntent);
setIgnoreVibrationsOnWirelessCharger(true);
createSystemReadyVibrationSettings();
+
+ Intent wirelessChargingIntent = getBatteryChangedIntent(BATTERY_PLUGGED_WIRELESS);
+ mVibrationSettings.mBatteryBroadcastReceiver.onReceive(
+ mContextSpy, wirelessChargingIntent);
+
// Check that initially, all usages are ignored due to the wireless charging.
for (int usage : ALL_USAGES) {
assertVibrationIgnoredForUsage(usage, Status.IGNORED_ON_WIRELESS_CHARGER);
}
Intent nonWirelessChargingIntent = getBatteryChangedIntent(BATTERY_PLUGGED_USB);
- mRegisteredBatteryBroadcastReceiver.onReceive(mContextSpy, nonWirelessChargingIntent);
+ mVibrationSettings.mBatteryBroadcastReceiver.onReceive(
+ mContextSpy, nonWirelessChargingIntent);
for (int usage : ALL_USAGES) {
assertVibrationNotIgnoredForUsage(usage);
@@ -401,7 +382,7 @@ public class VibrationSettingsTest {
USAGE_HARDWARE_FEEDBACK
));
- mRegisteredPowerModeListener.onLowPowerModeChanged(LOW_POWER_STATE);
+ mVibrationSettings.mLowPowerModeListener.onLowPowerModeChanged(LOW_POWER_STATE);
for (int usage : ALL_USAGES) {
if (expectedAllowedVibrations.contains(usage)) {
@@ -414,7 +395,7 @@ public class VibrationSettingsTest {
@Test
public void shouldIgnoreVibration_notInBatterySaverMode_allowsAnyUsage() {
- mRegisteredPowerModeListener.onLowPowerModeChanged(NORMAL_POWER_STATE);
+ mVibrationSettings.mLowPowerModeListener.onLowPowerModeChanged(NORMAL_POWER_STATE);
for (int usage : ALL_USAGES) {
assertVibrationNotIgnoredForUsage(usage);
@@ -606,7 +587,7 @@ public class VibrationSettingsTest {
// Testing the broadcast flow manually.
when(mAudioManagerMock.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_SILENT);
- mVibrationSettings.mSettingChangeReceiver.onReceive(mContextSpy,
+ mVibrationSettings.mRingerModeBroadcastReceiver.onReceive(mContextSpy,
new Intent(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION));
assertVibrationIgnoredForUsage(USAGE_RINGTONE, Status.IGNORED_FOR_RINGER_MODE);
@@ -862,16 +843,15 @@ public class VibrationSettingsTest {
mVibrationSettings.getCurrentIntensity(USAGE_RINGTONE));
// Test early update of settings based on new user id.
- putUserSetting(Settings.System.RING_VIBRATION_INTENSITY, VIBRATION_INTENSITY_LOW,
- NEW_USER_ID);
- mVibrationSettings.mUserSwitchObserver.onUserSwitching(NEW_USER_ID);
+ putUserSetting(Settings.System.RING_VIBRATION_INTENSITY, VIBRATION_INTENSITY_LOW, USER_ID);
+ mVibrationSettings.mUserSwitchObserver.onUserSwitching(USER_ID);
assertEquals(VIBRATION_INTENSITY_LOW,
mVibrationSettings.getCurrentIntensity(USAGE_RINGTONE));
// Test later update of settings for UserHandle.USER_CURRENT.
putUserSetting(Settings.System.RING_VIBRATION_INTENSITY, VIBRATION_INTENSITY_LOW,
UserHandle.USER_CURRENT);
- mVibrationSettings.mUserSwitchObserver.onUserSwitchComplete(NEW_USER_ID);
+ mVibrationSettings.mUserSwitchObserver.onUserSwitchComplete(USER_ID);
assertEquals(VIBRATION_INTENSITY_LOW,
mVibrationSettings.getCurrentIntensity(USAGE_RINGTONE));
}
@@ -1019,7 +999,7 @@ public class VibrationSettingsTest {
private void setRingerMode(int ringerMode) {
when(mAudioManagerMock.getRingerModeInternal()).thenReturn(ringerMode);
// Mock AudioManager broadcast of internal ringer mode change.
- mVibrationSettings.mSettingChangeReceiver.onReceive(mContextSpy,
+ mVibrationSettings.mRingerModeBroadcastReceiver.onReceive(mContextSpy,
new Intent(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION));
}
@@ -1034,14 +1014,6 @@ public class VibrationSettingsTest {
return new CallerInfo(attrs, uid, VIRTUAL_DEVICE_ID, opPkg, null);
}
- private void setBatteryReceiverRegistrationResult(Intent result) {
- doAnswer(invocation -> {
- mRegisteredBatteryBroadcastReceiver = invocation.getArgument(0);
- return result;
- }).when(mContextSpy).registerReceiver(any(BroadcastReceiver.class),
- argThat(filter -> filter.matchAction(Intent.ACTION_BATTERY_CHANGED)), anyInt());
- }
-
private Intent getBatteryChangedIntent(int extraPluggedValue) {
Intent batteryIntent = new Intent(Intent.ACTION_BATTERY_CHANGED);
batteryIntent.putExtra(EXTRA_PLUGGED, extraPluggedValue);
diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java
index e8d089c61362..f48ba65217e2 100644
--- a/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java
@@ -30,6 +30,7 @@ import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import android.graphics.Insets;
+import android.graphics.Point;
import android.graphics.Rect;
import android.platform.test.annotations.Presubmit;
import android.view.InsetsSource;
@@ -260,6 +261,27 @@ public class InsetsSourceProviderTest extends WindowTestsBase {
}
@Test
+ public void testUpdateInsetsControlPosition() {
+ final WindowState target = createWindow(null, TYPE_APPLICATION, "target");
+
+ final WindowState ime1 = createWindow(null, TYPE_INPUT_METHOD, "ime1");
+ ime1.getFrame().set(new Rect(0, 0, 0, 0));
+ mImeProvider.setWindowContainer(ime1, null, null);
+ mImeProvider.updateControlForTarget(target, false /* force */, null /* statsToken */);
+ ime1.getFrame().set(new Rect(0, 400, 500, 500));
+ mImeProvider.updateInsetsControlPosition(ime1);
+ assertEquals(new Point(0, 400), mImeProvider.getControl(target).getSurfacePosition());
+
+ final WindowState ime2 = createWindow(null, TYPE_INPUT_METHOD, "ime2");
+ ime2.getFrame().set(new Rect(0, 0, 0, 0));
+ mImeProvider.setWindowContainer(ime2, null, null);
+ mImeProvider.updateControlForTarget(target, false /* force */, null /* statsToken */);
+ ime2.getFrame().set(new Rect(0, 400, 500, 500));
+ mImeProvider.updateInsetsControlPosition(ime2);
+ assertEquals(new Point(0, 400), mImeProvider.getControl(target).getSurfacePosition());
+ }
+
+ @Test
public void testSetRequestedVisibleTypes() {
final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
final WindowState target = createWindow(null, TYPE_APPLICATION, "target");
diff --git a/tests/NetworkSecurityConfigTest/res/xml/ct_domains.xml b/tests/NetworkSecurityConfigTest/res/xml/ct_domains.xml
new file mode 100644
index 000000000000..67d4397afe7d
--- /dev/null
+++ b/tests/NetworkSecurityConfigTest/res/xml/ct_domains.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<network-security-config>
+ <base-config>
+ <certificateTransparency enabled="true" />
+ </base-config>
+ <domain-config>
+ <domain>android.com</domain>
+ <trust-anchors>
+ <certificates src="system" />
+ </trust-anchors>
+ </domain-config>
+ <domain-config>
+ <domain>subdomain_user.android.com</domain>
+ <trust-anchors>
+ <certificates src="user" />
+ </trust-anchors>
+ </domain-config>
+ <domain-config>
+ <certificateTransparency enabled="true" />
+ <domain>subdomain_user_ct.android.com</domain>
+ <trust-anchors>
+ <certificates src="user" />
+ </trust-anchors>
+ </domain-config>
+ <domain-config>
+ <domain>subdomain_inline.android.com</domain>
+ <trust-anchors>
+ <certificates src="@raw/ca_certs_pem" />
+ </trust-anchors>
+ </domain-config>
+ <domain-config>
+ <certificateTransparency enabled="true" />
+ <domain>subdomain_inline_ct.android.com</domain>
+ <trust-anchors>
+ <certificates src="@raw/ca_certs_pem" />
+ </trust-anchors>
+ </domain-config>
+</network-security-config>
diff --git a/tests/NetworkSecurityConfigTest/res/xml/ct_users.xml b/tests/NetworkSecurityConfigTest/res/xml/ct_users.xml
new file mode 100644
index 000000000000..c35fd71c3178
--- /dev/null
+++ b/tests/NetworkSecurityConfigTest/res/xml/ct_users.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<network-security-config>
+ <base-config>
+ <trust-anchors>
+ <certificates src="user" />
+ </trust-anchors>
+ </base-config>
+ <domain-config>
+ <domain>android.com</domain>
+ </domain-config>
+ <domain-config>
+ <certificateTransparency enabled="true" />
+ <domain>subdomain.android.com</domain>
+ </domain-config>
+</network-security-config>
diff --git a/tests/NetworkSecurityConfigTest/src/android/security/net/config/NetworkSecurityConfigTests.java b/tests/NetworkSecurityConfigTest/src/android/security/net/config/NetworkSecurityConfigTests.java
index 0494f174f191..c6fe06858e3f 100644
--- a/tests/NetworkSecurityConfigTest/src/android/security/net/config/NetworkSecurityConfigTests.java
+++ b/tests/NetworkSecurityConfigTest/src/android/security/net/config/NetworkSecurityConfigTests.java
@@ -111,7 +111,8 @@ public class NetworkSecurityConfigTests extends ActivityUnitTestCase<Activity> {
private NetworkSecurityConfig getSystemStoreConfig() {
return new NetworkSecurityConfig.Builder()
.addCertificatesEntryRef(
- new CertificatesEntryRef(SystemCertificateSource.getInstance(), false))
+ new CertificatesEntryRef(
+ SystemCertificateSource.getInstance(), false, false))
.build();
}
@@ -141,7 +142,8 @@ public class NetworkSecurityConfigTests extends ActivityUnitTestCase<Activity> {
NetworkSecurityConfig domain = new NetworkSecurityConfig.Builder()
.setPinSet(new PinSet(pins, Long.MAX_VALUE))
.addCertificatesEntryRef(
- new CertificatesEntryRef(SystemCertificateSource.getInstance(), false))
+ new CertificatesEntryRef(
+ SystemCertificateSource.getInstance(), false, false))
.build();
ArraySet<Pair<Domain, NetworkSecurityConfig>> domainMap
= new ArraySet<Pair<Domain, NetworkSecurityConfig>>();
@@ -159,7 +161,8 @@ public class NetworkSecurityConfigTests extends ActivityUnitTestCase<Activity> {
NetworkSecurityConfig domain = new NetworkSecurityConfig.Builder()
.setPinSet(new PinSet(pins, Long.MAX_VALUE))
.addCertificatesEntryRef(
- new CertificatesEntryRef(SystemCertificateSource.getInstance(), false))
+ new CertificatesEntryRef(
+ SystemCertificateSource.getInstance(), false, false))
.build();
ArraySet<Pair<Domain, NetworkSecurityConfig>> domainMap
= new ArraySet<Pair<Domain, NetworkSecurityConfig>>();
@@ -178,7 +181,8 @@ public class NetworkSecurityConfigTests extends ActivityUnitTestCase<Activity> {
NetworkSecurityConfig domain = new NetworkSecurityConfig.Builder()
.setPinSet(new PinSet(pins, Long.MAX_VALUE))
.addCertificatesEntryRef(
- new CertificatesEntryRef(SystemCertificateSource.getInstance(), true))
+ new CertificatesEntryRef(
+ SystemCertificateSource.getInstance(), true, false))
.build();
ArraySet<Pair<Domain, NetworkSecurityConfig>> domainMap
= new ArraySet<Pair<Domain, NetworkSecurityConfig>>();
@@ -245,7 +249,8 @@ public class NetworkSecurityConfigTests extends ActivityUnitTestCase<Activity> {
NetworkSecurityConfig domain = new NetworkSecurityConfig.Builder()
.setPinSet(new PinSet(pins, Long.MAX_VALUE))
.addCertificatesEntryRef(
- new CertificatesEntryRef(SystemCertificateSource.getInstance(), false))
+ new CertificatesEntryRef(
+ SystemCertificateSource.getInstance(), false, false))
.build();
ArraySet<Pair<Domain, NetworkSecurityConfig>> domainMap
= new ArraySet<Pair<Domain, NetworkSecurityConfig>>();
diff --git a/tests/NetworkSecurityConfigTest/src/android/security/net/config/XmlConfigTests.java b/tests/NetworkSecurityConfigTest/src/android/security/net/config/XmlConfigTests.java
index 81e05c1d4e42..542465d62a66 100644
--- a/tests/NetworkSecurityConfigTest/src/android/security/net/config/XmlConfigTests.java
+++ b/tests/NetworkSecurityConfigTest/src/android/security/net/config/XmlConfigTests.java
@@ -502,4 +502,47 @@ public class XmlConfigTests extends AndroidTestCase {
TestUtils.assertConnectionSucceeds(context, "android.com", 443);
TestUtils.assertConnectionSucceeds(context, "developer.android.com", 443);
}
+
+ public void testCertificateTransparencyDomainConfig() throws Exception {
+ XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.ct_domains,
+ TestUtils.makeApplicationInfo());
+ ApplicationConfig appConfig = new ApplicationConfig(source);
+ assertTrue(appConfig.hasPerDomainConfigs());
+ NetworkSecurityConfig config = appConfig.getConfigForHostname("");
+ assertNotNull(config);
+ // Check defaults.
+ assertTrue(config.isCertificateTransparencyVerificationRequired());
+
+ config = appConfig.getConfigForHostname("android.com");
+ assertTrue(config.isCertificateTransparencyVerificationRequired());
+
+ config = appConfig.getConfigForHostname("subdomain_user.android.com");
+ assertFalse(config.isCertificateTransparencyVerificationRequired());
+
+ config = appConfig.getConfigForHostname("subdomain_user_ct.android.com");
+ assertTrue(config.isCertificateTransparencyVerificationRequired());
+
+ config = appConfig.getConfigForHostname("subdomain_inline.android.com");
+ assertFalse(config.isCertificateTransparencyVerificationRequired());
+
+ config = appConfig.getConfigForHostname("subdomain_inline_ct.android.com");
+ assertTrue(config.isCertificateTransparencyVerificationRequired());
+ }
+
+ public void testCertificateTransparencyUserConfig() throws Exception {
+ XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.ct_users,
+ TestUtils.makeApplicationInfo());
+ ApplicationConfig appConfig = new ApplicationConfig(source);
+ assertTrue(appConfig.hasPerDomainConfigs());
+ NetworkSecurityConfig config = appConfig.getConfigForHostname("");
+ assertNotNull(config);
+ // Check defaults.
+ assertFalse(config.isCertificateTransparencyVerificationRequired());
+
+ config = appConfig.getConfigForHostname("android.com");
+ assertFalse(config.isCertificateTransparencyVerificationRequired());
+
+ config = appConfig.getConfigForHostname("subdomain.android.com");
+ assertTrue(config.isCertificateTransparencyVerificationRequired());
+ }
}