summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/api/current.txt19
-rw-r--r--core/api/system-current.txt14
-rw-r--r--core/java/android/app/ActivityManager.java8
-rw-r--r--core/java/android/app/SystemServiceRegistry.java2
-rw-r--r--core/java/android/companion/virtual/VirtualDeviceParams.java58
-rw-r--r--core/java/android/content/Context.java2
-rw-r--r--core/java/android/net/NetworkPolicyManager.java28
-rw-r--r--core/java/android/provider/Settings.java9
-rw-r--r--core/java/android/service/autofill/FillEventHistory.java25
-rw-r--r--core/java/android/service/dreams/DreamActivity.java2
-rw-r--r--core/java/android/service/dreams/DreamService.java3
-rw-r--r--core/java/android/view/AccessibilityInteractionController.java2
-rw-r--r--core/java/android/view/View.java83
-rw-r--r--core/java/android/view/ViewGroup.java6
-rw-r--r--core/java/android/view/ViewRootImpl.java10
-rw-r--r--core/java/android/view/accessibility/AccessibilityEvent.java18
-rw-r--r--core/java/android/view/accessibility/AccessibilityNodeInfo.java30
-rw-r--r--core/java/android/view/accessibility/AccessibilityRecord.java24
-rw-r--r--core/java/android/view/contentcapture/ContentCaptureSession.java1
-rw-r--r--core/java/android/widget/TextView.java8
-rw-r--r--core/java/com/android/internal/compat/ChangeReporter.java17
-rw-r--r--core/java/com/android/internal/os/ProcessCpuTracker.java34
-rw-r--r--core/java/com/android/internal/widget/LockPatternUtils.java15
-rw-r--r--core/proto/android/providers/settings/secure.proto2
-rw-r--r--core/res/res/values/attrs.xml4
-rw-r--r--core/res/res/values/public-staging.xml2
-rw-r--r--core/res/res/xml/irq_device_map.xml11
-rw-r--r--core/tests/coretests/src/android/view/accessibility/AccessibilityNodeInfoTest.java2
-rw-r--r--core/tests/overlaytests/device/Android.bp1
-rw-r--r--core/tests/overlaytests/device/src/com/android/overlaytest/OverlayBaseTest.java9
-rw-r--r--data/etc/services.core.protolog.json12
-rw-r--r--graphics/java/android/graphics/Gainmap.java12
-rw-r--r--libs/WindowManager/Shell/res/color-night/taskbar_background.xml (renamed from libs/WindowManager/Shell/res/color/split_divider_background.xml)3
-rw-r--r--libs/WindowManager/Shell/res/color/taskbar_background.xml2
-rw-r--r--libs/WindowManager/Shell/res/values-night/colors.xml1
-rw-r--r--libs/WindowManager/Shell/res/values/colors.xml3
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java17
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationRunner.java13
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java26
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellInit.java2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/util/TransitionUtil.java207
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java35
-rw-r--r--media/java/android/media/tv/tuner/frontend/IptvFrontendSettings.java16
-rw-r--r--media/java/android/media/tv/tuner/frontend/IptvFrontendSettingsFec.java12
-rw-r--r--packages/CredentialManager/src/com/android/credentialmanager/DataConverter.kt17
-rw-r--r--packages/CredentialManager/src/com/android/credentialmanager/TestUtils.kt18
-rw-r--r--packages/CredentialManager/src/com/android/credentialmanager/common/ui/BottomSheet.kt4
-rw-r--r--packages/SettingsLib/Spa/spa/build.gradle6
-rw-r--r--packages/SettingsLib/Spa/testutils/build.gradle6
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatterySaverUtils.java13
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/BatterySaverUtilsTest.java31
-rw-r--r--packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java1
-rw-r--r--packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java1
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java3
-rw-r--r--packages/Shell/AndroidManifest.xml1
-rw-r--r--packages/SystemUI/res-keyguard/values/strings.xml2
-rw-r--r--packages/SystemUI/res/values/config.xml4
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationTargetCompat.java216
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteTransitionCompat.java73
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java27
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java30
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java28
-rw-r--r--packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt614
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java18
-rw-r--r--packages/SystemUI/src/com/android/systemui/notetask/OWNERS2
-rw-r--r--packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/stylus/OWNERS2
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java43
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/notetask/OWNERS2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/shared/system/RemoteTransitionTest.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/stylus/OWNERS2
-rw-r--r--services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java2
-rw-r--r--services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java26
-rw-r--r--services/autofill/java/com/android/server/autofill/Session.java43
-rw-r--r--services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java14
-rw-r--r--services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java4
-rw-r--r--services/core/java/android/os/BatteryStatsInternal.java2
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerShellCommand.java4
-rw-r--r--services/core/java/com/android/server/am/AppProfiler.java8
-rw-r--r--services/core/java/com/android/server/am/BatteryStatsService.java23
-rw-r--r--services/core/java/com/android/server/am/OomAdjuster.java30
-rw-r--r--services/core/java/com/android/server/appop/AppOpsUidStateTrackerImpl.java9
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/face/FaceService.java4
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java15
-rw-r--r--services/core/java/com/android/server/locksettings/LockSettingsService.java116
-rw-r--r--services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java28
-rw-r--r--services/core/java/com/android/server/pm/ResilientAtomicFile.java265
-rw-r--r--services/core/java/com/android/server/pm/Settings.java1343
-rw-r--r--services/core/java/com/android/server/pm/ShortcutPackage.java3
-rw-r--r--services/core/java/com/android/server/pm/ShortcutPackageItem.java7
-rw-r--r--services/core/java/com/android/server/pm/ShortcutService.java105
-rw-r--r--services/core/java/com/android/server/pm/UserManagerService.java7
-rw-r--r--services/core/java/com/android/server/power/PowerManagerService.java15
-rw-r--r--services/core/java/com/android/server/power/stats/CpuWakeupStats.java8
-rw-r--r--services/core/java/com/android/server/wm/BackNavigationController.java186
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java23
-rw-r--r--services/core/java/com/android/server/wm/Task.java4
-rw-r--r--services/core/java/com/android/server/wm/Transition.java3
-rw-r--r--services/core/java/com/android/server/wm/WindowOrganizerController.java19
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java6
-rw-r--r--services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageManagerSettingsTests.java24
-rw-r--r--services/tests/servicestests/Android.bp1
-rw-r--r--services/tests/servicestests/AndroidTest.xml2
-rw-r--r--services/tests/servicestests/data/broken_shortcut.xmlbin0 -> 851 bytes
-rw-r--r--services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java2
-rw-r--r--services/tests/servicestests/src/com/android/server/am/UidObserverControllerTest.java6
-rw-r--r--services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java38
-rw-r--r--services/tests/servicestests/src/com/android/server/companion/virtual/audio/VirtualAudioControllerTest.java3
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java17
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java2
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java13
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TaskTests.java28
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java25
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TransitionTests.java7
-rw-r--r--telecomm/java/android/telecom/CallControl.java25
-rw-r--r--telecomm/java/android/telecom/CallEventCallback.java17
-rw-r--r--telephony/java/android/telephony/CarrierConfigManager.java5
-rw-r--r--wifi/java/src/android/net/wifi/sharedconnectivity/app/NetworkProviderInfo.java24
-rw-r--r--wifi/tests/src/android/net/wifi/sharedconnectivity/app/HotspotNetworkConnectionStatusTest.java6
-rw-r--r--wifi/tests/src/android/net/wifi/sharedconnectivity/app/HotspotNetworkTest.java12
-rw-r--r--wifi/tests/src/android/net/wifi/sharedconnectivity/app/KnownNetworkConnectionStatusTest.java7
-rw-r--r--wifi/tests/src/android/net/wifi/sharedconnectivity/app/KnownNetworkTest.java10
-rw-r--r--wifi/tests/src/android/net/wifi/sharedconnectivity/app/NetworkProviderInfoTest.java3
-rw-r--r--wifi/tests/src/android/net/wifi/sharedconnectivity/app/SharedConnectivityManagerTest.java7
-rw-r--r--wifi/tests/src/android/net/wifi/sharedconnectivity/service/SharedConnectivityServiceTest.java7
127 files changed, 2739 insertions, 1870 deletions
diff --git a/core/api/current.txt b/core/api/current.txt
index 5af80797c91f..272fab303911 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -375,7 +375,7 @@ package android {
public static final class R.attr {
ctor public R.attr();
field public static final int absListViewStyle = 16842858; // 0x101006a
- field public static final int accessibilityDataPrivate;
+ field public static final int accessibilityDataSensitive;
field public static final int accessibilityEventTypes = 16843648; // 0x1010380
field public static final int accessibilityFeedbackType = 16843650; // 0x1010382
field public static final int accessibilityFlags = 16843652; // 0x1010384
@@ -39862,6 +39862,7 @@ package android.service.autofill {
field public static final int TYPE_DATASET_AUTHENTICATION_SELECTED = 1; // 0x1
field public static final int TYPE_DATASET_SELECTED = 0; // 0x0
field public static final int TYPE_SAVE_SHOWN = 3; // 0x3
+ field public static final int TYPE_VIEW_REQUESTED_AUTOFILL = 6; // 0x6
field public static final int UI_TYPE_DIALOG = 3; // 0x3
field public static final int UI_TYPE_INLINE = 2; // 0x2
field public static final int UI_TYPE_MENU = 1; // 0x1
@@ -52218,7 +52219,7 @@ package android.view {
method public void invalidate();
method public void invalidateDrawable(@NonNull android.graphics.drawable.Drawable);
method public void invalidateOutline();
- method public boolean isAccessibilityDataPrivate();
+ method public boolean isAccessibilityDataSensitive();
method public boolean isAccessibilityFocused();
method public boolean isAccessibilityHeading();
method public boolean isActivated();
@@ -52398,7 +52399,7 @@ package android.view {
method public void scrollTo(int, int);
method public void sendAccessibilityEvent(int);
method public void sendAccessibilityEventUnchecked(android.view.accessibility.AccessibilityEvent);
- method public void setAccessibilityDataPrivate(int);
+ method public void setAccessibilityDataSensitive(int);
method public void setAccessibilityDelegate(@Nullable android.view.View.AccessibilityDelegate);
method public void setAccessibilityHeading(boolean);
method public void setAccessibilityLiveRegion(int);
@@ -52584,9 +52585,9 @@ package android.view {
method @CallSuper protected boolean verifyDrawable(@NonNull android.graphics.drawable.Drawable);
method @Deprecated public boolean willNotCacheDrawing();
method public boolean willNotDraw();
- field public static final int ACCESSIBILITY_DATA_PRIVATE_AUTO = 0; // 0x0
- field public static final int ACCESSIBILITY_DATA_PRIVATE_NO = 2; // 0x2
- field public static final int ACCESSIBILITY_DATA_PRIVATE_YES = 1; // 0x1
+ field public static final int ACCESSIBILITY_DATA_SENSITIVE_AUTO = 0; // 0x0
+ field public static final int ACCESSIBILITY_DATA_SENSITIVE_NO = 2; // 0x2
+ field public static final int ACCESSIBILITY_DATA_SENSITIVE_YES = 1; // 0x1
field public static final int ACCESSIBILITY_LIVE_REGION_ASSERTIVE = 2; // 0x2
field public static final int ACCESSIBILITY_LIVE_REGION_NONE = 0; // 0x0
field public static final int ACCESSIBILITY_LIVE_REGION_POLITE = 1; // 0x1
@@ -54056,11 +54057,11 @@ package android.view.accessibility {
method public int getSpeechStateChangeTypes();
method public int getWindowChanges();
method public void initFromParcel(android.os.Parcel);
- method public boolean isAccessibilityDataPrivate();
+ method public boolean isAccessibilityDataSensitive();
method @Deprecated public static android.view.accessibility.AccessibilityEvent obtain(int);
method @Deprecated public static android.view.accessibility.AccessibilityEvent obtain(android.view.accessibility.AccessibilityEvent);
method @Deprecated public static android.view.accessibility.AccessibilityEvent obtain();
- method public void setAccessibilityDataPrivate(boolean);
+ method public void setAccessibilityDataSensitive(boolean);
method public void setAction(int);
method public void setContentChangeTypes(int);
method public void setEventTime(long);
@@ -54251,6 +54252,7 @@ package android.view.accessibility {
method public int getWindowId();
method public boolean hasRequestInitialAccessibilityFocus();
method public boolean hasRequestTouchPassthrough();
+ method public boolean isAccessibilityDataSensitive();
method public boolean isAccessibilityFocused();
method public boolean isCheckable();
method public boolean isChecked();
@@ -54287,6 +54289,7 @@ package android.view.accessibility {
method public boolean removeAction(android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction);
method public boolean removeChild(android.view.View);
method public boolean removeChild(android.view.View, int);
+ method public void setAccessibilityDataSensitive(boolean);
method public void setAccessibilityFocused(boolean);
method public void setAvailableExtraData(java.util.List<java.lang.String>);
method @Deprecated public void setBoundsInParent(android.graphics.Rect);
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 744399de8225..8a6faa109522 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -3247,7 +3247,6 @@ package android.companion.virtual {
method @NonNull public java.util.Set<android.content.ComponentName> getBlockedCrossTaskNavigations();
method public int getDefaultActivityPolicy();
method public int getDefaultNavigationPolicy();
- method public int getDefaultRecentsPolicy();
method public int getDevicePolicy(int);
method public int getLockState();
method @Nullable public String getName();
@@ -3264,8 +3263,8 @@ package android.companion.virtual {
field public static final int NAVIGATION_POLICY_DEFAULT_ALLOWED = 0; // 0x0
field public static final int NAVIGATION_POLICY_DEFAULT_BLOCKED = 1; // 0x1
field public static final int POLICY_TYPE_AUDIO = 1; // 0x1
+ field public static final int POLICY_TYPE_RECENTS = 2; // 0x2
field public static final int POLICY_TYPE_SENSORS = 0; // 0x0
- field public static final int RECENTS_POLICY_ALLOW_IN_HOST_DEVICE_RECENTS = 1; // 0x1
}
public static final class VirtualDeviceParams.Builder {
@@ -3278,7 +3277,6 @@ package android.companion.virtual {
method @NonNull public android.companion.virtual.VirtualDeviceParams.Builder setAudioRecordingSessionId(int);
method @NonNull public android.companion.virtual.VirtualDeviceParams.Builder setBlockedActivities(@NonNull java.util.Set<android.content.ComponentName>);
method @NonNull public android.companion.virtual.VirtualDeviceParams.Builder setBlockedCrossTaskNavigations(@NonNull java.util.Set<android.content.ComponentName>);
- method @NonNull public android.companion.virtual.VirtualDeviceParams.Builder setDefaultRecentsPolicy(int);
method @NonNull public android.companion.virtual.VirtualDeviceParams.Builder setDevicePolicy(int, int);
method @NonNull @RequiresPermission(value=android.Manifest.permission.ADD_ALWAYS_UNLOCKED_DISPLAY, conditional=true) public android.companion.virtual.VirtualDeviceParams.Builder setLockState(int);
method @NonNull public android.companion.virtual.VirtualDeviceParams.Builder setName(@NonNull String);
@@ -9123,8 +9121,7 @@ package android.media.tv.tuner.frontend {
method public int getProtocolCapability();
}
- public class IptvFrontendSettings extends android.media.tv.tuner.frontend.FrontendSettings {
- method @NonNull public static android.media.tv.tuner.frontend.IptvFrontendSettings.Builder builder();
+ public final class IptvFrontendSettings extends android.media.tv.tuner.frontend.FrontendSettings {
method @IntRange(from=0) public long getBitrate();
method @NonNull public String getContentUrl();
method @NonNull @Size(min=4, max=16) public byte[] getDstIpAddress();
@@ -9145,6 +9142,7 @@ package android.media.tv.tuner.frontend {
}
public static final class IptvFrontendSettings.Builder {
+ ctor public IptvFrontendSettings.Builder();
method @NonNull public android.media.tv.tuner.frontend.IptvFrontendSettings build();
method @NonNull public android.media.tv.tuner.frontend.IptvFrontendSettings.Builder setBitrate(@IntRange(from=0) long);
method @NonNull public android.media.tv.tuner.frontend.IptvFrontendSettings.Builder setContentUrl(@NonNull String);
@@ -9157,8 +9155,7 @@ package android.media.tv.tuner.frontend {
method @NonNull public android.media.tv.tuner.frontend.IptvFrontendSettings.Builder setSrcPort(int);
}
- public class IptvFrontendSettingsFec {
- method @NonNull public static android.media.tv.tuner.frontend.IptvFrontendSettingsFec.Builder builder();
+ public final class IptvFrontendSettingsFec {
method @IntRange(from=0) public int getFecColNum();
method @IntRange(from=0) public int getFecRowNum();
method public int getFecType();
@@ -9169,6 +9166,7 @@ package android.media.tv.tuner.frontend {
}
public static final class IptvFrontendSettingsFec.Builder {
+ ctor public IptvFrontendSettingsFec.Builder();
method @NonNull public android.media.tv.tuner.frontend.IptvFrontendSettingsFec build();
method @NonNull public android.media.tv.tuner.frontend.IptvFrontendSettingsFec.Builder setFecColNum(@IntRange(from=0) int);
method @NonNull public android.media.tv.tuner.frontend.IptvFrontendSettingsFec.Builder setFecRowNum(@IntRange(from=0) int);
@@ -10117,7 +10115,7 @@ package android.net.wifi.sharedconnectivity.app {
}
public static final class NetworkProviderInfo.Builder {
- ctor public NetworkProviderInfo.Builder();
+ ctor public NetworkProviderInfo.Builder(@NonNull String, @NonNull String);
method @NonNull public android.net.wifi.sharedconnectivity.app.NetworkProviderInfo build();
method @NonNull public android.net.wifi.sharedconnectivity.app.NetworkProviderInfo.Builder setBatteryPercentage(@IntRange(from=0, to=100) int);
method @NonNull public android.net.wifi.sharedconnectivity.app.NetworkProviderInfo.Builder setConnectionStrength(@IntRange(from=0, to=3) int);
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index ba36d937edc3..87fe215edd85 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -630,7 +630,7 @@ public class ActivityManager {
PROCESS_CAPABILITY_FOREGROUND_LOCATION,
PROCESS_CAPABILITY_FOREGROUND_CAMERA,
PROCESS_CAPABILITY_FOREGROUND_MICROPHONE,
- PROCESS_CAPABILITY_NETWORK,
+ PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK,
PROCESS_CAPABILITY_BFSL,
})
@Retention(RetentionPolicy.SOURCE)
@@ -791,7 +791,7 @@ public class ActivityManager {
public static final int PROCESS_CAPABILITY_ALL = PROCESS_CAPABILITY_FOREGROUND_LOCATION
| PROCESS_CAPABILITY_FOREGROUND_CAMERA
| PROCESS_CAPABILITY_FOREGROUND_MICROPHONE
- | PROCESS_CAPABILITY_NETWORK
+ | PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK
| PROCESS_CAPABILITY_BFSL;
/**
@@ -810,7 +810,7 @@ public class ActivityManager {
pw.print((caps & PROCESS_CAPABILITY_FOREGROUND_LOCATION) != 0 ? 'L' : '-');
pw.print((caps & PROCESS_CAPABILITY_FOREGROUND_CAMERA) != 0 ? 'C' : '-');
pw.print((caps & PROCESS_CAPABILITY_FOREGROUND_MICROPHONE) != 0 ? 'M' : '-');
- pw.print((caps & PROCESS_CAPABILITY_NETWORK) != 0 ? 'N' : '-');
+ pw.print((caps & PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK) != 0 ? 'N' : '-');
pw.print((caps & PROCESS_CAPABILITY_BFSL) != 0 ? 'F' : '-');
}
@@ -819,7 +819,7 @@ public class ActivityManager {
sb.append((caps & PROCESS_CAPABILITY_FOREGROUND_LOCATION) != 0 ? 'L' : '-');
sb.append((caps & PROCESS_CAPABILITY_FOREGROUND_CAMERA) != 0 ? 'C' : '-');
sb.append((caps & PROCESS_CAPABILITY_FOREGROUND_MICROPHONE) != 0 ? 'M' : '-');
- sb.append((caps & PROCESS_CAPABILITY_NETWORK) != 0 ? 'N' : '-');
+ sb.append((caps & PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK) != 0 ? 'N' : '-');
sb.append((caps & PROCESS_CAPABILITY_BFSL) != 0 ? 'F' : '-');
}
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 83e015357589..dbba0c6f5e50 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -509,7 +509,7 @@ public final class SystemServiceRegistry {
new ServiceFetcher<InputManager>() {
@Override
public InputManager getService(ContextImpl ctx) {
- return InputManager.getInstance(ctx);
+ return InputManager.getInstance(ctx.getOuterContext());
}});
registerService(Context.DISPLAY_SERVICE, DisplayManager.class,
diff --git a/core/java/android/companion/virtual/VirtualDeviceParams.java b/core/java/android/companion/virtual/VirtualDeviceParams.java
index 9f3b60148004..3a60a695a294 100644
--- a/core/java/android/companion/virtual/VirtualDeviceParams.java
+++ b/core/java/android/companion/virtual/VirtualDeviceParams.java
@@ -140,7 +140,8 @@ public final class VirtualDeviceParams implements Parcelable {
* a given policy type.
* @hide
*/
- @IntDef(prefix = "POLICY_TYPE_", value = {POLICY_TYPE_SENSORS, POLICY_TYPE_AUDIO})
+ @IntDef(prefix = "POLICY_TYPE_", value = {POLICY_TYPE_SENSORS, POLICY_TYPE_AUDIO,
+ POLICY_TYPE_RECENTS})
@Retention(RetentionPolicy.SOURCE)
@Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE})
public @interface PolicyType {}
@@ -169,22 +170,21 @@ public final class VirtualDeviceParams implements Parcelable {
* <li>{@link #DEVICE_POLICY_CUSTOM}: audio framework will assign device specific session
* ids to players and recorders constructed within device context. The session ids are
* used to re-route corresponding audio streams to VirtualAudioDevice.
- * <ul/>
+ * </ul>
*/
public static final int POLICY_TYPE_AUDIO = 1;
- /** @hide */
- @IntDef(flag = true, prefix = "RECENTS_POLICY_",
- value = {RECENTS_POLICY_ALLOW_IN_HOST_DEVICE_RECENTS})
- @Retention(RetentionPolicy.SOURCE)
- @Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE})
- public @interface RecentsPolicy {}
-
/**
- * If set, activities launched on this virtual device are allowed to appear in the host device
- * of the recently launched activities list.
+ * Tells the activity manager how to handle recents entries for activities run on this device.
+ *
+ * <ul>
+ * <li>{@link #DEVICE_POLICY_DEFAULT}: Activities launched on VirtualDisplays owned by this
+ * device will appear in the host device recents.
+ * <li>{@link #DEVICE_POLICY_CUSTOM}: Activities launched on VirtualDisplays owned by this
+ * * device will not appear in recents.
+ * </ul>
*/
- public static final int RECENTS_POLICY_ALLOW_IN_HOST_DEVICE_RECENTS = 1 << 0;
+ public static final int POLICY_TYPE_RECENTS = 2;
private final int mLockState;
@NonNull private final ArraySet<UserHandle> mUsersWithMatchingAccounts;
@@ -201,8 +201,6 @@ public final class VirtualDeviceParams implements Parcelable {
@NonNull private final SparseIntArray mDevicePolicies;
@NonNull private final List<VirtualSensorConfig> mVirtualSensorConfigs;
@Nullable private final IVirtualSensorCallback mVirtualSensorCallback;
- @RecentsPolicy
- private final int mDefaultRecentsPolicy;
private final int mAudioPlaybackSessionId;
private final int mAudioRecordingSessionId;
@@ -219,7 +217,6 @@ public final class VirtualDeviceParams implements Parcelable {
@NonNull SparseIntArray devicePolicies,
@NonNull List<VirtualSensorConfig> virtualSensorConfigs,
@Nullable IVirtualSensorCallback virtualSensorCallback,
- @RecentsPolicy int defaultRecentsPolicy,
int audioPlaybackSessionId,
int audioRecordingSessionId) {
mLockState = lockState;
@@ -237,10 +234,8 @@ public final class VirtualDeviceParams implements Parcelable {
mDevicePolicies = Objects.requireNonNull(devicePolicies);
mVirtualSensorConfigs = Objects.requireNonNull(virtualSensorConfigs);
mVirtualSensorCallback = virtualSensorCallback;
- mDefaultRecentsPolicy = defaultRecentsPolicy;
mAudioPlaybackSessionId = audioPlaybackSessionId;
mAudioRecordingSessionId = audioRecordingSessionId;
-
}
@SuppressWarnings("unchecked")
@@ -259,7 +254,6 @@ public final class VirtualDeviceParams implements Parcelable {
parcel.readTypedList(mVirtualSensorConfigs, VirtualSensorConfig.CREATOR);
mVirtualSensorCallback =
IVirtualSensorCallback.Stub.asInterface(parcel.readStrongBinder());
- mDefaultRecentsPolicy = parcel.readInt();
mAudioPlaybackSessionId = parcel.readInt();
mAudioRecordingSessionId = parcel.readInt();
}
@@ -396,16 +390,6 @@ public final class VirtualDeviceParams implements Parcelable {
}
/**
- * Returns the policy of how to handle activities in recents.
- *
- * @see RecentsPolicy
- */
- @RecentsPolicy
- public int getDefaultRecentsPolicy() {
- return mDefaultRecentsPolicy;
- }
-
- /**
* Returns device-specific audio session id for playback.
*
* @see Builder#setAudioPlaybackSessionId(int)
@@ -443,7 +427,6 @@ public final class VirtualDeviceParams implements Parcelable {
dest.writeTypedList(mVirtualSensorConfigs);
dest.writeStrongBinder(
mVirtualSensorCallback != null ? mVirtualSensorCallback.asBinder() : null);
- dest.writeInt(mDefaultRecentsPolicy);
dest.writeInt(mAudioPlaybackSessionId);
dest.writeInt(mAudioRecordingSessionId);
}
@@ -478,7 +461,6 @@ public final class VirtualDeviceParams implements Parcelable {
&& Objects.equals(mBlockedActivities, that.mBlockedActivities)
&& mDefaultActivityPolicy == that.mDefaultActivityPolicy
&& Objects.equals(mName, that.mName)
- && mDefaultRecentsPolicy == that.mDefaultRecentsPolicy
&& mAudioPlaybackSessionId == that.mAudioPlaybackSessionId
&& mAudioRecordingSessionId == that.mAudioRecordingSessionId;
}
@@ -489,7 +471,7 @@ public final class VirtualDeviceParams implements Parcelable {
mLockState, mUsersWithMatchingAccounts, mAllowedCrossTaskNavigations,
mBlockedCrossTaskNavigations, mDefaultNavigationPolicy, mAllowedActivities,
mBlockedActivities, mDefaultActivityPolicy, mName, mDevicePolicies,
- mDefaultRecentsPolicy, mAudioPlaybackSessionId, mAudioRecordingSessionId);
+ mAudioPlaybackSessionId, mAudioRecordingSessionId);
for (int i = 0; i < mDevicePolicies.size(); i++) {
hashCode = 31 * hashCode + mDevicePolicies.keyAt(i);
hashCode = 31 * hashCode + mDevicePolicies.valueAt(i);
@@ -511,7 +493,6 @@ public final class VirtualDeviceParams implements Parcelable {
+ " mDefaultActivityPolicy=" + mDefaultActivityPolicy
+ " mName=" + mName
+ " mDevicePolicies=" + mDevicePolicies
- + " mDefaultRecentsPolicy=" + mDefaultRecentsPolicy
+ " mAudioPlaybackSessionId=" + mAudioPlaybackSessionId
+ " mAudioRecordingSessionId=" + mAudioRecordingSessionId
+ ")";
@@ -548,7 +529,6 @@ public final class VirtualDeviceParams implements Parcelable {
private boolean mDefaultActivityPolicyConfigured = false;
@Nullable private String mName;
@NonNull private SparseIntArray mDevicePolicies = new SparseIntArray();
- private int mDefaultRecentsPolicy;
private int mAudioPlaybackSessionId = AUDIO_SESSION_ID_GENERATE;
private int mAudioRecordingSessionId = AUDIO_SESSION_ID_GENERATE;
@@ -821,17 +801,6 @@ public final class VirtualDeviceParams implements Parcelable {
}
/**
- * Sets the policy to indicate how activities are handled in recents.
- *
- * @param defaultRecentsPolicy A policy specifying how to handle activities in recents.
- */
- @NonNull
- public Builder setDefaultRecentsPolicy(@RecentsPolicy int defaultRecentsPolicy) {
- mDefaultRecentsPolicy = defaultRecentsPolicy;
- return this;
- }
-
- /**
* Sets audio playback session id specific for this virtual device.
*
* <p>Audio players constructed within context associated with this virtual device
@@ -933,7 +902,6 @@ public final class VirtualDeviceParams implements Parcelable {
mDevicePolicies,
mVirtualSensorConfigs,
mVirtualSensorCallback,
- mDefaultRecentsPolicy,
mAudioPlaybackSessionId,
mAudioRecordingSessionId);
}
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index d0accb72a0e1..a412560d0347 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -528,7 +528,7 @@ public abstract class Context {
/**
* Flag for {@link #bindService}: allow the process hosting the target service to gain
- * {@link ActivityManager#PROCESS_CAPABILITY_NETWORK}, which allows it be able
+ * {@link ActivityManager#PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK}, which allows it be able
* to access network regardless of any power saving restrictions.
*
* @hide
diff --git a/core/java/android/net/NetworkPolicyManager.java b/core/java/android/net/NetworkPolicyManager.java
index 9341105675a2..104a8b2095d8 100644
--- a/core/java/android/net/NetworkPolicyManager.java
+++ b/core/java/android/net/NetworkPolicyManager.java
@@ -475,8 +475,8 @@ public class NetworkPolicyManager {
*
* @param uid The UID whose status needs to be checked.
* @return {@link ConnectivityManager#RESTRICT_BACKGROUND_STATUS_DISABLED},
- * {@link ConnectivityManager##RESTRICT_BACKGROUND_STATUS_ENABLED},
- * or {@link ConnectivityManager##RESTRICT_BACKGROUND_STATUS_WHITELISTED} to denote
+ * {@link ConnectivityManager#RESTRICT_BACKGROUND_STATUS_ENABLED},
+ * or {@link ConnectivityManager#RESTRICT_BACKGROUND_STATUS_WHITELISTED} to denote
* the current status of the UID.
* @hide
*/
@@ -769,6 +769,28 @@ public class NetworkPolicyManager {
}
/**
+ * Returns the default network capabilities
+ * ({@link ActivityManager#PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK
+ * ActivityManager.PROCESS_CAPABILITY_*}) of the specified process state.
+ * This <b>DOES NOT</b> return all default process capabilities for a proc state.
+ * @hide
+ */
+ public static int getDefaultProcessNetworkCapabilities(int procState) {
+ switch (procState) {
+ case ActivityManager.PROCESS_STATE_PERSISTENT:
+ case ActivityManager.PROCESS_STATE_PERSISTENT_UI:
+ case ActivityManager.PROCESS_STATE_TOP:
+ return ActivityManager.PROCESS_CAPABILITY_ALL;
+ case ActivityManager.PROCESS_STATE_BOUND_TOP:
+ case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE:
+ case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
+ return ActivityManager.PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK;
+ default:
+ return ActivityManager.PROCESS_CAPABILITY_NONE;
+ }
+ }
+
+ /**
* Returns true if {@param procState} is considered foreground and as such will be allowed
* to access network when the device is idle or in battery saver mode. Otherwise, false.
* @hide
@@ -784,7 +806,7 @@ public class NetworkPolicyManager {
public static boolean isProcStateAllowedWhileIdleOrPowerSaveMode(
int procState, @ProcessCapability int capability) {
return procState <= FOREGROUND_THRESHOLD_STATE
- || (capability & ActivityManager.PROCESS_CAPABILITY_NETWORK) != 0;
+ || (capability & ActivityManager.PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK) != 0;
}
/** @hide */
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index d7cd61567cc7..ef007746a67f 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -8289,6 +8289,15 @@ public final class Settings {
"accessibility_display_inversion_enabled";
/**
+ * Flag that specifies whether font size has been changed. The flag will
+ * be set when users change the scaled value of font size for the first time.
+ * @hide
+ */
+ @Readable
+ public static final String ACCESSIBILITY_FONT_SCALING_HAS_BEEN_CHANGED =
+ "accessibility_font_scaling_has_been_changed";
+
+ /**
* Setting that specifies whether display color space adjustment is
* enabled.
*
diff --git a/core/java/android/service/autofill/FillEventHistory.java b/core/java/android/service/autofill/FillEventHistory.java
index b0e847cd53f9..5d58120ef5bb 100644
--- a/core/java/android/service/autofill/FillEventHistory.java
+++ b/core/java/android/service/autofill/FillEventHistory.java
@@ -233,6 +233,22 @@ public final class FillEventHistory implements Parcelable {
*/
public static final int TYPE_DATASETS_SHOWN = 5;
+ /**
+ * The app/user requested for a field to be Autofilled.
+ *
+ * This event is fired when the view has been entered (by user or app) in order
+ * to differentiate from FillRequests that have been pretriggered for FillDialogs.
+ *
+ * For example, the user might navigate away from a screen without tapping any
+ * fields. In this case, a FillRequest/FillResponse has been generated, but was
+ * not used for Autofilling. The user did not intend to see an Autofill result,
+ * but a FillRequest was still generated. This is different from when the user
+ * did tap on a field after the pretriggered FillRequest, this event will appear
+ * in the FillEventHistory, signaling that the user did intend to Autofill
+ * something.
+ */
+ public static final int TYPE_VIEW_REQUESTED_AUTOFILL = 6;
+
/** @hide */
@IntDef(prefix = { "TYPE_" }, value = {
TYPE_DATASET_SELECTED,
@@ -240,7 +256,8 @@ public final class FillEventHistory implements Parcelable {
TYPE_AUTHENTICATION_SELECTED,
TYPE_SAVE_SHOWN,
TYPE_CONTEXT_COMMITTED,
- TYPE_DATASETS_SHOWN
+ TYPE_DATASETS_SHOWN,
+ TYPE_VIEW_REQUESTED_AUTOFILL
})
@Retention(RetentionPolicy.SOURCE)
@interface EventIds{}
@@ -659,8 +676,8 @@ public final class FillEventHistory implements Parcelable {
@Nullable AutofillId[] detectedFieldIds,
@Nullable FieldClassification[] detectedFieldClassifications,
int saveDialogNotShowReason, int uiType) {
- mEventType = Preconditions.checkArgumentInRange(eventType, 0, TYPE_DATASETS_SHOWN,
- "eventType");
+ mEventType = Preconditions.checkArgumentInRange(eventType, 0,
+ TYPE_VIEW_REQUESTED_AUTOFILL, "eventType");
mDatasetId = datasetId;
mClientState = clientState;
mSelectedDatasetIds = selectedDatasetIds;
@@ -723,6 +740,8 @@ public final class FillEventHistory implements Parcelable {
return "TYPE_CONTEXT_COMMITTED";
case TYPE_DATASETS_SHOWN:
return "TYPE_DATASETS_SHOWN";
+ case TYPE_VIEW_REQUESTED_AUTOFILL:
+ return "TYPE_VIEW_REQUESTED_AUTOFILL";
default:
return "TYPE_UNKNOWN";
}
diff --git a/core/java/android/service/dreams/DreamActivity.java b/core/java/android/service/dreams/DreamActivity.java
index ff14404f787e..a3892238f1e6 100644
--- a/core/java/android/service/dreams/DreamActivity.java
+++ b/core/java/android/service/dreams/DreamActivity.java
@@ -70,7 +70,7 @@ public class DreamActivity extends Activity {
@Override
public void onDestroy() {
- if (mCallback != null && !isFinishing()) {
+ if (mCallback != null) {
mCallback.onActivityDestroyed();
}
diff --git a/core/java/android/service/dreams/DreamService.java b/core/java/android/service/dreams/DreamService.java
index d79ea8929047..c7099fdd202a 100644
--- a/core/java/android/service/dreams/DreamService.java
+++ b/core/java/android/service/dreams/DreamService.java
@@ -1588,7 +1588,8 @@ public class DreamService extends Service implements Window.Callback {
// If DreamActivity is destroyed, wake up from Dream.
void onActivityDestroyed() {
mActivity = null;
- onDestroy();
+ mWindow = null;
+ detach();
}
}
diff --git a/core/java/android/view/AccessibilityInteractionController.java b/core/java/android/view/AccessibilityInteractionController.java
index 3cf56c0668c8..6804c5ca3e4f 100644
--- a/core/java/android/view/AccessibilityInteractionController.java
+++ b/core/java/android/view/AccessibilityInteractionController.java
@@ -172,7 +172,7 @@ public final class AccessibilityInteractionController {
private boolean isVisibleToAccessibilityService(View view) {
return view != null && (mA11yManager.isRequestFromAccessibilityTool()
- || !view.isAccessibilityDataPrivate());
+ || !view.isAccessibilityDataSensitive());
}
public void findAccessibilityNodeInfoByAccessibilityIdClientThread(
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index df6589e98da6..869efc69872e 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -3114,33 +3114,33 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* Accessibility interactions from services without {@code isAccessibilityTool} set to true are
* disallowed for any of the following conditions:
* <li>this view sets {@link #getFilterTouchesWhenObscured()}.</li>
- * <li>any parent of this view returns true from {@link #isAccessibilityDataPrivate()}.</li>
+ * <li>any parent of this view returns true from {@link #isAccessibilityDataSensitive()}.</li>
* </p>
*/
- public static final int ACCESSIBILITY_DATA_PRIVATE_AUTO = 0x00000000;
+ public static final int ACCESSIBILITY_DATA_SENSITIVE_AUTO = 0x00000000;
/**
* Only allow interactions from {@link android.accessibilityservice.AccessibilityService}s
* with the {@link android.accessibilityservice.AccessibilityServiceInfo#isAccessibilityTool}
* property set to true.
*/
- public static final int ACCESSIBILITY_DATA_PRIVATE_YES = 0x00000001;
+ public static final int ACCESSIBILITY_DATA_SENSITIVE_YES = 0x00000001;
/**
* Allow interactions from all {@link android.accessibilityservice.AccessibilityService}s,
* regardless of their
* {@link android.accessibilityservice.AccessibilityServiceInfo#isAccessibilityTool} property.
*/
- public static final int ACCESSIBILITY_DATA_PRIVATE_NO = 0x00000002;
+ public static final int ACCESSIBILITY_DATA_SENSITIVE_NO = 0x00000002;
/** @hide */
- @IntDef(prefix = { "ACCESSIBILITY_DATA_PRIVATE_" }, value = {
- ACCESSIBILITY_DATA_PRIVATE_AUTO,
- ACCESSIBILITY_DATA_PRIVATE_YES,
- ACCESSIBILITY_DATA_PRIVATE_NO,
+ @IntDef(prefix = { "ACCESSIBILITY_DATA_SENSITIVE_" }, value = {
+ ACCESSIBILITY_DATA_SENSITIVE_AUTO,
+ ACCESSIBILITY_DATA_SENSITIVE_YES,
+ ACCESSIBILITY_DATA_SENSITIVE_NO,
})
@Retention(RetentionPolicy.SOURCE)
- public @interface AccessibilityDataPrivate {}
+ public @interface AccessibilityDataSensitive {}
/**
* Mask for obtaining the bits which specify how to determine
@@ -4611,9 +4611,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* {@link android.accessibilityservice.AccessibilityServiceInfo#isAccessibilityTool} property
* set to true.
*/
- private int mExplicitAccessibilityDataPrivate = ACCESSIBILITY_DATA_PRIVATE_AUTO;
- /** Used to calculate and cache {@link #isAccessibilityDataPrivate()}. */
- private int mInferredAccessibilityDataPrivate = ACCESSIBILITY_DATA_PRIVATE_AUTO;
+ private int mExplicitAccessibilityDataSensitive = ACCESSIBILITY_DATA_SENSITIVE_AUTO;
+ /** Used to calculate and cache {@link #isAccessibilityDataSensitive()}. */
+ private int mInferredAccessibilityDataSensitive = ACCESSIBILITY_DATA_SENSITIVE_AUTO;
/**
* Specifies the id of a view for which this view serves as a label for
@@ -6016,9 +6016,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
setImportantForAccessibility(a.getInt(attr,
IMPORTANT_FOR_ACCESSIBILITY_DEFAULT));
break;
- case R.styleable.View_accessibilityDataPrivate:
- setAccessibilityDataPrivate(a.getInt(attr,
- ACCESSIBILITY_DATA_PRIVATE_AUTO));
+ case R.styleable.View_accessibilityDataSensitive:
+ setAccessibilityDataSensitive(a.getInt(attr,
+ ACCESSIBILITY_DATA_SENSITIVE_AUTO));
break;
case R.styleable.View_accessibilityLiveRegion:
setAccessibilityLiveRegion(a.getInt(attr, ACCESSIBILITY_LIVE_REGION_DEFAULT));
@@ -8660,9 +8660,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* is responsible for handling this call.
* </p>
* <p>
- * If this view sets {@link #isAccessibilityDataPrivate()} then this view should only append
+ * If this view sets {@link #isAccessibilityDataSensitive()} then this view should only append
* sensitive information to an event that also sets
- * {@link AccessibilityEvent#isAccessibilityDataPrivate()}.
+ * {@link AccessibilityEvent#isAccessibilityDataSensitive()}.
* </p>
* <p>
* <em>Note:</em> Accessibility events of certain types are not dispatched for
@@ -10697,6 +10697,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
info.setVisibleToUser(isVisibleToUser());
info.setImportantForAccessibility(isImportantForAccessibility());
+ info.setAccessibilityDataSensitive(isAccessibilityDataSensitive());
info.setPackageName(mContext.getPackageName());
info.setClassName(getAccessibilityClassName());
info.setStateDescription(getStateDescription());
@@ -13581,7 +13582,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
public void setFilterTouchesWhenObscured(boolean enabled) {
setFlags(enabled ? FILTER_TOUCHES_WHEN_OBSCURED : 0,
FILTER_TOUCHES_WHEN_OBSCURED);
- calculateAccessibilityDataPrivate();
+ calculateAccessibilityDataSensitive();
}
/**
@@ -14817,7 +14818,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
// source View's AccessibilityDataPrivate value, and then filtering is done when
// AccessibilityManagerService propagates events to each recipient AccessibilityService.
if (!AccessibilityManager.getInstance(mContext).isRequestFromAccessibilityTool()
- && isAccessibilityDataPrivate()) {
+ && isAccessibilityDataSensitive()) {
return false;
}
}
@@ -14833,43 +14834,43 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* set to true.
*
* <p>
- * See default behavior provided by {@link #ACCESSIBILITY_DATA_PRIVATE_AUTO}. Otherwise,
- * returns true for {@link #ACCESSIBILITY_DATA_PRIVATE_YES} or false for {@link
- * #ACCESSIBILITY_DATA_PRIVATE_NO}.
+ * See default behavior provided by {@link #ACCESSIBILITY_DATA_SENSITIVE_AUTO}. Otherwise,
+ * returns true for {@link #ACCESSIBILITY_DATA_SENSITIVE_YES} or false for {@link
+ * #ACCESSIBILITY_DATA_SENSITIVE_NO}.
* </p>
*
* @return True if this view should restrict accessibility service access to services that have
* the isAccessibilityTool property.
*/
@ViewDebug.ExportedProperty(category = "accessibility")
- public boolean isAccessibilityDataPrivate() {
- if (mInferredAccessibilityDataPrivate == ACCESSIBILITY_DATA_PRIVATE_AUTO) {
- calculateAccessibilityDataPrivate();
+ public boolean isAccessibilityDataSensitive() {
+ if (mInferredAccessibilityDataSensitive == ACCESSIBILITY_DATA_SENSITIVE_AUTO) {
+ calculateAccessibilityDataSensitive();
}
- return mInferredAccessibilityDataPrivate == ACCESSIBILITY_DATA_PRIVATE_YES;
+ return mInferredAccessibilityDataSensitive == ACCESSIBILITY_DATA_SENSITIVE_YES;
}
/**
- * Calculate and cache the inferred value for {@link #isAccessibilityDataPrivate()}.
+ * Calculate and cache the inferred value for {@link #isAccessibilityDataSensitive()}.
*
* <p>
* <strong>Note:</strong> This method needs to be called any time one of the below conditions
* changes, to recalculate the new value.
* </p>
*/
- void calculateAccessibilityDataPrivate() {
+ void calculateAccessibilityDataSensitive() {
// Use the explicit value if set.
- if (mExplicitAccessibilityDataPrivate != ACCESSIBILITY_DATA_PRIVATE_AUTO) {
- mInferredAccessibilityDataPrivate = mExplicitAccessibilityDataPrivate;
+ if (mExplicitAccessibilityDataSensitive != ACCESSIBILITY_DATA_SENSITIVE_AUTO) {
+ mInferredAccessibilityDataSensitive = mExplicitAccessibilityDataSensitive;
} else if (getFilterTouchesWhenObscured()) {
- // Views that set filterTouchesWhenObscured default to accessibilityDataPrivate.
- mInferredAccessibilityDataPrivate = ACCESSIBILITY_DATA_PRIVATE_YES;
- } else if (mParent instanceof View && ((View) mParent).isAccessibilityDataPrivate()) {
- // Descendants of an accessibilityDataPrivate View are also accessibilityDataPrivate.
- mInferredAccessibilityDataPrivate = ACCESSIBILITY_DATA_PRIVATE_YES;
+ // Views that set filterTouchesWhenObscured default to accessibilityDataSensitive.
+ mInferredAccessibilityDataSensitive = ACCESSIBILITY_DATA_SENSITIVE_YES;
+ } else if (mParent instanceof View && ((View) mParent).isAccessibilityDataSensitive()) {
+ // Descendants of accessibilityDataSensitive Views are also accessibilityDataSensitive.
+ mInferredAccessibilityDataSensitive = ACCESSIBILITY_DATA_SENSITIVE_YES;
} else {
- // Otherwise, default to not accessibilityDataPrivate.
- mInferredAccessibilityDataPrivate = ACCESSIBILITY_DATA_PRIVATE_NO;
+ // Otherwise, default to not accessibilityDataSensitive.
+ mInferredAccessibilityDataSensitive = ACCESSIBILITY_DATA_SENSITIVE_NO;
}
}
@@ -14879,10 +14880,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* {@link android.accessibilityservice.AccessibilityServiceInfo#isAccessibilityTool} property
* set to true.
*/
- public void setAccessibilityDataPrivate(
- @AccessibilityDataPrivate int accessibilityDataPrivate) {
- mExplicitAccessibilityDataPrivate = accessibilityDataPrivate;
- calculateAccessibilityDataPrivate();
+ public void setAccessibilityDataSensitive(
+ @AccessibilityDataSensitive int accessibilityDataSensitive) {
+ mExplicitAccessibilityDataSensitive = accessibilityDataSensitive;
+ calculateAccessibilityDataSensitive();
}
/**
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 73d447141cc1..46ae3ea21890 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -3921,10 +3921,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
}
@Override
- void calculateAccessibilityDataPrivate() {
- super.calculateAccessibilityDataPrivate();
+ void calculateAccessibilityDataSensitive() {
+ super.calculateAccessibilityDataSensitive();
for (int i = 0; i < mChildrenCount; i++) {
- mChildren[i].calculateAccessibilityDataPrivate();
+ mChildren[i].calculateAccessibilityDataSensitive();
}
}
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 71a3a7b7cc51..807af5b54081 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -1650,6 +1650,7 @@ public final class ViewRootImpl implements ViewParent,
mAttachInfo.mThreadedRenderer = renderer;
renderer.setSurfaceControl(mSurfaceControl, mBlastBufferQueue);
updateColorModeIfNeeded(attrs.getColorMode());
+ updateRenderHdrSdrRatio();
updateForceDarkMode();
mAttachInfo.mHardwareAccelerated = true;
mAttachInfo.mHardwareAccelerationRequested = true;
@@ -5379,6 +5380,11 @@ public final class ViewRootImpl implements ViewParent,
}
}
+ private void updateRenderHdrSdrRatio() {
+ mRenderHdrSdrRatio = mDisplay.getHdrSdrRatio();
+ mUpdateHdrSdrRatioInfo = true;
+ }
+
private void updateColorModeIfNeeded(@ActivityInfo.ColorMode int colorMode) {
if (mAttachInfo.mThreadedRenderer == null) {
return;
@@ -5396,8 +5402,7 @@ public final class ViewRootImpl implements ViewParent,
float desiredRatio = mAttachInfo.mThreadedRenderer.setColorMode(colorMode);
if (desiredRatio != mDesiredHdrSdrRatio) {
mDesiredHdrSdrRatio = desiredRatio;
- mRenderHdrSdrRatio = mDisplay.getHdrSdrRatio();
- mUpdateHdrSdrRatioInfo = true;
+ updateRenderHdrSdrRatio();
if (mDesiredHdrSdrRatio < 1.01f) {
mDisplay.unregisterHdrSdrRatioChangedListener(mHdrSdrRatioChangedListener);
@@ -8496,6 +8501,7 @@ public final class ViewRootImpl implements ViewParent,
if (mAttachInfo.mThreadedRenderer != null) {
mAttachInfo.mThreadedRenderer.setSurfaceControl(mSurfaceControl, mBlastBufferQueue);
}
+ updateRenderHdrSdrRatio();
if (mPreviousTransformHint != transformHint) {
mPreviousTransformHint = transformHint;
dispatchTransformHintChanged(transformHint);
diff --git a/core/java/android/view/accessibility/AccessibilityEvent.java b/core/java/android/view/accessibility/AccessibilityEvent.java
index 33b763bbf0c0..0acc0228ade4 100644
--- a/core/java/android/view/accessibility/AccessibilityEvent.java
+++ b/core/java/android/view/accessibility/AccessibilityEvent.java
@@ -56,7 +56,7 @@ import java.util.List;
* accessibility service has not requested to retrieve the window content the event will
* not contain reference to its source. <strong>Note: </strong> for events of type
* {@link #TYPE_NOTIFICATION_STATE_CHANGED} the source is never available, and Views that set
- * {@link android.view.View#isAccessibilityDataPrivate()} may not populate all event properties on
+ * {@link android.view.View#isAccessibilityDataSensitive()} may not populate all event properties on
* events sent from higher up in the view hierarchy.
* </p>
* <p>
@@ -1168,17 +1168,17 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par
* set to true.
*
* <p>
- * Initial value matches the {@link android.view.View#isAccessibilityDataPrivate} property from
- * the event's source node, if present, or false by default.
+ * Initial value matches the {@link android.view.View#isAccessibilityDataSensitive} property
+ * from the event's source node, if present, or false by default.
* </p>
*
* @return True if the event should be delivered only to isAccessibilityTool services, false
* otherwise.
- * @see #setAccessibilityDataPrivate
+ * @see #setAccessibilityDataSensitive
*/
@Override
- public boolean isAccessibilityDataPrivate() {
- return super.isAccessibilityDataPrivate();
+ public boolean isAccessibilityDataSensitive() {
+ return super.isAccessibilityDataSensitive();
}
/**
@@ -1193,13 +1193,13 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par
* no source) then this method must be called explicitly if you want non-default behavior.
* </p>
*
- * @param accessibilityDataPrivate True if the event should be delivered only to
+ * @param accessibilityDataSensitive True if the event should be delivered only to
* isAccessibilityTool services, false otherwise.
* @throws IllegalStateException If called from an AccessibilityService.
*/
@Override
- public void setAccessibilityDataPrivate(boolean accessibilityDataPrivate) {
- super.setAccessibilityDataPrivate(accessibilityDataPrivate);
+ public void setAccessibilityDataSensitive(boolean accessibilityDataSensitive) {
+ super.setAccessibilityDataSensitive(accessibilityDataSensitive);
}
/**
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index 247e0262d13f..9d82b7900689 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -834,6 +834,8 @@ public class AccessibilityNodeInfo implements Parcelable {
private static final int BOOLEAN_PROPERTY_REQUEST_TOUCH_PASSTHROUGH = 1 << 25;
+ private static final int BOOLEAN_PROPERTY_ACCESSIBILITY_DATA_SENSITIVE = 1 << 26;
+
/**
* Bits that provide the id of a virtual descendant of a view.
*/
@@ -2644,6 +2646,34 @@ public class AccessibilityNodeInfo implements Parcelable {
}
/**
+ * Gets if the node's accessibility data is considered sensitive.
+ *
+ * @return True if the node is editable, false otherwise.
+ * @see View#isAccessibilityDataSensitive()
+ */
+ public boolean isAccessibilityDataSensitive() {
+ return getBooleanProperty(BOOLEAN_PROPERTY_ACCESSIBILITY_DATA_SENSITIVE);
+ }
+
+ /**
+ * Sets whether this node's accessibility data is considered sensitive.
+ *
+ * <p>
+ * <strong>Note:</strong> Cannot be called from an {@link AccessibilityService}.
+ * This class is made immutable before being delivered to an AccessibilityService.
+ * </p>
+ *
+ * @param accessibilityDataSensitive True if the node's accessibility data is considered
+ * sensitive.
+ * @throws IllegalStateException If called from an AccessibilityService.
+ * @see View#setAccessibilityDataSensitive
+ */
+ public void setAccessibilityDataSensitive(boolean accessibilityDataSensitive) {
+ setBooleanProperty(BOOLEAN_PROPERTY_ACCESSIBILITY_DATA_SENSITIVE,
+ accessibilityDataSensitive);
+ }
+
+ /**
* If this node represents a visually distinct region of the screen that may update separately
* from the rest of the window, it is considered a pane. Set the pane title to indicate that
* the node is a pane, and to provide a title for it.
diff --git a/core/java/android/view/accessibility/AccessibilityRecord.java b/core/java/android/view/accessibility/AccessibilityRecord.java
index 789c740bbba2..38b564ade07d 100644
--- a/core/java/android/view/accessibility/AccessibilityRecord.java
+++ b/core/java/android/view/accessibility/AccessibilityRecord.java
@@ -72,7 +72,7 @@ public class AccessibilityRecord {
private static final int PROPERTY_FULL_SCREEN = 0x00000080;
private static final int PROPERTY_SCROLLABLE = 0x00000100;
private static final int PROPERTY_IMPORTANT_FOR_ACCESSIBILITY = 0x00000200;
- private static final int PROPERTY_ACCESSIBILITY_DATA_PRIVATE = 0x00000400;
+ private static final int PROPERTY_ACCESSIBILITY_DATA_SENSITIVE = 0x00000400;
private static final int GET_SOURCE_PREFETCH_FLAGS =
AccessibilityNodeInfo.FLAG_PREFETCH_ANCESTORS
@@ -160,8 +160,8 @@ public class AccessibilityRecord {
important = root.isImportantForAccessibility();
rootViewId = root.getAccessibilityViewId();
mSourceWindowId = root.getAccessibilityWindowId();
- setBooleanProperty(PROPERTY_ACCESSIBILITY_DATA_PRIVATE,
- root.isAccessibilityDataPrivate());
+ setBooleanProperty(PROPERTY_ACCESSIBILITY_DATA_SENSITIVE,
+ root.isAccessibilityDataSensitive());
}
setBooleanProperty(PROPERTY_IMPORTANT_FOR_ACCESSIBILITY, important);
mSourceNodeId = AccessibilityNodeInfo.makeNodeId(rootViewId, virtualDescendantId);
@@ -391,20 +391,20 @@ public class AccessibilityRecord {
}
/**
- * @see AccessibilityEvent#isAccessibilityDataPrivate
+ * @see AccessibilityEvent#isAccessibilityDataSensitive
* @hide
*/
- boolean isAccessibilityDataPrivate() {
- return getBooleanProperty(PROPERTY_ACCESSIBILITY_DATA_PRIVATE);
+ boolean isAccessibilityDataSensitive() {
+ return getBooleanProperty(PROPERTY_ACCESSIBILITY_DATA_SENSITIVE);
}
/**
- * @see AccessibilityEvent#setAccessibilityDataPrivate
+ * @see AccessibilityEvent#setAccessibilityDataSensitive
* @hide
*/
- void setAccessibilityDataPrivate(boolean accessibilityDataPrivate) {
+ void setAccessibilityDataSensitive(boolean accessibilityDataSensitive) {
enforceNotSealed();
- setBooleanProperty(PROPERTY_ACCESSIBILITY_DATA_PRIVATE, accessibilityDataPrivate);
+ setBooleanProperty(PROPERTY_ACCESSIBILITY_DATA_SENSITIVE, accessibilityDataSensitive);
}
/**
@@ -962,7 +962,7 @@ public class AccessibilityRecord {
appendUnless(false, PROPERTY_FULL_SCREEN, builder);
appendUnless(false, PROPERTY_SCROLLABLE, builder);
appendUnless(false, PROPERTY_IMPORTANT_FOR_ACCESSIBILITY, builder);
- appendUnless(false, PROPERTY_ACCESSIBILITY_DATA_PRIVATE, builder);
+ appendUnless(false, PROPERTY_ACCESSIBILITY_DATA_SENSITIVE, builder);
append(builder, "BeforeText", mBeforeText);
append(builder, "FromIndex", mFromIndex);
@@ -996,8 +996,8 @@ public class AccessibilityRecord {
case PROPERTY_SCROLLABLE: return "Scrollable";
case PROPERTY_IMPORTANT_FOR_ACCESSIBILITY:
return "ImportantForAccessibility";
- case PROPERTY_ACCESSIBILITY_DATA_PRIVATE:
- return "AccessibilityDataPrivate";
+ case PROPERTY_ACCESSIBILITY_DATA_SENSITIVE:
+ return "AccessibilityDataSensitive";
default: return Integer.toHexString(prop);
}
}
diff --git a/core/java/android/view/contentcapture/ContentCaptureSession.java b/core/java/android/view/contentcapture/ContentCaptureSession.java
index b7f03e1d6d72..3387d386188b 100644
--- a/core/java/android/view/contentcapture/ContentCaptureSession.java
+++ b/core/java/android/view/contentcapture/ContentCaptureSession.java
@@ -182,6 +182,7 @@ public abstract class ContentCaptureSession implements AutoCloseable {
/** @hide */
public static final int FLUSH_REASON_VIEW_TREE_APPEARED = 10;
+ /** TODO(b/271015194) */
@ChangeId
@EnabledSince(targetSdkVersion = UPSIDE_DOWN_CAKE)
static final long NOTIFY_NODES_DISAPPEAR_NOW_SENDS_TREE_EVENTS = 258825825L;
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index fd8f5495464c..1600a16566a5 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -13221,10 +13221,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
public void onPopulateAccessibilityEventInternal(AccessibilityEvent event) {
super.onPopulateAccessibilityEventInternal(event);
- if (this.isAccessibilityDataPrivate() && !event.isAccessibilityDataPrivate()) {
- // This view's accessibility data is private, but another view that generated this event
- // is not, so don't append this view's text to the event in order to prevent sharing
- // this view's contents with non-accessibility-tool services.
+ if (this.isAccessibilityDataSensitive() && !event.isAccessibilityDataSensitive()) {
+ // This view's accessibility data is sensitive, but another view that generated this
+ // event is not, so don't append this view's text to the event in order to prevent
+ // sharing this view's contents with non-accessibility-tool services.
return;
}
diff --git a/core/java/com/android/internal/compat/ChangeReporter.java b/core/java/com/android/internal/compat/ChangeReporter.java
index b9d3df678a91..8369a303889d 100644
--- a/core/java/com/android/internal/compat/ChangeReporter.java
+++ b/core/java/com/android/internal/compat/ChangeReporter.java
@@ -42,6 +42,7 @@ import java.util.Set;
public final class ChangeReporter {
private static final String TAG = "CompatibilityChangeReporter";
private int mSource;
+ private static final boolean sShouldReport = false;
private static final class ChangeReport {
long mChangeId;
@@ -89,14 +90,16 @@ public final class ChangeReporter {
* @param state of the reported change - enabled/disabled/only logged
*/
public void reportChange(int uid, long changeId, int state) {
- if (shouldWriteToStatsLog(uid, changeId, state)) {
- FrameworkStatsLog.write(FrameworkStatsLog.APP_COMPATIBILITY_CHANGE_REPORTED, uid,
- changeId, state, mSource);
- }
- if (shouldWriteToDebug(uid, changeId, state)) {
- debugLog(uid, changeId, state);
+ if (sShouldReport) {
+ if (shouldWriteToStatsLog(uid, changeId, state)) {
+ FrameworkStatsLog.write(FrameworkStatsLog.APP_COMPATIBILITY_CHANGE_REPORTED, uid,
+ changeId, state, mSource);
+ }
+ if (shouldWriteToDebug(uid, changeId, state)) {
+ debugLog(uid, changeId, state);
+ }
+ markAsReported(uid, new ChangeReport(changeId, state));
}
- markAsReported(uid, new ChangeReport(changeId, state));
}
/**
diff --git a/core/java/com/android/internal/os/ProcessCpuTracker.java b/core/java/com/android/internal/os/ProcessCpuTracker.java
index 65655b7b5a66..70514c30d90d 100644
--- a/core/java/com/android/internal/os/ProcessCpuTracker.java
+++ b/core/java/com/android/internal/os/ProcessCpuTracker.java
@@ -80,10 +80,6 @@ public class ProcessCpuTracker {
/** Stores user time and system time in jiffies. */
private final long[] mProcessStatsData = new long[4];
- /** Stores user time and system time in jiffies. Used for
- * public API to retrieve CPU use for a process. Must lock while in use. */
- private final long[] mSinglePidStatsData = new long[4];
-
private static final int[] PROCESS_FULL_STATS_FORMAT = new int[] {
PROC_SPACE_TERM,
PROC_SPACE_TERM|PROC_PARENS|PROC_OUT_STRING, // 2: name
@@ -629,17 +625,15 @@ public class ProcessCpuTracker {
* executing in both user and system code. Safe to call without lock held.
*/
public long getCpuTimeForPid(int pid) {
- synchronized (mSinglePidStatsData) {
- final String statFile = "/proc/" + pid + "/stat";
- final long[] statsData = mSinglePidStatsData;
- if (Process.readProcFile(statFile, PROCESS_STATS_FORMAT,
- null, statsData, null)) {
- long time = statsData[PROCESS_STAT_UTIME]
+ final String statFile = "/proc/" + pid + "/stat";
+ final long[] statsData = new long[4];
+ if (Process.readProcFile(statFile, PROCESS_STATS_FORMAT,
+ null, statsData, null)) {
+ long time = statsData[PROCESS_STAT_UTIME]
+ statsData[PROCESS_STAT_STIME];
- return time * mJiffyMillis;
- }
- return 0;
+ return time * mJiffyMillis;
}
+ return 0;
}
/**
@@ -647,15 +641,13 @@ public class ProcessCpuTracker {
* in the runqueue. Safe to call without lock held.
*/
public long getCpuDelayTimeForPid(int pid) {
- synchronized (mSinglePidStatsData) {
- final String statFile = "/proc/" + pid + "/schedstat";
- final long[] statsData = mSinglePidStatsData;
- if (Process.readProcFile(statFile, PROCESS_SCHEDSTATS_FORMAT,
- null, statsData, null)) {
- return statsData[PROCESS_SCHEDSTAT_CPU_DELAY_TIME] / 1_000_000;
- }
- return 0;
+ final String statFile = "/proc/" + pid + "/schedstat";
+ final long[] statsData = new long[4];
+ if (Process.readProcFile(statFile, PROCESS_SCHEDSTATS_FORMAT,
+ null, statsData, null)) {
+ return statsData[PROCESS_SCHEDSTAT_CPU_DELAY_TIME] / 1_000_000;
}
+ return 0;
}
/**
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 59f6d2b29481..b86020eb90ea 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -133,6 +133,21 @@ public class LockPatternUtils {
})
public @interface CredentialType {}
+ public static String credentialTypeToString(int credentialType) {
+ switch (credentialType) {
+ case CREDENTIAL_TYPE_NONE:
+ return "NONE";
+ case CREDENTIAL_TYPE_PATTERN:
+ return "PATTERN";
+ case CREDENTIAL_TYPE_PIN:
+ return "PIN";
+ case CREDENTIAL_TYPE_PASSWORD:
+ return "PASSWORD";
+ default:
+ return "UNKNOWN_" + credentialType;
+ }
+ }
+
/**
* Flag provided to {@link #verifyCredential(LockscreenCredential, int, int)} . If set, the
* method will return a handle to the Gatekeeper Password in the
diff --git a/core/proto/android/providers/settings/secure.proto b/core/proto/android/providers/settings/secure.proto
index 8caf12773260..a5d287c3e4b2 100644
--- a/core/proto/android/providers/settings/secure.proto
+++ b/core/proto/android/providers/settings/secure.proto
@@ -95,6 +95,8 @@ message SecureSettingsProto {
optional SettingProto hearing_aid_media_routing = 48 [ (android.privacy).dest = DEST_AUTOMATIC ];
optional SettingProto hearing_aid_system_sounds_routing = 49 [ (android.privacy).dest = DEST_AUTOMATIC ];
optional SettingProto accessibility_magnification_joystick_enabled = 50 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ // Settings for font scaling
+ optional SettingProto accessibility_font_scaling_has_been_changed = 51 [ (android.privacy).dest = DEST_AUTOMATIC ];
}
optional Accessibility accessibility = 2;
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 9252b149797b..2a67b44d6416 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -3201,8 +3201,8 @@
<!-- Describes whether this view should allow interactions from AccessibilityServices only
if the service sets the isAccessibilityTool property. -->
- <attr name="accessibilityDataPrivate" format="integer">
- <!-- The system determines whether the view's accessibility data is private
+ <attr name="accessibilityDataSensitive" format="integer">
+ <!-- The system determines whether the view's accessibility data is sensitive
- default (recommended). -->
<enum name="auto" value="0" />
<!-- Allow interactions from AccessibilityServices only if the service sets the
diff --git a/core/res/res/values/public-staging.xml b/core/res/res/values/public-staging.xml
index ee021001a54a..69d5feff2de9 100644
--- a/core/res/res/values/public-staging.xml
+++ b/core/res/res/values/public-staging.xml
@@ -114,7 +114,7 @@
<public name="handwritingBoundsOffsetTop" />
<public name="handwritingBoundsOffsetRight" />
<public name="handwritingBoundsOffsetBottom" />
- <public name="accessibilityDataPrivate" />
+ <public name="accessibilityDataSensitive" />
<public name="enableTextStylingShortcuts" />
<public name="requiredDisplayCategory"/>
<public name="removed_maxConcurrentSessionsCount" />
diff --git a/core/res/res/xml/irq_device_map.xml b/core/res/res/xml/irq_device_map.xml
index 86a44d6a9fe0..4fae8fb77687 100644
--- a/core/res/res/xml/irq_device_map.xml
+++ b/core/res/res/xml/irq_device_map.xml
@@ -17,14 +17,15 @@
*/
-->
<irq-device-map>
- <!-- This file maps devices (chips) that can send IRQs to the CPU (and bring it out of sleep) to
- logical subsystems in userspace code. Since each Android device has its own uniquely
- designed chipset, this mapping is expected to be empty by default and should be overridden
- by device specific configs.
+ <!-- This file maps devices (chips) that can send interrupts to the main processor (and bring it
+ out of sleep) to logical subsystems in userspace code. Since each Android device has its own
+ uniquely designed chipset, this mapping is expected to be empty by default and should be
+ overridden by device-specific configs.
This mapping helps the system to meaningfully attribute CPU wakeups to logical work that
happened on the device. The devices are referred to by their names as defined in the kernel.
- Currently defined subsystems are:
+ Currently, defined subsystems are:
- Alarm: Use this to denote wakeup alarms requested by apps via the AlarmManager API.
+ - Wifi: Use this to denote network traffic that uses the wifi transport.
The overlay should use tags <device> and <subsystem> to describe this mapping in the
following way:
diff --git a/core/tests/coretests/src/android/view/accessibility/AccessibilityNodeInfoTest.java b/core/tests/coretests/src/android/view/accessibility/AccessibilityNodeInfoTest.java
index 6d635af20645..3d4918b1bd42 100644
--- a/core/tests/coretests/src/android/view/accessibility/AccessibilityNodeInfoTest.java
+++ b/core/tests/coretests/src/android/view/accessibility/AccessibilityNodeInfoTest.java
@@ -58,7 +58,7 @@ public class AccessibilityNodeInfoTest {
// The number of flags held in boolean properties. Their values should also be double-checked
// in the methods above.
- private static final int NUM_BOOLEAN_PROPERTIES = 26;
+ private static final int NUM_BOOLEAN_PROPERTIES = 27;
@Test
public void testStandardActions_serializationFlagIsValid() {
diff --git a/core/tests/overlaytests/device/Android.bp b/core/tests/overlaytests/device/Android.bp
index 0d3b15a41e8c..2b22344a4ef2 100644
--- a/core/tests/overlaytests/device/Android.bp
+++ b/core/tests/overlaytests/device/Android.bp
@@ -29,6 +29,7 @@ android_test {
static_libs: [
"androidx.test.rules",
"testng",
+ "compatibility-device-util-axt",
],
test_suites: ["device-tests"],
data: [
diff --git a/core/tests/overlaytests/device/src/com/android/overlaytest/OverlayBaseTest.java b/core/tests/overlaytests/device/src/com/android/overlaytest/OverlayBaseTest.java
index 8e4b9efafccd..fcf71ed39ef5 100644
--- a/core/tests/overlaytests/device/src/com/android/overlaytest/OverlayBaseTest.java
+++ b/core/tests/overlaytests/device/src/com/android/overlaytest/OverlayBaseTest.java
@@ -37,10 +37,12 @@ import android.view.View;
import androidx.test.InstrumentationRegistry;
+import com.android.compatibility.common.util.AmUtils;
import com.android.internal.util.ArrayUtils;
import com.android.overlaytest.view.TestTextView;
import org.junit.Before;
+import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
@@ -70,6 +72,13 @@ public abstract class OverlayBaseTest {
mMode = mode;
}
+ @BeforeClass
+ public static void setUpClass() {
+ // Wait for package_added broadcasts to be handled so that OverlayManagerService
+ // can update it's internal state with the new packages.
+ AmUtils.waitForBroadcastBarrier();
+ }
+
@Before
public void setUp() {
mContext = InstrumentationRegistry.getContext();
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index 3d81d37aff20..05e17720b175 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -271,6 +271,12 @@
"group": "WM_DEBUG_APP_TRANSITIONS_ANIM",
"at": "com\/android\/server\/wm\/AppTransition.java"
},
+ "-1868518158": {
+ "message": "Pending back animation due to another animation is running",
+ "level": "WARN",
+ "group": "WM_DEBUG_BACK_PREVIEW",
+ "at": "com\/android\/server\/wm\/BackNavigationController.java"
+ },
"-1868124841": {
"message": "screenOnEarly=%b, awake=%b, currentAppOrientation=%d, orientationSensorEnabled=%b, keyguardDrawComplete=%b, windowManagerDrawComplete=%b",
"level": "VERBOSE",
@@ -1549,6 +1555,12 @@
"group": "WM_DEBUG_ORIENTATION",
"at": "com\/android\/server\/wm\/DragState.java"
},
+ "-692907078": {
+ "message": "Handling the deferred animation after transition finished",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_BACK_PREVIEW",
+ "at": "com\/android\/server\/wm\/BackNavigationController.java"
+ },
"-677449371": {
"message": "moveTaskToRootTask: moving task=%d to rootTaskId=%d toTop=%b",
"level": "DEBUG",
diff --git a/graphics/java/android/graphics/Gainmap.java b/graphics/java/android/graphics/Gainmap.java
index a7c508c75ac9..feedb7d3e2bf 100644
--- a/graphics/java/android/graphics/Gainmap.java
+++ b/graphics/java/android/graphics/Gainmap.java
@@ -63,20 +63,20 @@ import libcore.util.NativeAllocationRegistry;
* as follows:
*
* First, let W be a weight parameter determining how much the gainmap will be applied.
- * W = clamp((log(H) - log(displayRatioHdr)) /
- * (log(displayRatioHdr) - log(displayRatioSdr), 0, 1)
+ * W = clamp((log(H) - log(minDisplayRatioForHdrTransition)) /
+ * (log(displayRatioForFullHdr) - log(minDisplayRatioForHdrTransition), 0, 1)
*
* Next, let L be the gainmap value in log space. We compute this from the value G that was
* sampled from the texture as follows:
- * L = mix(log(gainmapRatioMin), log(gainmapRatioMax), pow(G, gainmapGamma))
+ * L = mix(log(ratioMin), log(ratioMax), pow(G, gamma))
*
* Finally, apply the gainmap to compute D, the displayed pixel. If the base image is SDR then
* compute:
* D = (B + epsilonSdr) * exp(L * W) - epsilonHdr
- * If the base image is HDR then compute:
- * D = (B + epsilonHdr) * exp(L * (W - 1)) - epsilonSdr
*
- * In the above math, log() is a natural logarithm and exp() is natural exponentiation.
+ * In the above math, log() is a natural logarithm and exp() is natural exponentiation. The base
+ * for these functions cancels out and does not affect the result, so other bases may be used
+ * if preferred.
*/
public final class Gainmap implements Parcelable {
diff --git a/libs/WindowManager/Shell/res/color/split_divider_background.xml b/libs/WindowManager/Shell/res/color-night/taskbar_background.xml
index 049980803ee3..9473cdd607d6 100644
--- a/libs/WindowManager/Shell/res/color/split_divider_background.xml
+++ b/libs/WindowManager/Shell/res/color-night/taskbar_background.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
- ~ Copyright (C) 2021 The Android Open Source Project
+ ~ Copyright (C) 2023 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
@@ -14,6 +14,7 @@
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
+<!-- Should be the same as in packages/apps/Launcher3/res/color-night-v31/taskbar_background.xml -->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@android:color/system_neutral1_500" android:lStar="15" />
</selector> \ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/color/taskbar_background.xml b/libs/WindowManager/Shell/res/color/taskbar_background.xml
index b3d260299106..0e165fca4fd3 100644
--- a/libs/WindowManager/Shell/res/color/taskbar_background.xml
+++ b/libs/WindowManager/Shell/res/color/taskbar_background.xml
@@ -16,5 +16,5 @@
-->
<!-- Should be the same as in packages/apps/Launcher3/res/color-v31/taskbar_background.xml -->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:color="@android:color/system_neutral1_500" android:lStar="15" />
+ <item android:color="@android:color/system_neutral1_500" android:lStar="95" />
</selector> \ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/values-night/colors.xml b/libs/WindowManager/Shell/res/values-night/colors.xml
index 83c4d93982f4..5c6bb57a7f1c 100644
--- a/libs/WindowManager/Shell/res/values-night/colors.xml
+++ b/libs/WindowManager/Shell/res/values-night/colors.xml
@@ -15,6 +15,7 @@
-->
<resources>
+ <color name="docked_divider_handle">#ffffff</color>
<!-- Bubbles -->
<color name="bubbles_icon_tint">@color/GM2_grey_200</color>
<!-- Splash screen-->
diff --git a/libs/WindowManager/Shell/res/values/colors.xml b/libs/WindowManager/Shell/res/values/colors.xml
index 965ab1519df4..6fb70006e67f 100644
--- a/libs/WindowManager/Shell/res/values/colors.xml
+++ b/libs/WindowManager/Shell/res/values/colors.xml
@@ -17,7 +17,8 @@
*/
-->
<resources>
- <color name="docked_divider_handle">#ffffff</color>
+ <color name="docked_divider_handle">#000000</color>
+ <color name="split_divider_background">@color/taskbar_background</color>
<drawable name="forced_resizable_background">#59000000</drawable>
<color name="minimize_dock_shadow_start">#60000000</color>
<color name="minimize_dock_shadow_end">#00000000</color>
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 b3fff1d05263..0b8759890359 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
@@ -552,6 +552,9 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
if (runner.isWaitingAnimation()) {
ProtoLog.w(WM_SHELL_BACK_PREVIEW, "Gesture released, but animation didn't ready.");
return;
+ } else if (runner.isAnimationCancelled()) {
+ invokeOrCancelBack();
+ return;
}
startPostCommitAnimation();
}
@@ -653,7 +656,19 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
}
@Override
- public void onAnimationCancelled() { }
+ public void onAnimationCancelled() {
+ mShellExecutor.execute(() -> {
+ final BackAnimationRunner runner = mAnimationDefinition.get(
+ mBackNavigationInfo.getType());
+ if (runner == null) {
+ return;
+ }
+ runner.cancelAnimation();
+ if (!mBackGestureStarted) {
+ invokeOrCancelBack();
+ }
+ });
+ }
};
mBackAnimationAdapter = new BackAnimationAdapter(runner);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationRunner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationRunner.java
index d70b8f53a911..82c523f337db 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationRunner.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationRunner.java
@@ -41,6 +41,9 @@ class BackAnimationRunner {
// Whether we are waiting to receive onAnimationStart
private boolean mWaitingAnimation;
+ /** True when the back animation is cancelled */
+ private boolean mAnimationCancelled;
+
BackAnimationRunner(@NonNull IOnBackInvokedCallback callback,
@NonNull IRemoteAnimationRunner runner) {
mCallback = callback;
@@ -81,9 +84,19 @@ class BackAnimationRunner {
void startGesture() {
mWaitingAnimation = true;
+ mAnimationCancelled = false;
}
boolean isWaitingAnimation() {
return mWaitingAnimation;
}
+
+ void cancelAnimation() {
+ mWaitingAnimation = false;
+ mAnimationCancelled = true;
+ }
+
+ boolean isAnimationCancelled() {
+ return mAnimationCancelled;
+ }
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
index 7ac4d51c1502..b447a543989e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
@@ -120,6 +120,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
private int mOrientation;
private int mRotation;
private int mDensity;
+ private int mUiMode;
private final boolean mDimNonImeSide;
private ValueAnimator mDividerFlingAnimator;
@@ -295,10 +296,12 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
final Rect rootBounds = configuration.windowConfiguration.getBounds();
final int orientation = configuration.orientation;
final int density = configuration.densityDpi;
+ final int uiMode = configuration.uiMode;
if (mOrientation == orientation
&& mRotation == rotation
&& mDensity == density
+ && mUiMode == uiMode
&& mRootBounds.equals(rootBounds)) {
return false;
}
@@ -310,6 +313,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
mRootBounds.set(rootBounds);
mRotation = rotation;
mDensity = density;
+ mUiMode = uiMode;
mDividerSnapAlgorithm = getSnapAlgorithm(mContext, mRootBounds, null);
updateDividerConfig(mContext);
initDividerPosition(mTempRect);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
index 427d79e3a1b9..225258773013 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
@@ -20,7 +20,6 @@ import static android.app.ActivityOptions.KEY_LAUNCH_ROOT_TASK_TOKEN;
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
import static android.app.ComponentOptions.KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED;
import static android.app.ComponentOptions.KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED_BY_PERMISSION;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
@@ -661,6 +660,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
@Nullable Bundle options2, @SplitPosition int splitPosition, float splitRatio,
@Nullable RemoteTransition remoteTransition, InstanceId instanceId) {
final WindowContainerTransaction wct = new WindowContainerTransaction();
+ prepareEvictChildTasksIfSplitActive(wct);
setSideStagePosition(splitPosition, wct);
options1 = options1 != null ? options1 : new Bundle();
addActivityOptions(options1, mSideStage);
@@ -675,6 +675,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
@SplitPosition int splitPosition, float splitRatio,
@Nullable RemoteTransition remoteTransition, InstanceId instanceId) {
final WindowContainerTransaction wct = new WindowContainerTransaction();
+ prepareEvictChildTasksIfSplitActive(wct);
setSideStagePosition(splitPosition, wct);
options1 = options1 != null ? options1 : new Bundle();
addActivityOptions(options1, mSideStage);
@@ -688,6 +689,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
int taskId, @Nullable Bundle options2, @SplitPosition int splitPosition,
float splitRatio, @Nullable RemoteTransition remoteTransition, InstanceId instanceId) {
final WindowContainerTransaction wct = new WindowContainerTransaction();
+ prepareEvictChildTasksIfSplitActive(wct);
setSideStagePosition(splitPosition, wct);
options1 = options1 != null ? options1 : new Bundle();
addActivityOptions(options1, mSideStage);
@@ -706,10 +708,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
private void startWithTask(WindowContainerTransaction wct, int mainTaskId,
@Nullable Bundle mainOptions, float splitRatio,
@Nullable RemoteTransition remoteTransition, InstanceId instanceId) {
- if (mMainStage.isActive()) {
- mMainStage.evictAllChildren(wct);
- mSideStage.evictAllChildren(wct);
- } else {
+ if (!mMainStage.isActive()) {
// Build a request WCT that will launch both apps such that task 0 is on the main stage
// while task 1 is on the side stage.
mMainStage.activate(wct, false /* reparent */);
@@ -1020,6 +1019,13 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
mSideStage.evictInvisibleChildren(wct);
}
+ void prepareEvictChildTasksIfSplitActive(WindowContainerTransaction wct) {
+ if (mMainStage.isActive()) {
+ mMainStage.evictAllChildren(wct);
+ mSideStage.evictAllChildren(wct);
+ }
+ }
+
Bundle resolveStartStage(@StageType int stage, @SplitPosition int position,
@Nullable Bundle options, @Nullable WindowContainerTransaction wct) {
switch (stage) {
@@ -2160,19 +2166,11 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
}
} else if (isOpening && inFullscreen) {
final int activityType = triggerTask.getActivityType();
- if (activityType == ACTIVITY_TYPE_ASSISTANT) {
- // We don't want assistant panel to dismiss split screen, so do nothing.
- } else if (activityType == ACTIVITY_TYPE_HOME
+ if (activityType == ACTIVITY_TYPE_HOME
|| activityType == ACTIVITY_TYPE_RECENTS) {
// Enter overview panel, so start recent transition.
mSplitTransitions.setRecentTransition(transition, request.getRemoteTransition(),
mRecentTransitionFinishedCallback);
- } else if (mSplitTransitions.mPendingRecent == null) {
- // If split-task is not controlled by recents animation
- // and occluded by the other fullscreen task, dismiss both.
- prepareExitSplitScreen(STAGE_TYPE_UNDEFINED, out);
- mSplitTransitions.setDismissTransition(
- transition, STAGE_TYPE_UNDEFINED, EXIT_REASON_UNKNOWN);
}
}
} else {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellInit.java b/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellInit.java
index ac52235375c4..2e2f569a52b8 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellInit.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellInit.java
@@ -21,6 +21,7 @@ import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_INIT;
import android.os.Build;
import android.os.SystemClock;
import android.util.Pair;
+import android.view.SurfaceControl;
import androidx.annotation.VisibleForTesting;
@@ -75,6 +76,7 @@ public class ShellInit {
@VisibleForTesting
public void init() {
ProtoLog.v(WM_SHELL_INIT, "Initializing Shell Components: %d", mInitCallbacks.size());
+ SurfaceControl.setDebugUsageAfterRelease(true);
// Init in order of registration
for (int i = 0; i < mInitCallbacks.size(); i++) {
final Pair<String, Runnable> info = mInitCallbacks.get(i);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/util/TransitionUtil.java b/libs/WindowManager/Shell/src/com/android/wm/shell/util/TransitionUtil.java
index 145f759d4de2..8c6e1e7f5f1b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/util/TransitionUtil.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/util/TransitionUtil.java
@@ -16,18 +16,40 @@
package com.android.wm.shell.util;
+import static android.app.ActivityTaskManager.INVALID_TASK_ID;
+import static android.view.RemoteAnimationTarget.MODE_CHANGING;
+import static android.view.RemoteAnimationTarget.MODE_CLOSING;
+import static android.view.RemoteAnimationTarget.MODE_OPENING;
+import static android.view.WindowManager.LayoutParams.INVALID_WINDOW_TYPE;
+import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
import static android.view.WindowManager.TRANSIT_CHANGE;
import static android.view.WindowManager.TRANSIT_CLOSE;
import static android.view.WindowManager.TRANSIT_KEYGUARD_GOING_AWAY;
import static android.view.WindowManager.TRANSIT_OPEN;
import static android.view.WindowManager.TRANSIT_TO_BACK;
import static android.view.WindowManager.TRANSIT_TO_FRONT;
+import static android.window.TransitionInfo.FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY;
import static android.window.TransitionInfo.FLAG_IS_DISPLAY;
+import static android.window.TransitionInfo.FLAG_IS_WALLPAPER;
+import static android.window.TransitionInfo.FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT;
+
+import static com.android.wm.shell.common.split.SplitScreenConstants.FLAG_IS_DIVIDER_BAR;
import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SuppressLint;
+import android.app.ActivityManager;
+import android.app.WindowConfiguration;
+import android.graphics.Rect;
+import android.util.ArrayMap;
+import android.util.SparseBooleanArray;
+import android.view.RemoteAnimationTarget;
+import android.view.SurfaceControl;
import android.view.WindowManager;
import android.window.TransitionInfo;
+import java.util.function.Predicate;
+
/** Various utility functions for transitions. */
public class TransitionUtil {
@@ -54,4 +76,189 @@ public class TransitionUtil {
return false;
}
+ /** Returns `true` if `change` is a wallpaper. */
+ public static boolean isWallpaper(TransitionInfo.Change change) {
+ return (change.getTaskInfo() == null)
+ && change.hasFlags(FLAG_IS_WALLPAPER)
+ && !change.hasFlags(FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY);
+ }
+
+ /** Returns `true` if `change` is not an app window or wallpaper. */
+ public static boolean isNonApp(TransitionInfo.Change change) {
+ return (change.getTaskInfo() == null)
+ && !change.hasFlags(FLAG_IS_WALLPAPER)
+ && !change.hasFlags(FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY);
+ }
+
+ /**
+ * Filter that selects leaf-tasks only. THIS IS ORDER-DEPENDENT! For it to work properly, you
+ * MUST call `test` in the same order that the changes appear in the TransitionInfo.
+ */
+ public static class LeafTaskFilter implements Predicate<TransitionInfo.Change> {
+ private final SparseBooleanArray mChildTaskTargets = new SparseBooleanArray();
+
+ @Override
+ public boolean test(TransitionInfo.Change change) {
+ final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
+ // Children always come before parent since changes are in top-to-bottom z-order.
+ if ((taskInfo == null) || mChildTaskTargets.get(taskInfo.taskId)) {
+ // has children, so not a leaf. Skip.
+ return false;
+ }
+ if (taskInfo.hasParentTask()) {
+ mChildTaskTargets.put(taskInfo.parentTaskId, true);
+ }
+ return true;
+ }
+ }
+
+
+ private static int newModeToLegacyMode(int newMode) {
+ switch (newMode) {
+ case WindowManager.TRANSIT_OPEN:
+ case WindowManager.TRANSIT_TO_FRONT:
+ return MODE_OPENING;
+ case WindowManager.TRANSIT_CLOSE:
+ case WindowManager.TRANSIT_TO_BACK:
+ return MODE_CLOSING;
+ default:
+ return MODE_CHANGING;
+ }
+ }
+
+ /**
+ * Very similar to Transitions#setupAnimHierarchy but specialized for leashes.
+ */
+ @SuppressLint("NewApi")
+ private static void setupLeash(@NonNull SurfaceControl leash,
+ @NonNull TransitionInfo.Change change, int layer,
+ @NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction t) {
+ final boolean isOpening = TransitionUtil.isOpeningType(info.getType());
+ // Put animating stuff above this line and put static stuff below it.
+ int zSplitLine = info.getChanges().size();
+ // changes should be ordered top-to-bottom in z
+ final int mode = change.getMode();
+
+ t.reparent(leash, info.getRootLeash());
+ final Rect absBounds =
+ (mode == TRANSIT_OPEN) ? change.getEndAbsBounds() : change.getStartAbsBounds();
+ t.setPosition(leash, absBounds.left - info.getRootOffset().x,
+ absBounds.top - info.getRootOffset().y);
+
+ // Put all the OPEN/SHOW on top
+ if (TransitionUtil.isOpeningType(mode)) {
+ if (isOpening) {
+ t.setLayer(leash, zSplitLine + info.getChanges().size() - layer);
+ if ((change.getFlags() & FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT) == 0) {
+ // if transferred, it should be left visible.
+ t.setAlpha(leash, 0.f);
+ }
+ } else {
+ // put on bottom and leave it visible
+ t.setLayer(leash, zSplitLine - layer);
+ }
+ } else if (TransitionUtil.isClosingType(mode)) {
+ if (isOpening) {
+ // put on bottom and leave visible
+ t.setLayer(leash, zSplitLine - layer);
+ } else {
+ // put on top
+ t.setLayer(leash, zSplitLine + info.getChanges().size() - layer);
+ }
+ } else { // CHANGE
+ t.setLayer(leash, zSplitLine + info.getChanges().size() - layer);
+ }
+ }
+
+ @SuppressLint("NewApi")
+ private static SurfaceControl createLeash(TransitionInfo info, TransitionInfo.Change change,
+ int order, SurfaceControl.Transaction t) {
+ // TODO: once we can properly sync transactions across process, then get rid of this leash.
+ if (change.getParent() != null && (change.getFlags() & FLAG_IS_WALLPAPER) != 0) {
+ // Special case for wallpaper atm. Normally these are left alone; but, a quirk of
+ // making leashes means we have to handle them specially.
+ return change.getLeash();
+ }
+ SurfaceControl leashSurface = new SurfaceControl.Builder()
+ .setName(change.getLeash().toString() + "_transition-leash")
+ .setContainerLayer()
+ // Initial the surface visible to respect the visibility of the original surface.
+ .setHidden(false)
+ .setParent(info.getRootLeash())
+ .build();
+ // Copied Transitions setup code (which expects bottom-to-top order, so we swap here)
+ setupLeash(leashSurface, change, info.getChanges().size() - order, info, t);
+ t.reparent(change.getLeash(), leashSurface);
+ t.setAlpha(change.getLeash(), 1.0f);
+ t.show(change.getLeash());
+ t.setPosition(change.getLeash(), 0, 0);
+ t.setLayer(change.getLeash(), 0);
+ return leashSurface;
+ }
+
+ /**
+ * Creates a new RemoteAnimationTarget from the provided change info
+ */
+ public static RemoteAnimationTarget newTarget(TransitionInfo.Change change, int order,
+ TransitionInfo info, SurfaceControl.Transaction t,
+ @Nullable ArrayMap<SurfaceControl, SurfaceControl> leashMap) {
+ final SurfaceControl leash = createLeash(info, change, order, t);
+ if (leashMap != null) {
+ leashMap.put(change.getLeash(), leash);
+ }
+ return newTarget(change, order, leash);
+ }
+
+ /**
+ * Creates a new RemoteAnimationTarget from the provided change and leash
+ */
+ public static RemoteAnimationTarget newTarget(TransitionInfo.Change change, int order,
+ SurfaceControl leash) {
+ int taskId;
+ boolean isNotInRecents;
+ ActivityManager.RunningTaskInfo taskInfo;
+ WindowConfiguration windowConfiguration;
+
+ taskInfo = change.getTaskInfo();
+ if (taskInfo != null) {
+ taskId = taskInfo.taskId;
+ isNotInRecents = !taskInfo.isRunning;
+ windowConfiguration = taskInfo.configuration.windowConfiguration;
+ } else {
+ taskId = INVALID_TASK_ID;
+ isNotInRecents = true;
+ windowConfiguration = new WindowConfiguration();
+ }
+
+ Rect localBounds = new Rect(change.getEndAbsBounds());
+ localBounds.offsetTo(change.getEndRelOffset().x, change.getEndRelOffset().y);
+
+ RemoteAnimationTarget target = new RemoteAnimationTarget(
+ taskId,
+ newModeToLegacyMode(change.getMode()),
+ // TODO: once we can properly sync transactions across process,
+ // then get rid of this leash.
+ leash,
+ (change.getFlags() & TransitionInfo.FLAG_TRANSLUCENT) != 0,
+ null,
+ // TODO(shell-transitions): we need to send content insets? evaluate how its used.
+ new Rect(0, 0, 0, 0),
+ order,
+ null,
+ localBounds,
+ new Rect(change.getEndAbsBounds()),
+ windowConfiguration,
+ isNotInRecents,
+ null,
+ new Rect(change.getStartAbsBounds()),
+ taskInfo,
+ change.getAllowEnterPip(),
+ (change.getFlags() & FLAG_IS_DIVIDER_BAR) != 0
+ ? TYPE_DOCK_DIVIDER : INVALID_WINDOW_TYPE
+ );
+ target.setWillShowImeOnTarget(
+ (change.getFlags() & TransitionInfo.FLAG_WILL_IME_SHOWN) != 0);
+ target.setRotationChange(change.getEndRotation() - change.getStartRotation());
+ return target;
+ }
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java
index ed0ac5f1cdca..3901dabcaec8 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java
@@ -284,41 +284,6 @@ public class SplitTransitionTests extends ShellTestCase {
@Test
@UiThreadTest
- public void testDismissFromBeingOccluded() {
- enterSplit();
-
- ActivityManager.RunningTaskInfo normalTask = new TestRunningTaskInfoBuilder()
- .setWindowingMode(WINDOWING_MODE_FULLSCREEN)
- .build();
-
- // Create a request to bring a normal task forward
- TransitionRequestInfo request =
- new TransitionRequestInfo(TRANSIT_TO_FRONT, normalTask, null);
- IBinder transition = mock(IBinder.class);
- WindowContainerTransaction result = mStageCoordinator.handleRequest(transition, request);
-
- assertTrue(containsSplitExit(result));
-
- // make sure we haven't made any local changes yet (need to wait until transition is ready)
- assertTrue(mStageCoordinator.isSplitScreenVisible());
-
- // simulate the transition
- TransitionInfo info = new TransitionInfoBuilder(TRANSIT_TO_FRONT, 0)
- .addChange(TRANSIT_TO_FRONT, normalTask)
- .addChange(TRANSIT_TO_BACK, mMainChild)
- .addChange(TRANSIT_TO_BACK, mSideChild)
- .build();
- mMainStage.onTaskVanished(mMainChild);
- mSideStage.onTaskVanished(mSideChild);
- mStageCoordinator.startAnimation(transition, info,
- mock(SurfaceControl.Transaction.class),
- mock(SurfaceControl.Transaction.class),
- mock(Transitions.TransitionFinishCallback.class));
- assertFalse(mStageCoordinator.isSplitScreenVisible());
- }
-
- @Test
- @UiThreadTest
public void testDismissFromMultiWindowSupport() {
enterSplit();
diff --git a/media/java/android/media/tv/tuner/frontend/IptvFrontendSettings.java b/media/java/android/media/tv/tuner/frontend/IptvFrontendSettings.java
index ba751027a3e4..65247a1a9efd 100644
--- a/media/java/android/media/tv/tuner/frontend/IptvFrontendSettings.java
+++ b/media/java/android/media/tv/tuner/frontend/IptvFrontendSettings.java
@@ -34,7 +34,7 @@ import java.lang.annotation.RetentionPolicy;
* @hide
*/
@SystemApi
-public class IptvFrontendSettings extends FrontendSettings {
+public final class IptvFrontendSettings extends FrontendSettings {
/** @hide */
@IntDef(prefix = "PROTOCOL_",
value = {PROTOCOL_UNDEFINED, PROTOCOL_UDP, PROTOCOL_RTP})
@@ -181,14 +181,6 @@ public class IptvFrontendSettings extends FrontendSettings {
}
/**
- * Creates a builder for {@link IptvFrontendSettings}.
- */
- @NonNull
- public static Builder builder() {
- return new Builder();
- }
-
- /**
* Builder for {@link IptvFrontendSettings}.
*/
public static final class Builder {
@@ -202,7 +194,7 @@ public class IptvFrontendSettings extends FrontendSettings {
private long mBitrate = 0;
private String mContentUrl = "";
- private Builder() {
+ public Builder() {
}
/**
@@ -309,8 +301,8 @@ public class IptvFrontendSettings extends FrontendSettings {
*/
@NonNull
public IptvFrontendSettings build() {
- return new IptvFrontendSettings(mSrcIpAddress, mDstIpAddress, mSrcPort,
- mDstPort, mFec, mProtocol, mIgmp, mBitrate, mContentUrl);
+ return new IptvFrontendSettings(mSrcIpAddress, mDstIpAddress, mSrcPort, mDstPort,
+ mFec, mProtocol, mIgmp, mBitrate, mContentUrl);
}
}
diff --git a/media/java/android/media/tv/tuner/frontend/IptvFrontendSettingsFec.java b/media/java/android/media/tv/tuner/frontend/IptvFrontendSettingsFec.java
index a70af17c9652..12eebee81bd7 100644
--- a/media/java/android/media/tv/tuner/frontend/IptvFrontendSettingsFec.java
+++ b/media/java/android/media/tv/tuner/frontend/IptvFrontendSettingsFec.java
@@ -31,7 +31,7 @@ import java.lang.annotation.RetentionPolicy;
* @hide
*/
@SystemApi
-public class IptvFrontendSettingsFec {
+public final class IptvFrontendSettingsFec {
/** @hide */
@IntDef(prefix = "FEC_TYPE_",
value = {FEC_TYPE_UNDEFINED, FEC_TYPE_COLUMN, FEC_TYPE_ROW, FEC_TYPE_COLUMN_ROW})
@@ -93,14 +93,6 @@ public class IptvFrontendSettingsFec {
}
/**
- * Creates a builder for {@link IptvFrontendSettingsFec}.
- */
- @NonNull
- public static Builder builder() {
- return new Builder();
- }
-
- /**
* Builder for {@link IptvFrontendSettingsFec}.
*/
public static final class Builder {
@@ -108,7 +100,7 @@ public class IptvFrontendSettingsFec {
private int mFecRowNum;
private int mFecColNum;
- private Builder() {
+ public Builder() {
}
/**
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/DataConverter.kt b/packages/CredentialManager/src/com/android/credentialmanager/DataConverter.kt
index a834994a5b0f..1f6c8ec5897b 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/DataConverter.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/DataConverter.kt
@@ -52,9 +52,7 @@ import androidx.credentials.CreateCustomCredentialRequest
import androidx.credentials.CreatePasswordRequest
import androidx.credentials.CredentialOption
import androidx.credentials.CreatePublicKeyCredentialRequest
-import androidx.credentials.CreatePublicKeyCredentialRequestPrivileged
import androidx.credentials.GetPublicKeyCredentialOption
-import androidx.credentials.GetPublicKeyCredentialOptionPrivileged
import androidx.credentials.PublicKeyCredential.Companion.TYPE_PUBLIC_KEY_CREDENTIAL
import androidx.credentials.provider.Action
import androidx.credentials.provider.AuthenticationAction
@@ -186,8 +184,6 @@ class GetFlowUtils {
)
if (credentialOptionJetpack is GetPublicKeyCredentialOption) {
credentialOptionJetpack.preferImmediatelyAvailableCredentials
- } else if (credentialOptionJetpack is GetPublicKeyCredentialOptionPrivileged) {
- credentialOptionJetpack.preferImmediatelyAvailableCredentials
} else {
false
}
@@ -448,23 +444,14 @@ class CreateFlowUtils {
createCredentialRequestJetpack.preferImmediatelyAvailableCredentials,
)
}
- is CreatePublicKeyCredentialRequestPrivileged -> {
- newRequestDisplayInfoFromPasskeyJson(
- requestJson = createCredentialRequestJetpack.requestJson,
- appLabel = appLabel,
- context = context,
- preferImmediatelyAvailableCredentials =
- createCredentialRequestJetpack.preferImmediatelyAvailableCredentials,
- )
- }
is CreateCustomCredentialRequest -> {
// TODO: directly use the display info once made public
val displayInfo = CreateCredentialRequest.DisplayInfo
.parseFromCredentialDataBundle(createCredentialRequest.credentialData)
?: return null
RequestDisplayInfo(
- title = displayInfo.userId,
- subtitle = displayInfo.userDisplayName,
+ title = displayInfo.userId.toString(),
+ subtitle = displayInfo.userDisplayName?.toString(),
type = CredentialType.UNKNOWN,
appName = appLabel,
typeIcon = displayInfo.credentialTypeIcon?.loadDrawable(context)
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/TestUtils.kt b/packages/CredentialManager/src/com/android/credentialmanager/TestUtils.kt
index 9216429eac52..75b12ff756ad 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/TestUtils.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/TestUtils.kt
@@ -25,7 +25,10 @@ import android.credentials.Credential.TYPE_PASSWORD_CREDENTIAL
import android.credentials.ui.AuthenticationEntry
import android.credentials.ui.Entry
import android.net.Uri
+import android.os.Bundle
import android.provider.Settings
+import androidx.credentials.provider.BeginGetPasswordOption
+import androidx.credentials.provider.BeginGetPublicKeyCredentialOption
import androidx.credentials.provider.CreateEntry
import androidx.credentials.provider.PasswordCredentialEntry
import androidx.credentials.provider.PublicKeyCredentialEntry
@@ -82,7 +85,9 @@ class GetTestUtils {
return Entry(
key,
subkey,
- RemoteCredentialEntry(pendingIntent).slice
+ RemoteCredentialEntry(pendingIntent, BeginGetPublicKeyCredentialOption(
+ Bundle(), "id", "requestjson"
+ )).slice
)
}
@@ -137,7 +142,8 @@ class GetTestUtils {
intent, (PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
or PendingIntent.FLAG_ONE_SHOT)
)
- val passwordEntry = PasswordCredentialEntry.Builder(context, userName, pendingIntent)
+ val passwordEntry = PasswordCredentialEntry.Builder(
+ context, userName, pendingIntent, BeginGetPasswordOption(Bundle(), "id"))
.setDisplayName(userDisplayName).setLastUsedTime(lastUsedTime).build()
return Entry(key, subkey, passwordEntry.slice, Intent())
}
@@ -158,8 +164,12 @@ class GetTestUtils {
intent, (PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
or PendingIntent.FLAG_ONE_SHOT)
)
- val passkeyEntry = PublicKeyCredentialEntry.Builder(context, userName, pendingIntent)
- .setDisplayName(userDisplayName).setLastUsedTime(lastUsedTime).build()
+ val passkeyEntry = PublicKeyCredentialEntry.Builder(
+ context,
+ userName,
+ pendingIntent,
+ BeginGetPublicKeyCredentialOption(Bundle(), "id", "requestjson")
+ ).setDisplayName(userDisplayName).setLastUsedTime(lastUsedTime).build()
return Entry(key, subkey, passkeyEntry.slice, Intent())
}
}
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/common/ui/BottomSheet.kt b/packages/CredentialManager/src/com/android/credentialmanager/common/ui/BottomSheet.kt
index 53d03c308a92..0cb2bb083fb8 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/common/ui/BottomSheet.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/common/ui/BottomSheet.kt
@@ -39,7 +39,9 @@ fun ModalBottomSheet(
skipHalfExpanded = true
)
ModalBottomSheetLayout(
- sheetBackgroundColor = MaterialTheme.colorScheme.surface,
+ sheetBackgroundColor = MaterialTheme.colorScheme.surfaceColorAtElevation(
+ ElevationTokens.Level1
+ ),
modifier = Modifier.background(Color.Transparent),
sheetState = state,
sheetContent = sheetContent,
diff --git a/packages/SettingsLib/Spa/spa/build.gradle b/packages/SettingsLib/Spa/spa/build.gradle
index 640aa01f307f..4563b7d75b22 100644
--- a/packages/SettingsLib/Spa/spa/build.gradle
+++ b/packages/SettingsLib/Spa/spa/build.gradle
@@ -48,11 +48,11 @@ android {
}
}
compileOptions {
- sourceCompatibility JavaVersion.VERSION_11
- targetCompatibility JavaVersion.VERSION_11
+ sourceCompatibility JavaVersion.VERSION_17
+ targetCompatibility JavaVersion.VERSION_17
}
kotlinOptions {
- jvmTarget = '11'
+ jvmTarget = '17'
freeCompilerArgs = ["-Xjvm-default=all"]
}
buildFeatures {
diff --git a/packages/SettingsLib/Spa/testutils/build.gradle b/packages/SettingsLib/Spa/testutils/build.gradle
index 536829e00b65..e7f7db2f1ec0 100644
--- a/packages/SettingsLib/Spa/testutils/build.gradle
+++ b/packages/SettingsLib/Spa/testutils/build.gradle
@@ -38,11 +38,11 @@ android {
}
}
compileOptions {
- sourceCompatibility JavaVersion.VERSION_11
- targetCompatibility JavaVersion.VERSION_11
+ sourceCompatibility JavaVersion.VERSION_17
+ targetCompatibility JavaVersion.VERSION_17
}
kotlinOptions {
- jvmTarget = '11'
+ jvmTarget = '17'
freeCompilerArgs = ["-Xjvm-default=all"]
}
buildFeatures {
diff --git a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatterySaverUtils.java b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatterySaverUtils.java
index 28353ab7dff4..52f3111d967c 100644
--- a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatterySaverUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatterySaverUtils.java
@@ -169,8 +169,11 @@ public class BatterySaverUtils {
*/
public static boolean maybeShowBatterySaverConfirmation(Context context, Bundle extras) {
if (Secure.getInt(context.getContentResolver(),
- Secure.LOW_POWER_WARNING_ACKNOWLEDGED, 0) != 0) {
- return false; // Already shown.
+ Secure.LOW_POWER_WARNING_ACKNOWLEDGED, 0) != 0
+ && Secure.getInt(context.getContentResolver(),
+ Secure.EXTRA_LOW_POWER_WARNING_ACKNOWLEDGED, 0) != 0) {
+ // Already shown.
+ return false;
}
context.sendBroadcast(
getSystemUiBroadcast(ACTION_SHOW_START_SAVER_CONFIRMATION, extras));
@@ -190,8 +193,10 @@ public class BatterySaverUtils {
}
private static void setBatterySaverConfirmationAcknowledged(Context context) {
- Secure.putIntForUser(context.getContentResolver(), Secure.LOW_POWER_WARNING_ACKNOWLEDGED, 1,
- UserHandle.USER_CURRENT);
+ Secure.putIntForUser(context.getContentResolver(),
+ Secure.LOW_POWER_WARNING_ACKNOWLEDGED, 1, UserHandle.USER_CURRENT);
+ Secure.putIntForUser(context.getContentResolver(),
+ Secure.EXTRA_LOW_POWER_WARNING_ACKNOWLEDGED, 1, UserHandle.USER_CURRENT);
}
/**
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/BatterySaverUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/BatterySaverUtilsTest.java
index a15fe9f90206..ad022a63eaf6 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/BatterySaverUtilsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/BatterySaverUtilsTest.java
@@ -69,6 +69,7 @@ public class BatterySaverUtilsTest {
@Test
public void testSetPowerSaveMode_enable_firstCall_needWarning() {
Secure.putString(mMockResolver, Secure.LOW_POWER_WARNING_ACKNOWLEDGED, "null");
+ Secure.putString(mMockResolver, Secure.EXTRA_LOW_POWER_WARNING_ACKNOWLEDGED, "null");
Secure.putString(mMockResolver, Secure.LOW_POWER_MANUAL_ACTIVATION_COUNT, "null");
assertThat(BatterySaverUtils.setPowerSaveMode(mMockContext, true, true)).isFalse();
@@ -77,15 +78,18 @@ public class BatterySaverUtilsTest {
verify(mMockPowerManager, times(0)).setPowerSaveModeEnabled(anyBoolean());
// They shouldn't have changed.
+ assertEquals(-1, Secure.getInt(mMockResolver, Secure.LOW_POWER_WARNING_ACKNOWLEDGED, -1));
assertEquals(-1,
- Secure.getInt(mMockResolver, Secure.LOW_POWER_WARNING_ACKNOWLEDGED, -1));
+ Secure.getInt(mMockResolver, Secure.EXTRA_LOW_POWER_WARNING_ACKNOWLEDGED, -1));
assertEquals(-2,
Secure.getInt(mMockResolver, Secure.LOW_POWER_MANUAL_ACTIVATION_COUNT, -2));
}
@Test
public void testSetPowerSaveMode_enable_secondCall_needWarning() {
- Secure.putInt(mMockResolver, Secure.LOW_POWER_WARNING_ACKNOWLEDGED, 1); // Already acked.
+ // Already acked.
+ Secure.putInt(mMockResolver, Secure.LOW_POWER_WARNING_ACKNOWLEDGED, 1);
+ Secure.putInt(mMockResolver, Secure.EXTRA_LOW_POWER_WARNING_ACKNOWLEDGED, 1);
Secure.putString(mMockResolver, Secure.LOW_POWER_MANUAL_ACTIVATION_COUNT, "null");
assertThat(BatterySaverUtils.setPowerSaveMode(mMockContext, true, true)).isTrue();
@@ -94,12 +98,17 @@ public class BatterySaverUtilsTest {
verify(mMockPowerManager, times(1)).setPowerSaveModeEnabled(eq(true));
assertEquals(1, Secure.getInt(mMockResolver, Secure.LOW_POWER_WARNING_ACKNOWLEDGED, -1));
- assertEquals(1, Secure.getInt(mMockResolver, Secure.LOW_POWER_MANUAL_ACTIVATION_COUNT, -2));
+ assertEquals(1,
+ Secure.getInt(mMockResolver, Secure.EXTRA_LOW_POWER_WARNING_ACKNOWLEDGED, -1));
+ assertEquals(1,
+ Secure.getInt(mMockResolver, Secure.LOW_POWER_MANUAL_ACTIVATION_COUNT, -2));
}
@Test
public void testSetPowerSaveMode_enable_thridCall_needWarning() {
- Secure.putInt(mMockResolver, Secure.LOW_POWER_WARNING_ACKNOWLEDGED, 1); // Already acked.
+ // Already acked.
+ Secure.putInt(mMockResolver, Secure.LOW_POWER_WARNING_ACKNOWLEDGED, 1);
+ Secure.putInt(mMockResolver, Secure.EXTRA_LOW_POWER_WARNING_ACKNOWLEDGED, 1);
Secure.putInt(mMockResolver, Secure.LOW_POWER_MANUAL_ACTIVATION_COUNT, 1);
assertThat(BatterySaverUtils.setPowerSaveMode(mMockContext, true, true)).isTrue();
@@ -108,12 +117,16 @@ public class BatterySaverUtilsTest {
verify(mMockPowerManager, times(1)).setPowerSaveModeEnabled(eq(true));
assertEquals(1, Secure.getInt(mMockResolver, Secure.LOW_POWER_WARNING_ACKNOWLEDGED, -1));
- assertEquals(2, Secure.getInt(mMockResolver, Secure.LOW_POWER_MANUAL_ACTIVATION_COUNT, -2));
+ assertEquals(1,
+ Secure.getInt(mMockResolver, Secure.EXTRA_LOW_POWER_WARNING_ACKNOWLEDGED, -1));
+ assertEquals(2,
+ Secure.getInt(mMockResolver, Secure.LOW_POWER_MANUAL_ACTIVATION_COUNT, -2));
}
@Test
public void testSetPowerSaveMode_enable_firstCall_noWarning() {
Secure.putString(mMockResolver, Secure.LOW_POWER_WARNING_ACKNOWLEDGED, "null");
+ Secure.putString(mMockResolver, Secure.EXTRA_LOW_POWER_WARNING_ACKNOWLEDGED, "null");
Secure.putString(mMockResolver, Secure.LOW_POWER_MANUAL_ACTIVATION_COUNT, "null");
assertThat(BatterySaverUtils.setPowerSaveMode(mMockContext, true, false)).isTrue();
@@ -122,12 +135,15 @@ public class BatterySaverUtilsTest {
verify(mMockPowerManager, times(1)).setPowerSaveModeEnabled(eq(true));
assertEquals(1, Secure.getInt(mMockResolver, Secure.LOW_POWER_WARNING_ACKNOWLEDGED, -1));
+ assertEquals(1,
+ Secure.getInt(mMockResolver, Secure.EXTRA_LOW_POWER_WARNING_ACKNOWLEDGED, -1));
assertEquals(1, Secure.getInt(mMockResolver, Secure.LOW_POWER_MANUAL_ACTIVATION_COUNT, -2));
}
@Test
public void testSetPowerSaveMode_disable_firstCall_noWarning() {
Secure.putString(mMockResolver, Secure.LOW_POWER_WARNING_ACKNOWLEDGED, "null");
+ Secure.putString(mMockResolver, Secure.EXTRA_LOW_POWER_WARNING_ACKNOWLEDGED, "null");
Secure.putString(mMockResolver, Secure.LOW_POWER_MANUAL_ACTIVATION_COUNT, "null");
// When disabling, needFirstTimeWarning doesn't matter.
@@ -137,6 +153,8 @@ public class BatterySaverUtilsTest {
verify(mMockPowerManager, times(1)).setPowerSaveModeEnabled(eq(false));
assertEquals(-1, Secure.getInt(mMockResolver, Secure.LOW_POWER_WARNING_ACKNOWLEDGED, -1));
+ assertEquals(-1,
+ Secure.getInt(mMockResolver, Secure.EXTRA_LOW_POWER_WARNING_ACKNOWLEDGED, -1));
assertEquals(-2,
Secure.getInt(mMockResolver, Secure.LOW_POWER_MANUAL_ACTIVATION_COUNT, -2));
}
@@ -144,6 +162,7 @@ public class BatterySaverUtilsTest {
@Test
public void testSetPowerSaveMode_disable_firstCall_needWarning() {
Secure.putString(mMockResolver, Secure.LOW_POWER_WARNING_ACKNOWLEDGED, "null");
+ Secure.putString(mMockResolver, Secure.EXTRA_LOW_POWER_WARNING_ACKNOWLEDGED, "null");
Secure.putString(mMockResolver, Secure.LOW_POWER_MANUAL_ACTIVATION_COUNT, "null");
// When disabling, needFirstTimeWarning doesn't matter.
@@ -153,6 +172,8 @@ public class BatterySaverUtilsTest {
verify(mMockPowerManager, times(1)).setPowerSaveModeEnabled(eq(false));
assertEquals(-1, Secure.getInt(mMockResolver, Secure.LOW_POWER_WARNING_ACKNOWLEDGED, -1));
+ assertEquals(-1,
+ Secure.getInt(mMockResolver, Secure.EXTRA_LOW_POWER_WARNING_ACKNOWLEDGED, -1));
assertEquals(-2,
Secure.getInt(mMockResolver, Secure.LOW_POWER_MANUAL_ACTIVATION_COUNT, -2));
}
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
index 93394f3872ee..f66fcba74bc5 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
@@ -239,5 +239,6 @@ public class SecureSettings {
Settings.Secure.HEARING_AID_CALL_ROUTING,
Settings.Secure.HEARING_AID_MEDIA_ROUTING,
Settings.Secure.HEARING_AID_SYSTEM_SOUNDS_ROUTING,
+ Settings.Secure.ACCESSIBILITY_FONT_SCALING_HAS_BEEN_CHANGED
};
}
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
index 96578626d5cc..558e19f19986 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
@@ -376,5 +376,6 @@ public class SecureSettingsValidators {
new DiscreteValueValidator(new String[] {"0", "1", "2"}));
VALIDATORS.put(Secure.HEARING_AID_SYSTEM_SOUNDS_ROUTING,
new DiscreteValueValidator(new String[] {"0", "1", "2"}));
+ VALIDATORS.put(Secure.ACCESSIBILITY_FONT_SCALING_HAS_BEEN_CHANGED, BOOLEAN_VALIDATOR);
}
}
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index fb3c3136280e..1a6920803b03 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -1852,6 +1852,9 @@ class SettingsProtoDumpUtil {
dumpSetting(s, p,
Settings.Secure.HEARING_AID_SYSTEM_SOUNDS_ROUTING,
SecureSettingsProto.Accessibility.HEARING_AID_SYSTEM_SOUNDS_ROUTING);
+ dumpSetting(s, p,
+ Settings.Secure.ACCESSIBILITY_FONT_SCALING_HAS_BEEN_CHANGED,
+ SecureSettingsProto.Accessibility.ACCESSIBILITY_FONT_SCALING_HAS_BEEN_CHANGED);
p.end(accessibilityToken);
final long adaptiveSleepToken = p.start(SecureSettingsProto.ADAPTIVE_SLEEP);
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 90bec4292313..d02e5693bbf3 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -721,6 +721,7 @@
<!-- Permission required for CTS test - CtsTelephonyTestCases -->
<uses-permission android:name="android.permission.BIND_TELECOM_CONNECTION_SERVICE" />
<uses-permission android:name="android.permission.MODIFY_CELL_BROADCASTS" />
+ <uses-permission android:name="android.permission.SATELLITE_COMMUNICATION" />
<!-- Permission required for CTS test - CtsPersistentDataBlockManagerTestCases -->
<uses-permission android:name="android.permission.ACCESS_PDB_STATE" />
diff --git a/packages/SystemUI/res-keyguard/values/strings.xml b/packages/SystemUI/res-keyguard/values/strings.xml
index 51f507cfeddb..11b4d79925c6 100644
--- a/packages/SystemUI/res-keyguard/values/strings.xml
+++ b/packages/SystemUI/res-keyguard/values/strings.xml
@@ -56,7 +56,7 @@
<string name="keyguard_plugged_in_charging_limited"><xliff:g id="percentage">%s</xliff:g> • Charging optimized to protect battery</string>
<!-- When the lock screen is showing and the phone plugged in with incompatible charger. -->
- <string name="keyguard_plugged_in_incompatible_charger"><xliff:g id="percentage">%s</xliff:g> • Incompatible charging</string>
+ <string name="keyguard_plugged_in_incompatible_charger"><xliff:g id="percentage">%s</xliff:g> • Issue with charging accessory</string>
<!-- On the keyguard screen, when pattern lock is disabled, only tell them to press menu to unlock. This is shown in small font at the bottom. -->
<string name="keyguard_instructions_when_pattern_disabled">Press Menu to unlock.</string>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 738cfd7c95bf..e65c327736e1 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -500,8 +500,8 @@
space -->
<bool name="config_showBatteryEstimateQSBH">false</bool>
- <!-- Whether to show a severe low battery dialog. -->
- <bool name="config_severe_battery_dialog">false</bool>
+ <!-- Whether to show extra battery saver confirmation dialog. -->
+ <bool name="config_extra_battery_saver_confirmation">false</bool>
<!-- A path representing a shield. Will sometimes be displayed with the battery icon when
needed. This path is a 10px wide and 13px tall. -->
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationTargetCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationTargetCompat.java
index ae6861812b4c..44f9d43f5470 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationTargetCompat.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationTargetCompat.java
@@ -16,30 +16,9 @@
package com.android.systemui.shared.system;
-import static android.app.ActivityTaskManager.INVALID_TASK_ID;
-import static android.view.RemoteAnimationTarget.MODE_CHANGING;
-import static android.view.RemoteAnimationTarget.MODE_CLOSING;
-import static android.view.RemoteAnimationTarget.MODE_OPENING;
-import static android.view.WindowManager.LayoutParams.INVALID_WINDOW_TYPE;
-import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
-import static android.view.WindowManager.TRANSIT_OPEN;
-import static android.window.TransitionInfo.FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY;
-import static android.window.TransitionInfo.FLAG_IS_WALLPAPER;
-import static android.window.TransitionInfo.FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT;
-
-import static com.android.wm.shell.common.split.SplitScreenConstants.FLAG_IS_DIVIDER_BAR;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SuppressLint;
-import android.app.ActivityManager;
-import android.app.WindowConfiguration;
-import android.graphics.Rect;
import android.util.ArrayMap;
-import android.util.SparseBooleanArray;
import android.view.RemoteAnimationTarget;
import android.view.SurfaceControl;
-import android.view.WindowManager;
import android.window.TransitionInfo;
import android.window.TransitionInfo.Change;
@@ -53,156 +32,6 @@ import java.util.function.Predicate;
*/
public class RemoteAnimationTargetCompat {
- private static int newModeToLegacyMode(int newMode) {
- switch (newMode) {
- case WindowManager.TRANSIT_OPEN:
- case WindowManager.TRANSIT_TO_FRONT:
- return MODE_OPENING;
- case WindowManager.TRANSIT_CLOSE:
- case WindowManager.TRANSIT_TO_BACK:
- return MODE_CLOSING;
- default:
- return MODE_CHANGING;
- }
- }
-
- /**
- * Almost a copy of Transitions#setupStartState.
- * TODO: remove when there is proper cross-process transaction sync.
- */
- @SuppressLint("NewApi")
- private static void setupLeash(@NonNull SurfaceControl leash,
- @NonNull TransitionInfo.Change change, int layer,
- @NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction t) {
- final boolean isOpening = TransitionUtil.isOpeningType(info.getType());
- // Put animating stuff above this line and put static stuff below it.
- int zSplitLine = info.getChanges().size();
- // changes should be ordered top-to-bottom in z
- final int mode = change.getMode();
-
- t.reparent(leash, info.getRootLeash());
- final Rect absBounds =
- (mode == TRANSIT_OPEN) ? change.getEndAbsBounds() : change.getStartAbsBounds();
- t.setPosition(leash, absBounds.left - info.getRootOffset().x,
- absBounds.top - info.getRootOffset().y);
-
- // Put all the OPEN/SHOW on top
- if (TransitionUtil.isOpeningType(mode)) {
- if (isOpening) {
- t.setLayer(leash, zSplitLine + info.getChanges().size() - layer);
- if ((change.getFlags() & FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT) == 0) {
- // if transferred, it should be left visible.
- t.setAlpha(leash, 0.f);
- }
- } else {
- // put on bottom and leave it visible
- t.setLayer(leash, zSplitLine - layer);
- }
- } else if (TransitionUtil.isClosingType(mode)) {
- if (isOpening) {
- // put on bottom and leave visible
- t.setLayer(leash, zSplitLine - layer);
- } else {
- // put on top
- t.setLayer(leash, zSplitLine + info.getChanges().size() - layer);
- }
- } else { // CHANGE
- t.setLayer(leash, zSplitLine + info.getChanges().size() - layer);
- }
- }
-
- @SuppressLint("NewApi")
- private static SurfaceControl createLeash(TransitionInfo info, TransitionInfo.Change change,
- int order, SurfaceControl.Transaction t) {
- // TODO: once we can properly sync transactions across process, then get rid of this leash.
- if (change.getParent() != null && (change.getFlags() & FLAG_IS_WALLPAPER) != 0) {
- // Special case for wallpaper atm. Normally these are left alone; but, a quirk of
- // making leashes means we have to handle them specially.
- return change.getLeash();
- }
- SurfaceControl leashSurface = new SurfaceControl.Builder()
- .setName(change.getLeash().toString() + "_transition-leash")
- .setContainerLayer()
- // Initial the surface visible to respect the visibility of the original surface.
- .setHidden(false)
- .setParent(info.getRootLeash())
- .build();
- // Copied Transitions setup code (which expects bottom-to-top order, so we swap here)
- setupLeash(leashSurface, change, info.getChanges().size() - order, info, t);
- t.reparent(change.getLeash(), leashSurface);
- t.setAlpha(change.getLeash(), 1.0f);
- t.show(change.getLeash());
- t.setPosition(change.getLeash(), 0, 0);
- t.setLayer(change.getLeash(), 0);
- return leashSurface;
- }
-
- /**
- * Creates a new RemoteAnimationTarget from the provided change info
- */
- public static RemoteAnimationTarget newTarget(TransitionInfo.Change change, int order,
- TransitionInfo info, SurfaceControl.Transaction t,
- @Nullable ArrayMap<SurfaceControl, SurfaceControl> leashMap) {
- final SurfaceControl leash = createLeash(info, change, order, t);
- if (leashMap != null) {
- leashMap.put(change.getLeash(), leash);
- }
- return newTarget(change, order, leash);
- }
-
- /**
- * Creates a new RemoteAnimationTarget from the provided change and leash
- */
- public static RemoteAnimationTarget newTarget(TransitionInfo.Change change, int order,
- SurfaceControl leash) {
- int taskId;
- boolean isNotInRecents;
- ActivityManager.RunningTaskInfo taskInfo;
- WindowConfiguration windowConfiguration;
-
- taskInfo = change.getTaskInfo();
- if (taskInfo != null) {
- taskId = taskInfo.taskId;
- isNotInRecents = !taskInfo.isRunning;
- windowConfiguration = taskInfo.configuration.windowConfiguration;
- } else {
- taskId = INVALID_TASK_ID;
- isNotInRecents = true;
- windowConfiguration = new WindowConfiguration();
- }
-
- Rect localBounds = new Rect(change.getEndAbsBounds());
- localBounds.offsetTo(change.getEndRelOffset().x, change.getEndRelOffset().y);
-
- RemoteAnimationTarget target = new RemoteAnimationTarget(
- taskId,
- newModeToLegacyMode(change.getMode()),
- // TODO: once we can properly sync transactions across process,
- // then get rid of this leash.
- leash,
- (change.getFlags() & TransitionInfo.FLAG_TRANSLUCENT) != 0,
- null,
- // TODO(shell-transitions): we need to send content insets? evaluate how its used.
- new Rect(0, 0, 0, 0),
- order,
- null,
- localBounds,
- new Rect(change.getEndAbsBounds()),
- windowConfiguration,
- isNotInRecents,
- null,
- new Rect(change.getStartAbsBounds()),
- taskInfo,
- change.getAllowEnterPip(),
- (change.getFlags() & FLAG_IS_DIVIDER_BAR) != 0
- ? TYPE_DOCK_DIVIDER : INVALID_WINDOW_TYPE
- );
- target.setWillShowImeOnTarget(
- (change.getFlags() & TransitionInfo.FLAG_WILL_IME_SHOWN) != 0);
- target.setRotationChange(change.getEndRotation() - change.getStartRotation());
- return target;
- }
-
/**
* Represents a TransitionInfo object as an array of old-style app targets
*
@@ -211,7 +40,7 @@ public class RemoteAnimationTargetCompat {
*/
public static RemoteAnimationTarget[] wrapApps(TransitionInfo info,
SurfaceControl.Transaction t, ArrayMap<SurfaceControl, SurfaceControl> leashMap) {
- return wrap(info, t, leashMap, new LeafTaskFilter());
+ return wrap(info, t, leashMap, new TransitionUtil.LeafTaskFilter());
}
/**
@@ -224,8 +53,8 @@ public class RemoteAnimationTargetCompat {
*/
public static RemoteAnimationTarget[] wrapNonApps(TransitionInfo info, boolean wallpapers,
SurfaceControl.Transaction t, ArrayMap<SurfaceControl, SurfaceControl> leashMap) {
- return wrap(info, t, leashMap, (change) ->
- (wallpapers ? isWallpaper(change) : isNonApp(change)));
+ return wrap(info, t, leashMap, (change) -> (wallpapers
+ ? TransitionUtil.isWallpaper(change) : TransitionUtil.isNonApp(change)));
}
private static RemoteAnimationTarget[] wrap(TransitionInfo info,
@@ -235,45 +64,10 @@ public class RemoteAnimationTargetCompat {
for (int i = 0; i < info.getChanges().size(); i++) {
TransitionInfo.Change change = info.getChanges().get(i);
if (filter.test(change)) {
- out.add(newTarget(change, info.getChanges().size() - i, info, t, leashMap));
+ out.add(TransitionUtil.newTarget(
+ change, info.getChanges().size() - i, info, t, leashMap));
}
}
return out.toArray(new RemoteAnimationTarget[out.size()]);
}
-
- /** Returns `true` if `change` is a wallpaper. */
- public static boolean isWallpaper(Change change) {
- return (change.getTaskInfo() == null)
- && change.hasFlags(FLAG_IS_WALLPAPER)
- && !change.hasFlags(FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY);
- }
-
- /** Returns `true` if `change` is not an app window or wallpaper. */
- public static boolean isNonApp(Change change) {
- return (change.getTaskInfo() == null)
- && !change.hasFlags(FLAG_IS_WALLPAPER)
- && !change.hasFlags(FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY);
- }
-
- /**
- * Filter that selects leaf-tasks only. THIS IS ORDER-DEPENDENT! For it to work properly, you
- * MUST call `test` in the same order that the changes appear in the TransitionInfo.
- */
- public static class LeafTaskFilter implements Predicate<Change> {
- private final SparseBooleanArray mChildTaskTargets = new SparseBooleanArray();
-
- @Override
- public boolean test(Change change) {
- final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
- // Children always come before parent since changes are in top-to-bottom z-order.
- if ((taskInfo == null) || mChildTaskTargets.get(taskInfo.taskId)) {
- // has children, so not a leaf. Skip.
- return false;
- }
- if (taskInfo.hasParentTask()) {
- mChildTaskTargets.put(taskInfo.parentTaskId, true);
- }
- return true;
- }
- }
}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteTransitionCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteTransitionCompat.java
index 0d19b877e43c..fca55b1c69b4 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteTransitionCompat.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteTransitionCompat.java
@@ -21,8 +21,6 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
import static android.view.WindowManager.TRANSIT_CHANGE;
import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_LOCKED;
-import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.newTarget;
-
import android.annotation.SuppressLint;
import android.app.ActivityManager;
import android.app.ActivityTaskManager;
@@ -45,7 +43,6 @@ import android.window.WindowContainerToken;
import android.window.WindowContainerTransaction;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.systemui.shared.recents.model.ThumbnailData;
import com.android.wm.shell.util.TransitionUtil;
import java.util.ArrayList;
@@ -58,7 +55,7 @@ public class RemoteTransitionCompat {
/** Constructor specifically for recents animation */
public static RemoteTransition newRemoteTransition(RecentsAnimationListener recents,
- RecentsAnimationControllerCompat controller, IApplicationThread appThread) {
+ IApplicationThread appThread) {
IRemoteTransition remote = new IRemoteTransition.Stub() {
final RecentsControllerWrap mRecentsSession = new RecentsControllerWrap();
IBinder mToken = null;
@@ -69,7 +66,7 @@ public class RemoteTransitionCompat {
IRemoteTransitionFinishedCallback finishedCallback) {
// TODO(b/177438007): Move this set-up logic into launcher's animation impl.
mToken = transition;
- mRecentsSession.start(controller, recents, mToken, info, t, finishedCallback);
+ mRecentsSession.start(recents, mToken, info, t, finishedCallback);
}
@Override
@@ -98,9 +95,8 @@ public class RemoteTransitionCompat {
* TODO(b/177438007): Remove this once Launcher handles shell transitions directly.
*/
@VisibleForTesting
- static class RecentsControllerWrap extends RecentsAnimationControllerCompat {
+ static class RecentsControllerWrap extends IRecentsAnimationController.Default {
private RecentsAnimationListener mListener = null;
- private RecentsAnimationControllerCompat mWrapped = null;
private IRemoteTransitionFinishedCallback mFinishCB = null;
/**
@@ -137,7 +133,7 @@ public class RemoteTransitionCompat {
/** The latest state that the recents animation is operating in. */
private int mState = STATE_NORMAL;
- void start(RecentsAnimationControllerCompat wrapped, RecentsAnimationListener listener,
+ void start(RecentsAnimationListener listener,
IBinder transition, TransitionInfo info, SurfaceControl.Transaction t,
IRemoteTransitionFinishedCallback finishedCallback) {
if (mInfo != null) {
@@ -145,7 +141,6 @@ public class RemoteTransitionCompat {
+ " recents is already active.");
}
mListener = listener;
- mWrapped = wrapped;
mInfo = info;
mFinishCB = finishedCallback;
mPausingTasks = new ArrayList<>();
@@ -160,16 +155,15 @@ public class RemoteTransitionCompat {
final ArrayList<RemoteAnimationTarget> apps = new ArrayList<>();
final ArrayList<RemoteAnimationTarget> wallpapers = new ArrayList<>();
- RemoteAnimationTargetCompat.LeafTaskFilter leafTaskFilter =
- new RemoteAnimationTargetCompat.LeafTaskFilter();
+ TransitionUtil.LeafTaskFilter leafTaskFilter = new TransitionUtil.LeafTaskFilter();
// About layering: we divide up the "layer space" into 3 regions (each the size of
// the change count). This lets us categorize things into above/below/between
// while maintaining their relative ordering.
for (int i = 0; i < info.getChanges().size(); ++i) {
final TransitionInfo.Change change = info.getChanges().get(i);
final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
- if (RemoteAnimationTargetCompat.isWallpaper(change)) {
- final RemoteAnimationTarget target = newTarget(change,
+ if (TransitionUtil.isWallpaper(change)) {
+ final RemoteAnimationTarget target = TransitionUtil.newTarget(change,
// wallpapers go into the "below" layer space
info.getChanges().size() - i, info, t, mLeashMap);
wallpapers.add(target);
@@ -177,7 +171,7 @@ public class RemoteTransitionCompat {
t.setAlpha(target.leash, 1);
} else if (leafTaskFilter.test(change)) {
// start by putting everything into the "below" layer space.
- final RemoteAnimationTarget target = newTarget(change,
+ final RemoteAnimationTarget target = TransitionUtil.newTarget(change,
info.getChanges().size() - i, info, t, mLeashMap);
apps.add(target);
if (TransitionUtil.isClosingType(change.getMode())) {
@@ -203,7 +197,8 @@ public class RemoteTransitionCompat {
}
}
t.apply();
- mListener.onAnimationStart(this, apps.toArray(new RemoteAnimationTarget[apps.size()]),
+ mListener.onAnimationStart(new RecentsAnimationControllerCompat(this),
+ apps.toArray(new RemoteAnimationTarget[apps.size()]),
wallpapers.toArray(new RemoteAnimationTarget[wallpapers.size()]),
new Rect(0, 0, 0, 0), new Rect());
}
@@ -217,8 +212,8 @@ public class RemoteTransitionCompat {
TransitionInfo.Change recentsOpening = null;
boolean foundRecentsClosing = false;
boolean hasChangingApp = false;
- final RemoteAnimationTargetCompat.LeafTaskFilter leafTaskFilter =
- new RemoteAnimationTargetCompat.LeafTaskFilter();
+ final TransitionUtil.LeafTaskFilter leafTaskFilter =
+ new TransitionUtil.LeafTaskFilter();
for (int i = 0; i < info.getChanges().size(); ++i) {
final TransitionInfo.Change change = info.getChanges().get(i);
final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
@@ -308,7 +303,8 @@ public class RemoteTransitionCompat {
int pausingIdx = TaskState.indexOf(mPausingTasks, change);
if (pausingIdx >= 0) {
// Something is showing/opening a previously-pausing app.
- targets[i] = newTarget(change, layer, mPausingTasks.get(pausingIdx).mLeash);
+ targets[i] = TransitionUtil.newTarget(change, layer,
+ mPausingTasks.get(pausingIdx).mLeash);
mOpeningTasks.add(mPausingTasks.remove(pausingIdx));
// Setup hides opening tasks initially, so make it visible again (since we
// are already showing it).
@@ -316,7 +312,7 @@ public class RemoteTransitionCompat {
t.setAlpha(change.getLeash(), 1.f);
} else {
// We are receiving new opening tasks, so convert to onTasksAppeared.
- targets[i] = newTarget(change, layer, info, t, mLeashMap);
+ targets[i] = TransitionUtil.newTarget(change, layer, info, t, mLeashMap);
t.reparent(targets[i].leash, mInfo.getRootLeash());
t.setLayer(targets[i].leash, layer);
mOpeningTasks.add(new TaskState(change, targets[i].leash));
@@ -344,13 +340,9 @@ public class RemoteTransitionCompat {
}
}
- @Override public ThumbnailData screenshotTask(int taskId) {
+ @Override public TaskSnapshot screenshotTask(int taskId) {
try {
- final TaskSnapshot snapshot =
- ActivityTaskManager.getService().takeTaskSnapshot(taskId);
- if (snapshot != null) {
- return new ThumbnailData(snapshot);
- }
+ return ActivityTaskManager.getService().takeTaskSnapshot(taskId);
} catch (RemoteException e) {
Log.e(TAG, "Failed to screenshot task", e);
}
@@ -358,30 +350,24 @@ public class RemoteTransitionCompat {
}
@Override public void setInputConsumerEnabled(boolean enabled) {
- if (enabled) {
- // transient launches don't receive focus automatically. Since we are taking over
- // the gesture now, take focus explicitly.
- // This also moves recents back to top if the user gestured before a switch
- // animation finished.
- try {
- ActivityTaskManager.getService().setFocusedTask(mRecentsTaskId);
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to set focused task", e);
- }
+ if (!enabled) return;
+ // transient launches don't receive focus automatically. Since we are taking over
+ // the gesture now, take focus explicitly.
+ // This also moves recents back to top if the user gestured before a switch
+ // animation finished.
+ try {
+ ActivityTaskManager.getService().setFocusedTask(mRecentsTaskId);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to set focused task", e);
}
- if (mWrapped != null) mWrapped.setInputConsumerEnabled(enabled);
}
@Override public void setAnimationTargetsBehindSystemBars(boolean behindSystemBars) {
- if (mWrapped != null) mWrapped.setAnimationTargetsBehindSystemBars(behindSystemBars);
}
@Override public void setFinishTaskTransaction(int taskId,
PictureInPictureSurfaceTransaction finishTransaction, SurfaceControl overlay) {
mPipTransaction = finishTransaction;
- if (mWrapped != null) {
- mWrapped.setFinishTaskTransaction(taskId, finishTransaction, overlay);
- }
}
@Override
@@ -391,7 +377,6 @@ public class RemoteTransitionCompat {
Log.e(TAG, "Duplicate call to finish", new RuntimeException());
return;
}
- if (mWrapped != null) mWrapped.finish(toHome, sendUserLeaveHint);
final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
final WindowContainerTransaction wct = new WindowContainerTransaction();
@@ -464,7 +449,6 @@ public class RemoteTransitionCompat {
// for releasing the leashes created by local.
mInfo.releaseAllSurfaces();
// Reset all members.
- mWrapped = null;
mListener = null;
mFinishCB = null;
mPausingTasks = null;
@@ -478,23 +462,20 @@ public class RemoteTransitionCompat {
}
@Override public void setDeferCancelUntilNextTransition(boolean defer, boolean screenshot) {
- if (mWrapped != null) mWrapped.setDeferCancelUntilNextTransition(defer, screenshot);
}
@Override public void cleanupScreenshot() {
- if (mWrapped != null) mWrapped.cleanupScreenshot();
}
@Override public void setWillFinishToHome(boolean willFinishToHome) {
mWillFinishToHome = willFinishToHome;
- if (mWrapped != null) mWrapped.setWillFinishToHome(willFinishToHome);
}
/**
* @see IRecentsAnimationController#removeTask
*/
@Override public boolean removeTask(int taskId) {
- return mWrapped != null ? mWrapped.removeTask(taskId) : false;
+ return false;
}
/**
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java
index c1fae9e44bd3..33bea027cd20 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java
@@ -69,6 +69,7 @@ public class KeyguardPasswordView extends KeyguardAbsKeyInputView {
private Interpolator mLinearOutSlowInInterpolator;
private Interpolator mFastOutLinearInInterpolator;
+ private DisappearAnimationListener mDisappearAnimationListener;
public KeyguardPasswordView(Context context) {
this(context, null);
@@ -186,9 +187,13 @@ public class KeyguardPasswordView extends KeyguardAbsKeyInputView {
return;
}
Insets shownInsets = controller.getShownStateInsets();
- Insets insets = Insets.add(shownInsets, Insets.of(0, 0, 0,
- (int) (-shownInsets.bottom / 4
- * anim.getAnimatedFraction())));
+ int dist = (int) (-shownInsets.bottom / 4
+ * anim.getAnimatedFraction());
+ Insets insets = Insets.add(shownInsets, Insets.of(0, 0, 0, dist));
+ if (mDisappearAnimationListener != null) {
+ mDisappearAnimationListener.setTranslationY(-dist);
+ }
+
controller.setInsetsAndAlpha(insets,
(float) animation.getAnimatedValue(),
anim.getAnimatedFraction());
@@ -209,6 +214,7 @@ public class KeyguardPasswordView extends KeyguardAbsKeyInputView {
controller.finish(false);
runOnFinishImeAnimationRunnable();
finishRunnable.run();
+ mDisappearAnimationListener = null;
Trace.endSection();
});
}
@@ -286,4 +292,19 @@ public class KeyguardPasswordView extends KeyguardAbsKeyInputView {
}
});
}
+
+ /**
+ * Listens to the progress of the disappear animation and handles it.
+ */
+ interface DisappearAnimationListener {
+ void setTranslationY(int transY);
+ }
+
+ /**
+ * Set an instance of the disappear animation listener to this class. This will be
+ * removed when the animation completes.
+ */
+ public void setDisappearAnimationListener(DisappearAnimationListener listener) {
+ mDisappearAnimationListener = listener;
+ }
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
index c6f0eeed108f..66d5d097ab04 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -173,6 +173,17 @@ public class KeyguardSecurityContainer extends ConstraintLayout {
private @Mode int mCurrentMode = MODE_UNINITIALIZED;
private int mWidth = -1;
+ /**
+ * This callback is used to animate KeyguardSecurityContainer and its child views based on
+ * the interaction with the ime. After
+ * {@link WindowInsetsAnimation.Callback#onPrepare(WindowInsetsAnimation)},
+ * {@link #onApplyWindowInsets} is called where we
+ * set the bottom padding to be the height of the keyboard. We use this padding to determine
+ * the delta of vertical distance for y-translation animations.
+ * Note that bottom padding is not set when the disappear animation is started because
+ * we are deferring the y translation logic to the animator in
+ * {@link KeyguardPasswordView#startDisappearAnimation(Runnable)}
+ */
private final WindowInsetsAnimation.Callback mWindowInsetsAnimationCallback =
new WindowInsetsAnimation.Callback(DISPATCH_MODE_STOP) {
@@ -213,7 +224,6 @@ public class KeyguardSecurityContainer extends ConstraintLayout {
continue;
}
interpolatedFraction = animation.getInterpolatedFraction();
-
final int paddingBottom = (int) MathUtils.lerp(
start, end,
interpolatedFraction);
@@ -568,13 +578,21 @@ public class KeyguardSecurityContainer extends ConstraintLayout {
*/
public void startDisappearAnimation(SecurityMode securitySelection) {
mDisappearAnimRunning = true;
- mViewMode.startDisappearAnimation(securitySelection);
+ if (securitySelection == SecurityMode.Password
+ && mSecurityViewFlipper.getSecurityView() instanceof KeyguardPasswordView) {
+ ((KeyguardPasswordView) mSecurityViewFlipper.getSecurityView())
+ .setDisappearAnimationListener(this::setTranslationY);
+ } else {
+ mViewMode.startDisappearAnimation(securitySelection);
+ }
}
/**
* This will run when the bouncer shows in all cases except when the user drags the bouncer up.
*/
public void startAppearAnimation(SecurityMode securityMode) {
+ setTranslationY(0f);
+ setAlpha(1f);
updateChildren(0 /* translationY */, 1f /* alpha */);
mViewMode.startAppearAnimation(securityMode);
}
@@ -623,7 +641,13 @@ public class KeyguardSecurityContainer extends ConstraintLayout {
int inset = max(bottomInset, imeInset);
int paddingBottom = max(inset, getContext().getResources()
.getDimensionPixelSize(R.dimen.keyguard_security_view_bottom_margin));
- setPadding(getPaddingLeft(), getPaddingTop(), getPaddingRight(), paddingBottom);
+ // If security mode is password, we rely on the animation value of defined in
+ // KeyguardPasswordView to determine the y translation animation.
+ // This means that we will prevent the WindowInsetsAnimationCallback from setting any y
+ // translation values by preventing the setting of the padding here.
+ if (!mDisappearAnimRunning) {
+ setPadding(getPaddingLeft(), getPaddingTop(), getPaddingRight(), paddingBottom);
+ }
return insets.inset(0, 0, 0, inset);
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index a4ec8e1b72f2..866b502e00ac 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -685,7 +685,10 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
public void onTrustManagedChanged(boolean managed, int userId) {
Assert.isMainThread();
mUserTrustIsManaged.put(userId, managed);
- mUserTrustIsUsuallyManaged.put(userId, mTrustManager.isTrustUsuallyManaged(userId));
+ boolean trustUsuallyManaged = mTrustManager.isTrustUsuallyManaged(userId);
+ mLogger.logTrustUsuallyManagedUpdated(userId, mUserTrustIsUsuallyManaged.get(userId),
+ trustUsuallyManaged, "onTrustManagedChanged");
+ mUserTrustIsUsuallyManaged.put(userId, trustUsuallyManaged);
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
if (cb != null) {
@@ -2393,8 +2396,12 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
updateSecondaryLockscreenRequirement(user);
List<UserInfo> allUsers = mUserManager.getUsers();
for (UserInfo userInfo : allUsers) {
+ boolean trustUsuallyManaged = mTrustManager.isTrustUsuallyManaged(userInfo.id);
+ mLogger.logTrustUsuallyManagedUpdated(userInfo.id,
+ mUserTrustIsUsuallyManaged.get(userInfo.id),
+ trustUsuallyManaged, "init from constructor");
mUserTrustIsUsuallyManaged.put(userInfo.id,
- mTrustManager.isTrustUsuallyManaged(userInfo.id));
+ trustUsuallyManaged);
}
updateAirplaneModeState();
@@ -2434,9 +2441,11 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
}
private void updateFaceEnrolled(int userId) {
- mIsFaceEnrolled = mFaceManager != null && !mFaceSensorProperties.isEmpty()
+ Boolean isFaceEnrolled = mFaceManager != null && !mFaceSensorProperties.isEmpty()
&& mBiometricEnabledForUser.get(userId)
&& mAuthController.isFaceAuthEnrolled(userId);
+ mIsFaceEnrolled = isFaceEnrolled;
+ mLogger.logFaceEnrolledUpdated(mIsFaceEnrolled, isFaceEnrolled);
}
public boolean isFaceSupported() {
@@ -3103,9 +3112,13 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
@VisibleForTesting
boolean isUnlockWithFingerprintPossible(int userId) {
// TODO (b/242022358), make this rely on onEnrollmentChanged event and update it only once.
- mIsUnlockWithFingerprintPossible.put(userId, mFpm != null
+ boolean fpEnrolled = mFpm != null
&& !mFingerprintSensorProperties.isEmpty()
- && !isFingerprintDisabled(userId) && mFpm.hasEnrolledTemplates(userId));
+ && !isFingerprintDisabled(userId) && mFpm.hasEnrolledTemplates(userId);
+ mLogger.logFpEnrolledUpdated(userId,
+ mIsUnlockWithFingerprintPossible.getOrDefault(userId, false),
+ fpEnrolled);
+ mIsUnlockWithFingerprintPossible.put(userId, fpEnrolled);
return mIsUnlockWithFingerprintPossible.get(userId);
}
@@ -3221,7 +3234,10 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
void handleUserSwitching(int userId, CountDownLatch latch) {
Assert.isMainThread();
clearBiometricRecognized();
- mUserTrustIsUsuallyManaged.put(userId, mTrustManager.isTrustUsuallyManaged(userId));
+ boolean trustUsuallyManaged = mTrustManager.isTrustUsuallyManaged(userId);
+ mLogger.logTrustUsuallyManagedUpdated(userId, mUserTrustIsUsuallyManaged.get(userId),
+ trustUsuallyManaged, "userSwitching");
+ mUserTrustIsUsuallyManaged.put(userId, trustUsuallyManaged);
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
if (cb != null) {
diff --git a/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt b/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt
index e53f6adb62a4..fb2c02ad8c48 100644
--- a/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt
+++ b/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt
@@ -26,6 +26,7 @@ import com.android.keyguard.FaceAuthUiEvent
import com.android.keyguard.KeyguardListenModel
import com.android.keyguard.KeyguardUpdateMonitorCallback
import com.android.keyguard.TrustGrantFlags
+import com.android.systemui.log.dagger.KeyguardUpdateMonitorLog
import com.android.systemui.plugins.log.LogBuffer
import com.android.systemui.plugins.log.LogLevel
import com.android.systemui.plugins.log.LogLevel.DEBUG
@@ -33,18 +34,15 @@ import com.android.systemui.plugins.log.LogLevel.ERROR
import com.android.systemui.plugins.log.LogLevel.INFO
import com.android.systemui.plugins.log.LogLevel.VERBOSE
import com.android.systemui.plugins.log.LogLevel.WARNING
-import com.android.systemui.log.dagger.KeyguardUpdateMonitorLog
import com.google.errorprone.annotations.CompileTimeConstant
import javax.inject.Inject
private const val TAG = "KeyguardUpdateMonitorLog"
-/**
- * Helper class for logging for [com.android.keyguard.KeyguardUpdateMonitor]
- */
-class KeyguardUpdateMonitorLogger @Inject constructor(
- @KeyguardUpdateMonitorLog private val logBuffer: LogBuffer
-) {
+/** Helper class for logging for [com.android.keyguard.KeyguardUpdateMonitor] */
+class KeyguardUpdateMonitorLogger
+@Inject
+constructor(@KeyguardUpdateMonitorLog private val logBuffer: LogBuffer) {
fun d(@CompileTimeConstant msg: String) = log(msg, DEBUG)
fun e(@CompileTimeConstant msg: String) = log(msg, ERROR)
@@ -56,15 +54,16 @@ class KeyguardUpdateMonitorLogger @Inject constructor(
fun log(@CompileTimeConstant msg: String, level: LogLevel) = logBuffer.log(TAG, level, msg)
fun logActiveUnlockTriggered(reason: String?) {
- logBuffer.log("ActiveUnlock", DEBUG,
- { str1 = reason },
- { "initiate active unlock triggerReason=$str1" })
+ logBuffer.log(
+ "ActiveUnlock",
+ DEBUG,
+ { str1 = reason },
+ { "initiate active unlock triggerReason=$str1" }
+ )
}
fun logAuthInterruptDetected(active: Boolean) {
- logBuffer.log(TAG, DEBUG,
- { bool1 = active },
- { "onAuthInterruptDetected($bool1)" })
+ logBuffer.log(TAG, DEBUG, { bool1 = active }, { "onAuthInterruptDetected($bool1)" })
}
fun logBroadcastReceived(action: String?) {
@@ -72,9 +71,12 @@ class KeyguardUpdateMonitorLogger @Inject constructor(
}
fun logDeviceProvisionedState(deviceProvisioned: Boolean) {
- logBuffer.log(TAG, DEBUG,
- { bool1 = deviceProvisioned },
- { "DEVICE_PROVISIONED state = $bool1" })
+ logBuffer.log(
+ TAG,
+ DEBUG,
+ { bool1 = deviceProvisioned },
+ { "DEVICE_PROVISIONED state = $bool1" }
+ )
}
fun logException(ex: Exception, @CompileTimeConstant logMsg: String) {
@@ -82,46 +84,56 @@ class KeyguardUpdateMonitorLogger @Inject constructor(
}
fun logFaceAcquired(acquireInfo: Int) {
- logBuffer.log(TAG, DEBUG,
- { int1 = acquireInfo },
- { "Face acquired acquireInfo=$int1" })
+ logBuffer.log(TAG, DEBUG, { int1 = acquireInfo }, { "Face acquired acquireInfo=$int1" })
}
fun logFaceAuthDisabledForUser(userId: Int) {
- logBuffer.log(TAG, DEBUG,
- { int1 = userId },
- { "Face authentication disabled by DPM for userId: $int1" })
+ logBuffer.log(
+ TAG,
+ DEBUG,
+ { int1 = userId },
+ { "Face authentication disabled by DPM for userId: $int1" }
+ )
}
fun logFaceAuthError(msgId: Int, originalErrMsg: String) {
- logBuffer.log(TAG, DEBUG, {
- str1 = originalErrMsg
- int1 = msgId
- }, { "Face error received: $str1 msgId= $int1" })
+ logBuffer.log(
+ TAG,
+ DEBUG,
+ {
+ str1 = originalErrMsg
+ int1 = msgId
+ },
+ { "Face error received: $str1 msgId= $int1" }
+ )
}
fun logFaceAuthForWrongUser(authUserId: Int) {
- logBuffer.log(TAG, DEBUG,
- { int1 = authUserId },
- { "Face authenticated for wrong user: $int1" })
+ logBuffer.log(
+ TAG,
+ DEBUG,
+ { int1 = authUserId },
+ { "Face authenticated for wrong user: $int1" }
+ )
}
fun logFaceAuthHelpMsg(msgId: Int, helpMsg: String?) {
- logBuffer.log(TAG, DEBUG, {
- int1 = msgId
- str1 = helpMsg
- }, { "Face help received, msgId: $int1 msg: $str1" })
+ logBuffer.log(
+ TAG,
+ DEBUG,
+ {
+ int1 = msgId
+ str1 = helpMsg
+ },
+ { "Face help received, msgId: $int1 msg: $str1" }
+ )
}
fun logFaceAuthRequested(reason: String?) {
- logBuffer.log(TAG, DEBUG, {
- str1 = reason
- }, { "requestFaceAuth() reason=$str1" })
+ logBuffer.log(TAG, DEBUG, { str1 = reason }, { "requestFaceAuth() reason=$str1" })
}
fun logFaceAuthSuccess(userId: Int) {
- logBuffer.log(TAG, DEBUG,
- { int1 = userId },
- { "Face auth succeeded for user $int1" })
+ logBuffer.log(TAG, DEBUG, { int1 = userId }, { "Face auth succeeded for user $int1" })
}
fun logFaceLockoutReset(@LockoutMode mode: Int) {
@@ -133,21 +145,30 @@ class KeyguardUpdateMonitorLogger @Inject constructor(
}
fun logFaceUnlockPossible(isFaceUnlockPossible: Boolean) {
- logBuffer.log(TAG, DEBUG,
- { bool1 = isFaceUnlockPossible },
- {"isUnlockWithFacePossible: $bool1"})
+ logBuffer.log(
+ TAG,
+ DEBUG,
+ { bool1 = isFaceUnlockPossible },
+ { "isUnlockWithFacePossible: $bool1" }
+ )
}
fun logFingerprintAuthForWrongUser(authUserId: Int) {
- logBuffer.log(TAG, DEBUG,
- { int1 = authUserId },
- { "Fingerprint authenticated for wrong user: $int1" })
+ logBuffer.log(
+ TAG,
+ DEBUG,
+ { int1 = authUserId },
+ { "Fingerprint authenticated for wrong user: $int1" }
+ )
}
fun logFingerprintDisabledForUser(userId: Int) {
- logBuffer.log(TAG, DEBUG,
- { int1 = userId },
- { "Fingerprint disabled by DPM for userId: $int1" })
+ logBuffer.log(
+ TAG,
+ DEBUG,
+ { int1 = userId },
+ { "Fingerprint disabled by DPM for userId: $int1" }
+ )
}
fun logFingerprintLockoutReset(@LockoutMode mode: Int) {
@@ -155,16 +176,24 @@ class KeyguardUpdateMonitorLogger @Inject constructor(
}
fun logFingerprintRunningState(fingerprintRunningState: Int) {
- logBuffer.log(TAG, DEBUG,
- { int1 = fingerprintRunningState },
- { "fingerprintRunningState: $int1" })
+ logBuffer.log(
+ TAG,
+ DEBUG,
+ { int1 = fingerprintRunningState },
+ { "fingerprintRunningState: $int1" }
+ )
}
fun logFingerprintSuccess(userId: Int, isStrongBiometric: Boolean) {
- logBuffer.log(TAG, DEBUG, {
- int1 = userId
- bool1 = isStrongBiometric
- }, {"Fingerprint auth successful: userId: $int1, isStrongBiometric: $bool1"})
+ logBuffer.log(
+ TAG,
+ DEBUG,
+ {
+ int1 = userId
+ bool1 = isStrongBiometric
+ },
+ { "Fingerprint auth successful: userId: $int1, isStrongBiometric: $bool1" }
+ )
}
fun logFaceDetected(userId: Int, isStrongBiometric: Boolean) {
@@ -182,29 +211,42 @@ class KeyguardUpdateMonitorLogger @Inject constructor(
}
fun logFingerprintError(msgId: Int, originalErrMsg: String) {
- logBuffer.log(TAG, DEBUG, {
- str1 = originalErrMsg
- int1 = msgId
- }, { "Fingerprint error received: $str1 msgId= $int1" })
+ logBuffer.log(
+ TAG,
+ DEBUG,
+ {
+ str1 = originalErrMsg
+ int1 = msgId
+ },
+ { "Fingerprint error received: $str1 msgId= $int1" }
+ )
}
fun logInvalidSubId(subId: Int) {
- logBuffer.log(TAG, INFO,
- { int1 = subId },
- { "Previously active sub id $int1 is now invalid, will remove" })
+ logBuffer.log(
+ TAG,
+ INFO,
+ { int1 = subId },
+ { "Previously active sub id $int1 is now invalid, will remove" }
+ )
}
fun logPrimaryKeyguardBouncerChanged(
- primaryBouncerIsOrWillBeShowing: Boolean,
- primaryBouncerFullyShown: Boolean
+ primaryBouncerIsOrWillBeShowing: Boolean,
+ primaryBouncerFullyShown: Boolean
) {
- logBuffer.log(TAG, DEBUG, {
- bool1 = primaryBouncerIsOrWillBeShowing
- bool2 = primaryBouncerFullyShown
- }, {
- "handlePrimaryBouncerChanged " +
+ logBuffer.log(
+ TAG,
+ DEBUG,
+ {
+ bool1 = primaryBouncerIsOrWillBeShowing
+ bool2 = primaryBouncerFullyShown
+ },
+ {
+ "handlePrimaryBouncerChanged " +
"primaryBouncerIsOrWillBeShowing=$bool1 primaryBouncerFullyShown=$bool2"
- })
+ }
+ )
}
fun logKeyguardListenerModel(model: KeyguardListenModel) {
@@ -212,98 +254,134 @@ class KeyguardUpdateMonitorLogger @Inject constructor(
}
fun logKeyguardShowingChanged(showing: Boolean, occluded: Boolean, visible: Boolean) {
- logBuffer.log(TAG, DEBUG, {
- bool1 = showing
- bool2 = occluded
- bool3 = visible
- }, {
- "keyguardShowingChanged(showing=$bool1 occluded=$bool2 visible=$bool3)"
- })
+ logBuffer.log(
+ TAG,
+ DEBUG,
+ {
+ bool1 = showing
+ bool2 = occluded
+ bool3 = visible
+ },
+ { "keyguardShowingChanged(showing=$bool1 occluded=$bool2 visible=$bool3)" }
+ )
}
fun logMissingSupervisorAppError(userId: Int) {
- logBuffer.log(TAG, ERROR,
- { int1 = userId },
- { "No Profile Owner or Device Owner supervision app found for User $int1" })
+ logBuffer.log(
+ TAG,
+ ERROR,
+ { int1 = userId },
+ { "No Profile Owner or Device Owner supervision app found for User $int1" }
+ )
}
fun logPhoneStateChanged(newState: String?) {
- logBuffer.log(TAG, DEBUG,
- { str1 = newState },
- { "handlePhoneStateChanged($str1)" })
+ logBuffer.log(TAG, DEBUG, { str1 = newState }, { "handlePhoneStateChanged($str1)" })
}
fun logRegisterCallback(callback: KeyguardUpdateMonitorCallback?) {
- logBuffer.log(TAG, VERBOSE,
- { str1 = "$callback" },
- { "*** register callback for $str1" })
+ logBuffer.log(TAG, VERBOSE, { str1 = "$callback" }, { "*** register callback for $str1" })
}
fun logRetryingAfterFaceHwUnavailable(retryCount: Int) {
- logBuffer.log(TAG, WARNING,
- { int1 = retryCount },
- { "Retrying face after HW unavailable, attempt $int1" })
+ logBuffer.log(
+ TAG,
+ WARNING,
+ { int1 = retryCount },
+ { "Retrying face after HW unavailable, attempt $int1" }
+ )
}
fun logRetryAfterFpErrorWithDelay(msgId: Int, errString: String?, delay: Int) {
- logBuffer.log(TAG, DEBUG, {
- int1 = msgId
- int2 = delay
- str1 = "$errString"
- }, {
- "Fingerprint scheduling retry auth after $int2 ms due to($int1) -> $str1"
- })
+ logBuffer.log(
+ TAG,
+ DEBUG,
+ {
+ int1 = msgId
+ int2 = delay
+ str1 = "$errString"
+ },
+ { "Fingerprint scheduling retry auth after $int2 ms due to($int1) -> $str1" }
+ )
}
fun logRetryAfterFpHwUnavailable(retryCount: Int) {
- logBuffer.log(TAG, WARNING,
- { int1 = retryCount },
- { "Retrying fingerprint attempt: $int1" })
+ logBuffer.log(
+ TAG,
+ WARNING,
+ { int1 = retryCount },
+ { "Retrying fingerprint attempt: $int1" }
+ )
}
fun logSendPrimaryBouncerChanged(
primaryBouncerIsOrWillBeShowing: Boolean,
primaryBouncerFullyShown: Boolean,
) {
- logBuffer.log(TAG, DEBUG, {
- bool1 = primaryBouncerIsOrWillBeShowing
- bool2 = primaryBouncerFullyShown
- }, {
- "sendPrimaryBouncerChanged primaryBouncerIsOrWillBeShowing=$bool1 " +
+ logBuffer.log(
+ TAG,
+ DEBUG,
+ {
+ bool1 = primaryBouncerIsOrWillBeShowing
+ bool2 = primaryBouncerFullyShown
+ },
+ {
+ "sendPrimaryBouncerChanged primaryBouncerIsOrWillBeShowing=$bool1 " +
"primaryBouncerFullyShown=$bool2"
- })
+ }
+ )
}
fun logServiceStateChange(subId: Int, serviceState: ServiceState?) {
- logBuffer.log(TAG, DEBUG, {
- int1 = subId
- str1 = "$serviceState"
- }, { "handleServiceStateChange(subId=$int1, serviceState=$str1)" })
+ logBuffer.log(
+ TAG,
+ DEBUG,
+ {
+ int1 = subId
+ str1 = "$serviceState"
+ },
+ { "handleServiceStateChange(subId=$int1, serviceState=$str1)" }
+ )
}
fun logServiceStateIntent(action: String?, serviceState: ServiceState?, subId: Int) {
- logBuffer.log(TAG, VERBOSE, {
- str1 = action
- str2 = "$serviceState"
- int1 = subId
- }, { "action $str1 serviceState=$str2 subId=$int1" })
+ logBuffer.log(
+ TAG,
+ VERBOSE,
+ {
+ str1 = action
+ str2 = "$serviceState"
+ int1 = subId
+ },
+ { "action $str1 serviceState=$str2 subId=$int1" }
+ )
}
fun logSimState(subId: Int, slotId: Int, state: Int) {
- logBuffer.log(TAG, DEBUG, {
- int1 = subId
- int2 = slotId
- long1 = state.toLong()
- }, { "handleSimStateChange(subId=$int1, slotId=$int2, state=$long1)" })
+ logBuffer.log(
+ TAG,
+ DEBUG,
+ {
+ int1 = subId
+ int2 = slotId
+ long1 = state.toLong()
+ },
+ { "handleSimStateChange(subId=$int1, slotId=$int2, state=$long1)" }
+ )
}
fun logSimStateFromIntent(action: String?, extraSimState: String?, slotId: Int, subId: Int) {
- logBuffer.log(TAG, VERBOSE, {
- str1 = action
- str2 = extraSimState
- int1 = slotId
- int2 = subId
- }, { "action $str1 state: $str2 slotId: $int1 subid: $int2" })
+ logBuffer.log(
+ TAG,
+ VERBOSE,
+ {
+ str1 = action
+ str2 = extraSimState
+ int1 = slotId
+ int2 = subId
+ },
+ { "action $str1 state: $str2 slotId: $int1 subid: $int2" }
+ )
}
fun logSimUnlocked(subId: Int) {
@@ -311,78 +389,98 @@ class KeyguardUpdateMonitorLogger @Inject constructor(
}
fun logStartedListeningForFace(faceRunningState: Int, faceAuthUiEvent: FaceAuthUiEvent) {
- logBuffer.log(TAG, VERBOSE, {
- int1 = faceRunningState
- str1 = faceAuthUiEvent.reason
- str2 = faceAuthUiEvent.extraInfoToString()
- }, { "startListeningForFace(): $int1, reason: $str1 $str2" })
+ logBuffer.log(
+ TAG,
+ VERBOSE,
+ {
+ int1 = faceRunningState
+ str1 = faceAuthUiEvent.reason
+ str2 = faceAuthUiEvent.extraInfoToString()
+ },
+ { "startListeningForFace(): $int1, reason: $str1 $str2" }
+ )
}
fun logStartedListeningForFaceFromWakeUp(faceRunningState: Int, @WakeReason pmWakeReason: Int) {
- logBuffer.log(TAG, VERBOSE, {
- int1 = faceRunningState
- str1 = PowerManager.wakeReasonToString(pmWakeReason)
- }, { "startListeningForFace(): $int1, reason: wakeUp-$str1" })
+ logBuffer.log(
+ TAG,
+ VERBOSE,
+ {
+ int1 = faceRunningState
+ str1 = PowerManager.wakeReasonToString(pmWakeReason)
+ },
+ { "startListeningForFace(): $int1, reason: wakeUp-$str1" }
+ )
}
fun logStoppedListeningForFace(faceRunningState: Int, faceAuthReason: String) {
- logBuffer.log(TAG, VERBOSE, {
- int1 = faceRunningState
- str1 = faceAuthReason
- }, { "stopListeningForFace(): currentFaceRunningState: $int1, reason: $str1" })
+ logBuffer.log(
+ TAG,
+ VERBOSE,
+ {
+ int1 = faceRunningState
+ str1 = faceAuthReason
+ },
+ { "stopListeningForFace(): currentFaceRunningState: $int1, reason: $str1" }
+ )
}
fun logSubInfo(subInfo: SubscriptionInfo?) {
- logBuffer.log(TAG, VERBOSE,
- { str1 = "$subInfo" },
- { "SubInfo:$str1" })
+ logBuffer.log(TAG, VERBOSE, { str1 = "$subInfo" }, { "SubInfo:$str1" })
}
fun logTimeFormatChanged(newTimeFormat: String?) {
- logBuffer.log(TAG, DEBUG,
- { str1 = newTimeFormat },
- { "handleTimeFormatUpdate timeFormat=$str1" })
+ logBuffer.log(
+ TAG,
+ DEBUG,
+ { str1 = newTimeFormat },
+ { "handleTimeFormatUpdate timeFormat=$str1" }
+ )
}
fun logUdfpsPointerDown(sensorId: Int) {
- logBuffer.log(TAG, DEBUG,
- { int1 = sensorId },
- { "onUdfpsPointerDown, sensorId: $int1" })
+ logBuffer.log(TAG, DEBUG, { int1 = sensorId }, { "onUdfpsPointerDown, sensorId: $int1" })
}
fun logUdfpsPointerUp(sensorId: Int) {
- logBuffer.log(TAG, DEBUG,
- { int1 = sensorId },
- { "onUdfpsPointerUp, sensorId: $int1" })
+ logBuffer.log(TAG, DEBUG, { int1 = sensorId }, { "onUdfpsPointerUp, sensorId: $int1" })
}
fun logUnexpectedFaceCancellationSignalState(faceRunningState: Int, unlockPossible: Boolean) {
- logBuffer.log(TAG, ERROR, {
- int1 = faceRunningState
- bool1 = unlockPossible
- }, {
- "Cancellation signal is not null, high chance of bug in " +
- "face auth lifecycle management. " +
- "Face state: $int1, unlockPossible: $bool1"
- })
+ logBuffer.log(
+ TAG,
+ ERROR,
+ {
+ int1 = faceRunningState
+ bool1 = unlockPossible
+ },
+ {
+ "Cancellation signal is not null, high chance of bug in " +
+ "face auth lifecycle management. " +
+ "Face state: $int1, unlockPossible: $bool1"
+ }
+ )
}
fun logUnexpectedFpCancellationSignalState(
fingerprintRunningState: Int,
unlockPossible: Boolean
) {
- logBuffer.log(TAG, ERROR, {
- int1 = fingerprintRunningState
- bool1 = unlockPossible
- }, {
- "Cancellation signal is not null, high chance of bug in " +
- "fp auth lifecycle management. FP state: $int1, unlockPossible: $bool1"
- })
+ logBuffer.log(
+ TAG,
+ ERROR,
+ {
+ int1 = fingerprintRunningState
+ bool1 = unlockPossible
+ },
+ {
+ "Cancellation signal is not null, high chance of bug in " +
+ "fp auth lifecycle management. FP state: $int1, unlockPossible: $bool1"
+ }
+ )
}
fun logUnregisterCallback(callback: KeyguardUpdateMonitorCallback?) {
- logBuffer.log(TAG, VERBOSE,
- { str1 = "$callback" },
- { "*** unregister callback for $str1" })
+ logBuffer.log(TAG, VERBOSE, { str1 = "$callback" }, { "*** unregister callback for $str1" })
}
fun logUserRequestedUnlock(
@@ -390,75 +488,149 @@ class KeyguardUpdateMonitorLogger @Inject constructor(
reason: String?,
dismissKeyguard: Boolean
) {
- logBuffer.log("ActiveUnlock", DEBUG, {
- str1 = requestOrigin?.name
- str2 = reason
- bool1 = dismissKeyguard
- }, { "reportUserRequestedUnlock origin=$str1 reason=$str2 dismissKeyguard=$bool1" })
+ logBuffer.log(
+ "ActiveUnlock",
+ DEBUG,
+ {
+ str1 = requestOrigin?.name
+ str2 = reason
+ bool1 = dismissKeyguard
+ },
+ { "reportUserRequestedUnlock origin=$str1 reason=$str2 dismissKeyguard=$bool1" }
+ )
}
fun logTrustGrantedWithFlags(
- flags: Int,
- newlyUnlocked: Boolean,
- userId: Int,
- message: String?
+ flags: Int,
+ newlyUnlocked: Boolean,
+ userId: Int,
+ message: String?
) {
- logBuffer.log(TAG, DEBUG, {
- int1 = flags
- bool1 = newlyUnlocked
- int2 = userId
- str1 = message
- }, { "trustGrantedWithFlags[user=$int2] newlyUnlocked=$bool1 " +
- "flags=${TrustGrantFlags(int1)} message=$str1" })
- }
-
- fun logTrustChanged(
- wasTrusted: Boolean,
- isNowTrusted: Boolean,
- userId: Int
- ) {
- logBuffer.log(TAG, DEBUG, {
- bool1 = wasTrusted
- bool2 = isNowTrusted
- int1 = userId
- }, { "onTrustChanged[user=$int1] wasTrusted=$bool1 isNowTrusted=$bool2" })
+ logBuffer.log(
+ TAG,
+ DEBUG,
+ {
+ int1 = flags
+ bool1 = newlyUnlocked
+ int2 = userId
+ str1 = message
+ },
+ {
+ "trustGrantedWithFlags[user=$int2] newlyUnlocked=$bool1 " +
+ "flags=${TrustGrantFlags(int1)} message=$str1"
+ }
+ )
+ }
+
+ fun logTrustChanged(wasTrusted: Boolean, isNowTrusted: Boolean, userId: Int) {
+ logBuffer.log(
+ TAG,
+ DEBUG,
+ {
+ bool1 = wasTrusted
+ bool2 = isNowTrusted
+ int1 = userId
+ },
+ { "onTrustChanged[user=$int1] wasTrusted=$bool1 isNowTrusted=$bool2" }
+ )
}
fun logKeyguardStateUpdate(
- secure: Boolean,
- canDismissLockScreen: Boolean,
- trusted: Boolean,
- trustManaged: Boolean
-
+ secure: Boolean,
+ canDismissLockScreen: Boolean,
+ trusted: Boolean,
+ trustManaged: Boolean
) {
- logBuffer.log("KeyguardState", DEBUG, {
- bool1 = secure
- bool2 = canDismissLockScreen
- bool3 = trusted
- bool4 = trustManaged
- }, { "#update secure=$bool1 canDismissKeyguard=$bool2" +
- " trusted=$bool3 trustManaged=$bool4" })
+ logBuffer.log(
+ "KeyguardState",
+ DEBUG,
+ {
+ bool1 = secure
+ bool2 = canDismissLockScreen
+ bool3 = trusted
+ bool4 = trustManaged
+ },
+ {
+ "#update secure=$bool1 canDismissKeyguard=$bool2" +
+ " trusted=$bool3 trustManaged=$bool4"
+ }
+ )
}
fun logSkipUpdateFaceListeningOnWakeup(@WakeReason pmWakeReason: Int) {
- logBuffer.log(TAG, VERBOSE, {
- str1 = PowerManager.wakeReasonToString(pmWakeReason)
- }, { "Skip updating face listening state on wakeup from $str1"})
+ logBuffer.log(
+ TAG,
+ VERBOSE,
+ { str1 = PowerManager.wakeReasonToString(pmWakeReason) },
+ { "Skip updating face listening state on wakeup from $str1" }
+ )
}
fun logTaskStackChangedForAssistant(assistantVisible: Boolean) {
- logBuffer.log(TAG, VERBOSE, {
- bool1 = assistantVisible
- }, {
- "TaskStackChanged for ACTIVITY_TYPE_ASSISTANT, assistant visible: $bool1"
- })
+ logBuffer.log(
+ TAG,
+ VERBOSE,
+ { bool1 = assistantVisible },
+ { "TaskStackChanged for ACTIVITY_TYPE_ASSISTANT, assistant visible: $bool1" }
+ )
}
fun logAssistantVisible(assistantVisible: Boolean) {
- logBuffer.log(TAG, VERBOSE, {
- bool1 = assistantVisible
- }, {
- "Updating mAssistantVisible to new value: $bool1"
- })
+ logBuffer.log(
+ TAG,
+ VERBOSE,
+ { bool1 = assistantVisible },
+ { "Updating mAssistantVisible to new value: $bool1" }
+ )
+ }
+
+ fun logFaceEnrolledUpdated(oldValue: Boolean, newValue: Boolean) {
+ logBuffer.log(
+ TAG,
+ DEBUG,
+ {
+ bool1 = oldValue
+ bool2 = newValue
+ },
+ { "Face enrolled state changed: old: $bool1, new: $bool2" }
+ )
+ }
+
+ fun logFpEnrolledUpdated(userId: Int, oldValue: Boolean, newValue: Boolean) {
+ logBuffer.log(
+ TAG,
+ DEBUG,
+ {
+ int1 = userId
+ bool1 = oldValue
+ bool2 = newValue
+ },
+ { "Fp enrolled state changed for userId: $int1 old: $bool1, new: $bool2" }
+ )
+ }
+
+ fun logTrustUsuallyManagedUpdated(
+ userId: Int,
+ oldValue: Boolean,
+ newValue: Boolean,
+ context: String
+ ) {
+ logBuffer.log(
+ TAG,
+ DEBUG,
+ {
+ int1 = userId
+ bool1 = oldValue
+ bool2 = newValue
+ str1 = context
+ },
+ {
+ "trustUsuallyManaged changed for " +
+ "userId: $int1 " +
+ "old: $bool1, " +
+ "new: $bool2 " +
+ "context: $context"
+ }
+ )
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
index 4db1da3f1c95..0dfb9b1f13c7 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
@@ -1007,7 +1007,11 @@ public class NavigationBar extends ViewController<NavigationBarView> implements
private void notifyNavigationBarSurface() {
ViewRootImpl viewRoot = mView.getViewRootImpl();
- SurfaceControl surface = viewRoot != null ? viewRoot.getSurfaceControl() : null;
+ SurfaceControl surface = viewRoot != null
+ && viewRoot.getSurfaceControl() != null
+ && viewRoot.getSurfaceControl().isValid()
+ ? viewRoot.getSurfaceControl()
+ : null;
mOverviewProxyService.onNavigationBarSurfaceChanged(surface);
}
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
index 342e0b006c18..f28c275158b9 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
@@ -28,6 +28,7 @@ import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Configuration;
import android.content.res.Resources;
+import android.graphics.Insets;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.PointF;
@@ -54,6 +55,7 @@ import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.ViewConfiguration;
+import android.view.WindowInsets;
import android.view.WindowManager;
import android.window.BackEvent;
@@ -776,6 +778,19 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack
return true;
}
+ private boolean isValidTrackpadBackGesture(boolean isTrackpadEvent) {
+ if (!isTrackpadEvent) {
+ return false;
+ }
+ // for trackpad gestures, unless the whole screen is excluded region, 3-finger swipe
+ // gestures are allowed even if the cursor is in the excluded region.
+ WindowInsets windowInsets = mWindowManager.getCurrentWindowMetrics().getWindowInsets();
+ Insets insets = windowInsets.getInsets(WindowInsets.Type.systemBars());
+ final Rect excludeBounds = mExcludeRegion.getBounds();
+ return !excludeBounds.contains(insets.left, insets.top, mDisplaySize.x - insets.right,
+ mDisplaySize.y - insets.bottom);
+ }
+
private boolean isWithinTouchRegion(int x, int y) {
// If the point is inside the PiP or Nav bar overlay excluded bounds, then ignore the back
// gesture
@@ -896,7 +911,8 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack
&& (isTrackpadEvent || isWithinInsets)
&& !mGestureBlockingActivityRunning
&& !QuickStepContract.isBackGestureDisabled(mSysUiFlags)
- && (isTrackpadEvent || isWithinTouchRegion((int) ev.getX(), (int) ev.getY()));
+ && (isValidTrackpadBackGesture(isTrackpadEvent) || isWithinTouchRegion(
+ (int) ev.getX(), (int) ev.getY()));
if (mAllowGesture) {
mEdgeBackPlugin.setIsLeftPanel(mIsOnLeftEdge);
mEdgeBackPlugin.onMotionEvent(ev);
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/OWNERS b/packages/SystemUI/src/com/android/systemui/notetask/OWNERS
index 7ccb316dbca5..0ec996be72de 100644
--- a/packages/SystemUI/src/com/android/systemui/notetask/OWNERS
+++ b/packages/SystemUI/src/com/android/systemui/notetask/OWNERS
@@ -5,4 +5,6 @@ juliacr@google.com
madym@google.com
mgalhardo@google.com
petrcermak@google.com
+stevenckng@google.com
+tkachenkoi@google.com
vanjan@google.com \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
index 2522e1c5b798..7a42642f2667 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
@@ -154,6 +154,7 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI {
private final Intent mOpenBatterySettings = settings(Intent.ACTION_POWER_USAGE_SUMMARY);
private final Intent mOpenBatterySaverSettings =
settings(Settings.ACTION_BATTERY_SAVER_SETTINGS);
+ private final boolean mUseExtraSaverConfirmation;
private int mBatteryLevel;
private int mBucket;
@@ -197,6 +198,8 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI {
mDialogLaunchAnimator = dialogLaunchAnimator;
mUiEventLogger = uiEventLogger;
mUserTracker = userTracker;
+ mUseExtraSaverConfirmation =
+ mContext.getResources().getBoolean(R.bool.config_extra_battery_saver_confirmation);
}
@Override
@@ -644,7 +647,7 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI {
}
private void showStartSaverConfirmation(Bundle extras) {
- if (mSaverConfirmation != null) return;
+ if (mSaverConfirmation != null || mUseExtraSaverConfirmation) return;
final SystemUIDialog d = new SystemUIDialog(mContext);
final boolean confirmOnly = extras.getBoolean(BatterySaverUtils.EXTRA_CONFIRM_TEXT_ONLY);
final int batterySaverTriggerMode =
@@ -679,6 +682,10 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI {
resolver,
Secure.LOW_POWER_WARNING_ACKNOWLEDGED,
1, mUserTracker.getUserId());
+ Secure.putIntForUser(
+ resolver,
+ Secure.EXTRA_LOW_POWER_WARNING_ACKNOWLEDGED,
+ 1, mUserTracker.getUserId());
});
} else {
d.setTitle(R.string.battery_saver_confirmation_title);
diff --git a/packages/SystemUI/src/com/android/systemui/stylus/OWNERS b/packages/SystemUI/src/com/android/systemui/stylus/OWNERS
index 7ccb316dbca5..0ec996be72de 100644
--- a/packages/SystemUI/src/com/android/systemui/stylus/OWNERS
+++ b/packages/SystemUI/src/com/android/systemui/stylus/OWNERS
@@ -5,4 +5,6 @@ juliacr@google.com
madym@google.com
mgalhardo@google.com
petrcermak@google.com
+stevenckng@google.com
+tkachenkoi@google.com
vanjan@google.com \ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java
index 1bbc19931c21..531006da8210 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java
@@ -37,6 +37,7 @@ import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -160,6 +161,29 @@ public class KeyguardSecurityContainerTest extends SysuiTestCase {
}
@Test
+ public void testOnApplyWindowInsets_disappearAnimation_paddingNotSet() {
+ int paddingBottom = getContext().getResources()
+ .getDimensionPixelSize(R.dimen.keyguard_security_view_bottom_margin);
+ int imeInsetAmount = paddingBottom + 1;
+ int systemBarInsetAmount = 0;
+ initMode(MODE_DEFAULT);
+
+ Insets imeInset = Insets.of(0, 0, 0, imeInsetAmount);
+ Insets systemBarInset = Insets.of(0, 0, 0, systemBarInsetAmount);
+
+ WindowInsets insets = new WindowInsets.Builder()
+ .setInsets(ime(), imeInset)
+ .setInsetsIgnoringVisibility(systemBars(), systemBarInset)
+ .build();
+
+ ensureViewFlipperIsMocked();
+ mKeyguardSecurityContainer.startDisappearAnimation(
+ KeyguardSecurityModel.SecurityMode.Password);
+ mKeyguardSecurityContainer.onApplyWindowInsets(insets);
+ assertThat(mKeyguardSecurityContainer.getPaddingBottom()).isNotEqualTo(imeInsetAmount);
+ }
+
+ @Test
public void testDefaultViewMode() {
initMode(MODE_ONE_HANDED);
initMode(MODE_DEFAULT);
@@ -376,6 +400,17 @@ public class KeyguardSecurityContainerTest extends SysuiTestCase {
assertThat(mKeyguardSecurityContainer.getScaleY()).isEqualTo(1);
}
+ @Test
+ public void testDisappearAnimationPassword() {
+ ensureViewFlipperIsMocked();
+ KeyguardPasswordView keyguardPasswordView = mock(KeyguardPasswordView.class);
+ when(mSecurityViewFlipper.getSecurityView()).thenReturn(keyguardPasswordView);
+
+ mKeyguardSecurityContainer
+ .startDisappearAnimation(KeyguardSecurityModel.SecurityMode.Password);
+ verify(keyguardPasswordView).setDisappearAnimationListener(any());
+ }
+
private BackEvent createBackEvent(float touchX, float progress) {
return new BackEvent(0, 0, progress, BackEvent.EDGE_LEFT);
}
@@ -446,4 +481,12 @@ public class KeyguardSecurityContainerTest extends SysuiTestCase {
mUserSwitcherController, () -> {
}, mFalsingA11yDelegate);
}
+
+ private void ensureViewFlipperIsMocked() {
+ mSecurityViewFlipper = mock(KeyguardSecurityViewFlipper.class);
+ KeyguardPasswordView keyguardPasswordView = mock(KeyguardPasswordView.class);
+ when(mSecurityViewFlipper.getSecurityView()).thenReturn(keyguardPasswordView);
+ mKeyguardSecurityContainer.mSecurityViewFlipper = mSecurityViewFlipper;
+ }
+
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/notetask/OWNERS b/packages/SystemUI/tests/src/com/android/systemui/notetask/OWNERS
index 7ccb316dbca5..0ec996be72de 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/notetask/OWNERS
+++ b/packages/SystemUI/tests/src/com/android/systemui/notetask/OWNERS
@@ -5,4 +5,6 @@ juliacr@google.com
madym@google.com
mgalhardo@google.com
petrcermak@google.com
+stevenckng@google.com
+tkachenkoi@google.com
vanjan@google.com \ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/system/RemoteTransitionTest.java b/packages/SystemUI/tests/src/com/android/systemui/shared/system/RemoteTransitionTest.java
index 4478039912c8..64e58d0de2b9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shared/system/RemoteTransitionTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shared/system/RemoteTransitionTest.java
@@ -49,6 +49,7 @@ import android.window.TransitionInfo;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
+import com.android.wm.shell.util.TransitionUtil;
import org.junit.Before;
import org.junit.Test;
@@ -120,7 +121,7 @@ public class RemoteTransitionTest extends SysuiTestCase {
change.setTaskInfo(createTaskInfo(1 /* taskId */, ACTIVITY_TYPE_HOME));
change.setEndAbsBounds(endBounds);
change.setEndRelOffset(0, 0);
- RemoteAnimationTarget wrapped = RemoteAnimationTargetCompat.newTarget(
+ RemoteAnimationTarget wrapped = TransitionUtil.newTarget(
change, 0 /* order */, tinfo, mock(SurfaceControl.Transaction.class), null);
assertEquals(ACTIVITY_TYPE_HOME, wrapped.windowConfiguration.getActivityType());
assertEquals(new Rect(0, 0, 100, 140), wrapped.localBounds);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/stylus/OWNERS b/packages/SystemUI/tests/src/com/android/systemui/stylus/OWNERS
index 7ccb316dbca5..0ec996be72de 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/stylus/OWNERS
+++ b/packages/SystemUI/tests/src/com/android/systemui/stylus/OWNERS
@@ -5,4 +5,6 @@ juliacr@google.com
madym@google.com
mgalhardo@google.com
petrcermak@google.com
+stevenckng@google.com
+tkachenkoi@google.com
vanjan@google.com \ No newline at end of file
diff --git a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
index a3592166ba03..e159f18809c4 100644
--- a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
+++ b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
@@ -1635,7 +1635,7 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ
return false;
}
- if (event.isAccessibilityDataPrivate()
+ if (event.isAccessibilityDataSensitive()
&& (mFetchFlags & AccessibilityNodeInfo.FLAG_SERVICE_IS_ACCESSIBILITY_TOOL) == 0) {
return false;
}
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index 43b816bae651..61032dc7a59c 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -849,6 +849,32 @@ final class AutofillManagerServiceImpl
}
}
+
+ /**
+ * Updates the last fill response when a view was entered.
+ */
+ void logViewEntered(int sessionId, @Nullable Bundle clientState) {
+ synchronized (mLock) {
+ if (!isValidEventLocked("logViewEntered", sessionId)) {
+ return;
+ }
+
+ if (mEventHistory.getEvents() != null) {
+ // Do not log this event more than once
+ for (Event event : mEventHistory.getEvents()) {
+ if (event.getType() == Event.TYPE_VIEW_REQUESTED_AUTOFILL) {
+ Slog.v(TAG, "logViewEntered: already logged TYPE_VIEW_REQUESTED_AUTOFILL");
+ return;
+ }
+ }
+ }
+
+ mEventHistory.addEvent(
+ new Event(Event.TYPE_VIEW_REQUESTED_AUTOFILL, null, clientState, null,
+ null, null, null, null, null, null, null));
+ }
+ }
+
void logAugmentedAutofillAuthenticationSelected(int sessionId, @Nullable String selectedDataset,
@Nullable Bundle clientState) {
synchronized (mLock) {
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 598521f31ff5..4a12e3843972 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -442,6 +442,18 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
private boolean mPreviouslyFillDialogPotentiallyStarted;
/**
+ * Keeps track of if the user entered view, this is used to
+ * distinguish Fill Request that did not have user interaction
+ * with ones that did.
+ *
+ * This is set to true when entering view - after FillDialog FillRequest
+ * or on plain user tap.
+ */
+ @NonNull
+ @GuardedBy("mLock")
+ private boolean mLogViewEntered;
+
+ /**
* Keeps the fill dialog trigger ids of the last response. This invalidates
* the trigger ids of the previous response.
*/
@@ -1289,6 +1301,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
mMetricsLogger.write(newLogMaker(MetricsEvent.AUTOFILL_SESSION_STARTED)
.addTaggedData(MetricsEvent.FIELD_AUTOFILL_FLAGS, flags));
+ mLogViewEntered = false;
}
/**
@@ -1413,6 +1426,14 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
mService.setLastResponse(id, response);
+ synchronized (mLock) {
+ if (mLogViewEntered) {
+ mLogViewEntered = false;
+ mService.logViewEntered(id, null);
+ }
+ }
+
+
final long disableDuration = response.getDisableDuration();
final boolean autofillDisabled = disableDuration > 0;
if (autofillDisabled) {
@@ -3545,6 +3566,28 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
return;
}
+ synchronized (mLock) {
+ if (!mLogViewEntered) {
+ // If the current request is for FillDialog (preemptive)
+ // then this is the first time that the view is entered
+ // (mLogViewEntered == false) in this case, setLastResponse()
+ // has already been called, so just log here.
+ // If the current request is not and (mLogViewEntered == false)
+ // then the last session is being tracked (setLastResponse not called)
+ // so this calling logViewEntered will be a nop.
+ // Calling logViewEntered() twice will only log it once
+ // TODO(271181979): this is broken for multiple partitions
+ mService.logViewEntered(this.id, null);
+ }
+
+ // If this is the first time view is entered for inline, the last
+ // session is still being tracked, so logViewEntered() needs
+ // to be delayed until setLastResponse is called.
+ // For fill dialog requests case logViewEntered is already called above
+ // so this will do nothing. Assumption: only one fill dialog per session
+ mLogViewEntered = true;
+ }
+
// Previously, fill request will only start whenever a view is entered.
// With Fill Dialog, request starts prior to view getting entered. So, we can't end
// the event at this moment, otherwise we will be wrongly attributing fill dialog
diff --git a/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java b/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java
index e52f1d9c61db..1c4602803426 100644
--- a/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java
+++ b/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java
@@ -16,7 +16,6 @@
package com.android.server.companion.virtual;
-import static android.companion.virtual.VirtualDeviceParams.RECENTS_POLICY_ALLOW_IN_HOST_DEVICE_RECENTS;
import static android.content.pm.ActivityInfo.FLAG_CAN_DISPLAY_ON_REMOTE_DEVICES;
import static android.view.WindowManager.LayoutParams.FLAG_SECURE;
import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
@@ -29,7 +28,6 @@ import android.app.compat.CompatChanges;
import android.companion.virtual.VirtualDeviceManager.ActivityListener;
import android.companion.virtual.VirtualDeviceParams;
import android.companion.virtual.VirtualDeviceParams.ActivityPolicy;
-import android.companion.virtual.VirtualDeviceParams.RecentsPolicy;
import android.compat.annotation.ChangeId;
import android.compat.annotation.EnabledSince;
import android.content.ComponentName;
@@ -137,8 +135,8 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController
new ArraySet<>();
@Nullable private final SecureWindowCallback mSecureWindowCallback;
@Nullable private final List<String> mDisplayCategories;
- @RecentsPolicy
- private final int mDefaultRecentsPolicy;
+
+ private final boolean mShowTasksInHostDeviceRecents;
/**
* Creates a window policy controller that is generic to the different use cases of virtual
@@ -166,7 +164,7 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController
* virtual display.
* @param intentListenerCallback Callback that is called to intercept intents when matching
* passed in filters.
- * @param defaultRecentsPolicy a policy to indicate how to handle activities in recents.
+ * @param showTasksInHostDeviceRecents whether to show activities in recents on the host device.
*/
public GenericWindowPolicyController(int windowFlags, int systemWindowFlags,
@NonNull ArraySet<UserHandle> allowedUsers,
@@ -181,7 +179,7 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController
@NonNull SecureWindowCallback secureWindowCallback,
@NonNull IntentListenerCallback intentListenerCallback,
@NonNull List<String> displayCategories,
- @RecentsPolicy int defaultRecentsPolicy) {
+ boolean showTasksInHostDeviceRecents) {
super();
mAllowedUsers = allowedUsers;
mAllowedCrossTaskNavigations = new ArraySet<>(allowedCrossTaskNavigations);
@@ -196,7 +194,7 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController
mSecureWindowCallback = secureWindowCallback;
mIntentListenerCallback = intentListenerCallback;
mDisplayCategories = displayCategories;
- mDefaultRecentsPolicy = defaultRecentsPolicy;
+ mShowTasksInHostDeviceRecents = showTasksInHostDeviceRecents;
}
/**
@@ -337,7 +335,7 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController
@Override
public boolean canShowTasksInHostDeviceRecents() {
- return (mDefaultRecentsPolicy & RECENTS_POLICY_ALLOW_IN_HOST_DEVICE_RECENTS) != 0;
+ return mShowTasksInHostDeviceRecents;
}
@Override
diff --git a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
index ee1b1fd4a500..2d010cf66e9b 100644
--- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
+++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
@@ -846,7 +846,9 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
this::onSecureWindowShown,
this::shouldInterceptIntent,
displayCategories,
- mParams.getDefaultRecentsPolicy());
+ mParams.getDevicePolicy(
+ VirtualDeviceParams.POLICY_TYPE_RECENTS)
+ == VirtualDeviceParams.DEVICE_POLICY_DEFAULT);
gwpc.registerRunningAppsChangedListener(/* listener= */ this);
return gwpc;
}
diff --git a/services/core/java/android/os/BatteryStatsInternal.java b/services/core/java/android/os/BatteryStatsInternal.java
index 17ef9a232401..c6f63dd73a25 100644
--- a/services/core/java/android/os/BatteryStatsInternal.java
+++ b/services/core/java/android/os/BatteryStatsInternal.java
@@ -38,11 +38,13 @@ public abstract class BatteryStatsInternal {
public static final int CPU_WAKEUP_SUBSYSTEM_UNKNOWN = -1;
public static final int CPU_WAKEUP_SUBSYSTEM_ALARM = 1;
+ public static final int CPU_WAKEUP_SUBSYSTEM_WIFI = 2;
/** @hide */
@IntDef(prefix = {"CPU_WAKEUP_SUBSYSTEM_"}, value = {
CPU_WAKEUP_SUBSYSTEM_UNKNOWN,
CPU_WAKEUP_SUBSYSTEM_ALARM,
+ CPU_WAKEUP_SUBSYSTEM_WIFI,
})
@Retention(RetentionPolicy.SOURCE)
@interface CpuWakeupSubsystem {
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index 4c1835eb80f8..02c1b8b31300 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -19,7 +19,7 @@ package com.android.server.am;
import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_CAMERA;
import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_LOCATION;
import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_MICROPHONE;
-import static android.app.ActivityManager.PROCESS_CAPABILITY_NETWORK;
+import static android.app.ActivityManager.PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK;
import static android.app.ActivityManagerInternal.ALLOW_NON_FULL;
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
import static android.app.ActivityTaskManager.RESIZE_MODE_SYSTEM;
@@ -2014,7 +2014,7 @@ final class ActivityManagerShellCommand extends ShellCommand {
int mask = PROCESS_CAPABILITY_FOREGROUND_LOCATION
| PROCESS_CAPABILITY_FOREGROUND_CAMERA
| PROCESS_CAPABILITY_FOREGROUND_MICROPHONE
- | PROCESS_CAPABILITY_NETWORK;
+ | PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK;
while ((opt=getNextOption()) != null) {
if (opt.equals("--oom")) {
diff --git a/services/core/java/com/android/server/am/AppProfiler.java b/services/core/java/com/android/server/am/AppProfiler.java
index 050ac194616f..ac2c725ce80d 100644
--- a/services/core/java/com/android/server/am/AppProfiler.java
+++ b/services/core/java/com/android/server/am/AppProfiler.java
@@ -1892,15 +1892,11 @@ public class AppProfiler {
}
long getCpuTimeForPid(int pid) {
- synchronized (mProcessCpuTracker) {
- return mProcessCpuTracker.getCpuTimeForPid(pid);
- }
+ return mProcessCpuTracker.getCpuTimeForPid(pid);
}
long getCpuDelayTimeForPid(int pid) {
- synchronized (mProcessCpuTracker) {
- return mProcessCpuTracker.getCpuDelayTimeForPid(pid);
- }
+ return mProcessCpuTracker.getCpuDelayTimeForPid(pid);
}
List<ProcessCpuTracker.Stats> getCpuStats(Predicate<ProcessCpuTracker.Stats> predicate) {
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index 160756616907..0ee883f745ca 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -23,6 +23,7 @@ import static android.Manifest.permission.NETWORK_STACK;
import static android.Manifest.permission.POWER_SAVER;
import static android.Manifest.permission.UPDATE_DEVICE_STATS;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED;
+import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK;
import static android.os.BatteryStats.POWER_DATA_UNAVAILABLE;
@@ -479,9 +480,29 @@ public final class BatteryStatsService extends IBatteryStats.Stub
BatteryStatsService.this.noteJobsDeferred(uid, numDeferred, sinceLast);
}
+ private int transportToSubsystem(NetworkCapabilities nc) {
+ if (nc.hasTransport(TRANSPORT_WIFI)) {
+ return CPU_WAKEUP_SUBSYSTEM_WIFI;
+ }
+ return CPU_WAKEUP_SUBSYSTEM_UNKNOWN;
+ }
+
@Override
public void noteCpuWakingNetworkPacket(Network network, long elapsedMillis, int uid) {
- Slog.d(TAG, "Wakeup due to incoming packet on network " + network + " to uid " + uid);
+ if (uid < 0) {
+ Slog.e(TAG, "Invalid uid for waking network packet: " + uid);
+ return;
+ }
+ final ConnectivityManager cm = mContext.getSystemService(ConnectivityManager.class);
+ final NetworkCapabilities nc = cm.getNetworkCapabilities(network);
+ final int subsystem = transportToSubsystem(nc);
+
+ if (subsystem == CPU_WAKEUP_SUBSYSTEM_UNKNOWN) {
+ Slog.wtf(TAG, "Could not map transport for network: " + network
+ + " while attributing wakeup by packet sent to uid: " + uid);
+ return;
+ }
+ noteCpuWakingActivity(subsystem, elapsedMillis, uid);
}
@Override
diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java
index 086b77b03f57..712142185863 100644
--- a/services/core/java/com/android/server/am/OomAdjuster.java
+++ b/services/core/java/com/android/server/am/OomAdjuster.java
@@ -22,8 +22,8 @@ import static android.app.ActivityManager.PROCESS_CAPABILITY_BFSL;
import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_CAMERA;
import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_LOCATION;
import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_MICROPHONE;
-import static android.app.ActivityManager.PROCESS_CAPABILITY_NETWORK;
import static android.app.ActivityManager.PROCESS_CAPABILITY_NONE;
+import static android.app.ActivityManager.PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK;
import static android.app.ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
import static android.app.ActivityManager.PROCESS_STATE_BOUND_TOP;
import static android.app.ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
@@ -117,6 +117,7 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.ServiceInfo;
+import android.net.NetworkPolicyManager;
import android.os.Handler;
import android.os.IBinder;
import android.os.PowerManagerInternal;
@@ -2280,14 +2281,15 @@ public class OomAdjuster {
// elevated to a high enough procstate anyway to get network unless they
// request otherwise, so don't propagate the network capability by default
// in this case unless they explicitly request it.
- if ((cstate.getCurCapability() & PROCESS_CAPABILITY_NETWORK) != 0) {
+ if ((cstate.getCurCapability()
+ & PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK) != 0) {
if (clientProcState <= PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
// This is used to grant network access to Expedited Jobs.
if (cr.hasFlag(Context.BIND_BYPASS_POWER_NETWORK_RESTRICTIONS)) {
- capability |= PROCESS_CAPABILITY_NETWORK;
+ capability |= PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK;
}
} else {
- capability |= PROCESS_CAPABILITY_NETWORK;
+ capability |= PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK;
}
}
@@ -2798,27 +2800,33 @@ public class OomAdjuster {
}
private int getDefaultCapability(ProcessRecord app, int procState) {
+ final int networkCapabilities =
+ NetworkPolicyManager.getDefaultProcessNetworkCapabilities(procState);
+ final int baseCapabilities;
switch (procState) {
case PROCESS_STATE_PERSISTENT:
case PROCESS_STATE_PERSISTENT_UI:
case PROCESS_STATE_TOP:
- return PROCESS_CAPABILITY_ALL; // BFSL allowed
+ baseCapabilities = PROCESS_CAPABILITY_ALL; // BFSL allowed
+ break;
case PROCESS_STATE_BOUND_TOP:
- return PROCESS_CAPABILITY_NETWORK | PROCESS_CAPABILITY_BFSL;
+ baseCapabilities = PROCESS_CAPABILITY_BFSL;
+ break;
case PROCESS_STATE_FOREGROUND_SERVICE:
if (app.getActiveInstrumentation() != null) {
- return PROCESS_CAPABILITY_ALL_IMPLICIT | PROCESS_CAPABILITY_NETWORK ;
+ baseCapabilities = PROCESS_CAPABILITY_ALL_IMPLICIT;
} else {
// Capability from foreground service is conditional depending on
// foregroundServiceType in the manifest file and the
// mAllowWhileInUsePermissionInFgs flag.
- return PROCESS_CAPABILITY_NETWORK;
+ baseCapabilities = PROCESS_CAPABILITY_NONE;
}
- case PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
- return PROCESS_CAPABILITY_NETWORK;
+ break;
default:
- return PROCESS_CAPABILITY_NONE;
+ baseCapabilities = PROCESS_CAPABILITY_NONE;
+ break;
}
+ return baseCapabilities | networkCapabilities;
}
/**
diff --git a/services/core/java/com/android/server/appop/AppOpsUidStateTrackerImpl.java b/services/core/java/com/android/server/appop/AppOpsUidStateTrackerImpl.java
index 49279d44ea7c..2d6966ad0cf8 100644
--- a/services/core/java/com/android/server/appop/AppOpsUidStateTrackerImpl.java
+++ b/services/core/java/com/android/server/appop/AppOpsUidStateTrackerImpl.java
@@ -327,9 +327,12 @@ class AppOpsUidStateTrackerImpl implements AppOpsUidStateTracker {
}
private void commitUidPendingState(int uid) {
- int pendingUidState = mPendingUidStates.get(uid, MIN_PRIORITY_UID_STATE);
- int pendingCapability = mPendingCapability.get(uid, PROCESS_CAPABILITY_NONE);
- boolean pendingVisibleAppWidget = mPendingVisibleAppWidget.get(uid, false);
+ int pendingUidState = mPendingUidStates.get(uid,
+ mUidStates.get(uid, MIN_PRIORITY_UID_STATE));
+ int pendingCapability = mPendingCapability.get(uid,
+ mCapability.get(uid, PROCESS_CAPABILITY_NONE));
+ boolean pendingVisibleAppWidget = mPendingVisibleAppWidget.get(uid,
+ mVisibleAppWidget.get(uid, false));
int uidState = mUidStates.get(uid, MIN_PRIORITY_UID_STATE);
int capability = mCapability.get(uid, PROCESS_CAPABILITY_NONE);
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java b/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java
index 6d7b2cb40e21..c2994a953f31 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java
@@ -260,9 +260,8 @@ public class FaceService extends SystemService {
if (provider == null) {
Slog.w(TAG, "Null provider for authenticate");
return -1;
- } else {
- options.setSensorId(provider.first);
}
+ options.setSensorId(provider.first);
return provider.second.scheduleAuthenticate(token, operationId,
0 /* cookie */, new ClientMonitorCallbackConverter(receiver), options,
@@ -286,6 +285,7 @@ public class FaceService extends SystemService {
Slog.w(TAG, "Null provider for detectFace");
return -1;
}
+ options.setSensorId(provider.first);
return provider.second.scheduleFaceDetect(token,
new ClientMonitorCallbackConverter(receiver), options,
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
index f6c1375730bb..dc00ffc9f922 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
@@ -261,7 +261,6 @@ public class FingerprintService extends SystemService {
final String opPackageName = options.getOpPackageName();
final String attributionTag = options.getAttributionTag();
final int userId = options.getUserId();
- final int sensorId = options.getSensorId();
if (!canUseFingerprint(
opPackageName,
@@ -298,21 +297,22 @@ public class FingerprintService extends SystemService {
: BiometricsProtoEnums.CLIENT_FINGERPRINT_MANAGER;
final Pair<Integer, ServiceProvider> provider;
- if (sensorId == FingerprintManager.SENSOR_ID_ANY) {
+ if (options.getSensorId() == FingerprintManager.SENSOR_ID_ANY) {
provider = mRegistry.getSingleProvider();
} else {
Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
- provider = new Pair<>(sensorId, mRegistry.getProviderForSensor(sensorId));
+ provider = new Pair<>(options.getSensorId(),
+ mRegistry.getProviderForSensor(options.getSensorId()));
}
+
if (provider == null) {
Slog.w(TAG, "Null provider for authenticate");
return -1;
- } else {
- options.setSensorId(provider.first);
}
+ options.setSensorId(provider.first);
final FingerprintSensorPropertiesInternal sensorProps =
- provider.second.getSensorProperties(sensorId);
+ provider.second.getSensorProperties(options.getSensorId());
if (!isKeyguard && !Utils.isSettings(getContext(), opPackageName)
&& sensorProps != null && sensorProps.isAnyUdfpsType()) {
try {
@@ -431,9 +431,8 @@ public class FingerprintService extends SystemService {
if (provider == null) {
Slog.w(TAG, "Null provider for detectFingerprint");
return -1;
- } else {
- options.setSensorId(provider.first);
}
+ options.setSensorId(provider.first);
return provider.second.scheduleFingerDetect(token,
new ClientMonitorCallbackConverter(receiver), options,
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index 5a832b78487c..4f28432a20a2 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -33,7 +33,6 @@ import static android.os.UserHandle.USER_SYSTEM;
import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_NONE;
import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PASSWORD;
import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PASSWORD_OR_PIN;
-import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PATTERN;
import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PIN;
import static com.android.internal.widget.LockPatternUtils.CURRENT_LSKF_BASED_PROTECTOR_ID_KEY;
import static com.android.internal.widget.LockPatternUtils.EscrowTokenStateChangeCallback;
@@ -82,7 +81,6 @@ import android.hardware.fingerprint.Fingerprint;
import android.hardware.fingerprint.FingerprintManager;
import android.net.Uri;
import android.os.Binder;
-import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
@@ -117,7 +115,6 @@ import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.EventLog;
-import android.util.Log;
import android.util.LongSparseArray;
import android.util.Slog;
import android.util.SparseArray;
@@ -201,7 +198,6 @@ public class LockSettingsService extends ILockSettings.Stub {
private static final String TAG = "LockSettingsService";
private static final String PERMISSION = ACCESS_KEYGUARD_SECURE_STORAGE;
private static final String BIOMETRIC_PERMISSION = MANAGE_BIOMETRIC;
- private static final boolean DEBUG = Build.IS_DEBUGGABLE && Log.isLoggable(TAG, Log.DEBUG);
private static final int PROFILE_KEY_IV_SIZE = 12;
private static final String SEPARATE_PROFILE_CHALLENGE_KEY = "lockscreen.profilechallenge";
@@ -381,7 +377,6 @@ public class LockSettingsService extends ILockSettings.Stub {
*/
private void tieProfileLockIfNecessary(int profileUserId,
LockscreenCredential profileUserPassword) {
- if (DEBUG) Slog.v(TAG, "Check child profile lock for user: " + profileUserId);
// Only for profiles that shares credential with parent
if (!isCredentialSharableWithParent(profileUserId)) {
return;
@@ -399,8 +394,7 @@ public class LockSettingsService extends ILockSettings.Stub {
// as its parent.
final int parentId = mUserManager.getProfileParent(profileUserId).id;
if (!isUserSecure(parentId) && !profileUserPassword.isNone()) {
- if (DEBUG) Slog.v(TAG, "Parent does not have a screen lock but profile has one");
-
+ Slogf.i(TAG, "Clearing password for profile user %d to match parent", profileUserId);
setLockCredentialInternal(LockscreenCredential.createNone(), profileUserPassword,
profileUserId, /* isLockTiedToParent= */ true);
return;
@@ -416,7 +410,6 @@ public class LockSettingsService extends ILockSettings.Stub {
Slog.e(TAG, "Failed to talk to GateKeeper service", e);
return;
}
- if (DEBUG) Slog.v(TAG, "Tie profile to parent now!");
try (LockscreenCredential unifiedProfilePassword = generateRandomProfilePassword()) {
setLockCredentialInternal(unifiedProfilePassword, profileUserPassword, profileUserId,
/* isLockTiedToParent= */ true);
@@ -690,8 +683,8 @@ public class LockSettingsService extends ILockSettings.Stub {
PendingIntent intent = PendingIntent.getActivity(mContext, 0, unlockIntent,
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE_UNAUDITED);
- Slog.d(TAG, TextUtils.formatSimple("showing encryption notification, user: %d; reason: %s",
- user.getIdentifier(), reason));
+ Slogf.d(TAG, "Showing encryption notification for user %d; reason: %s",
+ user.getIdentifier(), reason);
showEncryptionNotification(user, title, message, detail, intent);
}
@@ -735,7 +728,7 @@ public class LockSettingsService extends ILockSettings.Stub {
}
private void hideEncryptionNotification(UserHandle userHandle) {
- Slog.d(TAG, "hide encryption notification, user: " + userHandle.getIdentifier());
+ Slogf.d(TAG, "Hiding encryption notification for user %d", userHandle.getIdentifier());
mNotificationManager.cancelAsUser(null, SystemMessage.NOTE_FBE_ENCRYPTED_NOTIFICATION,
userHandle);
}
@@ -888,7 +881,6 @@ public class LockSettingsService extends ILockSettings.Stub {
&& !getBoolean("migrated_frp", false, 0)) {
migrateFrpCredential();
setBoolean("migrated_frp", true, 0);
- Slog.i(TAG, "Migrated migrated_frp.");
}
}
@@ -1034,7 +1026,7 @@ public class LockSettingsService extends ILockSettings.Stub {
private void enforceFrpResolved() {
final int mainUserId = mInjector.getUserManagerInternal().getMainUserId();
if (mainUserId < 0) {
- Slog.i(TAG, "No Main user on device; skip enforceFrpResolved");
+ Slog.d(TAG, "No Main user on device; skipping enforceFrpResolved");
return;
}
final ContentResolver cr = mContext.getContentResolver();
@@ -1269,7 +1261,6 @@ public class LockSettingsService extends ILockSettings.Stub {
}
private void unlockKeystore(byte[] password, int userHandle) {
- if (DEBUG) Slog.v(TAG, "Unlock keystore for user: " + userHandle);
Authorization.onLockScreenEvent(false, userHandle, password, null);
}
@@ -1279,7 +1270,7 @@ public class LockSettingsService extends ILockSettings.Stub {
NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException,
CertificateException, IOException {
- if (DEBUG) Slog.v(TAG, "Get child profile decrypted key");
+ Slogf.d(TAG, "Decrypting password for tied profile %d", userId);
byte[] storedData = mStorage.readChildProfileLock(userId);
if (storedData == null) {
throw new FileNotFoundException("Child profile lock file not found");
@@ -1328,7 +1319,6 @@ public class LockSettingsService extends ILockSettings.Stub {
* {@link com.android.server.SystemServiceManager#unlockUser} </em>
*/
private void unlockUser(@UserIdInt int userId) {
- Slogf.i(TAG, "Unlocking user %d", userId);
// TODO: make this method fully async so we can update UI with progress strings
final boolean alreadyUnlocked = mUserManager.isUserUnlockingOrUnlocked(userId);
final CountDownLatch latch = new CountDownLatch(1);
@@ -1638,7 +1628,6 @@ public class LockSettingsService extends ILockSettings.Stub {
LockscreenCredential savedCredential, int userId, boolean isLockTiedToParent) {
Objects.requireNonNull(credential);
Objects.requireNonNull(savedCredential);
- if (DEBUG) Slog.d(TAG, "setLockCredentialInternal: user=" + userId);
synchronized (mSpManager) {
if (savedCredential.isNone() && isProfileWithUnifiedLock(userId)) {
// get credential from keystore when profile has unified lock
@@ -1720,6 +1709,7 @@ public class LockSettingsService extends ILockSettings.Stub {
if (passwordHistoryLength == 0) {
passwordHistory = "";
} else {
+ Slogf.d(TAG, "Adding new password to password history for user %d", userHandle);
final byte[] hashFactor = getHashFactor(password, userHandle);
final byte[] salt = getSalt(userHandle).getBytes();
String hash = password.passwordToHistoryHash(salt, hashFactor);
@@ -1751,7 +1741,6 @@ public class LockSettingsService extends ILockSettings.Stub {
if (salt == 0) {
salt = SecureRandomUtils.randomLong();
setLong(LockPatternUtils.LOCK_PASSWORD_SALT_KEY, salt, userId);
- Slog.v(TAG, "Initialized lock password salt for user: " + userId);
}
return Long.toHexString(salt);
}
@@ -1875,7 +1864,8 @@ public class LockSettingsService extends ILockSettings.Stub {
@VisibleForTesting /** Note: this method is overridden in unit tests */
protected void tieProfileLockToParent(int profileUserId, int parentUserId,
LockscreenCredential password) {
- if (DEBUG) Slog.v(TAG, "tieProfileLockToParent for user: " + profileUserId);
+ Slogf.i(TAG, "Tying lock for profile user %d to parent user %d", profileUserId,
+ parentUserId);
final byte[] iv;
final byte[] ciphertext;
final long parentSid;
@@ -2002,7 +1992,7 @@ public class LockSettingsService extends ILockSettings.Stub {
@Override
public void resetKeyStore(int userId) {
checkWritePermission();
- if (DEBUG) Slog.v(TAG, "Reset keystore for user: " + userId);
+ Slogf.d(TAG, "Resetting keystore for user %d", userId);
List<Integer> profileUserIds = new ArrayList<>();
List<LockscreenCredential> profileUserDecryptedPasswords = new ArrayList<>();
final List<UserInfo> profiles = mUserManager.getProfiles(userId);
@@ -2039,7 +2029,6 @@ public class LockSettingsService extends ILockSettings.Stub {
int piUserId = profileUserIds.get(i);
LockscreenCredential piUserDecryptedPassword = profileUserDecryptedPasswords.get(i);
if (piUserId != -1 && piUserDecryptedPassword != null) {
- if (DEBUG) Slog.v(TAG, "Restore tied profile lock");
tieProfileLockToParent(piUserId, userId, piUserDecryptedPassword);
}
if (piUserDecryptedPassword != null) {
@@ -2132,7 +2121,7 @@ public class LockSettingsService extends ILockSettings.Stub {
Slog.e(TAG, "FRP credential can only be verified prior to provisioning.");
return VerifyCredentialResponse.ERROR;
}
- Slog.d(TAG, "doVerifyCredential: user=" + userId);
+ Slogf.i(TAG, "Verifying lockscreen credential for user %d", userId);
final AuthenticationResult authResult;
VerifyCredentialResponse response;
@@ -2166,6 +2155,7 @@ public class LockSettingsService extends ILockSettings.Stub {
}
}
if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
+ Slogf.i(TAG, "Successfully verified lockscreen credential for user %d", userId);
onCredentialVerified(authResult.syntheticPassword,
PasswordMetrics.computeForCredential(credential), userId);
if ((flags & VERIFY_FLAG_REQUEST_GK_PW_HANDLE) != 0) {
@@ -2324,13 +2314,18 @@ public class LockSettingsService extends ILockSettings.Stub {
}
private void removeKeystoreProfileKey(int targetUserId) {
- Slog.i(TAG, "Remove keystore profile key for user: " + targetUserId);
+ final String encryptAlias = PROFILE_KEY_NAME_ENCRYPT + targetUserId;
+ final String decryptAlias = PROFILE_KEY_NAME_DECRYPT + targetUserId;
try {
- mJavaKeyStore.deleteEntry(PROFILE_KEY_NAME_ENCRYPT + targetUserId);
- mJavaKeyStore.deleteEntry(PROFILE_KEY_NAME_DECRYPT + targetUserId);
+ if (mJavaKeyStore.containsAlias(encryptAlias) ||
+ mJavaKeyStore.containsAlias(decryptAlias)) {
+ Slogf.i(TAG, "Removing keystore profile key for user %d", targetUserId);
+ mJavaKeyStore.deleteEntry(encryptAlias);
+ mJavaKeyStore.deleteEntry(decryptAlias);
+ }
} catch (KeyStoreException e) {
- // We have tried our best to remove all keys
- Slog.e(TAG, "Unable to remove keystore profile key for user:" + targetUserId, e);
+ // We have tried our best to remove the key.
+ Slogf.e(TAG, e, "Error removing keystore profile key for user %d", targetUserId);
}
}
@@ -2678,7 +2673,7 @@ public class LockSettingsService extends ILockSettings.Stub {
@VisibleForTesting
SyntheticPassword initializeSyntheticPassword(int userId) {
synchronized (mSpManager) {
- Slog.i(TAG, "Initialize SyntheticPassword for user: " + userId);
+ Slogf.i(TAG, "Initializing synthetic password for user %d", userId);
Preconditions.checkState(getCurrentLskfBasedProtectorId(userId) ==
SyntheticPasswordManager.NULL_PROTECTOR_ID,
"Cannot reinitialize SP");
@@ -2689,6 +2684,7 @@ public class LockSettingsService extends ILockSettings.Stub {
setCurrentLskfBasedProtectorId(protectorId, userId);
setUserKeyProtection(userId, sp.deriveFileBasedEncryptionKey());
onSyntheticPasswordCreated(userId, sp);
+ Slogf.i(TAG, "Successfully initialized synthetic password for user %d", userId);
return sp;
}
}
@@ -2725,8 +2721,11 @@ public class LockSettingsService extends ILockSettings.Stub {
final long finalHandle = handle;
mHandler.postDelayed(() -> {
synchronized (mGatekeeperPasswords) {
- Slog.d(TAG, "Removing handle: " + finalHandle);
- mGatekeeperPasswords.remove(finalHandle);
+ if (mGatekeeperPasswords.get(finalHandle) != null) {
+ Slogf.d(TAG, "Cached Gatekeeper password with handle %016x has expired",
+ finalHandle);
+ mGatekeeperPasswords.remove(finalHandle);
+ }
}
}, GK_PW_HANDLE_STORE_DURATION_MS);
@@ -2775,7 +2774,8 @@ public class LockSettingsService extends ILockSettings.Stub {
@GuardedBy("mSpManager")
private long setLockCredentialWithSpLocked(LockscreenCredential credential,
SyntheticPassword sp, int userId) {
- if (DEBUG) Slog.d(TAG, "setLockCredentialWithSpLocked: user=" + userId);
+ Slogf.i(TAG, "Changing lockscreen credential of user %d; newCredentialType=%s\n",
+ userId, LockPatternUtils.credentialTypeToString(credential.getType()));
final int savedCredentialType = getCredentialTypeInternal(userId);
final long oldProtectorId = getCurrentLskfBasedProtectorId(userId);
final long newProtectorId = mSpManager.createLskfBasedProtector(getGateKeeperService(),
@@ -2820,6 +2820,7 @@ public class LockSettingsService extends ILockSettings.Stub {
}
}
mSpManager.destroyLskfBasedProtector(oldProtectorId, userId);
+ Slogf.i(TAG, "Successfully changed lockscreen credential of user %d", userId);
return newProtectorId;
}
@@ -2904,6 +2905,7 @@ public class LockSettingsService extends ILockSettings.Stub {
public byte[] getHashFactor(LockscreenCredential currentCredential, int userId) {
checkPasswordReadPermission();
try {
+ Slogf.d(TAG, "Getting password history hash factor for user %d", userId);
if (isProfileWithUnifiedLock(userId)) {
try {
currentCredential = getDecryptedPasswordForTiedProfile(userId);
@@ -2929,7 +2931,7 @@ public class LockSettingsService extends ILockSettings.Stub {
private long addEscrowToken(@NonNull byte[] token, @TokenType int type, int userId,
@NonNull EscrowTokenStateChangeCallback callback) {
- if (DEBUG) Slog.d(TAG, "addEscrowToken: user=" + userId + ", type=" + type);
+ Slogf.i(TAG, "Adding escrow token for user %d", userId);
synchronized (mSpManager) {
// If the user has no LSKF, then the token can be activated immediately. Otherwise, the
// token can't be activated until the SP is unlocked by another protector (normally the
@@ -2947,18 +2949,20 @@ public class LockSettingsService extends ILockSettings.Stub {
long handle = mSpManager.addPendingToken(token, type, userId, callback);
if (sp != null) {
// Activate the token immediately
+ Slogf.i(TAG, "Immediately activating escrow token %016x", handle);
mSpManager.createTokenBasedProtector(handle, sp, userId);
+ } else {
+ Slogf.i(TAG, "Escrow token %016x will be activated when user is unlocked", handle);
}
return handle;
}
}
private void activateEscrowTokens(SyntheticPassword sp, int userId) {
- if (DEBUG) Slog.d(TAG, "activateEscrowTokens: user=" + userId);
synchronized (mSpManager) {
disableEscrowTokenOnNonManagedDevicesIfNeeded(userId);
for (long handle : mSpManager.getPendingTokensForUser(userId)) {
- Slog.i(TAG, TextUtils.formatSimple("activateEscrowTokens: %x %d ", handle, userId));
+ Slogf.i(TAG, "Activating escrow token %016x for user %d", handle, userId);
mSpManager.createTokenBasedProtector(handle, sp, userId);
}
}
@@ -3029,6 +3033,8 @@ public class LockSettingsService extends ILockSettings.Stub {
@GuardedBy("mSpManager")
private boolean setLockCredentialWithTokenInternalLocked(LockscreenCredential credential,
long tokenHandle, byte[] token, int userId) {
+ Slogf.i(TAG, "Resetting lockscreen credential of user %d using escrow token %016x",
+ userId, tokenHandle);
final AuthenticationResult result;
result = mSpManager.unlockTokenBasedProtector(getGateKeeperService(), tokenHandle, token,
userId);
@@ -3051,8 +3057,9 @@ public class LockSettingsService extends ILockSettings.Stub {
private boolean unlockUserWithToken(long tokenHandle, byte[] token, int userId) {
AuthenticationResult authResult;
synchronized (mSpManager) {
+ Slogf.i(TAG, "Unlocking user %d using escrow token %016x", userId, tokenHandle);
if (!mSpManager.hasEscrowData(userId)) {
- Slog.w(TAG, "Escrow token is disabled on the current user");
+ Slogf.w(TAG, "Escrow token support is disabled on user %d", userId);
return false;
}
authResult = mSpManager.unlockTokenBasedProtector(getGateKeeperService(), tokenHandle,
@@ -3063,6 +3070,7 @@ public class LockSettingsService extends ILockSettings.Stub {
}
}
+ Slogf.i(TAG, "Unlocked synthetic password for user %d using escrow token", userId);
onCredentialVerified(authResult.syntheticPassword,
loadPasswordMetrics(authResult.syntheticPassword, userId), userId);
return true;
@@ -3090,21 +3098,6 @@ public class LockSettingsService extends ILockSettings.Stub {
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(timestamp));
}
- private static String credentialTypeToString(int credentialType) {
- switch (credentialType) {
- case CREDENTIAL_TYPE_NONE:
- return "None";
- case CREDENTIAL_TYPE_PATTERN:
- return "Pattern";
- case CREDENTIAL_TYPE_PIN:
- return "Pin";
- case CREDENTIAL_TYPE_PASSWORD:
- return "Password";
- default:
- return "Unknown " + credentialType;
- }
- }
-
@Override
protected void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) {
if (!DumpUtils.checkDumpPermission(mContext, TAG, printWriter)) return;
@@ -3121,22 +3114,23 @@ public class LockSettingsService extends ILockSettings.Stub {
pw.println("User " + userId);
pw.increaseIndent();
synchronized (mSpManager) {
- pw.println(TextUtils.formatSimple("LSKF-based SP protector ID: %x",
+ pw.println(TextUtils.formatSimple("LSKF-based SP protector ID: %016x",
getCurrentLskfBasedProtectorId(userId)));
- pw.println(TextUtils.formatSimple("LSKF last changed: %s (previous protector: %x)",
- timestampToString(getLong(LSKF_LAST_CHANGED_TIME_KEY, 0, userId)),
- getLong(PREV_LSKF_BASED_PROTECTOR_ID_KEY, 0, userId)));
+ pw.println(TextUtils.formatSimple(
+ "LSKF last changed: %s (previous protector: %016x)",
+ timestampToString(getLong(LSKF_LAST_CHANGED_TIME_KEY, 0, userId)),
+ getLong(PREV_LSKF_BASED_PROTECTOR_ID_KEY, 0, userId)));
}
try {
- pw.println(TextUtils.formatSimple("SID: %x",
+ pw.println(TextUtils.formatSimple("SID: %016x",
getGateKeeperService().getSecureUserId(userId)));
} catch (RemoteException e) {
// ignore.
}
- // It's OK to dump the password type since anyone with physical access can just
+ // It's OK to dump the credential type since anyone with physical access can just
// observe it from the keyguard directly.
pw.println("Quality: " + getKeyguardStoredQuality(userId));
- pw.println("CredentialType: " + credentialTypeToString(
+ pw.println("CredentialType: " + LockPatternUtils.credentialTypeToString(
getCredentialTypeInternal(userId)));
pw.println("SeparateChallenge: " + getSeparateProfileChallengeEnabledInternal(userId));
pw.println(TextUtils.formatSimple("Metrics: %s",
@@ -3194,6 +3188,11 @@ public class LockSettingsService extends ILockSettings.Stub {
* if we are running an automotive build.
*/
private void disableEscrowTokenOnNonManagedDevicesIfNeeded(int userId) {
+
+ if (!mSpManager.hasAnyEscrowData(userId)) {
+ return;
+ }
+
// TODO(b/258213147): Remove
final long identity = Binder.clearCallingIdentity();
try {
@@ -3238,7 +3237,7 @@ public class LockSettingsService extends ILockSettings.Stub {
}
// Disable escrow token permanently on all other device/user types.
- Slog.i(TAG, "Disabling escrow token on user " + userId);
+ Slogf.i(TAG, "Permanently disabling support for escrow tokens on user %d", userId);
mSpManager.destroyEscrowData(userId);
}
@@ -3470,6 +3469,7 @@ public class LockSettingsService extends ILockSettings.Stub {
synchronized (mSpManager) {
mSpManager.verifyChallenge(getGateKeeperService(), sp, 0L, userId);
}
+ Slogf.i(TAG, "Restored synthetic password for user %d using reboot escrow", userId);
onCredentialVerified(sp, loadPasswordMetrics(sp, userId), userId);
}
}
diff --git a/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java b/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java
index d070b416c53c..1663b019d769 100644
--- a/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java
+++ b/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java
@@ -744,6 +744,11 @@ class SyntheticPasswordManager {
&& hasState(SP_P1_NAME, NULL_PROTECTOR_ID, userId);
}
+ public boolean hasAnyEscrowData(int userId) {
+ return hasState(SP_E0_NAME, NULL_PROTECTOR_ID, userId)
+ || hasState(SP_P1_NAME, NULL_PROTECTOR_ID, userId);
+ }
+
public void destroyEscrowData(int userId) {
destroyState(SP_E0_NAME, NULL_PROTECTOR_ID, userId);
destroyState(SP_P1_NAME, NULL_PROTECTOR_ID, userId);
@@ -786,11 +791,11 @@ class SyntheticPasswordManager {
}
Set<Integer> usedSlots = getUsedWeaverSlots();
if (!usedSlots.contains(slot)) {
- Slog.i(TAG, "Destroy weaver slot " + slot + " for user " + userId);
+ Slogf.i(TAG, "Erasing Weaver slot %d", slot);
weaverEnroll(slot, null, null);
mPasswordSlotManager.markSlotDeleted(slot);
} else {
- Slog.w(TAG, "Skip destroying reused weaver slot " + slot + " for user " + userId);
+ Slogf.i(TAG, "Weaver slot %d was already reused; not erasing it", slot);
}
}
}
@@ -858,11 +863,13 @@ class SyntheticPasswordManager {
long sid = GateKeeper.INVALID_SECURE_USER_ID;
final byte[] protectorSecret;
+ Slogf.i(TAG, "Creating LSKF-based protector %016x for user %d", protectorId, userId);
+
if (isWeaverAvailable()) {
// Weaver is available, so make the protector use it to verify the LSKF. Do this even
// if the LSKF is empty, as that gives us support for securely deleting the protector.
int weaverSlot = getNextAvailableWeaverSlot();
- Slog.i(TAG, "Weaver enroll password to slot " + weaverSlot + " for user " + userId);
+ Slogf.i(TAG, "Enrolling LSKF for user %d into Weaver slot %d", userId, weaverSlot);
byte[] weaverSecret = weaverEnroll(weaverSlot, stretchedLskfToWeaverKey(stretchedLskf),
null);
if (weaverSecret == null) {
@@ -892,6 +899,7 @@ class SyntheticPasswordManager {
} catch (RemoteException ignore) {
Slog.w(TAG, "Failed to clear SID from gatekeeper");
}
+ Slogf.i(TAG, "Enrolling LSKF for user %d into Gatekeeper", userId);
GateKeeperResponse response;
try {
response = gatekeeper.enroll(fakeUserId(userId), null, null,
@@ -964,6 +972,7 @@ class SyntheticPasswordManager {
&& LockPatternUtils.userOwnsFrpCredential(mContext, userInfo)
&& getCredentialType(protectorId, userInfo.id) !=
LockPatternUtils.CREDENTIAL_TYPE_NONE) {
+ Slog.i(TAG, "Migrating FRP credential to persistent data block");
PasswordData pwd = PasswordData.fromBytes(loadState(PASSWORD_DATA_NAME, protectorId,
userInfo.id));
int weaverSlot = loadWeaverSlot(protectorId, userInfo.id);
@@ -1092,9 +1101,10 @@ class SyntheticPasswordManager {
Slog.w(TAG, "User is not escrowable");
return false;
}
+ Slogf.i(TAG, "Creating token-based protector %016x for user %d", tokenHandle, userId);
if (isWeaverAvailable()) {
int slot = getNextAvailableWeaverSlot();
- Slog.i(TAG, "Weaver enroll token to slot " + slot + " for user " + userId);
+ Slogf.i(TAG, "Using Weaver slot %d for new token-based protector", slot);
if (weaverEnroll(slot, null, tokenData.weaverSecret) == null) {
Slog.e(TAG, "Failed to enroll weaver secret when activating token");
return false;
@@ -1170,8 +1180,9 @@ class SyntheticPasswordManager {
storedType = pwd.credentialType;
}
if (!credential.checkAgainstStoredType(storedType)) {
- Slog.e(TAG, TextUtils.formatSimple("Credential type mismatch: expected %d actual %d",
- storedType, credential.getType()));
+ Slogf.e(TAG, "Credential type mismatch: stored type is %s but provided type is %s",
+ LockPatternUtils.credentialTypeToString(storedType),
+ LockPatternUtils.credentialTypeToString(credential.getType()));
result.gkResponse = VerifyCredentialResponse.ERROR;
return result;
}
@@ -1473,6 +1484,7 @@ class SyntheticPasswordManager {
/** Destroy a token-based SP protector. */
public void destroyTokenBasedProtector(long protectorId, int userId) {
+ Slogf.i(TAG, "Destroying token-based protector %016x for user %d", protectorId, userId);
SyntheticPasswordBlob blob = SyntheticPasswordBlob.fromBytes(loadState(SP_BLOB_NAME,
protectorId, userId));
destroyProtectorCommon(protectorId, userId);
@@ -1498,6 +1510,7 @@ class SyntheticPasswordManager {
* Destroy an LSKF-based SP protector. This is used when the user's LSKF is changed.
*/
public void destroyLskfBasedProtector(long protectorId, int userId) {
+ Slogf.i(TAG, "Destroying LSKF-based protector %016x for user %d", protectorId, userId);
destroyProtectorCommon(protectorId, userId);
destroyState(PASSWORD_DATA_NAME, protectorId, userId);
destroyState(PASSWORD_METRICS_NAME, protectorId, userId);
@@ -1658,6 +1671,9 @@ class SyntheticPasswordManager {
}
private String getProtectorKeyAlias(long protectorId) {
+ // Note, this arguably has a bug: %x should be %016x so that the protector ID is left-padded
+ // with zeroes, like how the synthetic password state files are named. It's too late to fix
+ // this, though, and it doesn't actually matter.
return TextUtils.formatSimple("%s%x", PROTECTOR_KEY_ALIAS_PREFIX, protectorId);
}
diff --git a/services/core/java/com/android/server/pm/ResilientAtomicFile.java b/services/core/java/com/android/server/pm/ResilientAtomicFile.java
new file mode 100644
index 000000000000..19aa4f8e8d0b
--- /dev/null
+++ b/services/core/java/com/android/server/pm/ResilientAtomicFile.java
@@ -0,0 +1,265 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.pm;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.FileUtils;
+import android.os.ParcelFileDescriptor;
+import android.util.Log;
+import android.util.Slog;
+
+import com.android.server.security.FileIntegrity;
+
+import libcore.io.IoUtils;
+
+import java.io.Closeable;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+final class ResilientAtomicFile implements Closeable {
+ private static final String LOG_TAG = "ResilientAtomicFile";
+
+ private final File mFile;
+
+ private final File mTemporaryBackup;
+
+ private final File mReserveCopy;
+
+ private final int mFileMode;
+
+ private final String mDebugName;
+
+ private final ReadEventLogger mReadEventLogger;
+
+ // Write state.
+ private FileOutputStream mMainOutStream = null;
+ private FileInputStream mMainInStream = null;
+ private FileOutputStream mReserveOutStream = null;
+ private FileInputStream mReserveInStream = null;
+
+ // Read state.
+ private File mCurrentFile = null;
+ private FileInputStream mCurrentInStream = null;
+
+ private void finalizeOutStream(FileOutputStream str) throws IOException {
+ // Flash/sync + set permissions.
+ str.flush();
+ FileUtils.sync(str);
+ FileUtils.setPermissions(str.getFD(), mFileMode, -1, -1);
+ }
+
+ ResilientAtomicFile(@NonNull File file, @NonNull File temporaryBackup,
+ @NonNull File reserveCopy, int fileMode, String debugName,
+ @Nullable ReadEventLogger readEventLogger) {
+ mFile = file;
+ mTemporaryBackup = temporaryBackup;
+ mReserveCopy = reserveCopy;
+ mFileMode = fileMode;
+ mDebugName = debugName;
+ mReadEventLogger = readEventLogger;
+ }
+
+ public File getBaseFile() {
+ return mFile;
+ }
+
+ public FileOutputStream startWrite() throws IOException {
+ if (mMainOutStream != null) {
+ throw new IllegalStateException("Duplicate startWrite call?");
+ }
+
+ new File(mFile.getParent()).mkdirs();
+
+ if (mFile.exists()) {
+ // Presence of backup settings file indicates that we failed
+ // to persist packages earlier. So preserve the older
+ // backup for future reference since the current packages
+ // might have been corrupted.
+ if (!mTemporaryBackup.exists()) {
+ if (!mFile.renameTo(mTemporaryBackup)) {
+ throw new IOException("Unable to backup " + mDebugName
+ + " file, current changes will be lost at reboot");
+ }
+ } else {
+ mFile.delete();
+ Slog.w(LOG_TAG, "Preserving older " + mDebugName + " backup");
+ }
+ }
+ // Reserve copy is not valid anymore.
+ mReserveCopy.delete();
+
+ // In case of MT access, it's possible the files get overwritten during write.
+ // Let's open all FDs we need now.
+ mMainOutStream = new FileOutputStream(mFile);
+ mMainInStream = new FileInputStream(mFile);
+ mReserveOutStream = new FileOutputStream(mReserveCopy);
+ mReserveInStream = new FileInputStream(mReserveCopy);
+
+ return mMainOutStream;
+ }
+
+ public void finishWrite(FileOutputStream str) throws IOException {
+ if (mMainOutStream != str) {
+ throw new IllegalStateException("Invalid incoming stream.");
+ }
+
+ // Flush and set permissions.
+ try (FileOutputStream mainOutStream = mMainOutStream) {
+ mMainOutStream = null;
+ finalizeOutStream(mainOutStream);
+ }
+ // New file successfully written, old one are no longer needed.
+ mTemporaryBackup.delete();
+
+ try (FileInputStream mainInStream = mMainInStream;
+ FileInputStream reserveInStream = mReserveInStream) {
+ mMainInStream = null;
+ mReserveInStream = null;
+
+ // Copy main file to reserve.
+ try (FileOutputStream reserveOutStream = mReserveOutStream) {
+ mReserveOutStream = null;
+ FileUtils.copy(mainInStream, reserveOutStream);
+ finalizeOutStream(reserveOutStream);
+ }
+
+ // Protect both main and reserve using fs-verity.
+ try (ParcelFileDescriptor mainPfd = ParcelFileDescriptor.dup(mainInStream.getFD());
+ ParcelFileDescriptor copyPfd = ParcelFileDescriptor.dup(reserveInStream.getFD())) {
+ FileIntegrity.setUpFsVerity(mainPfd);
+ FileIntegrity.setUpFsVerity(copyPfd);
+ } catch (IOException e) {
+ Slog.e(LOG_TAG, "Failed to verity-protect " + mDebugName, e);
+ }
+ } catch (IOException e) {
+ Slog.e(LOG_TAG, "Failed to write reserve copy " + mDebugName + ": " + mReserveCopy, e);
+ }
+ }
+
+ public void failWrite(FileOutputStream str) {
+ if (mMainOutStream != str) {
+ throw new IllegalStateException("Invalid incoming stream.");
+ }
+
+ // Close all FDs.
+ close();
+
+ // Clean up partially written files
+ if (mFile.exists()) {
+ if (!mFile.delete()) {
+ Slog.i(LOG_TAG, "Failed to clean up mangled file: " + mFile);
+ }
+ }
+ }
+
+ public FileInputStream openRead() throws IOException {
+ if (mTemporaryBackup.exists()) {
+ try {
+ mCurrentFile = mTemporaryBackup;
+ mCurrentInStream = new FileInputStream(mCurrentFile);
+ if (mReadEventLogger != null) {
+ mReadEventLogger.logEvent(Log.INFO,
+ "Need to read from backup " + mDebugName + " file");
+ }
+ if (mFile.exists()) {
+ // If both the backup and normal file exist, we
+ // ignore the normal one since it might have been
+ // corrupted.
+ Slog.w(LOG_TAG, "Cleaning up " + mDebugName + " file " + mFile);
+ mFile.delete();
+ }
+ // Ignore reserve copy as well.
+ mReserveCopy.delete();
+ } catch (java.io.IOException e) {
+ // We'll try for the normal settings file.
+ }
+ }
+
+ if (mCurrentInStream != null) {
+ return mCurrentInStream;
+ }
+
+ if (mFile.exists()) {
+ mCurrentFile = mFile;
+ mCurrentInStream = new FileInputStream(mCurrentFile);
+ } else if (mReserveCopy.exists()) {
+ mCurrentFile = mReserveCopy;
+ mCurrentInStream = new FileInputStream(mCurrentFile);
+ if (mReadEventLogger != null) {
+ mReadEventLogger.logEvent(Log.INFO,
+ "Need to read from reserve copy " + mDebugName + " file");
+ }
+ }
+
+ if (mCurrentInStream == null) {
+ if (mReadEventLogger != null) {
+ mReadEventLogger.logEvent(Log.INFO, "No " + mDebugName + " file");
+ }
+ }
+
+ return mCurrentInStream;
+ }
+
+ public void failRead(FileInputStream str, Exception e) {
+ if (mCurrentInStream != str) {
+ throw new IllegalStateException("Invalid incoming stream.");
+ }
+ mCurrentInStream = null;
+ IoUtils.closeQuietly(str);
+
+ if (mReadEventLogger != null) {
+ mReadEventLogger.logEvent(Log.ERROR,
+ "Error reading " + mDebugName + ", removing " + mCurrentFile + '\n'
+ + Log.getStackTraceString(e));
+ }
+
+ mCurrentFile.delete();
+ mCurrentFile = null;
+ }
+
+ public void delete() {
+ mFile.delete();
+ mTemporaryBackup.delete();
+ mReserveCopy.delete();
+ }
+
+ @Override
+ public void close() {
+ IoUtils.closeQuietly(mMainOutStream);
+ IoUtils.closeQuietly(mMainInStream);
+ IoUtils.closeQuietly(mReserveOutStream);
+ IoUtils.closeQuietly(mReserveInStream);
+ IoUtils.closeQuietly(mCurrentInStream);
+ mMainOutStream = null;
+ mMainInStream = null;
+ mReserveOutStream = null;
+ mReserveInStream = null;
+ mCurrentInStream = null;
+ mCurrentFile = null;
+ }
+
+ public String toString() {
+ return mFile.getPath();
+ }
+
+ interface ReadEventLogger {
+ void logEvent(int priority, String msg);
+ }
+}
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index f1998f764e7c..b6557d000463 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -119,7 +119,6 @@ import com.android.server.pm.resolution.ComponentResolver;
import com.android.server.pm.verify.domain.DomainVerificationLegacySettings;
import com.android.server.pm.verify.domain.DomainVerificationManagerInternal;
import com.android.server.pm.verify.domain.DomainVerificationPersistence;
-import com.android.server.security.FileIntegrity;
import com.android.server.utils.Slogf;
import com.android.server.utils.Snappable;
import com.android.server.utils.SnapshotCache;
@@ -172,7 +171,7 @@ import java.util.function.Consumer;
/**
* Holds information about dynamic settings.
*/
-public final class Settings implements Watchable, Snappable {
+public final class Settings implements Watchable, Snappable, ResilientAtomicFile.ReadEventLogger {
private static final String TAG = "PackageSettings";
/**
@@ -344,7 +343,7 @@ public final class Settings implements Watchable, Snappable {
private static final String ATTR_BLOCK_UNINSTALL = "blockUninstall";
private static final String ATTR_ENABLED = "enabled";
private static final String ATTR_ENABLED_CALLER = "enabledCaller";
- private static final String ATTR_DOMAIN_VERIFICATON_STATE = "domainVerificationStatus";
+ private static final String ATTR_DOMAIN_VERIFICATION_STATE = "domainVerificationStatus";
private static final String ATTR_APP_LINK_GENERATION = "app-link-generation";
private static final String ATTR_INSTALL_REASON = "install-reason";
private static final String ATTR_UNINSTALL_REASON = "uninstall-reason";
@@ -1511,16 +1510,22 @@ public final class Settings implements Watchable, Snappable {
return new File(new File(mSystemDir, "users"), Integer.toString(userId));
}
- // The method itself does not have to be guarded, but the file does.
- @GuardedBy("mPackageRestrictionsLock")
- private File getUserPackagesStateFile(int userId) {
- return new File(getUserSystemDirectory(userId), "package-restrictions.xml");
+ private ResilientAtomicFile getUserPackagesStateFile(int userId) {
+ File mainFile = new File(getUserSystemDirectory(userId), "package-restrictions.xml");
+ File temporaryBackup = new File(getUserSystemDirectory(userId),
+ "package-restrictions-backup.xml");
+ File reserveCopy = new File(getUserSystemDirectory(userId),
+ "package-restrictions.xml.reservecopy");
+ return new ResilientAtomicFile(mainFile, temporaryBackup, reserveCopy,
+ FileUtils.S_IRUSR | FileUtils.S_IWUSR | FileUtils.S_IRGRP | FileUtils.S_IWGRP,
+ "package restrictions", this);
}
- // The method itself does not have to be guarded, but the file does.
- @GuardedBy("mPackageRestrictionsLock")
- private File getUserPackagesStateBackupFile(int userId) {
- return new File(getUserSystemDirectory(userId), "package-restrictions-backup.xml");
+ private ResilientAtomicFile getSettingsFile() {
+ return new ResilientAtomicFile(mSettingsFilename, mPreviousSettingsFilename,
+ mSettingsReserveCopyFilename,
+ FileUtils.S_IRUSR | FileUtils.S_IWUSR | FileUtils.S_IRGRP | FileUtils.S_IWGRP,
+ "package manager settings", this);
}
private File getUserRuntimePermissionsFile(int userId) {
@@ -1730,272 +1735,243 @@ public final class Settings implements Watchable, Snappable {
}
}
+ @Override
+ public void logEvent(int priority, String msg) {
+ mReadMessages.append(msg + "\n");
+ PackageManagerService.reportSettingsProblem(priority, msg);
+ }
+
+
void readPackageRestrictionsLPr(int userId,
@NonNull ArrayMap<String, Long> origFirstInstallTimes) {
if (DEBUG_MU) {
Log.i(TAG, "Reading package restrictions for user=" + userId);
}
- FileInputStream str = null;
- synchronized (mPackageRestrictionsLock) {
- File userPackagesStateFile = getUserPackagesStateFile(userId);
- File backupFile = getUserPackagesStateBackupFile(userId);
- if (backupFile.exists()) {
- try {
- str = new FileInputStream(backupFile);
- mReadMessages.append("Reading from backup stopped packages file\n");
- PackageManagerService.reportSettingsProblem(Log.INFO,
- "Need to read from backup stopped packages file");
- if (userPackagesStateFile.exists()) {
- // If both the backup and normal file exist, we
- // ignore the normal one since it might have been
- // corrupted.
- Slog.w(PackageManagerService.TAG, "Cleaning up stopped packages file "
- + userPackagesStateFile);
- userPackagesStateFile.delete();
+ try (ResilientAtomicFile atomicFile = getUserPackagesStateFile(userId)) {
+ FileInputStream str = null;
+ try {
+ synchronized (mPackageRestrictionsLock) {
+ str = atomicFile.openRead();
+ if (str == null) {
+ // At first boot, make sure no packages are stopped.
+ // We usually want to have third party apps initialize
+ // in the stopped state, but not at first boot. Also
+ // consider all applications to be installed.
+ for (PackageSetting pkg : mPackages.values()) {
+ pkg.setUserState(userId, 0, COMPONENT_ENABLED_STATE_DEFAULT,
+ true /*installed*/,
+ false /*stopped*/,
+ false /*notLaunched*/,
+ false /*hidden*/,
+ 0 /*distractionFlags*/,
+ null /*suspendParams*/,
+ false /*instantApp*/,
+ false /*virtualPreload*/,
+ null /*lastDisableAppCaller*/,
+ null /*enabledComponents*/,
+ null /*disabledComponents*/,
+ PackageManager.INSTALL_REASON_UNKNOWN,
+ PackageManager.UNINSTALL_REASON_UNKNOWN,
+ null /*harmfulAppWarning*/,
+ null /* splashScreenTheme*/,
+ 0 /*firstInstallTime*/
+ );
+ }
+ return;
}
- } catch (java.io.IOException e) {
- // We'll try for the normal settings file.
}
- }
-
- if (str == null && userPackagesStateFile.exists()) {
- try {
- str = new FileInputStream(userPackagesStateFile);
- if (DEBUG_MU) Log.i(TAG, "Reading " + userPackagesStateFile);
- } catch (java.io.IOException e) {
- mReadMessages.append("Error reading: " + e.toString());
- PackageManagerService.reportSettingsProblem(Log.ERROR,
- "Error reading settings: " + e);
- Slog.wtf(TAG, "Error reading package manager stopped packages", e);
- }
- }
- }
-
- if (str == null) {
- mReadMessages.append("No stopped packages file found\n");
- PackageManagerService.reportSettingsProblem(Log.INFO,
- "No stopped packages file; "
- + "assuming all started");
- // At first boot, make sure no packages are stopped.
- // We usually want to have third party apps initialize
- // in the stopped state, but not at first boot. Also
- // consider all applications to be installed.
- for (PackageSetting pkg : mPackages.values()) {
- pkg.setUserState(userId, 0, COMPONENT_ENABLED_STATE_DEFAULT,
- true /*installed*/,
- false /*stopped*/,
- false /*notLaunched*/,
- false /*hidden*/,
- 0 /*distractionFlags*/,
- null /*suspendParams*/,
- false /*instantApp*/,
- false /*virtualPreload*/,
- null /*lastDisableAppCaller*/,
- null /*enabledComponents*/,
- null /*disabledComponents*/,
- PackageManager.INSTALL_REASON_UNKNOWN,
- PackageManager.UNINSTALL_REASON_UNKNOWN,
- null /*harmfulAppWarning*/,
- null /* splashScreenTheme*/,
- 0 /*firstInstallTime*/
- );
- }
- return;
- }
- try {
- final TypedXmlPullParser parser = Xml.resolvePullParser(str);
-
- int type;
- while ((type=parser.next()) != XmlPullParser.START_TAG
- && type != XmlPullParser.END_DOCUMENT) {
- ;
- }
+ final TypedXmlPullParser parser = Xml.resolvePullParser(str);
- if (type != XmlPullParser.START_TAG) {
- mReadMessages.append("No start tag found in package restrictions file\n");
- PackageManagerService.reportSettingsProblem(Log.WARN,
- "No start tag found in package manager stopped packages");
- return;
- }
+ int type;
+ while ((type = parser.next()) != XmlPullParser.START_TAG
+ && type != XmlPullParser.END_DOCUMENT) {
+ // nothing
+ }
- int outerDepth = parser.getDepth();
- PackageSetting ps = null;
- while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
- && (type != XmlPullParser.END_TAG
- || parser.getDepth() > outerDepth)) {
- if (type == XmlPullParser.END_TAG
- || type == XmlPullParser.TEXT) {
- continue;
+ if (type != XmlPullParser.START_TAG) {
+ mReadMessages.append("No start tag found in package restrictions file\n");
+ PackageManagerService.reportSettingsProblem(Log.WARN,
+ "No start tag found in package manager package restrictions file");
+ return;
}
- String tagName = parser.getName();
- if (tagName.equals(TAG_PACKAGE)) {
- String name = parser.getAttributeValue(null, ATTR_NAME);
- ps = mPackages.get(name);
- if (ps == null) {
- Slog.w(PackageManagerService.TAG, "No package known for stopped package "
- + name);
- XmlUtils.skipCurrentTag(parser);
+ int outerDepth = parser.getDepth();
+ PackageSetting ps = null;
+ while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+ && (type != XmlPullParser.END_TAG
+ || parser.getDepth() > outerDepth)) {
+ if (type == XmlPullParser.END_TAG
+ || type == XmlPullParser.TEXT) {
continue;
}
- final long ceDataInode =
- parser.getAttributeLong(null, ATTR_CE_DATA_INODE, 0);
- final boolean installed =
- parser.getAttributeBoolean(null, ATTR_INSTALLED, true);
- final boolean stopped =
- parser.getAttributeBoolean(null, ATTR_STOPPED, false);
- final boolean notLaunched =
- parser.getAttributeBoolean(null, ATTR_NOT_LAUNCHED, false);
-
- // For backwards compatibility with the previous name of "blocked", which
- // now means hidden, read the old attribute as well.
- boolean hidden = parser.getAttributeBoolean(null, ATTR_HIDDEN, false);
- if (!hidden) {
- hidden = parser.getAttributeBoolean(null, ATTR_BLOCKED, false);
- }
+ String tagName = parser.getName();
+ if (tagName.equals(TAG_PACKAGE)) {
+ String name = parser.getAttributeValue(null, ATTR_NAME);
+ ps = mPackages.get(name);
+ if (ps == null) {
+ Slog.w(PackageManagerService.TAG,
+ "No package known for package restrictions " + name);
+ XmlUtils.skipCurrentTag(parser);
+ continue;
+ }
- final int distractionFlags = parser.getAttributeInt(null, ATTR_DISTRACTION_FLAGS, 0);
- final boolean suspended = parser.getAttributeBoolean(null, ATTR_SUSPENDED, false);
- String oldSuspendingPackage = parser.getAttributeValue(null,
- ATTR_SUSPENDING_PACKAGE);
- final String dialogMessage = parser.getAttributeValue(null,
- ATTR_SUSPEND_DIALOG_MESSAGE);
- if (suspended && oldSuspendingPackage == null) {
- oldSuspendingPackage = PLATFORM_PACKAGE_NAME;
- }
+ final long ceDataInode =
+ parser.getAttributeLong(null, ATTR_CE_DATA_INODE, 0);
+ final boolean installed =
+ parser.getAttributeBoolean(null, ATTR_INSTALLED, true);
+ final boolean stopped =
+ parser.getAttributeBoolean(null, ATTR_STOPPED, false);
+ final boolean notLaunched =
+ parser.getAttributeBoolean(null, ATTR_NOT_LAUNCHED, false);
+
+ // For backwards compatibility with the previous name of "blocked", which
+ // now means hidden, read the old attribute as well.
+ boolean hidden = parser.getAttributeBoolean(null, ATTR_HIDDEN, false);
+ if (!hidden) {
+ hidden = parser.getAttributeBoolean(null, ATTR_BLOCKED, false);
+ }
- final boolean blockUninstall =
- parser.getAttributeBoolean(null, ATTR_BLOCK_UNINSTALL, false);
- final boolean instantApp =
- parser.getAttributeBoolean(null, ATTR_INSTANT_APP, false);
- final boolean virtualPreload =
- parser.getAttributeBoolean(null, ATTR_VIRTUAL_PRELOAD, false);
- final int enabled = parser.getAttributeInt(null, ATTR_ENABLED,
- COMPONENT_ENABLED_STATE_DEFAULT);
- final String enabledCaller = parser.getAttributeValue(null,
- ATTR_ENABLED_CALLER);
- final String harmfulAppWarning =
- parser.getAttributeValue(null, ATTR_HARMFUL_APP_WARNING);
- final int verifState = parser.getAttributeInt(null,
- ATTR_DOMAIN_VERIFICATON_STATE,
- PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED);
- final int installReason = parser.getAttributeInt(null, ATTR_INSTALL_REASON,
- PackageManager.INSTALL_REASON_UNKNOWN);
- final int uninstallReason = parser.getAttributeInt(null, ATTR_UNINSTALL_REASON,
- PackageManager.UNINSTALL_REASON_UNKNOWN);
- final String splashScreenTheme = parser.getAttributeValue(null,
- ATTR_SPLASH_SCREEN_THEME);
- final long firstInstallTime = parser.getAttributeLongHex(null,
- ATTR_FIRST_INSTALL_TIME, 0);
-
- ArraySet<String> enabledComponents = null;
- ArraySet<String> disabledComponents = null;
- PersistableBundle suspendedAppExtras = null;
- PersistableBundle suspendedLauncherExtras = null;
- SuspendDialogInfo oldSuspendDialogInfo = null;
-
- int packageDepth = parser.getDepth();
- ArrayMap<String, SuspendParams> suspendParamsMap = null;
- while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
- && (type != XmlPullParser.END_TAG
- || parser.getDepth() > packageDepth)) {
- if (type == XmlPullParser.END_TAG
- || type == XmlPullParser.TEXT) {
- continue;
+ final int distractionFlags = parser.getAttributeInt(null,
+ ATTR_DISTRACTION_FLAGS, 0);
+ final boolean suspended = parser.getAttributeBoolean(null, ATTR_SUSPENDED,
+ false);
+ String oldSuspendingPackage = parser.getAttributeValue(null,
+ ATTR_SUSPENDING_PACKAGE);
+ final String dialogMessage = parser.getAttributeValue(null,
+ ATTR_SUSPEND_DIALOG_MESSAGE);
+ if (suspended && oldSuspendingPackage == null) {
+ oldSuspendingPackage = PLATFORM_PACKAGE_NAME;
}
- switch (parser.getName()) {
- case TAG_ENABLED_COMPONENTS:
- enabledComponents = readComponentsLPr(parser);
- break;
- case TAG_DISABLED_COMPONENTS:
- disabledComponents = readComponentsLPr(parser);
- break;
- case TAG_SUSPENDED_APP_EXTRAS:
- suspendedAppExtras = PersistableBundle.restoreFromXml(parser);
- break;
- case TAG_SUSPENDED_LAUNCHER_EXTRAS:
- suspendedLauncherExtras = PersistableBundle.restoreFromXml(parser);
- break;
- case TAG_SUSPENDED_DIALOG_INFO:
- oldSuspendDialogInfo = SuspendDialogInfo.restoreFromXml(parser);
- break;
- case TAG_SUSPEND_PARAMS:
- final String suspendingPackage = parser.getAttributeValue(null,
- ATTR_SUSPENDING_PACKAGE);
- if (suspendingPackage == null) {
- Slog.wtf(TAG, "No suspendingPackage found inside tag "
- + TAG_SUSPEND_PARAMS);
- continue;
- }
- if (suspendParamsMap == null) {
- suspendParamsMap = new ArrayMap<>();
- }
- suspendParamsMap.put(suspendingPackage,
- SuspendParams.restoreFromXml(parser));
- break;
- default:
- Slog.wtf(TAG, "Unknown tag " + parser.getName() + " under tag "
- + TAG_PACKAGE);
+
+ final boolean blockUninstall =
+ parser.getAttributeBoolean(null, ATTR_BLOCK_UNINSTALL, false);
+ final boolean instantApp =
+ parser.getAttributeBoolean(null, ATTR_INSTANT_APP, false);
+ final boolean virtualPreload =
+ parser.getAttributeBoolean(null, ATTR_VIRTUAL_PRELOAD, false);
+ final int enabled = parser.getAttributeInt(null, ATTR_ENABLED,
+ COMPONENT_ENABLED_STATE_DEFAULT);
+ final String enabledCaller = parser.getAttributeValue(null,
+ ATTR_ENABLED_CALLER);
+ final String harmfulAppWarning =
+ parser.getAttributeValue(null, ATTR_HARMFUL_APP_WARNING);
+ final int verifState = parser.getAttributeInt(null,
+ ATTR_DOMAIN_VERIFICATION_STATE,
+ PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED);
+ final int installReason = parser.getAttributeInt(null, ATTR_INSTALL_REASON,
+ PackageManager.INSTALL_REASON_UNKNOWN);
+ final int uninstallReason = parser.getAttributeInt(null,
+ ATTR_UNINSTALL_REASON,
+ PackageManager.UNINSTALL_REASON_UNKNOWN);
+ final String splashScreenTheme = parser.getAttributeValue(null,
+ ATTR_SPLASH_SCREEN_THEME);
+ final long firstInstallTime = parser.getAttributeLongHex(null,
+ ATTR_FIRST_INSTALL_TIME, 0);
+
+ ArraySet<String> enabledComponents = null;
+ ArraySet<String> disabledComponents = null;
+ PersistableBundle suspendedAppExtras = null;
+ PersistableBundle suspendedLauncherExtras = null;
+ SuspendDialogInfo oldSuspendDialogInfo = null;
+
+ int packageDepth = parser.getDepth();
+ ArrayMap<String, SuspendParams> suspendParamsMap = null;
+ while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+ && (type != XmlPullParser.END_TAG
+ || parser.getDepth() > packageDepth)) {
+ if (type == XmlPullParser.END_TAG
+ || type == XmlPullParser.TEXT) {
+ continue;
+ }
+ switch (parser.getName()) {
+ case TAG_ENABLED_COMPONENTS:
+ enabledComponents = readComponentsLPr(parser);
+ break;
+ case TAG_DISABLED_COMPONENTS:
+ disabledComponents = readComponentsLPr(parser);
+ break;
+ case TAG_SUSPENDED_APP_EXTRAS:
+ suspendedAppExtras = PersistableBundle.restoreFromXml(parser);
+ break;
+ case TAG_SUSPENDED_LAUNCHER_EXTRAS:
+ suspendedLauncherExtras = PersistableBundle.restoreFromXml(
+ parser);
+ break;
+ case TAG_SUSPENDED_DIALOG_INFO:
+ oldSuspendDialogInfo = SuspendDialogInfo.restoreFromXml(parser);
+ break;
+ case TAG_SUSPEND_PARAMS:
+ final String suspendingPackage = parser.getAttributeValue(null,
+ ATTR_SUSPENDING_PACKAGE);
+ if (suspendingPackage == null) {
+ Slog.wtf(TAG, "No suspendingPackage found inside tag "
+ + TAG_SUSPEND_PARAMS);
+ continue;
+ }
+ if (suspendParamsMap == null) {
+ suspendParamsMap = new ArrayMap<>();
+ }
+ suspendParamsMap.put(suspendingPackage,
+ SuspendParams.restoreFromXml(parser));
+ break;
+ default:
+ Slog.wtf(TAG, "Unknown tag " + parser.getName() + " under tag "
+ + TAG_PACKAGE);
+ }
+ }
+ if (oldSuspendDialogInfo == null && !TextUtils.isEmpty(dialogMessage)) {
+ oldSuspendDialogInfo = new SuspendDialogInfo.Builder()
+ .setMessage(dialogMessage)
+ .build();
+ }
+ if (suspended && suspendParamsMap == null) {
+ final SuspendParams suspendParams = new SuspendParams(
+ oldSuspendDialogInfo,
+ suspendedAppExtras,
+ suspendedLauncherExtras);
+ suspendParamsMap = new ArrayMap<>();
+ suspendParamsMap.put(oldSuspendingPackage, suspendParams);
}
- }
- if (oldSuspendDialogInfo == null && !TextUtils.isEmpty(dialogMessage)) {
- oldSuspendDialogInfo = new SuspendDialogInfo.Builder()
- .setMessage(dialogMessage)
- .build();
- }
- if (suspended && suspendParamsMap == null) {
- final SuspendParams suspendParams = new SuspendParams(
- oldSuspendDialogInfo,
- suspendedAppExtras,
- suspendedLauncherExtras);
- suspendParamsMap = new ArrayMap<>();
- suspendParamsMap.put(oldSuspendingPackage, suspendParams);
- }
- if (blockUninstall) {
- setBlockUninstallLPw(userId, name, true);
+ if (blockUninstall) {
+ setBlockUninstallLPw(userId, name, true);
+ }
+ ps.setUserState(userId, ceDataInode, enabled, installed, stopped,
+ notLaunched,
+ hidden, distractionFlags, suspendParamsMap, instantApp,
+ virtualPreload,
+ enabledCaller, enabledComponents, disabledComponents, installReason,
+ uninstallReason, harmfulAppWarning, splashScreenTheme,
+ firstInstallTime != 0 ? firstInstallTime :
+ origFirstInstallTimes.getOrDefault(name, 0L));
+
+ mDomainVerificationManager.setLegacyUserState(name, userId, verifState);
+ } else if (tagName.equals("preferred-activities")) {
+ readPreferredActivitiesLPw(parser, userId);
+ } else if (tagName.equals(TAG_PERSISTENT_PREFERRED_ACTIVITIES)) {
+ readPersistentPreferredActivitiesLPw(parser, userId);
+ } else if (tagName.equals(TAG_CROSS_PROFILE_INTENT_FILTERS)) {
+ readCrossProfileIntentFiltersLPw(parser, userId);
+ } else if (tagName.equals(TAG_DEFAULT_APPS)) {
+ readDefaultAppsLPw(parser, userId);
+ } else if (tagName.equals(TAG_BLOCK_UNINSTALL_PACKAGES)) {
+ readBlockUninstallPackagesLPw(parser, userId);
+ } else {
+ Slog.w(PackageManagerService.TAG,
+ "Unknown element under <stopped-packages>: "
+ + parser.getName());
+ XmlUtils.skipCurrentTag(parser);
}
- ps.setUserState(userId, ceDataInode, enabled, installed, stopped, notLaunched,
- hidden, distractionFlags, suspendParamsMap, instantApp, virtualPreload,
- enabledCaller, enabledComponents, disabledComponents, installReason,
- uninstallReason, harmfulAppWarning, splashScreenTheme,
- firstInstallTime != 0 ? firstInstallTime :
- origFirstInstallTimes.getOrDefault(name, 0L));
-
- mDomainVerificationManager.setLegacyUserState(name, userId, verifState);
- } else if (tagName.equals("preferred-activities")) {
- readPreferredActivitiesLPw(parser, userId);
- } else if (tagName.equals(TAG_PERSISTENT_PREFERRED_ACTIVITIES)) {
- readPersistentPreferredActivitiesLPw(parser, userId);
- } else if (tagName.equals(TAG_CROSS_PROFILE_INTENT_FILTERS)) {
- readCrossProfileIntentFiltersLPw(parser, userId);
- } else if (tagName.equals(TAG_DEFAULT_APPS)) {
- readDefaultAppsLPw(parser, userId);
- } else if (tagName.equals(TAG_BLOCK_UNINSTALL_PACKAGES)) {
- readBlockUninstallPackagesLPw(parser, userId);
- } else {
- Slog.w(PackageManagerService.TAG, "Unknown element under <stopped-packages>: "
- + parser.getName());
- XmlUtils.skipCurrentTag(parser);
}
- }
-
- str.close();
- } catch (XmlPullParserException e) {
- mReadMessages.append("Error reading: " + e.toString());
- PackageManagerService.reportSettingsProblem(Log.ERROR,
- "Error reading stopped packages: " + e);
- Slog.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages",
- e);
+ } catch (IOException | XmlPullParserException e) {
+ // Remove corrupted file and retry.
+ atomicFile.failRead(str, e);
- } catch (java.io.IOException e) {
- mReadMessages.append("Error reading: " + e.toString());
- PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e);
- Slog.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages",
- e);
+ readPackageRestrictionsLPr(userId, origFirstInstallTimes);
+ }
}
}
@@ -2165,219 +2141,176 @@ public final class Settings implements Watchable, Snappable {
Log.i(TAG, "Writing package restrictions for user=" + userId);
}
- final File userPackagesStateFile;
- final File backupFile;
- final FileOutputStream fstr;
-
- synchronized (mPackageRestrictionsLock) {
- if (!sync) {
- int pending = mPendingAsyncPackageRestrictionsWrites.get(userId, 0) - 1;
- if (pending < 0) {
- Log.i(TAG, "Cancel writing package restrictions for user=" + userId);
- return;
- }
- mPendingAsyncPackageRestrictionsWrites.put(userId, pending);
- }
+ FileOutputStream str = null;
+ try (ResilientAtomicFile atomicFile = getUserPackagesStateFile(userId)) {
+ try {
+ synchronized (mPackageRestrictionsLock) {
+ if (!sync) {
+ int pending = mPendingAsyncPackageRestrictionsWrites.get(userId, 0) - 1;
+ if (pending < 0) {
+ Log.i(TAG, "Cancel writing package restrictions for user=" + userId);
+ return;
+ }
+ mPendingAsyncPackageRestrictionsWrites.put(userId, pending);
+ }
- // Keep the old stopped packages around until we know the new ones have
- // been successfully written.
- userPackagesStateFile = getUserPackagesStateFile(userId);
- backupFile = getUserPackagesStateBackupFile(userId);
- new File(userPackagesStateFile.getParent()).mkdirs();
- if (userPackagesStateFile.exists()) {
- // Presence of backup settings file indicates that we failed
- // to persist packages earlier. So preserve the older
- // backup for future reference since the current packages
- // might have been corrupted.
- if (!backupFile.exists()) {
- if (!userPackagesStateFile.renameTo(backupFile)) {
+ try {
+ str = atomicFile.startWrite();
+ } catch (java.io.IOException e) {
Slog.wtf(PackageManagerService.TAG,
- "Unable to backup user packages state file, "
- + "current changes will be lost at reboot");
+ "Unable to write package manager package restrictions, "
+ + " current changes will be lost at reboot", e);
return;
}
- } else {
- userPackagesStateFile.delete();
- Slog.w(PackageManagerService.TAG, "Preserving older stopped packages backup");
}
- }
-
- try {
- fstr = new FileOutputStream(userPackagesStateFile);
- // File is created, set permissions.
- FileUtils.setPermissions(userPackagesStateFile.toString(),
- FileUtils.S_IRUSR | FileUtils.S_IWUSR
- | FileUtils.S_IRGRP | FileUtils.S_IWGRP,
- -1, -1);
- } catch (java.io.IOException e) {
- Slog.wtf(PackageManagerService.TAG,
- "Unable to write package manager user packages state, "
- + " current changes will be lost at reboot", e);
- return;
- }
- }
- try {
- synchronized (mLock) {
- final TypedXmlSerializer serializer = Xml.resolveSerializer(fstr);
- serializer.startDocument(null, true);
- serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output",
- true);
+ synchronized (mLock) {
+ final TypedXmlSerializer serializer = Xml.resolveSerializer(str);
+ serializer.startDocument(null, true);
+ serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output",
+ true);
- serializer.startTag(null, TAG_PACKAGE_RESTRICTIONS);
+ serializer.startTag(null, TAG_PACKAGE_RESTRICTIONS);
- if (DEBUG_MU) {
- Slogf.i(TAG, "Writing %s (%d packages)", userPackagesStateFile,
- mPackages.values().size());
- }
- for (final PackageSetting pkg : mPackages.values()) {
- final PackageUserStateInternal ustate = pkg.readUserState(userId);
if (DEBUG_MU) {
- Log.v(TAG, " pkg=" + pkg.getPackageName()
- + ", installed=" + ustate.isInstalled()
- + ", state=" + ustate.getEnabledState());
+ Slogf.i(TAG, "Writing %s (%d packages)", atomicFile,
+ mPackages.values().size());
}
+ for (final PackageSetting pkg : mPackages.values()) {
+ final PackageUserStateInternal ustate = pkg.readUserState(userId);
+ if (DEBUG_MU) {
+ Log.v(TAG, " pkg=" + pkg.getPackageName()
+ + ", installed=" + ustate.isInstalled()
+ + ", state=" + ustate.getEnabledState());
+ }
- serializer.startTag(null, TAG_PACKAGE);
- serializer.attribute(null, ATTR_NAME, pkg.getPackageName());
- if (ustate.getCeDataInode() != 0) {
- serializer.attributeLong(null, ATTR_CE_DATA_INODE, ustate.getCeDataInode());
- }
- if (!ustate.isInstalled()) {
- serializer.attributeBoolean(null, ATTR_INSTALLED, false);
- }
- if (ustate.isStopped()) {
- serializer.attributeBoolean(null, ATTR_STOPPED, true);
- }
- if (ustate.isNotLaunched()) {
- serializer.attributeBoolean(null, ATTR_NOT_LAUNCHED, true);
- }
- if (ustate.isHidden()) {
- serializer.attributeBoolean(null, ATTR_HIDDEN, true);
- }
- if (ustate.getDistractionFlags() != 0) {
- serializer.attributeInt(null, ATTR_DISTRACTION_FLAGS,
- ustate.getDistractionFlags());
- }
- if (ustate.isSuspended()) {
- serializer.attributeBoolean(null, ATTR_SUSPENDED, true);
- }
- if (ustate.isInstantApp()) {
- serializer.attributeBoolean(null, ATTR_INSTANT_APP, true);
- }
- if (ustate.isVirtualPreload()) {
- serializer.attributeBoolean(null, ATTR_VIRTUAL_PRELOAD, true);
- }
- if (ustate.getEnabledState() != COMPONENT_ENABLED_STATE_DEFAULT) {
- serializer.attributeInt(null, ATTR_ENABLED, ustate.getEnabledState());
- if (ustate.getLastDisableAppCaller() != null) {
- serializer.attribute(null, ATTR_ENABLED_CALLER,
- ustate.getLastDisableAppCaller());
+ serializer.startTag(null, TAG_PACKAGE);
+ serializer.attribute(null, ATTR_NAME, pkg.getPackageName());
+ if (ustate.getCeDataInode() != 0) {
+ serializer.attributeLong(null, ATTR_CE_DATA_INODE,
+ ustate.getCeDataInode());
}
- }
- if (ustate.getInstallReason() != PackageManager.INSTALL_REASON_UNKNOWN) {
- serializer.attributeInt(null, ATTR_INSTALL_REASON,
- ustate.getInstallReason());
- }
- serializer.attributeLongHex(null, ATTR_FIRST_INSTALL_TIME,
- ustate.getFirstInstallTimeMillis());
- if (ustate.getUninstallReason() != PackageManager.UNINSTALL_REASON_UNKNOWN) {
- serializer.attributeInt(null, ATTR_UNINSTALL_REASON,
- ustate.getUninstallReason());
- }
- if (ustate.getHarmfulAppWarning() != null) {
- serializer.attribute(null, ATTR_HARMFUL_APP_WARNING,
- ustate.getHarmfulAppWarning());
- }
- if (ustate.getSplashScreenTheme() != null) {
- serializer.attribute(null, ATTR_SPLASH_SCREEN_THEME,
- ustate.getSplashScreenTheme());
- }
- if (ustate.isSuspended()) {
- for (int i = 0; i < ustate.getSuspendParams().size(); i++) {
- final String suspendingPackage = ustate.getSuspendParams().keyAt(i);
- serializer.startTag(null, TAG_SUSPEND_PARAMS);
- serializer.attribute(null, ATTR_SUSPENDING_PACKAGE, suspendingPackage);
- final SuspendParams params =
- ustate.getSuspendParams().valueAt(i);
- if (params != null) {
- params.saveToXml(serializer);
+ if (!ustate.isInstalled()) {
+ serializer.attributeBoolean(null, ATTR_INSTALLED, false);
+ }
+ if (ustate.isStopped()) {
+ serializer.attributeBoolean(null, ATTR_STOPPED, true);
+ }
+ if (ustate.isNotLaunched()) {
+ serializer.attributeBoolean(null, ATTR_NOT_LAUNCHED, true);
+ }
+ if (ustate.isHidden()) {
+ serializer.attributeBoolean(null, ATTR_HIDDEN, true);
+ }
+ if (ustate.getDistractionFlags() != 0) {
+ serializer.attributeInt(null, ATTR_DISTRACTION_FLAGS,
+ ustate.getDistractionFlags());
+ }
+ if (ustate.isSuspended()) {
+ serializer.attributeBoolean(null, ATTR_SUSPENDED, true);
+ }
+ if (ustate.isInstantApp()) {
+ serializer.attributeBoolean(null, ATTR_INSTANT_APP, true);
+ }
+ if (ustate.isVirtualPreload()) {
+ serializer.attributeBoolean(null, ATTR_VIRTUAL_PRELOAD, true);
+ }
+ if (ustate.getEnabledState() != COMPONENT_ENABLED_STATE_DEFAULT) {
+ serializer.attributeInt(null, ATTR_ENABLED, ustate.getEnabledState());
+ if (ustate.getLastDisableAppCaller() != null) {
+ serializer.attribute(null, ATTR_ENABLED_CALLER,
+ ustate.getLastDisableAppCaller());
}
- serializer.endTag(null, TAG_SUSPEND_PARAMS);
}
- }
- final ArraySet<String> enabledComponents = ustate.getEnabledComponents();
- if (enabledComponents != null && enabledComponents.size() > 0) {
- serializer.startTag(null, TAG_ENABLED_COMPONENTS);
- for (int i = 0; i < enabledComponents.size(); i++) {
- serializer.startTag(null, TAG_ITEM);
- serializer.attribute(null, ATTR_NAME,
- enabledComponents.valueAt(i));
- serializer.endTag(null, TAG_ITEM);
+ if (ustate.getInstallReason() != PackageManager.INSTALL_REASON_UNKNOWN) {
+ serializer.attributeInt(null, ATTR_INSTALL_REASON,
+ ustate.getInstallReason());
}
- serializer.endTag(null, TAG_ENABLED_COMPONENTS);
- }
- final ArraySet<String> disabledComponents = ustate.getDisabledComponents();
- if (disabledComponents != null && disabledComponents.size() > 0) {
- serializer.startTag(null, TAG_DISABLED_COMPONENTS);
- for (int i = 0; i < disabledComponents.size(); i++) {
- serializer.startTag(null, TAG_ITEM);
- serializer.attribute(null, ATTR_NAME,
- disabledComponents.valueAt(i));
- serializer.endTag(null, TAG_ITEM);
+ serializer.attributeLongHex(null, ATTR_FIRST_INSTALL_TIME,
+ ustate.getFirstInstallTimeMillis());
+ if (ustate.getUninstallReason()
+ != PackageManager.UNINSTALL_REASON_UNKNOWN) {
+ serializer.attributeInt(null, ATTR_UNINSTALL_REASON,
+ ustate.getUninstallReason());
+ }
+ if (ustate.getHarmfulAppWarning() != null) {
+ serializer.attribute(null, ATTR_HARMFUL_APP_WARNING,
+ ustate.getHarmfulAppWarning());
+ }
+ if (ustate.getSplashScreenTheme() != null) {
+ serializer.attribute(null, ATTR_SPLASH_SCREEN_THEME,
+ ustate.getSplashScreenTheme());
+ }
+ if (ustate.isSuspended()) {
+ for (int i = 0; i < ustate.getSuspendParams().size(); i++) {
+ final String suspendingPackage = ustate.getSuspendParams().keyAt(i);
+ serializer.startTag(null, TAG_SUSPEND_PARAMS);
+ serializer.attribute(null, ATTR_SUSPENDING_PACKAGE,
+ suspendingPackage);
+ final SuspendParams params =
+ ustate.getSuspendParams().valueAt(i);
+ if (params != null) {
+ params.saveToXml(serializer);
+ }
+ serializer.endTag(null, TAG_SUSPEND_PARAMS);
+ }
+ }
+ final ArraySet<String> enabledComponents = ustate.getEnabledComponents();
+ if (enabledComponents != null && enabledComponents.size() > 0) {
+ serializer.startTag(null, TAG_ENABLED_COMPONENTS);
+ for (int i = 0; i < enabledComponents.size(); i++) {
+ serializer.startTag(null, TAG_ITEM);
+ serializer.attribute(null, ATTR_NAME,
+ enabledComponents.valueAt(i));
+ serializer.endTag(null, TAG_ITEM);
+ }
+ serializer.endTag(null, TAG_ENABLED_COMPONENTS);
+ }
+ final ArraySet<String> disabledComponents = ustate.getDisabledComponents();
+ if (disabledComponents != null && disabledComponents.size() > 0) {
+ serializer.startTag(null, TAG_DISABLED_COMPONENTS);
+ for (int i = 0; i < disabledComponents.size(); i++) {
+ serializer.startTag(null, TAG_ITEM);
+ serializer.attribute(null, ATTR_NAME,
+ disabledComponents.valueAt(i));
+ serializer.endTag(null, TAG_ITEM);
+ }
+ serializer.endTag(null, TAG_DISABLED_COMPONENTS);
}
- serializer.endTag(null, TAG_DISABLED_COMPONENTS);
- }
-
- serializer.endTag(null, TAG_PACKAGE);
- }
- writePreferredActivitiesLPr(serializer, userId, true);
- writePersistentPreferredActivitiesLPr(serializer, userId);
- writeCrossProfileIntentFiltersLPr(serializer, userId);
- writeDefaultAppsLPr(serializer, userId);
- writeBlockUninstallPackagesLPr(serializer, userId);
+ serializer.endTag(null, TAG_PACKAGE);
+ }
- serializer.endTag(null, TAG_PACKAGE_RESTRICTIONS);
+ writePreferredActivitiesLPr(serializer, userId, true);
+ writePersistentPreferredActivitiesLPr(serializer, userId);
+ writeCrossProfileIntentFiltersLPr(serializer, userId);
+ writeDefaultAppsLPr(serializer, userId);
+ writeBlockUninstallPackagesLPr(serializer, userId);
- serializer.endDocument();
- }
+ serializer.endTag(null, TAG_PACKAGE_RESTRICTIONS);
- fstr.flush();
- FileUtils.sync(fstr);
- IoUtils.closeQuietly(fstr);
+ serializer.endDocument();
+ }
- synchronized (mPackageRestrictionsLock) {
- // File is created, set permissions.
- FileUtils.setPermissions(userPackagesStateFile.toString(),
- FileUtils.S_IRUSR | FileUtils.S_IWUSR
- | FileUtils.S_IRGRP | FileUtils.S_IWGRP,
- -1, -1);
- // New settings successfully written, old ones are no longer needed.
- backupFile.delete();
- }
+ atomicFile.finishWrite(str);
- if (DEBUG_MU) {
- Log.i(TAG, "New settings successfully written for user=" + userId + ": "
- + userPackagesStateFile);
- }
+ if (DEBUG_MU) {
+ Log.i(TAG, "New package restrictions successfully written for user=" + userId
+ + ": " + atomicFile);
+ }
- com.android.internal.logging.EventLogTags.writeCommitSysConfigFile(
- "package-user-" + userId, SystemClock.uptimeMillis() - startTime);
+ com.android.internal.logging.EventLogTags.writeCommitSysConfigFile(
+ "package-user-" + userId, SystemClock.uptimeMillis() - startTime);
- // Done, all is good!
- return;
- } catch (java.io.IOException e) {
- Slog.wtf(PackageManagerService.TAG,
- "Unable to write package manager user packages state, "
- + " current changes will be lost at reboot", e);
- }
-
- // Clean up partially written files
- if (userPackagesStateFile.exists()) {
- if (!userPackagesStateFile.delete()) {
- Log.i(PackageManagerService.TAG, "Failed to clean up mangled file: "
- + mStoppedPackagesFilename);
+ // Done, all is good!
+ return;
+ } catch (java.io.IOException e) {
+ Slog.wtf(PackageManagerService.TAG,
+ "Unable to write package manager package restrictions, "
+ + " current changes will be lost at reboot", e);
+ if (str != null) {
+ atomicFile.failWrite(str);
+ }
}
}
}
@@ -2589,153 +2522,108 @@ public final class Settings implements Watchable, Snappable {
// right time.
invalidatePackageCache();
- // Keep the old settings around until we know the new ones have
- // been successfully written.
- if (mSettingsFilename.exists()) {
- // Presence of backup settings file indicates that we failed
- // to persist settings earlier. So preserve the older
- // backup for future reference since the current settings
- // might have been corrupted.
- if (!mPreviousSettingsFilename.exists()) {
- if (!mSettingsFilename.renameTo(mPreviousSettingsFilename)) {
- Slog.wtf(PackageManagerService.TAG,
- "Unable to store older package manager settings, "
- + " current changes will be lost at reboot");
- return;
- }
- } else {
- mSettingsFilename.delete();
- Slog.w(PackageManagerService.TAG, "Preserving older settings backup");
- }
- }
-
mPastSignatures.clear();
- try {
- final FileOutputStream fstr = new FileOutputStream(mSettingsFilename);
- final TypedXmlSerializer serializer = Xml.resolveSerializer(fstr);
- serializer.startDocument(null, true);
- serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
-
- serializer.startTag(null, "packages");
-
- for (int i = 0; i < mVersion.size(); i++) {
- final String volumeUuid = mVersion.keyAt(i);
- final VersionInfo ver = mVersion.valueAt(i);
-
- serializer.startTag(null, TAG_VERSION);
- XmlUtils.writeStringAttribute(serializer, ATTR_VOLUME_UUID, volumeUuid);
- serializer.attributeInt(null, ATTR_SDK_VERSION, ver.sdkVersion);
- serializer.attributeInt(null, ATTR_DATABASE_VERSION, ver.databaseVersion);
- XmlUtils.writeStringAttribute(serializer, ATTR_BUILD_FINGERPRINT,
- ver.buildFingerprint);
- XmlUtils.writeStringAttribute(serializer, ATTR_FINGERPRINT, ver.fingerprint);
- serializer.endTag(null, TAG_VERSION);
- }
+ try (ResilientAtomicFile atomicFile = getSettingsFile()) {
+ FileOutputStream str = null;
+ try {
+ str = atomicFile.startWrite();
- if (mVerifierDeviceIdentity != null) {
- serializer.startTag(null, "verifier");
- serializer.attribute(null, "device", mVerifierDeviceIdentity.toString());
- serializer.endTag(null, "verifier");
- }
+ final TypedXmlSerializer serializer = Xml.resolveSerializer(str);
+ serializer.startDocument(null, true);
+ serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output",
+ true);
- serializer.startTag(null, "permission-trees");
- mPermissions.writePermissionTrees(serializer);
- serializer.endTag(null, "permission-trees");
+ serializer.startTag(null, "packages");
- serializer.startTag(null, "permissions");
- mPermissions.writePermissions(serializer);
- serializer.endTag(null, "permissions");
+ for (int i = 0; i < mVersion.size(); i++) {
+ final String volumeUuid = mVersion.keyAt(i);
+ final VersionInfo ver = mVersion.valueAt(i);
- for (final PackageSetting pkg : mPackages.values()) {
- if (pkg.getPkg() != null && pkg.getPkg().isApex()) {
- // Don't persist APEX which doesn't have a valid app id and will fail to load
- continue;
+ serializer.startTag(null, TAG_VERSION);
+ XmlUtils.writeStringAttribute(serializer, ATTR_VOLUME_UUID, volumeUuid);
+ serializer.attributeInt(null, ATTR_SDK_VERSION, ver.sdkVersion);
+ serializer.attributeInt(null, ATTR_DATABASE_VERSION, ver.databaseVersion);
+ XmlUtils.writeStringAttribute(serializer, ATTR_BUILD_FINGERPRINT,
+ ver.buildFingerprint);
+ XmlUtils.writeStringAttribute(serializer, ATTR_FINGERPRINT, ver.fingerprint);
+ serializer.endTag(null, TAG_VERSION);
}
- writePackageLPr(serializer, pkg);
- }
- for (final PackageSetting pkg : mDisabledSysPackages.values()) {
- if (pkg.getPkg() != null && pkg.getPkg().isApex()) {
- // Don't persist APEX which doesn't have a valid app id and will fail to load
- continue;
+ if (mVerifierDeviceIdentity != null) {
+ serializer.startTag(null, "verifier");
+ serializer.attribute(null, "device", mVerifierDeviceIdentity.toString());
+ serializer.endTag(null, "verifier");
}
- writeDisabledSysPackageLPr(serializer, pkg);
- }
- for (final SharedUserSetting usr : mSharedUsers.values()) {
- serializer.startTag(null, "shared-user");
- serializer.attribute(null, ATTR_NAME, usr.name);
- serializer.attributeInt(null, "userId", usr.mAppId);
- usr.signatures.writeXml(serializer, "sigs", mPastSignatures.untrackedStorage());
- serializer.endTag(null, "shared-user");
- }
+ serializer.startTag(null, "permission-trees");
+ mPermissions.writePermissionTrees(serializer);
+ serializer.endTag(null, "permission-trees");
- if (mRenamedPackages.size() > 0) {
- for (Map.Entry<String, String> e : mRenamedPackages.entrySet()) {
- serializer.startTag(null, "renamed-package");
- serializer.attribute(null, "new", e.getKey());
- serializer.attribute(null, "old", e.getValue());
- serializer.endTag(null, "renamed-package");
+ serializer.startTag(null, "permissions");
+ mPermissions.writePermissions(serializer);
+ serializer.endTag(null, "permissions");
+
+ for (final PackageSetting pkg : mPackages.values()) {
+ if (pkg.getPkg() != null && pkg.getPkg().isApex()) {
+ // Don't persist APEX which doesn't have a valid app id and will fail to
+ // load
+ continue;
+ }
+ writePackageLPr(serializer, pkg);
}
- }
- mDomainVerificationManager.writeSettings(computer, serializer,
- false /* includeSignatures */, UserHandle.USER_ALL);
+ for (final PackageSetting pkg : mDisabledSysPackages.values()) {
+ if (pkg.getPkg() != null && pkg.getPkg().isApex()) {
+ // Don't persist APEX which doesn't have a valid app id and will fail to
+ // load
+ continue;
+ }
+ writeDisabledSysPackageLPr(serializer, pkg);
+ }
- mKeySetManagerService.writeKeySetManagerServiceLPr(serializer);
+ for (final SharedUserSetting usr : mSharedUsers.values()) {
+ serializer.startTag(null, "shared-user");
+ serializer.attribute(null, ATTR_NAME, usr.name);
+ serializer.attributeInt(null, "userId", usr.mAppId);
+ usr.signatures.writeXml(serializer, "sigs", mPastSignatures.untrackedStorage());
+ serializer.endTag(null, "shared-user");
+ }
- serializer.endTag(null, "packages");
+ if (mRenamedPackages.size() > 0) {
+ for (Map.Entry<String, String> e : mRenamedPackages.entrySet()) {
+ serializer.startTag(null, "renamed-package");
+ serializer.attribute(null, "new", e.getKey());
+ serializer.attribute(null, "old", e.getValue());
+ serializer.endTag(null, "renamed-package");
+ }
+ }
- serializer.endDocument();
+ mDomainVerificationManager.writeSettings(computer, serializer,
+ false /* includeSignatures */, UserHandle.USER_ALL);
- fstr.flush();
- FileUtils.sync(fstr);
- fstr.close();
+ mKeySetManagerService.writeKeySetManagerServiceLPr(serializer);
- // New settings successfully written, old ones are no longer needed.
- mPreviousSettingsFilename.delete();
- mSettingsReserveCopyFilename.delete();
+ serializer.endTag(null, "packages");
- FileUtils.setPermissions(mSettingsFilename.toString(),
- FileUtils.S_IRUSR | FileUtils.S_IWUSR | FileUtils.S_IRGRP | FileUtils.S_IWGRP,
- -1, -1);
+ serializer.endDocument();
- try (FileInputStream in = new FileInputStream(mSettingsFilename);
- FileOutputStream out = new FileOutputStream(mSettingsReserveCopyFilename)) {
- FileUtils.copy(in, out);
- out.flush();
- FileUtils.sync(out);
- } catch (IOException e) {
- Slog.e(TAG,
- "Failed to write reserve copy of settings: " + mSettingsReserveCopyFilename,
- e);
- }
+ atomicFile.finishWrite(str);
- try {
- FileIntegrity.setUpFsVerity(mSettingsFilename);
- FileIntegrity.setUpFsVerity(mSettingsReserveCopyFilename);
- } catch (IOException e) {
- Slog.e(TAG, "Failed to verity-protect settings", e);
- }
-
- writeKernelMappingLPr();
- writePackageListLPr();
- writeAllUsersPackageRestrictionsLPr(sync);
- writeAllRuntimePermissionsLPr();
- com.android.internal.logging.EventLogTags.writeCommitSysConfigFile(
- "package", SystemClock.uptimeMillis() - startTime);
- return;
+ writeKernelMappingLPr();
+ writePackageListLPr();
+ writeAllUsersPackageRestrictionsLPr(sync);
+ writeAllRuntimePermissionsLPr();
+ com.android.internal.logging.EventLogTags.writeCommitSysConfigFile(
+ "package", SystemClock.uptimeMillis() - startTime);
+ return;
- } catch(java.io.IOException e) {
- Slog.wtf(PackageManagerService.TAG, "Unable to write package manager settings, "
- + "current changes will be lost at reboot", e);
- }
- // Clean up partially written files
- if (mSettingsFilename.exists()) {
- if (!mSettingsFilename.delete()) {
- Slog.wtf(PackageManagerService.TAG, "Failed to clean up mangled file: "
- + mSettingsFilename);
+ } catch (java.io.IOException e) {
+ Slog.wtf(PackageManagerService.TAG, "Unable to write package manager settings, "
+ + "current changes will be lost at reboot", e);
+ if (str != null) {
+ atomicFile.failWrite(str);
+ }
}
}
//Debug.stopMethodTracing();
@@ -3160,183 +3048,140 @@ public final class Settings implements Watchable, Snappable {
mInstallerPackages.clear();
originalFirstInstallTimes.clear();
- File file = null;
- FileInputStream str = null;
-
- try {
- // Check if the previous write was incomplete.
- if (mPreviousSettingsFilename.exists()) {
- try {
- file = mPreviousSettingsFilename;
- str = new FileInputStream(file);
- mReadMessages.append("Reading from backup settings file\n");
- PackageManagerService.reportSettingsProblem(Log.INFO,
- "Need to read from backup settings file");
- if (mSettingsFilename.exists()) {
- // If both the previous and current settings files exist,
- // we ignore the current since it might have been corrupted.
- Slog.w(PackageManagerService.TAG, "Cleaning up settings file "
- + mSettingsFilename);
- mSettingsFilename.delete();
- }
- // Ignore reserve copy as well.
- mSettingsReserveCopyFilename.delete();
- } catch (java.io.IOException e) {
- // We'll try for the normal settings file.
- }
- }
- if (str == null) {
- if (mSettingsFilename.exists()) {
- // Using packages.xml.
- file = mSettingsFilename;
- str = new FileInputStream(file);
- } else if (mSettingsReserveCopyFilename.exists()) {
- // Using reserve copy.
- file = mSettingsReserveCopyFilename;
- str = new FileInputStream(file);
- mReadMessages.append("Reading from reserve copy settings file\n");
- PackageManagerService.reportSettingsProblem(Log.INFO,
- "Need to read from reserve copy settings file");
+ try (ResilientAtomicFile atomicFile = getSettingsFile()) {
+ FileInputStream str = null;
+ try {
+ str = atomicFile.openRead();
+ if (str == null) {
+ // Not necessary, but will avoid wtf-s in the "finally" section.
+ findOrCreateVersion(StorageManager.UUID_PRIVATE_INTERNAL).forceCurrent();
+ findOrCreateVersion(StorageManager.UUID_PRIMARY_PHYSICAL).forceCurrent();
+ return false;
}
- }
- if (str == null) {
- // No available data sources.
- mReadMessages.append("No settings file found\n");
- PackageManagerService.reportSettingsProblem(Log.INFO,
- "No settings file; creating initial state");
- // Not necessary, but will avoid wtf-s in the "finally" section.
- findOrCreateVersion(StorageManager.UUID_PRIVATE_INTERNAL).forceCurrent();
- findOrCreateVersion(StorageManager.UUID_PRIMARY_PHYSICAL).forceCurrent();
- return false;
- }
- final TypedXmlPullParser parser = Xml.resolvePullParser(str);
+ final TypedXmlPullParser parser = Xml.resolvePullParser(str);
- int type;
- while ((type = parser.next()) != XmlPullParser.START_TAG
- && type != XmlPullParser.END_DOCUMENT) {
- ;
- }
-
- if (type != XmlPullParser.START_TAG) {
- mReadMessages.append("No start tag found in settings file\n");
- PackageManagerService.reportSettingsProblem(Log.WARN,
- "No start tag found in package manager settings");
- Slog.wtf(PackageManagerService.TAG,
- "No start tag found in package manager settings");
- return false;
- }
+ int type;
+ while ((type = parser.next()) != XmlPullParser.START_TAG
+ && type != XmlPullParser.END_DOCUMENT) {
+ // nothing
+ }
- int outerDepth = parser.getDepth();
- while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
- && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
- if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
- continue;
+ if (type != XmlPullParser.START_TAG) {
+ mReadMessages.append("No start tag found in settings file\n");
+ PackageManagerService.reportSettingsProblem(Log.WARN,
+ "No start tag found in package manager settings");
+ Slog.wtf(PackageManagerService.TAG,
+ "No start tag found in package manager settings");
+ return false;
}
- String tagName = parser.getName();
- if (tagName.equals("package")) {
- readPackageLPw(parser, users, originalFirstInstallTimes);
- } else if (tagName.equals("permissions")) {
- mPermissions.readPermissions(parser);
- } else if (tagName.equals("permission-trees")) {
- mPermissions.readPermissionTrees(parser);
- } else if (tagName.equals("shared-user")) {
- readSharedUserLPw(parser, users);
- } else if (tagName.equals("preferred-packages")) {
- // no longer used.
- } else if (tagName.equals("preferred-activities")) {
- // Upgrading from old single-user implementation;
- // these are the preferred activities for user 0.
- readPreferredActivitiesLPw(parser, 0);
- } else if (tagName.equals(TAG_PERSISTENT_PREFERRED_ACTIVITIES)) {
- // TODO: check whether this is okay! as it is very
- // similar to how preferred-activities are treated
- readPersistentPreferredActivitiesLPw(parser, 0);
- } else if (tagName.equals(TAG_CROSS_PROFILE_INTENT_FILTERS)) {
- // TODO: check whether this is okay! as it is very
- // similar to how preferred-activities are treated
- readCrossProfileIntentFiltersLPw(parser, 0);
- } else if (tagName.equals(TAG_DEFAULT_BROWSER)) {
- readDefaultAppsLPw(parser, 0);
- } else if (tagName.equals("updated-package")) {
- readDisabledSysPackageLPw(parser, users);
- } else if (tagName.equals("renamed-package")) {
- String nname = parser.getAttributeValue(null, "new");
- String oname = parser.getAttributeValue(null, "old");
- if (nname != null && oname != null) {
- mRenamedPackages.put(nname, oname);
+ int outerDepth = parser.getDepth();
+ while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+ && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
+ if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
+ continue;
}
- } else if (tagName.equals("last-platform-version")) {
- // Upgrade from older XML schema
- final VersionInfo internal = findOrCreateVersion(
- StorageManager.UUID_PRIVATE_INTERNAL);
- final VersionInfo external = findOrCreateVersion(
- StorageManager.UUID_PRIMARY_PHYSICAL);
-
- internal.sdkVersion = parser.getAttributeInt(null, "internal", 0);
- external.sdkVersion = parser.getAttributeInt(null, "external", 0);
- internal.buildFingerprint = external.buildFingerprint =
- XmlUtils.readStringAttribute(parser, "buildFingerprint");
- internal.fingerprint = external.fingerprint =
- XmlUtils.readStringAttribute(parser, "fingerprint");
-
- } else if (tagName.equals("database-version")) {
- // Upgrade from older XML schema
- final VersionInfo internal = findOrCreateVersion(
- StorageManager.UUID_PRIVATE_INTERNAL);
- final VersionInfo external = findOrCreateVersion(
- StorageManager.UUID_PRIMARY_PHYSICAL);
-
- internal.databaseVersion = parser.getAttributeInt(null, "internal", 0);
- external.databaseVersion = parser.getAttributeInt(null, "external", 0);
-
- } else if (tagName.equals("verifier")) {
- final String deviceIdentity = parser.getAttributeValue(null, "device");
- try {
- mVerifierDeviceIdentity = VerifierDeviceIdentity.parse(deviceIdentity);
- } catch (IllegalArgumentException e) {
- Slog.w(PackageManagerService.TAG, "Discard invalid verifier device id: "
- + e.getMessage());
+
+ String tagName = parser.getName();
+ if (tagName.equals("package")) {
+ readPackageLPw(parser, users, originalFirstInstallTimes);
+ } else if (tagName.equals("permissions")) {
+ mPermissions.readPermissions(parser);
+ } else if (tagName.equals("permission-trees")) {
+ mPermissions.readPermissionTrees(parser);
+ } else if (tagName.equals("shared-user")) {
+ readSharedUserLPw(parser, users);
+ } else if (tagName.equals("preferred-packages")) {
+ // no longer used.
+ } else if (tagName.equals("preferred-activities")) {
+ // Upgrading from old single-user implementation;
+ // these are the preferred activities for user 0.
+ readPreferredActivitiesLPw(parser, 0);
+ } else if (tagName.equals(TAG_PERSISTENT_PREFERRED_ACTIVITIES)) {
+ // TODO: check whether this is okay! as it is very
+ // similar to how preferred-activities are treated
+ readPersistentPreferredActivitiesLPw(parser, 0);
+ } else if (tagName.equals(TAG_CROSS_PROFILE_INTENT_FILTERS)) {
+ // TODO: check whether this is okay! as it is very
+ // similar to how preferred-activities are treated
+ readCrossProfileIntentFiltersLPw(parser, 0);
+ } else if (tagName.equals(TAG_DEFAULT_BROWSER)) {
+ readDefaultAppsLPw(parser, 0);
+ } else if (tagName.equals("updated-package")) {
+ readDisabledSysPackageLPw(parser, users);
+ } else if (tagName.equals("renamed-package")) {
+ String nname = parser.getAttributeValue(null, "new");
+ String oname = parser.getAttributeValue(null, "old");
+ if (nname != null && oname != null) {
+ mRenamedPackages.put(nname, oname);
+ }
+ } else if (tagName.equals("last-platform-version")) {
+ // Upgrade from older XML schema
+ final VersionInfo internal = findOrCreateVersion(
+ StorageManager.UUID_PRIVATE_INTERNAL);
+ final VersionInfo external = findOrCreateVersion(
+ StorageManager.UUID_PRIMARY_PHYSICAL);
+
+ internal.sdkVersion = parser.getAttributeInt(null, "internal", 0);
+ external.sdkVersion = parser.getAttributeInt(null, "external", 0);
+ internal.buildFingerprint = external.buildFingerprint =
+ XmlUtils.readStringAttribute(parser, "buildFingerprint");
+ internal.fingerprint = external.fingerprint =
+ XmlUtils.readStringAttribute(parser, "fingerprint");
+
+ } else if (tagName.equals("database-version")) {
+ // Upgrade from older XML schema
+ final VersionInfo internal = findOrCreateVersion(
+ StorageManager.UUID_PRIVATE_INTERNAL);
+ final VersionInfo external = findOrCreateVersion(
+ StorageManager.UUID_PRIMARY_PHYSICAL);
+
+ internal.databaseVersion = parser.getAttributeInt(null, "internal", 0);
+ external.databaseVersion = parser.getAttributeInt(null, "external", 0);
+
+ } else if (tagName.equals("verifier")) {
+ final String deviceIdentity = parser.getAttributeValue(null, "device");
+ try {
+ mVerifierDeviceIdentity = VerifierDeviceIdentity.parse(deviceIdentity);
+ } catch (IllegalArgumentException e) {
+ Slog.w(PackageManagerService.TAG, "Discard invalid verifier device id: "
+ + e.getMessage());
+ }
+ } else if (TAG_READ_EXTERNAL_STORAGE.equals(tagName)) {
+ // No longer used.
+ } else if (tagName.equals("keyset-settings")) {
+ mKeySetManagerService.readKeySetsLPw(parser,
+ mKeySetRefs.untrackedStorage());
+ } else if (TAG_VERSION.equals(tagName)) {
+ final String volumeUuid = XmlUtils.readStringAttribute(parser,
+ ATTR_VOLUME_UUID);
+ final VersionInfo ver = findOrCreateVersion(volumeUuid);
+ ver.sdkVersion = parser.getAttributeInt(null, ATTR_SDK_VERSION);
+ ver.databaseVersion = parser.getAttributeInt(null, ATTR_DATABASE_VERSION);
+ ver.buildFingerprint = XmlUtils.readStringAttribute(parser,
+ ATTR_BUILD_FINGERPRINT);
+ ver.fingerprint = XmlUtils.readStringAttribute(parser, ATTR_FINGERPRINT);
+ } else if (tagName.equals(
+ DomainVerificationPersistence.TAG_DOMAIN_VERIFICATIONS)) {
+ mDomainVerificationManager.readSettings(computer, parser);
+ } else if (tagName.equals(
+ DomainVerificationLegacySettings.TAG_DOMAIN_VERIFICATIONS_LEGACY)) {
+ mDomainVerificationManager.readLegacySettings(parser);
+ } else {
+ Slog.w(PackageManagerService.TAG, "Unknown element under <packages>: "
+ + parser.getName());
+ XmlUtils.skipCurrentTag(parser);
}
- } else if (TAG_READ_EXTERNAL_STORAGE.equals(tagName)) {
- // No longer used.
- } else if (tagName.equals("keyset-settings")) {
- mKeySetManagerService.readKeySetsLPw(parser, mKeySetRefs.untrackedStorage());
- } else if (TAG_VERSION.equals(tagName)) {
- final String volumeUuid = XmlUtils.readStringAttribute(parser,
- ATTR_VOLUME_UUID);
- final VersionInfo ver = findOrCreateVersion(volumeUuid);
- ver.sdkVersion = parser.getAttributeInt(null, ATTR_SDK_VERSION);
- ver.databaseVersion = parser.getAttributeInt(null, ATTR_DATABASE_VERSION);
- ver.buildFingerprint = XmlUtils.readStringAttribute(parser,
- ATTR_BUILD_FINGERPRINT);
- ver.fingerprint = XmlUtils.readStringAttribute(parser, ATTR_FINGERPRINT);
- } else if (tagName.equals(DomainVerificationPersistence.TAG_DOMAIN_VERIFICATIONS)) {
- mDomainVerificationManager.readSettings(computer, parser);
- } else if (tagName.equals(
- DomainVerificationLegacySettings.TAG_DOMAIN_VERIFICATIONS_LEGACY)) {
- mDomainVerificationManager.readLegacySettings(parser);
- } else {
- Slog.w(PackageManagerService.TAG, "Unknown element under <packages>: "
- + parser.getName());
- XmlUtils.skipCurrentTag(parser);
}
- }
- str.close();
- } catch (IOException | XmlPullParserException e) {
- mReadMessages.append("Error reading: " + e.toString());
- PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e);
- Slog.wtf(PackageManagerService.TAG, "Error reading package manager settings", e);
+ str.close();
+ } catch (IOException | XmlPullParserException e) {
+ // Remove corrupted file and retry.
+ atomicFile.failRead(str, e);
- // Remove corrupted file and retry.
- Slog.e(TAG,
- "Error reading package manager settings, removing " + file + " and retrying.",
- e);
- file.delete();
-
- // Ignore the result to not mark this as a "first boot".
- readSettingsLPw(computer, users, originalFirstInstallTimes);
+ // Ignore the result to not mark this as a "first boot".
+ readSettingsLPw(computer, users, originalFirstInstallTimes);
+ }
}
return true;
@@ -4488,10 +4333,7 @@ public final class Settings implements Watchable, Snappable {
mPreferredActivities.remove(userId);
synchronized (mPackageRestrictionsLock) {
- File file = getUserPackagesStateFile(userId);
- file.delete();
- file = getUserPackagesStateBackupFile(userId);
- file.delete();
+ getUserPackagesStateFile(userId).delete();
mPendingAsyncPackageRestrictionsWrites.delete(userId);
}
@@ -5034,19 +4876,20 @@ public final class Settings implements Watchable, Snappable {
}
}
pw.print(prefix); pw.print(" timeStamp=");
- date.setTime(ps.getLastModifiedTime());
- pw.println(sdf.format(date));
+ date.setTime(ps.getLastModifiedTime());
+ pw.println(sdf.format(date));
pw.print(prefix); pw.print(" lastUpdateTime=");
- date.setTime(ps.getLastUpdateTime());
- pw.println(sdf.format(date));
- if (ps.getInstallSource().mInstallerPackageName != null) {
- pw.print(prefix); pw.print(" installerPackageName=");
- pw.println(ps.getInstallSource().mInstallerPackageName);
- }
- if (ps.getInstallSource().mInstallerPackageUid != INVALID_UID) {
- pw.print(prefix); pw.print(" installerPackageUid=");
- pw.println(ps.getInstallSource().mInstallerPackageUid);
- }
+ date.setTime(ps.getLastUpdateTime());
+ pw.println(sdf.format(date));
+ pw.print(prefix); pw.print(" installerPackageName=");
+ pw.println(ps.getInstallSource().mInstallerPackageName);
+ pw.print(prefix); pw.print(" installerPackageUid=");
+ pw.println(ps.getInstallSource().mInstallerPackageUid);
+ pw.print(prefix); pw.print(" initiatingPackageName=");
+ pw.println(ps.getInstallSource().mInitiatingPackageName);
+ pw.print(prefix); pw.print(" originatingPackageName=");
+ pw.println(ps.getInstallSource().mOriginatingPackageName);
+
if (ps.getInstallSource().mUpdateOwnerPackageName != null) {
pw.print(prefix); pw.print(" updateOwnerPackageName=");
pw.println(ps.getInstallSource().mUpdateOwnerPackageName);
diff --git a/services/core/java/com/android/server/pm/ShortcutPackage.java b/services/core/java/com/android/server/pm/ShortcutPackage.java
index 67639fbef124..28cb7f0b03a6 100644
--- a/services/core/java/com/android/server/pm/ShortcutPackage.java
+++ b/services/core/java/com/android/server/pm/ShortcutPackage.java
@@ -2048,6 +2048,9 @@ class ShortcutPackage extends ShortcutPackageItem {
shortcutUser.getUserId(), fromBackup);
// Don't use addShortcut(), we don't need to save the icon.
ret.mShortcuts.put(si.getId(), si);
+ } catch (IOException e) {
+ // Don't ignore IO exceptions.
+ throw e;
} catch (Exception e) {
// b/246540168 malformed shortcuts should be ignored
Slog.e(TAG, "Failed parsing shortcut.", e);
diff --git a/services/core/java/com/android/server/pm/ShortcutPackageItem.java b/services/core/java/com/android/server/pm/ShortcutPackageItem.java
index e20330d562f6..8b118da1cdbe 100644
--- a/services/core/java/com/android/server/pm/ShortcutPackageItem.java
+++ b/services/core/java/com/android/server/pm/ShortcutPackageItem.java
@@ -27,6 +27,7 @@ import android.util.Xml;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.Preconditions;
import com.android.modules.utils.TypedXmlSerializer;
+import com.android.server.security.FileIntegrity;
import org.json.JSONException;
import org.json.JSONObject;
@@ -180,6 +181,12 @@ abstract class ShortcutPackageItem {
os.flush();
file.finishWrite(os);
+
+ try {
+ FileIntegrity.setUpFsVerity(path);
+ } catch (IOException e) {
+ Slog.e(TAG, "Failed to verity-protect " + path, e);
+ }
} catch (XmlPullParserException | IOException e) {
Slog.e(TAG, "Failed to write to file " + file.getBaseFile(), e);
file.failWrite(os);
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index 372b3bb8681b..20cb485434b0 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -119,7 +119,6 @@ import com.android.modules.utils.TypedXmlPullParser;
import com.android.modules.utils.TypedXmlSerializer;
import com.android.server.LocalServices;
import com.android.server.SystemService;
-import com.android.server.security.FileIntegrity;
import com.android.server.uri.UriGrantsManagerInternal;
import org.json.JSONArray;
@@ -1070,57 +1069,38 @@ public class ShortcutService extends IShortcutService.Stub {
}
@VisibleForTesting
- final File getUserFile(@UserIdInt int userId) {
- return new File(injectUserDataPath(userId), FILENAME_USER_PACKAGES);
- }
-
- @VisibleForTesting
- final File getReserveCopyUserFile(@UserIdInt int userId) {
- return new File(injectUserDataPath(userId), FILENAME_USER_PACKAGES_RESERVE_COPY);
+ final ResilientAtomicFile getUserFile(@UserIdInt int userId) {
+ File mainFile = new File(injectUserDataPath(userId), FILENAME_USER_PACKAGES);
+ File temporaryBackup = new File(injectUserDataPath(userId),
+ FILENAME_USER_PACKAGES + ".backup");
+ File reserveCopy = new File(injectUserDataPath(userId),
+ FILENAME_USER_PACKAGES_RESERVE_COPY);
+ int fileMode = FileUtils.S_IRWXU | FileUtils.S_IRWXG | FileUtils.S_IXOTH;
+ return new ResilientAtomicFile(mainFile, temporaryBackup, reserveCopy, fileMode,
+ "user shortcut", null);
}
@GuardedBy("mLock")
private void saveUserLocked(@UserIdInt int userId) {
- final File path = getUserFile(userId);
- if (DEBUG || DEBUG_REBOOT) {
- Slog.d(TAG, "Saving to " + path);
- }
-
- final File reservePath = getReserveCopyUserFile(userId);
- reservePath.delete();
-
- path.getParentFile().mkdirs();
- final AtomicFile file = new AtomicFile(path);
- FileOutputStream os = null;
- try {
- os = file.startWrite();
-
- saveUserInternalLocked(userId, os, /* forBackup= */ false);
+ try (ResilientAtomicFile file = getUserFile(userId)) {
+ FileOutputStream os = null;
+ try {
+ if (DEBUG || DEBUG_REBOOT) {
+ Slog.d(TAG, "Saving to " + file);
+ }
- file.finishWrite(os);
+ os = file.startWrite();
- // Remove all dangling bitmap files.
- cleanupDanglingBitmapDirectoriesLocked(userId);
- } catch (XmlPullParserException | IOException e) {
- Slog.e(TAG, "Failed to write to file " + file.getBaseFile(), e);
- file.failWrite(os);
- }
+ saveUserInternalLocked(userId, os, /* forBackup= */ false);
- // Store the reserve copy of the file.
- try (FileInputStream in = new FileInputStream(path);
- FileOutputStream out = new FileOutputStream(reservePath)) {
- FileUtils.copy(in, out);
- FileUtils.sync(out);
- } catch (IOException e) {
- Slog.e(TAG, "Failed to write reserve copy: " + path, e);
- }
+ file.finishWrite(os);
- // Protect both primary and reserve copy with fs-verity.
- try {
- FileIntegrity.setUpFsVerity(path);
- FileIntegrity.setUpFsVerity(reservePath);
- } catch (IOException e) {
- Slog.e(TAG, "Failed to verity-protect", e);
+ // Remove all dangling bitmap files.
+ cleanupDanglingBitmapDirectoriesLocked(userId);
+ } catch (XmlPullParserException | IOException e) {
+ Slog.e(TAG, "Failed to write to file " + file, e);
+ file.failWrite(os);
+ }
}
getUserShortcutsLocked(userId).logSharingShortcutStats(mMetricsLogger);
@@ -1157,29 +1137,26 @@ public class ShortcutService extends IShortcutService.Stub {
@Nullable
private ShortcutUser loadUserLocked(@UserIdInt int userId) {
- final File path = getUserFile(userId);
- if (DEBUG || DEBUG_REBOOT) {
- Slog.d(TAG, "Loading from " + path);
- }
-
- try (FileInputStream in = new AtomicFile(path).openRead()) {
- return loadUserInternal(userId, in, /* forBackup= */ false);
- } catch (FileNotFoundException e) {
- if (DEBUG || DEBUG_REBOOT) {
- Slog.d(TAG, "Not found " + path);
- }
- } catch (Exception e) {
- final File reservePath = getReserveCopyUserFile(userId);
- Slog.e(TAG, "Reading from reserve copy: " + reservePath, e);
- try (FileInputStream in = new AtomicFile(reservePath).openRead()) {
+ try (ResilientAtomicFile file = getUserFile(userId)) {
+ FileInputStream in = null;
+ try {
+ if (DEBUG || DEBUG_REBOOT) {
+ Slog.d(TAG, "Loading from " + file);
+ }
+ in = file.openRead();
+ if (in == null) {
+ if (DEBUG || DEBUG_REBOOT) {
+ Slog.d(TAG, "Not found " + file);
+ }
+ return null;
+ }
return loadUserInternal(userId, in, /* forBackup= */ false);
- } catch (Exception exceptionReadingReserveFile) {
- Slog.e(TAG, "Failed to read reserve copy: " + reservePath,
- exceptionReadingReserveFile);
+ } catch (Exception e) {
+ // Remove corrupted file and retry.
+ file.failRead(in, e);
+ return loadUserLocked(userId);
}
- Slog.e(TAG, "Failed to read file " + path, e);
}
- return null;
}
private ShortcutUser loadUserInternal(@UserIdInt int userId, InputStream is,
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index b21243a7baec..2f98d3485d90 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -3635,6 +3635,13 @@ public class UserManagerService extends IUserManager.Stub {
} finally {
IoUtils.closeQuietly(fis);
}
+
+ synchronized (mUsersLock) {
+ if (mUsers.size() == 0) {
+ Slog.e(LOG_TAG, "mUsers is empty, fallback to single user");
+ fallbackToSingleUserLP();
+ }
+ }
}
/**
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index bf8cbeac30c8..2e8a150f2b6d 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -5693,6 +5693,7 @@ public final class PowerManagerService extends SystemService
}
if (eventTime > now) {
+ Slog.e(TAG, "Event time " + eventTime + " cannot be newer than " + now);
throw new IllegalArgumentException("event time must not be in the future");
}
@@ -5708,7 +5709,9 @@ public final class PowerManagerService extends SystemService
@Override // Binder call
public void wakeUp(long eventTime, @WakeReason int reason, String details,
String opPackageName) {
- if (eventTime > mClock.uptimeMillis()) {
+ final long now = mClock.uptimeMillis();
+ if (eventTime > now) {
+ Slog.e(TAG, "Event time " + eventTime + " cannot be newer than " + now);
throw new IllegalArgumentException("event time must not be in the future");
}
@@ -5760,7 +5763,9 @@ public final class PowerManagerService extends SystemService
@Override // Binder call
public void nap(long eventTime) {
- if (eventTime > mClock.uptimeMillis()) {
+ final long now = mClock.uptimeMillis();
+ if (eventTime > now) {
+ Slog.e(TAG, "Event time " + eventTime + " cannot be newer than " + now);
throw new IllegalArgumentException("event time must not be in the future");
}
@@ -6525,7 +6530,9 @@ public final class PowerManagerService extends SystemService
@Override // Binder call
public void boostScreenBrightness(long eventTime) {
+ final long now = mClock.uptimeMillis();
if (eventTime > mClock.uptimeMillis()) {
+ Slog.e(TAG, "Event time " + eventTime + " cannot be newer than " + now);
throw new IllegalArgumentException("event time must not be in the future");
}
@@ -6684,7 +6691,9 @@ public final class PowerManagerService extends SystemService
@RequiresPermission(android.Manifest.permission.DEVICE_POWER)
private void goToSleepInternal(IntArray groupIds, long eventTime, int reason, int flags) {
- if (eventTime > mClock.uptimeMillis()) {
+ final long now = mClock.uptimeMillis();
+ if (eventTime > now) {
+ Slog.e(TAG, "Event time " + eventTime + " cannot be newer than " + now);
throw new IllegalArgumentException("event time must not be in the future");
}
diff --git a/services/core/java/com/android/server/power/stats/CpuWakeupStats.java b/services/core/java/com/android/server/power/stats/CpuWakeupStats.java
index 54f3476d3b86..e8c0e5924252 100644
--- a/services/core/java/com/android/server/power/stats/CpuWakeupStats.java
+++ b/services/core/java/com/android/server/power/stats/CpuWakeupStats.java
@@ -18,6 +18,7 @@ package com.android.server.power.stats;
import static android.os.BatteryStatsInternal.CPU_WAKEUP_SUBSYSTEM_ALARM;
import static android.os.BatteryStatsInternal.CPU_WAKEUP_SUBSYSTEM_UNKNOWN;
+import static android.os.BatteryStatsInternal.CPU_WAKEUP_SUBSYSTEM_WIFI;
import android.content.Context;
import android.os.Handler;
@@ -49,6 +50,7 @@ public class CpuWakeupStats {
private static final String TAG = "CpuWakeupStats";
private static final String SUBSYSTEM_ALARM_STRING = "Alarm";
+ private static final String SUBSYSTEM_ALARM_WIFI = "Wifi";
@VisibleForTesting
static final long WAKEUP_RETENTION_MS = 3 * 24 * 60 * 60_000; // 3 days.
@VisibleForTesting
@@ -74,6 +76,8 @@ public class CpuWakeupStats {
switch (subsystem) {
case CPU_WAKEUP_SUBSYSTEM_ALARM:
return FrameworkStatsLog.KERNEL_WAKEUP_ATTRIBUTED__REASON__ALARM;
+ case CPU_WAKEUP_SUBSYSTEM_WIFI:
+ return FrameworkStatsLog.KERNEL_WAKEUP_ATTRIBUTED__REASON__WIFI;
}
return FrameworkStatsLog.KERNEL_WAKEUP_ATTRIBUTED__REASON__UNKNOWN;
}
@@ -425,6 +429,8 @@ public class CpuWakeupStats {
switch (rawSubsystem) {
case SUBSYSTEM_ALARM_STRING:
return CPU_WAKEUP_SUBSYSTEM_ALARM;
+ case SUBSYSTEM_ALARM_WIFI:
+ return CPU_WAKEUP_SUBSYSTEM_WIFI;
}
return CPU_WAKEUP_SUBSYSTEM_UNKNOWN;
}
@@ -433,6 +439,8 @@ public class CpuWakeupStats {
switch (subsystem) {
case CPU_WAKEUP_SUBSYSTEM_ALARM:
return SUBSYSTEM_ALARM_STRING;
+ case CPU_WAKEUP_SUBSYSTEM_WIFI:
+ return SUBSYSTEM_ALARM_WIFI;
case CPU_WAKEUP_SUBSYSTEM_UNKNOWN:
return "Unknown";
}
diff --git a/services/core/java/com/android/server/wm/BackNavigationController.java b/services/core/java/com/android/server/wm/BackNavigationController.java
index a229fc5b00d3..2d45dc20c963 100644
--- a/services/core/java/com/android/server/wm/BackNavigationController.java
+++ b/services/core/java/com/android/server/wm/BackNavigationController.java
@@ -75,6 +75,11 @@ class BackNavigationController {
private final ArrayList<WindowContainer> mTmpOpenApps = new ArrayList<>();
private final ArrayList<WindowContainer> mTmpCloseApps = new ArrayList<>();
+ // This will be set if the back navigation is in progress and the current transition is still
+ // running. The pending animation builder will do the animation stuff includes creating leashes,
+ // re-parenting leashes and set launch behind, etc. Will be handled when transition finished.
+ private AnimationHandler.ScheduleAnimationBuilder mPendingAnimationBuilder;
+
/**
* true if the back predictability feature is enabled
*/
@@ -305,25 +310,26 @@ class BackNavigationController {
|| backType == BackNavigationInfo.TYPE_CROSS_ACTIVITY)
&& adapter != null;
- // Only prepare animation if no leash has been created (no animation is running).
- // TODO(b/241808055): Cancel animation when preparing back animation.
- if (prepareAnimation
- && (removedWindowContainer.hasCommittedReparentToAnimationLeash()
- || removedWindowContainer.mTransitionController.inTransition())) {
- Slog.w(TAG, "Can't prepare back animation due to another animation is running.");
- prepareAnimation = false;
- }
-
if (prepareAnimation) {
- mPendingAnimation = mAnimationHandler.scheduleAnimation(backType, adapter,
- currentTask, prevTask, currentActivity, prevActivity);
- prepareAnimation = mPendingAnimation != null;
- mBackAnimationInProgress = prepareAnimation;
- if (prepareAnimation) {
- mWindowManagerService.mWindowPlacerLocked.requestTraversal();
- if (mShowWallpaper) {
- currentTask.getDisplayContent().mWallpaperController
- .adjustWallpaperWindows();
+ final AnimationHandler.ScheduleAnimationBuilder builder =
+ mAnimationHandler.prepareAnimation(backType, adapter,
+ currentTask, prevTask, currentActivity, prevActivity);
+ mBackAnimationInProgress = builder != null;
+ if (mBackAnimationInProgress) {
+ if (removedWindowContainer.hasCommittedReparentToAnimationLeash()
+ || removedWindowContainer.mTransitionController.inTransition()
+ || mWindowManagerService.mSyncEngine.hasPendingSyncSets()) {
+ ProtoLog.w(WM_DEBUG_BACK_PREVIEW,
+ "Pending back animation due to another animation is running");
+ mPendingAnimationBuilder = builder;
+ // Current transition is still running, we have to defer the hiding to the
+ // client process to prevent the unexpected relayout when handling the back
+ // animation.
+ if (prevActivity != null) {
+ prevActivity.setDeferHidingClient(true);
+ }
+ } else {
+ scheduleAnimation(builder);
}
}
}
@@ -345,6 +351,15 @@ class BackNavigationController {
return isWaitBackTransition() || mNavigationMonitor.isMonitoring();
}
+ private void scheduleAnimation(@NonNull AnimationHandler.ScheduleAnimationBuilder builder) {
+ mPendingAnimation = builder.build();
+ mWindowManagerService.mWindowPlacerLocked.requestTraversal();
+ if (mShowWallpaper) {
+ mWindowManagerService.getDefaultDisplayContentLocked().mWallpaperController
+ .adjustWallpaperWindows();
+ }
+ }
+
private boolean isWaitBackTransition() {
return mAnimationHandler.mComposed && mAnimationHandler.mWaitTransition;
}
@@ -526,6 +541,57 @@ class BackNavigationController {
mAnimationHandler.clearBackAnimateTarget(cleanupTransaction);
}
+ /**
+ * Handle the pending animation when the running transition finished.
+ * @param targets The final animation targets derived in transition.
+ */
+ boolean handleDeferredBackAnimation(@NonNull ArrayList<Transition.ChangeInfo> targets) {
+ if (!mBackAnimationInProgress || mPendingAnimationBuilder == null) {
+ return false;
+ }
+
+ ProtoLog.d(WM_DEBUG_BACK_PREVIEW,
+ "Handling the deferred animation after transition finished");
+
+ // Show the target surface and its parents to prevent it or its parents hidden when
+ // the transition finished.
+ // The target could be affected by transition when :
+ // Open transition -> the open target in back navigation
+ // Close transition -> the close target in back navigation.
+ boolean hasTarget = false;
+ final SurfaceControl.Transaction t =
+ mPendingAnimationBuilder.mCloseTarget.getPendingTransaction();
+ for (int i = 0; i < targets.size(); i++) {
+ final WindowContainer wc = targets.get(i).mContainer;
+ if (wc.asActivityRecord() == null && wc.asTask() == null) {
+ continue;
+ } else if (!mPendingAnimationBuilder.containTarget(wc)) {
+ continue;
+ }
+
+ hasTarget = true;
+ t.show(wc.getSurfaceControl());
+ }
+
+ if (!hasTarget) {
+ // Skip if no target participated in current finished transition.
+ Slog.w(TAG, "Finished transition didn't include the targets"
+ + " open: " + mPendingAnimationBuilder.mOpenTarget
+ + " close: " + mPendingAnimationBuilder.mCloseTarget);
+ try {
+ mPendingAnimationBuilder.mBackAnimationAdapter.getRunner().onAnimationCancelled();
+ } catch (RemoteException e) {
+ throw new RuntimeException(e);
+ }
+ mPendingAnimationBuilder = null;
+ return false;
+ }
+
+ scheduleAnimation(mPendingAnimationBuilder);
+ mPendingAnimationBuilder = null;
+ return true;
+ }
+
/**
* Create and handling animations status for an open/close animation targets.
*/
@@ -638,6 +704,7 @@ class BackNavigationController {
if (open) {
return wc == mOpenAdaptor.mTarget || mOpenAdaptor.mTarget.hasChild(wc);
}
+
if (mSwitchType == TASK_SWITCH) {
return wc == mCloseAdaptor.mTarget
|| (wc.asTask() != null && wc.hasChild(mCloseAdaptor.mTarget));
@@ -841,23 +908,22 @@ class BackNavigationController {
}
}
- Runnable scheduleAnimation(int backType, BackAnimationAdapter adapter,
+ ScheduleAnimationBuilder prepareAnimation(int backType, BackAnimationAdapter adapter,
Task currentTask, Task previousTask, ActivityRecord currentActivity,
ActivityRecord previousActivity) {
switch (backType) {
case BackNavigationInfo.TYPE_RETURN_TO_HOME:
return new ScheduleAnimationBuilder(backType, adapter)
.setIsLaunchBehind(true)
- .setComposeTarget(currentTask, previousTask)
- .build();
+ .setComposeTarget(currentTask, previousTask);
case BackNavigationInfo.TYPE_CROSS_ACTIVITY:
return new ScheduleAnimationBuilder(backType, adapter)
.setComposeTarget(currentActivity, previousActivity)
- .setOpeningSnapshot(getActivitySnapshot(previousActivity)).build();
+ .setOpeningSnapshot(getActivitySnapshot(previousActivity));
case BackNavigationInfo.TYPE_CROSS_TASK:
return new ScheduleAnimationBuilder(backType, adapter)
.setComposeTarget(currentTask, previousTask)
- .setOpeningSnapshot(getTaskSnapshot(previousTask)).build();
+ .setOpeningSnapshot(getTaskSnapshot(previousTask));
}
return null;
}
@@ -891,6 +957,11 @@ class BackNavigationController {
return this;
}
+ boolean containTarget(@NonNull WindowContainer wc) {
+ return wc == mOpenTarget || wc == mCloseTarget
+ || wc.hasChild(mOpenTarget) || wc.hasChild(mCloseTarget);
+ }
+
Runnable build() {
if (mOpenTarget == null || mCloseTarget == null) {
return null;
@@ -967,47 +1038,41 @@ class BackNavigationController {
}
};
}
+ }
+ }
- private void setLaunchBehind(ActivityRecord activity) {
- if (activity == null) {
- return;
- }
- if (!activity.isVisibleRequested()) {
- activity.setVisibility(true);
- }
- activity.mLaunchTaskBehind = true;
-
- // Handle fixed rotation launching app.
- final DisplayContent dc = activity.mDisplayContent;
- dc.rotateInDifferentOrientationIfNeeded(activity);
- if (activity.hasFixedRotationTransform()) {
- // Set the record so we can recognize it to continue to update display
- // orientation if the previous activity becomes the top later.
- dc.setFixedRotationLaunchingApp(activity,
- activity.getWindowConfiguration().getRotation());
- }
+ private static void setLaunchBehind(@NonNull ActivityRecord activity) {
+ if (!activity.isVisibleRequested()) {
+ activity.setVisibility(true);
+ }
+ activity.mLaunchTaskBehind = true;
+
+ // Handle fixed rotation launching app.
+ final DisplayContent dc = activity.mDisplayContent;
+ dc.rotateInDifferentOrientationIfNeeded(activity);
+ if (activity.hasFixedRotationTransform()) {
+ // Set the record so we can recognize it to continue to update display
+ // orientation if the previous activity becomes the top later.
+ dc.setFixedRotationLaunchingApp(activity,
+ activity.getWindowConfiguration().getRotation());
+ }
- ProtoLog.d(WM_DEBUG_BACK_PREVIEW,
- "Setting Activity.mLauncherTaskBehind to true. Activity=%s", activity);
- activity.mTaskSupervisor.mStoppingActivities.remove(activity);
- activity.getDisplayContent().ensureActivitiesVisible(null /* starting */,
- 0 /* configChanges */, false /* preserveWindows */, true);
- }
- private void restoreLaunchBehind(ActivityRecord activity) {
- if (activity == null) {
- return;
- }
+ ProtoLog.d(WM_DEBUG_BACK_PREVIEW,
+ "Setting Activity.mLauncherTaskBehind to true. Activity=%s", activity);
+ activity.mTaskSupervisor.mStoppingActivities.remove(activity);
+ activity.getDisplayContent().ensureActivitiesVisible(null /* starting */,
+ 0 /* configChanges */, false /* preserveWindows */, true);
+ }
- activity.mDisplayContent.continueUpdateOrientationForDiffOrienLaunchingApp();
+ private static void restoreLaunchBehind(@NonNull ActivityRecord activity) {
+ activity.mDisplayContent.continueUpdateOrientationForDiffOrienLaunchingApp();
- // Restore the launch-behind state.
- activity.mTaskSupervisor.scheduleLaunchTaskBehindComplete(activity.token);
- activity.mLaunchTaskBehind = false;
- ProtoLog.d(WM_DEBUG_BACK_PREVIEW,
- "Setting Activity.mLauncherTaskBehind to false. Activity=%s",
- activity);
- }
- }
+ // Restore the launch-behind state.
+ activity.mTaskSupervisor.scheduleLaunchTaskBehindComplete(activity.token);
+ activity.mLaunchTaskBehind = false;
+ ProtoLog.d(WM_DEBUG_BACK_PREVIEW,
+ "Setting Activity.mLauncherTaskBehind to false. Activity=%s",
+ activity);
}
void checkAnimationReady(WallpaperController wallpaperController) {
@@ -1039,6 +1104,7 @@ class BackNavigationController {
mNavigationMonitor.stopMonitor();
mBackAnimationInProgress = false;
mShowWallpaper = false;
+ mPendingAnimationBuilder = null;
}
private static TaskSnapshot getActivitySnapshot(@NonNull ActivityRecord r) {
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 86c4e0f7c6c6..947eddeaa3eb 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -38,6 +38,9 @@ import static android.os.Process.SYSTEM_UID;
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
import static android.util.DisplayMetrics.DENSITY_DEFAULT;
import static android.util.RotationUtils.deltaRotation;
+import static android.util.TypedValue.COMPLEX_UNIT_DIP;
+import static android.util.TypedValue.COMPLEX_UNIT_MASK;
+import static android.util.TypedValue.COMPLEX_UNIT_SHIFT;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD;
import static android.view.Display.FLAG_PRIVATE;
@@ -170,6 +173,7 @@ import android.content.pm.ActivityInfo;
import android.content.pm.ActivityInfo.ScreenOrientation;
import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
+import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.ColorSpace;
import android.graphics.Insets;
@@ -206,6 +210,7 @@ import android.util.Size;
import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
+import android.util.TypedValue;
import android.util.proto.ProtoOutputStream;
import android.view.ContentRecordingSession;
import android.view.Display;
@@ -1684,14 +1689,16 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
private int getMinimalTaskSizeDp() {
final Context displayConfigurationContext =
mAtmService.mContext.createConfigurationContext(getConfiguration());
- final float minimalSize =
- displayConfigurationContext.getResources().getDimension(
- R.dimen.default_minimal_size_resizable_task);
- if (Double.compare(mDisplayMetrics.density, 0.0) == 0) {
- throw new IllegalArgumentException("Display with ID=" + getDisplayId() + "has invalid "
- + "DisplayMetrics.density= 0.0");
- }
- return (int) (minimalSize / mDisplayMetrics.density);
+ final Resources res = displayConfigurationContext.getResources();
+ final TypedValue value = new TypedValue();
+ res.getValue(R.dimen.default_minimal_size_resizable_task, value, true /* resolveRefs */);
+ final int valueUnit = ((value.data >> COMPLEX_UNIT_SHIFT) & COMPLEX_UNIT_MASK);
+ if (value.type != TypedValue.TYPE_DIMENSION || valueUnit != COMPLEX_UNIT_DIP) {
+ throw new IllegalArgumentException(
+ "Resource ID #0x" + Integer.toHexString(R.dimen.default_minimal_size_resizable_task)
+ + " is not in valid type or unit");
+ }
+ return (int) TypedValue.complexToFloat(value.data);
}
private boolean updateOrientation(boolean forceUpdate) {
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 0a833f4f2dba..7433c7e58392 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -2035,6 +2035,10 @@ class Task extends TaskFragment {
Rect outOverrideBounds = getResolvedOverrideConfiguration().windowConfiguration.getBounds();
if (windowingMode == WINDOWING_MODE_FULLSCREEN) {
+ if (!mCreatedByOrganizer) {
+ // Use empty bounds to indicate "fill parent".
+ outOverrideBounds.setEmpty();
+ }
// The bounds for fullscreen mode shouldn't be adjusted by minimal size. Otherwise if
// the parent or display is smaller than the size, the content may be cropped.
return;
diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java
index 12cfa2634244..a30ab11d9f6d 100644
--- a/services/core/java/com/android/server/wm/Transition.java
+++ b/services/core/java/com/android/server/wm/Transition.java
@@ -989,6 +989,9 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
cleanUpInternal();
mController.updateAnimatingState(mTmpTransaction);
mTmpTransaction.apply();
+
+ // Handle back animation if it's already started.
+ mController.mAtm.mBackNavigationController.handleDeferredBackAnimation(mTargets);
}
void abort() {
diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java
index 8e22821820a1..b9cb59a17a2e 100644
--- a/services/core/java/com/android/server/wm/WindowOrganizerController.java
+++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java
@@ -74,7 +74,9 @@ import android.graphics.Point;
import android.graphics.Rect;
import android.os.Binder;
import android.os.Bundle;
+import android.os.Handler;
import android.os.IBinder;
+import android.os.Looper;
import android.os.Parcel;
import android.os.RemoteException;
import android.util.AndroidRuntimeException;
@@ -998,11 +1000,14 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
activityOptions.setCallerDisplayId(DEFAULT_DISPLAY);
}
final Bundle options = activityOptions != null ? activityOptions.toBundle() : null;
- waitAsyncStart(() -> mService.mAmInternal.sendIntentSender(
+ int res = waitAsyncStart(() -> mService.mAmInternal.sendIntentSender(
hop.getPendingIntent().getTarget(),
hop.getPendingIntent().getWhitelistToken(), 0 /* code */,
hop.getActivityIntent(), resolvedType, null /* finishReceiver */,
null /* requiredPermission */, options));
+ if (ActivityManager.isStartResultSuccessful(res)) {
+ effects |= TRANSACT_EFFECTS_LIFECYCLE;
+ }
break;
}
case HIERARCHY_OP_TYPE_START_SHORTCUT: {
@@ -1353,9 +1358,16 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
* Post and wait for the result of the activity start to prevent potential deadlock against
* {@link WindowManagerGlobalLock}.
*/
- private void waitAsyncStart(IntSupplier startActivity) {
+ private int waitAsyncStart(IntSupplier startActivity) {
final Integer[] starterResult = {null};
- mService.mH.post(() -> {
+ final Handler handler = (Looper.myLooper() == mService.mH.getLooper())
+ // uncommon case where a queued transaction is trying to start an activity. We can't
+ // post to our own thread and wait (otherwise we deadlock), so use anim thread
+ // instead (which is 1 higher priority).
+ ? mService.mWindowManager.mAnimationHandler
+ // Otherwise just put it on main handler
+ : mService.mH;
+ handler.post(() -> {
try {
starterResult[0] = startActivity.getAsInt();
} catch (Throwable t) {
@@ -1372,6 +1384,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
} catch (InterruptedException ignored) {
}
}
+ return starterResult[0];
}
private int sanitizeAndApplyHierarchyOp(WindowContainer container,
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 6133c184e871..e9c23a052422 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -16406,12 +16406,12 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
mInjector.getPackageManager().getPackagesForUid(caller.getUid()));
Preconditions.checkArgument(callerUidPackageNames.contains(packageName),
"Caller uid doesn't match the one for the provided package.");
+
+ return checkProvisioningPreconditionSkipPermission(action, packageName, caller.getUserId())
+ == STATUS_OK;
} finally {
mInjector.binderRestoreCallingIdentity(ident);
}
-
- return checkProvisioningPreconditionSkipPermission(action, packageName, caller.getUserId())
- == STATUS_OK;
}
@Override
diff --git a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageManagerSettingsTests.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageManagerSettingsTests.java
index a39e0216f4e5..836f8581e8eb 100644
--- a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageManagerSettingsTests.java
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageManagerSettingsTests.java
@@ -566,6 +566,22 @@ public class PackageManagerSettingsTests {
}
@Test
+ public void testWriteCorruptReadPackageRestrictions() {
+ final Settings settingsUnderTest = makeSettings();
+
+ populateDistractionFlags(settingsUnderTest);
+ settingsUnderTest.writePackageRestrictionsLPr(0, /*sync=*/true);
+
+ // Corrupt primary file.
+ writeCorruptedPackageRestrictions(0);
+
+ // now read and verify
+ populateDefaultSettings(settingsUnderTest);
+ settingsUnderTest.readPackageRestrictionsLPr(0, mOrigFirstInstallTimes);
+ verifyDistractionFlags(settingsUnderTest);
+ }
+
+ @Test
public void testReadWritePackageRestrictionsAsync() {
final Settings settingsWrite = makeSettings();
final Settings settingsRead = makeSettings();
@@ -1811,6 +1827,14 @@ public class PackageManagerSettingsTests {
.getBytes());
}
+ private void writeCorruptedPackageRestrictions(final int userId) {
+ writeFile(new File(InstrumentationRegistry.getContext().getFilesDir(), "system/users/"
+ + userId + "/package-restrictions.xml"),
+ ("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
+ + "<package-restrictions>\n"
+ + " <pkg name=\"" + PACKAGE_NAME_1 + "\" ").getBytes());
+ }
+
private static void writeStoppedPackagesXml() {
writeFile(new File(InstrumentationRegistry.getContext().getFilesDir(), "system/packages-stopped.xml"),
( "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"
diff --git a/services/tests/servicestests/Android.bp b/services/tests/servicestests/Android.bp
index 3a7b9a49f161..90dbd539f029 100644
--- a/services/tests/servicestests/Android.bp
+++ b/services/tests/servicestests/Android.bp
@@ -115,6 +115,7 @@ android_test {
":StubTestApp",
":SuspendTestApp",
":MediaButtonReceiverHolderTestHelperApp",
+ "data/broken_shortcut.xml",
],
java_resources: [
diff --git a/services/tests/servicestests/AndroidTest.xml b/services/tests/servicestests/AndroidTest.xml
index d9676470aca3..b304968f3e69 100644
--- a/services/tests/servicestests/AndroidTest.xml
+++ b/services/tests/servicestests/AndroidTest.xml
@@ -21,6 +21,8 @@
<option name="cleanup" value="true" />
<option name="push-file" key="SimpleServiceTestApp3.apk"
value="/data/local/tmp/cts/content/SimpleServiceTestApp3.apk" />
+ <option name="push-file" key="broken_shortcut.xml"
+ value="/data/local/tmp/cts/content/broken_shortcut.xml" />
</target_preparer>
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
diff --git a/services/tests/servicestests/data/broken_shortcut.xml b/services/tests/servicestests/data/broken_shortcut.xml
new file mode 100644
index 000000000000..f2b083ddc3a0
--- /dev/null
+++ b/services/tests/servicestests/data/broken_shortcut.xml
Binary files differ
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java
index 93dfee6f2da4..8c7b0c5a569a 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java
@@ -528,7 +528,7 @@ public class ActivityManagerServiceTest {
ActivityManager.PROCESS_CAPABILITY_NONE,
ActivityManager.PROCESS_CAPABILITY_NONE,
ActivityManager.PROCESS_CAPABILITY_NONE,
- ActivityManager.PROCESS_CAPABILITY_NETWORK,
+ ActivityManager.PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK,
};
final Map<Integer, ChangeRecord> changeItems = new HashMap<>();
for (int i = 0; i < changesForPendingUidRecords.length; ++i) {
diff --git a/services/tests/servicestests/src/com/android/server/am/UidObserverControllerTest.java b/services/tests/servicestests/src/com/android/server/am/UidObserverControllerTest.java
index 8a3f246fd656..f788c92b24b2 100644
--- a/services/tests/servicestests/src/com/android/server/am/UidObserverControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/UidObserverControllerTest.java
@@ -18,8 +18,8 @@ package com.android.server.am;
import static android.app.ActivityManager.PROCESS_CAPABILITY_ALL;
import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_LOCATION;
-import static android.app.ActivityManager.PROCESS_CAPABILITY_NETWORK;
import static android.app.ActivityManager.PROCESS_CAPABILITY_NONE;
+import static android.app.ActivityManager.PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK;
import static android.app.ActivityManager.PROCESS_STATE_CACHED_RECENT;
import static android.app.ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
import static android.app.ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
@@ -185,10 +185,10 @@ public class UidObserverControllerTest {
verifyNoMoreInteractions(observer2);
addPendingChange(TEST_UID1, UidRecord.CHANGE_PROCSTATE | UidRecord.CHANGE_CAPABILITY,
- PROCESS_STATE_RECEIVER, 111, PROCESS_CAPABILITY_NETWORK, false);
+ PROCESS_STATE_RECEIVER, 111, PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK, false);
mUidObserverController.dispatchUidsChanged();
verify(observer2).onUidStateChanged(TEST_UID1, PROCESS_STATE_RECEIVER,
- 111, PROCESS_CAPABILITY_NETWORK);
+ 111, PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK);
verifyNoMoreInteractions(observer1);
verifyNoMoreInteractions(observer2);
diff --git a/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java
index 09a84da9406a..2967c5c53e8a 100644
--- a/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java
@@ -18,6 +18,7 @@ package com.android.server.companion.virtual;
import static android.companion.virtual.VirtualDeviceParams.DEVICE_POLICY_CUSTOM;
import static android.companion.virtual.VirtualDeviceParams.DEVICE_POLICY_DEFAULT;
+import static android.companion.virtual.VirtualDeviceParams.POLICY_TYPE_RECENTS;
import static android.companion.virtual.VirtualDeviceParams.POLICY_TYPE_SENSORS;
import static android.content.Context.DEVICE_ID_DEFAULT;
import static android.content.Context.DEVICE_ID_INVALID;
@@ -117,6 +118,7 @@ import com.android.server.sensors.SensorManagerInternal;
import com.google.android.collect.Sets;
+import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -372,6 +374,11 @@ public class VirtualDeviceManagerServiceTest {
mDeviceImpl = createVirtualDevice(VIRTUAL_DEVICE_ID_1, DEVICE_OWNER_UID_1);
}
+ @After
+ public void tearDown() {
+ mDeviceImpl.close();
+ }
+
@Test
public void getDeviceIdForDisplayId_invalidDisplayId_returnsDefault() {
assertThat(mVdm.getDeviceIdForDisplayId(Display.INVALID_DISPLAY))
@@ -444,6 +451,7 @@ public class VirtualDeviceManagerServiceTest {
.setBlockedActivities(getBlockedActivities())
.setDevicePolicy(POLICY_TYPE_SENSORS, DEVICE_POLICY_CUSTOM)
.build();
+ mDeviceImpl.close();
mDeviceImpl = createVirtualDevice(VIRTUAL_DEVICE_ID_1, DEVICE_OWNER_UID_1, params);
assertThat(mVdm.getDevicePolicy(mDeviceImpl.getDeviceId(), POLICY_TYPE_SENSORS))
@@ -451,6 +459,35 @@ public class VirtualDeviceManagerServiceTest {
}
@Test
+ public void getDevicePolicy_defaultRecentsPolicy_gwpcCanShowRecentsOnHostDevice() {
+ VirtualDeviceParams params = new VirtualDeviceParams
+ .Builder()
+ .build();
+ mDeviceImpl.close();
+ mDeviceImpl = createVirtualDevice(VIRTUAL_DEVICE_ID_1, DEVICE_OWNER_UID_1, params);
+ addVirtualDisplay(mDeviceImpl, DISPLAY_ID_1);
+
+ GenericWindowPolicyController gwpc =
+ mDeviceImpl.getDisplayWindowPolicyControllerForTest(DISPLAY_ID_1);
+ assertThat(gwpc.canShowTasksInHostDeviceRecents()).isTrue();
+ }
+
+ @Test
+ public void getDevicePolicy_customRecentsPolicy_gwpcCannotShowRecentsOnHostDevice() {
+ VirtualDeviceParams params = new VirtualDeviceParams
+ .Builder()
+ .setDevicePolicy(POLICY_TYPE_RECENTS, DEVICE_POLICY_CUSTOM)
+ .build();
+ mDeviceImpl.close();
+ mDeviceImpl = createVirtualDevice(VIRTUAL_DEVICE_ID_1, DEVICE_OWNER_UID_1, params);
+ addVirtualDisplay(mDeviceImpl, DISPLAY_ID_1);
+
+ GenericWindowPolicyController gwpc =
+ mDeviceImpl.getDisplayWindowPolicyControllerForTest(DISPLAY_ID_1);
+ assertThat(gwpc.canShowTasksInHostDeviceRecents()).isFalse();
+ }
+
+ @Test
public void getDeviceOwnerUid_oneDevice_returnsCorrectId() {
int ownerUid = mLocalService.getDeviceOwnerUid(mDeviceImpl.getDeviceId());
assertThat(ownerUid).isEqualTo(mDeviceImpl.getOwnerUid());
@@ -501,6 +538,7 @@ public class VirtualDeviceManagerServiceTest {
doReturn(SENSOR_HANDLE).when(mSensorManagerInternalMock).createRuntimeSensor(
anyInt(), anyInt(), anyString(), anyString(), anyInt(), any());
+ mDeviceImpl.close();
mDeviceImpl = createVirtualDevice(VIRTUAL_DEVICE_ID_1, DEVICE_OWNER_UID_1, params);
VirtualSensor sensor = mLocalService.getVirtualSensor(VIRTUAL_DEVICE_ID_1, SENSOR_HANDLE);
diff --git a/services/tests/servicestests/src/com/android/server/companion/virtual/audio/VirtualAudioControllerTest.java b/services/tests/servicestests/src/com/android/server/companion/virtual/audio/VirtualAudioControllerTest.java
index 7b5af1e0fe98..d9e4da73c1c3 100644
--- a/services/tests/servicestests/src/com/android/server/companion/virtual/audio/VirtualAudioControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/companion/virtual/audio/VirtualAudioControllerTest.java
@@ -90,8 +90,7 @@ public class VirtualAudioControllerTest {
/* secureWindowCallback= */ null,
/* intentListenerCallback= */ null,
/* displayCategories= */ new ArrayList<>(),
- /* recentsPolicy= */
- VirtualDeviceParams.RECENTS_POLICY_ALLOW_IN_HOST_DEVICE_RECENTS);
+ /* showTasksInHostDeviceRecents= */ true);
}
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
index 0a718e329498..e65f8cf2a199 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
@@ -4007,6 +4007,18 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
// TODO Check all other fields
}
+ public void testLoadCorruptedShortcuts() throws Exception {
+ initService();
+
+ addPackage("com.android.chrome", 0, 0);
+
+ ShortcutUser user = new ShortcutUser(mService, 0);
+
+ File corruptedShortcutPackage = new File("/data/local/tmp/cts/content/",
+ "broken_shortcut.xml");
+ assertNull(ShortcutPackage.loadFromFile(mService, user, corruptedShortcutPackage, false));
+ }
+
public void testSaveCorruptAndLoadUser() throws Exception {
// First, create some shortcuts and save.
runWithCaller(CALLING_PACKAGE_1, UserHandle.USER_SYSTEM, () -> {
@@ -4096,11 +4108,12 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
// Save and corrupt the primary files.
mService.saveDirtyInfo();
- try (Writer os = new FileWriter(mService.getUserFile(UserHandle.USER_SYSTEM))) {
+ try (Writer os = new FileWriter(
+ mService.getUserFile(UserHandle.USER_SYSTEM).getBaseFile())) {
os.write("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
+ "<user locales=\"en\" last-app-scan-time2=\"14400000");
}
- try (Writer os = new FileWriter(mService.getUserFile(USER_10))) {
+ try (Writer os = new FileWriter(mService.getUserFile(USER_10).getBaseFile())) {
os.write("<?xml version='1.0' encoding='utf");
}
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java
index 15fd73cf4674..01e56a0ddae6 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java
@@ -2349,7 +2349,7 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
* can still be read.
*/
public void testLoadLegacySavedFile() throws Exception {
- final File path = mService.getUserFile(USER_0);
+ final File path = mService.getUserFile(USER_0).getBaseFile();
path.getParentFile().mkdirs();
try (Writer w = new FileWriter(path)) {
w.write(readTestAsset("shortcut/shortcut_legacy_file.xml"));
diff --git a/services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java b/services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java
index 8cc362c1820c..17f6d51a74f3 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java
@@ -35,6 +35,8 @@ import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.never;
+import android.app.WindowConfiguration;
+import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.graphics.Point;
import android.graphics.Rect;
@@ -45,6 +47,7 @@ import android.platform.test.annotations.Presubmit;
import android.provider.DeviceConfig;
import android.util.DisplayMetrics;
import android.view.ContentRecordingSession;
+import android.view.Gravity;
import android.view.Surface;
import android.view.SurfaceControl;
@@ -258,8 +261,17 @@ public class ContentRecorderTests extends WindowTestsBase {
@Test
public void testOnTaskBoundsConfigurationChanged_notifiesCallback() {
+ mTask.getRootTask().setWindowingMode(WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW);
+
final int recordedWidth = 333;
final int recordedHeight = 999;
+
+ final ActivityInfo info = new ActivityInfo();
+ info.windowLayout = new ActivityInfo.WindowLayout(-1 /* width */,
+ -1 /* widthFraction */, -1 /* height */, -1 /* heightFraction */,
+ Gravity.NO_GRAVITY, recordedWidth, recordedHeight);
+ mTask.setMinDimensions(info);
+
// WHEN a recording is ongoing.
mContentRecorder.setContentRecordingSession(mTaskSession);
mContentRecorder.updateRecording();
@@ -267,7 +279,6 @@ public class ContentRecorderTests extends WindowTestsBase {
// WHEN a configuration change arrives, and the recorded content is a different size.
mTask.setBounds(new Rect(0, 0, recordedWidth, recordedHeight));
- mContentRecorder.onConfigurationChanged(mDefaultDisplay.getLastOrientation());
assertThat(mContentRecorder.isCurrentlyRecording()).isTrue();
// THEN content in the captured DisplayArea is scaled to fit the surface size.
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
index 9cd80a34b714..5208e5a2dc2f 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
@@ -535,6 +535,34 @@ public class TaskTests extends WindowTestsBase {
assertEquals(reqBounds.height(), task.getBounds().height());
}
+ /** Tests that the task bounds adjust properly to changes between FULLSCREEN and FREEFORM */
+ @Test
+ public void testBoundsOnModeChangeFreeformToFullscreen() {
+ DisplayContent display = mAtm.mRootWindowContainer.getDefaultDisplay();
+ Task rootTask = new TaskBuilder(mSupervisor).setDisplay(display).setCreateActivity(true)
+ .setWindowingMode(WINDOWING_MODE_FREEFORM).build();
+ Task task = rootTask.getBottomMostTask();
+ task.getRootActivity().setOrientation(SCREEN_ORIENTATION_UNSPECIFIED);
+ DisplayInfo info = new DisplayInfo();
+ display.mDisplay.getDisplayInfo(info);
+ final Rect fullScreenBounds = new Rect(0, 0, info.logicalWidth, info.logicalHeight);
+ final Rect freeformBounds = new Rect(fullScreenBounds);
+ freeformBounds.inset((int) (freeformBounds.width() * 0.2),
+ (int) (freeformBounds.height() * 0.2));
+ task.setBounds(freeformBounds);
+
+ assertEquals(freeformBounds, task.getBounds());
+
+ // FULLSCREEN inherits bounds
+ rootTask.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
+ assertEquals(fullScreenBounds, task.getBounds());
+ assertEquals(freeformBounds, task.mLastNonFullscreenBounds);
+
+ // FREEFORM restores bounds
+ rootTask.setWindowingMode(WINDOWING_MODE_FREEFORM);
+ assertEquals(freeformBounds, task.getBounds());
+ }
+
/**
* Tests that a task with forced orientation has orientation-consistent bounds within the
* parent.
diff --git a/services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java b/services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java
index fec079b7b15b..7e4a9de950e5 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java
@@ -30,6 +30,9 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doAnswer;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
@@ -39,6 +42,7 @@ import android.graphics.Insets;
import android.graphics.Rect;
import android.hardware.display.DisplayManagerGlobal;
import android.util.DisplayMetrics;
+import android.util.TypedValue;
import android.view.Display;
import android.view.DisplayCutout;
import android.view.DisplayInfo;
@@ -47,6 +51,8 @@ import com.android.server.wm.DisplayWindowSettings.SettingsProvider.SettingsEntr
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
class TestDisplayContent extends DisplayContent {
@@ -197,10 +203,21 @@ class TestDisplayContent extends DisplayContent {
MockitoAnnotations.initMocks(this);
doReturn(mMockContext).when(mService.mContext).createConfigurationContext(any());
doReturn(mResources).when(mMockContext).getResources();
- doReturn(valueDp * mDisplayMetrics.density)
- .when(mResources)
- .getDimension(
- com.android.internal.R.dimen.default_minimal_size_resizable_task);
+ doAnswer(
+ new Answer() {
+ @Override
+ public Object answer(InvocationOnMock i) {
+ Object[] args = i.getArguments();
+ TypedValue v = (TypedValue) args[1];
+ v.type = TypedValue.TYPE_DIMENSION;
+ v.data = TypedValue.createComplexDimension(valueDp,
+ TypedValue.COMPLEX_UNIT_DIP);
+ return null;
+ }
+ }
+ ).when(mResources).getValue(
+ eq(com.android.internal.R.dimen.default_minimal_size_resizable_task),
+ any(TypedValue.class), eq(true));
return this;
}
Builder setDeviceStateController(@NonNull DeviceStateController deviceStateController) {
diff --git a/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java b/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
index b8bb45f05ab5..048e2ccc82b4 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
@@ -19,6 +19,7 @@ package com.android.server.wm;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
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.content.pm.ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS;
@@ -1699,7 +1700,8 @@ public class TransitionTests extends WindowTestsBase {
@Test
public void testTransitionVisibleChange() {
registerTestTransitionPlayer();
- final ActivityRecord app = createActivityRecord(mDisplayContent);
+ final ActivityRecord app = createActivityRecord(
+ mDisplayContent, WINDOWING_MODE_MULTI_WINDOW, ACTIVITY_TYPE_STANDARD);
final Transition transition = new Transition(TRANSIT_OPEN, 0 /* flags */,
app.mTransitionController, mWm.mSyncEngine);
app.mTransitionController.moveToCollecting(transition, BLASTSyncEngine.METHOD_NONE);
@@ -1749,7 +1751,8 @@ public class TransitionTests extends WindowTestsBase {
@Test
public void testVisibleChange_snapshot() {
registerTestTransitionPlayer();
- final ActivityRecord app = createActivityRecord(mDisplayContent);
+ final ActivityRecord app = createActivityRecord(
+ mDisplayContent, WINDOWING_MODE_MULTI_WINDOW, ACTIVITY_TYPE_STANDARD);
final Transition transition = new Transition(TRANSIT_CHANGE, 0 /* flags */,
app.mTransitionController, mWm.mSyncEngine);
app.mTransitionController.moveToCollecting(transition, BLASTSyncEngine.METHOD_NONE);
diff --git a/telecomm/java/android/telecom/CallControl.java b/telecomm/java/android/telecom/CallControl.java
index 97538c1c833f..50f2ad4561cc 100644
--- a/telecomm/java/android/telecom/CallControl.java
+++ b/telecomm/java/android/telecom/CallControl.java
@@ -294,18 +294,21 @@ public final class CallControl {
/**
* Raises an event to the {@link android.telecom.InCallService} implementations tracking this
* call via {@link android.telecom.Call.Callback#onConnectionEvent(Call, String, Bundle)}.
- * These events and the associated extra keys for the {@code Bundle} parameter are defined
- * in Android X. This API is used to relay additional information about a call other than
- * what is specified in the {@link android.telecom.CallAttributes} to
- * {@link android.telecom.InCallService}s. This might include, for example, a change to the list
- * of participants in a meeting, or the name of the speakers who have their hand raised. Where
- * appropriate, the {@link InCallService}s tracking this call may choose to render this
- * additional information about the call. An automotive calling UX, for example may have enough
- * screen real estate to indicate the number of participants in a meeting, but to prevent
- * distractions could suppress the list of participants.
+ * These events and the associated extra keys for the {@code Bundle} parameter are mutually
+ * defined by a VoIP application and {@link android.telecom.InCallService}. This API is used to
+ * relay additional information about a call other than what is specified in the
+ * {@link android.telecom.CallAttributes} to {@link android.telecom.InCallService}s. This might
+ * include, for example, a change to the list of participants in a meeting, or the name of the
+ * speakers who have their hand raised. Where appropriate, the {@link InCallService}s tracking
+ * this call may choose to render this additional information about the call. An automotive
+ * calling UX, for example may have enough screen real estate to indicate the number of
+ * participants in a meeting, but to prevent distractions could suppress the list of
+ * participants.
*
- * @param event that is defined in AndroidX (ex. The number of participants changed)
- * @param extras the updated value in relation to the event (ex. 4 participants)
+ * @param event a string event identifier agreed upon between a VoIP application and an
+ * {@link android.telecom.InCallService}
+ * @param extras a {@link android.os.Bundle} containing information about the event, as agreed
+ * upon between a VoIP application and {@link android.telecom.InCallService}.
*/
public void sendEvent(@NonNull String event, @NonNull Bundle extras) {
Objects.requireNonNull(event);
diff --git a/telecomm/java/android/telecom/CallEventCallback.java b/telecomm/java/android/telecom/CallEventCallback.java
index d96c406c4294..a41c0113e933 100644
--- a/telecomm/java/android/telecom/CallEventCallback.java
+++ b/telecomm/java/android/telecom/CallEventCallback.java
@@ -60,14 +60,17 @@ public interface CallEventCallback {
/**
* Informs this {@link android.telecom.CallEventCallback} on events raised from a
- * {@link android.telecom.InCallService} presenting this call. The event key and extra values
- * are defined in AndroidX. This enables alternative calling surfaces, such as an automotive
- * UI, to relay requests to perform other non-standard call actions to the app. For example,
- * an automotive calling solution may offer the ability for the user to raise their hand
- * during a meeting.
+ * {@link android.telecom.InCallService} presenting this call. These events and the
+ * associated extra keys for the {@code Bundle} parameter are mutually defined by a VoIP
+ * application and {@link android.telecom.InCallService}. This enables alternative calling
+ * surfaces, such as an automotive UI, to relay requests to perform other non-standard call
+ * actions to the app. For example, an automotive calling solution may offer the ability for
+ * the user to raise their hand during a meeting.
*
- * @param event that is defined in AndroidX (ex. the number of participants changed)
- * @param extras the updated value in relation to the event (ex. 4 participants)
+ * @param event a string event identifier agreed upon between a VoIP application and an
+ * {@link android.telecom.InCallService}
+ * @param extras a {@link android.os.Bundle} containing information about the event, as agreed
+ * upon between a VoIP application and {@link android.telecom.InCallService}.
*/
void onEvent(@NonNull String event, @NonNull Bundle extras);
}
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 77af95619492..918ae7901dbe 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -537,10 +537,9 @@ public class CarrierConfigManager {
/**
* CDMA activation goes through OTASP.
- * <p>
- * TODO: This should be combined with config_use_hfa_for_provisioning and implemented as an enum
- * (NONE, HFA, OTASP).
*/
+ // TODO: This should be combined with config_use_hfa_for_provisioning and implemented as an enum
+ // (NONE, HFA, OTASP).
public static final String KEY_USE_OTASP_FOR_PROVISIONING_BOOL =
"use_otasp_for_provisioning_bool";
diff --git a/wifi/java/src/android/net/wifi/sharedconnectivity/app/NetworkProviderInfo.java b/wifi/java/src/android/net/wifi/sharedconnectivity/app/NetworkProviderInfo.java
index 1b35b626c302..ed4d699ad4de 100644
--- a/wifi/java/src/android/net/wifi/sharedconnectivity/app/NetworkProviderInfo.java
+++ b/wifi/java/src/android/net/wifi/sharedconnectivity/app/NetworkProviderInfo.java
@@ -80,9 +80,11 @@ public final class NetworkProviderInfo implements Parcelable {
DEVICE_TYPE_WATCH,
DEVICE_TYPE_AUTO
})
- public @interface DeviceType {}
+ public @interface DeviceType {
+ }
- @DeviceType private final int mDeviceType;
+ @DeviceType
+ private final int mDeviceType;
private final String mDeviceName;
private final String mModelName;
private final int mBatteryPercentage;
@@ -98,7 +100,12 @@ public final class NetworkProviderInfo implements Parcelable {
private int mBatteryPercentage;
private int mConnectionStrength;
- public Builder() {}
+ public Builder(@NonNull String deviceName, @NonNull String modelName) {
+ Objects.requireNonNull(deviceName);
+ Objects.requireNonNull(modelName);
+ mDeviceName = deviceName;
+ mModelName = modelName;
+ }
/**
* Sets the device type that provides connectivity.
@@ -120,6 +127,7 @@ public final class NetworkProviderInfo implements Parcelable {
*/
@NonNull
public Builder setDeviceName(@NonNull String deviceName) {
+ Objects.requireNonNull(deviceName);
mDeviceName = deviceName;
return this;
}
@@ -132,6 +140,7 @@ public final class NetworkProviderInfo implements Parcelable {
*/
@NonNull
public Builder setModelName(@NonNull String modelName) {
+ Objects.requireNonNull(modelName);
mModelName = modelName;
return this;
}
@@ -176,15 +185,9 @@ public final class NetworkProviderInfo implements Parcelable {
int batteryPercentage, int connectionStrength) {
if (deviceType != DEVICE_TYPE_UNKNOWN && deviceType != DEVICE_TYPE_PHONE
&& deviceType != DEVICE_TYPE_TABLET && deviceType != DEVICE_TYPE_LAPTOP
- && deviceType != DEVICE_TYPE_WATCH && deviceType != DEVICE_TYPE_AUTO) {
+ && deviceType != DEVICE_TYPE_WATCH && deviceType != DEVICE_TYPE_AUTO) {
throw new IllegalArgumentException("Illegal device type");
}
- if (Objects.isNull(deviceName)) {
- throw new IllegalArgumentException("DeviceName must be set");
- }
- if (Objects.isNull(modelName)) {
- throw new IllegalArgumentException("ModelName must be set");
- }
if (batteryPercentage < 0 || batteryPercentage > 100) {
throw new IllegalArgumentException("BatteryPercentage must be in range 0-100");
}
@@ -269,6 +272,7 @@ public final class NetworkProviderInfo implements Parcelable {
return Objects.hash(mDeviceType, mDeviceName, mModelName, mBatteryPercentage,
mConnectionStrength);
}
+
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeInt(mDeviceType);
diff --git a/wifi/tests/src/android/net/wifi/sharedconnectivity/app/HotspotNetworkConnectionStatusTest.java b/wifi/tests/src/android/net/wifi/sharedconnectivity/app/HotspotNetworkConnectionStatusTest.java
index 1f76b484e6ae..b18ab5060924 100644
--- a/wifi/tests/src/android/net/wifi/sharedconnectivity/app/HotspotNetworkConnectionStatusTest.java
+++ b/wifi/tests/src/android/net/wifi/sharedconnectivity/app/HotspotNetworkConnectionStatusTest.java
@@ -41,9 +41,9 @@ import java.util.Arrays;
public class HotspotNetworkConnectionStatusTest {
private static final long DEVICE_ID = 11L;
private static final NetworkProviderInfo NETWORK_PROVIDER_INFO =
- new NetworkProviderInfo.Builder().setDeviceType(DEVICE_TYPE_TABLET)
- .setDeviceName("TEST_NAME").setModelName("TEST_MODEL")
- .setConnectionStrength(2).setBatteryPercentage(50).build();
+ new NetworkProviderInfo.Builder("TEST_NAME", "TEST_MODEL")
+ .setDeviceType(DEVICE_TYPE_TABLET).setConnectionStrength(2)
+ .setBatteryPercentage(50).build();
private static final int NETWORK_TYPE = NETWORK_TYPE_CELLULAR;
private static final String NETWORK_NAME = "TEST_NETWORK";
private static final String HOTSPOT_SSID = "TEST_SSID";
diff --git a/wifi/tests/src/android/net/wifi/sharedconnectivity/app/HotspotNetworkTest.java b/wifi/tests/src/android/net/wifi/sharedconnectivity/app/HotspotNetworkTest.java
index b76927095cf9..8e396b68ad3a 100644
--- a/wifi/tests/src/android/net/wifi/sharedconnectivity/app/HotspotNetworkTest.java
+++ b/wifi/tests/src/android/net/wifi/sharedconnectivity/app/HotspotNetworkTest.java
@@ -42,9 +42,9 @@ import java.util.Arrays;
public class HotspotNetworkTest {
private static final long DEVICE_ID = 11L;
private static final NetworkProviderInfo NETWORK_PROVIDER_INFO =
- new NetworkProviderInfo.Builder().setDeviceType(DEVICE_TYPE_TABLET)
- .setDeviceName("TEST_NAME").setModelName("TEST_MODEL")
- .setConnectionStrength(2).setBatteryPercentage(50).build();
+ new NetworkProviderInfo.Builder("TEST_NAME", "TEST_MODEL")
+ .setDeviceType(DEVICE_TYPE_TABLET).setConnectionStrength(2)
+ .setBatteryPercentage(50).build();
private static final int NETWORK_TYPE = NETWORK_TYPE_CELLULAR;
private static final String NETWORK_NAME = "TEST_NETWORK";
private static final String HOTSPOT_SSID = "TEST_SSID";
@@ -53,9 +53,9 @@ public class HotspotNetworkTest {
private static final long DEVICE_ID_1 = 111L;
private static final NetworkProviderInfo NETWORK_PROVIDER_INFO1 =
- new NetworkProviderInfo.Builder().setDeviceType(DEVICE_TYPE_PHONE)
- .setDeviceName("TEST_NAME").setModelName("TEST_MODEL")
- .setConnectionStrength(2).setBatteryPercentage(50).build();
+ new NetworkProviderInfo.Builder("TEST_NAME", "TEST_MODEL")
+ .setDeviceType(DEVICE_TYPE_PHONE).setConnectionStrength(2)
+ .setBatteryPercentage(50).build();
private static final int NETWORK_TYPE_1 = NETWORK_TYPE_WIFI;
private static final String NETWORK_NAME_1 = "TEST_NETWORK1";
private static final String HOTSPOT_SSID_1 = "TEST_SSID1";
diff --git a/wifi/tests/src/android/net/wifi/sharedconnectivity/app/KnownNetworkConnectionStatusTest.java b/wifi/tests/src/android/net/wifi/sharedconnectivity/app/KnownNetworkConnectionStatusTest.java
index 2a6046fd6944..f98a0fcc7574 100644
--- a/wifi/tests/src/android/net/wifi/sharedconnectivity/app/KnownNetworkConnectionStatusTest.java
+++ b/wifi/tests/src/android/net/wifi/sharedconnectivity/app/KnownNetworkConnectionStatusTest.java
@@ -42,10 +42,9 @@ public class KnownNetworkConnectionStatusTest {
private static final String SSID = "TEST_SSID";
private static final int[] SECURITY_TYPES = {SECURITY_TYPE_WEP};
private static final NetworkProviderInfo NETWORK_PROVIDER_INFO =
- new NetworkProviderInfo.Builder()
- .setDeviceType(DEVICE_TYPE_TABLET).setDeviceName("TEST_NAME").setModelName(
- "TEST_MODEL")
- .setConnectionStrength(2).setBatteryPercentage(50).build();
+ new NetworkProviderInfo.Builder("TEST_NAME", "TEST_MODEL")
+ .setDeviceType(DEVICE_TYPE_TABLET).setConnectionStrength(2)
+ .setBatteryPercentage(50).build();
private static final String SSID_1 = "TEST_SSID1";
private static final String BUNDLE_KEY = "INT-KEY";
private static final int BUNDLE_VALUE = 1;
diff --git a/wifi/tests/src/android/net/wifi/sharedconnectivity/app/KnownNetworkTest.java b/wifi/tests/src/android/net/wifi/sharedconnectivity/app/KnownNetworkTest.java
index 1b9a7ebd7856..1ecba7644cf9 100644
--- a/wifi/tests/src/android/net/wifi/sharedconnectivity/app/KnownNetworkTest.java
+++ b/wifi/tests/src/android/net/wifi/sharedconnectivity/app/KnownNetworkTest.java
@@ -44,16 +44,16 @@ public class KnownNetworkTest {
private static final String SSID = "TEST_SSID";
private static final int[] SECURITY_TYPES = {SECURITY_TYPE_WEP};
private static final NetworkProviderInfo NETWORK_PROVIDER_INFO =
- new NetworkProviderInfo.Builder().setDeviceType(DEVICE_TYPE_TABLET)
- .setDeviceName("TEST_NAME").setModelName("TEST_MODEL").setConnectionStrength(2)
+ new NetworkProviderInfo.Builder("TEST_NAME", "TEST_MODEL")
+ .setDeviceType(DEVICE_TYPE_TABLET).setConnectionStrength(2)
.setBatteryPercentage(50).build();
private static final int NETWORK_SOURCE_1 = NETWORK_SOURCE_CLOUD_SELF;
private static final String SSID_1 = "TEST_SSID1";
private static final int[] SECURITY_TYPES_1 = {SECURITY_TYPE_PSK};
private static final NetworkProviderInfo NETWORK_PROVIDER_INFO1 =
- new NetworkProviderInfo.Builder().setDeviceType(DEVICE_TYPE_PHONE)
- .setDeviceName("TEST_NAME_1").setModelName("TEST_MODEL_1")
- .setConnectionStrength(3).setBatteryPercentage(33).build();
+ new NetworkProviderInfo.Builder("TEST_NAME_1", "TEST_MODEL_1")
+ .setDeviceType(DEVICE_TYPE_PHONE).setConnectionStrength(3)
+ .setBatteryPercentage(33).build();
/**
* Verifies parcel serialization/deserialization.
diff --git a/wifi/tests/src/android/net/wifi/sharedconnectivity/app/NetworkProviderInfoTest.java b/wifi/tests/src/android/net/wifi/sharedconnectivity/app/NetworkProviderInfoTest.java
index 5de65442b9be..8f35d8d94a8b 100644
--- a/wifi/tests/src/android/net/wifi/sharedconnectivity/app/NetworkProviderInfoTest.java
+++ b/wifi/tests/src/android/net/wifi/sharedconnectivity/app/NetworkProviderInfoTest.java
@@ -116,8 +116,7 @@ public class NetworkProviderInfoTest {
}
private NetworkProviderInfo.Builder buildNetworkProviderInfoBuilder() {
- return new NetworkProviderInfo.Builder().setDeviceType(DEVICE_TYPE)
- .setDeviceName(DEVICE_NAME).setModelName(DEVICE_MODEL)
+ return new NetworkProviderInfo.Builder(DEVICE_NAME, DEVICE_MODEL).setDeviceType(DEVICE_TYPE)
.setBatteryPercentage(BATTERY_PERCENTAGE)
.setConnectionStrength(CONNECTION_STRENGTH);
}
diff --git a/wifi/tests/src/android/net/wifi/sharedconnectivity/app/SharedConnectivityManagerTest.java b/wifi/tests/src/android/net/wifi/sharedconnectivity/app/SharedConnectivityManagerTest.java
index 9fc352cf133f..8c573e302213 100644
--- a/wifi/tests/src/android/net/wifi/sharedconnectivity/app/SharedConnectivityManagerTest.java
+++ b/wifi/tests/src/android/net/wifi/sharedconnectivity/app/SharedConnectivityManagerTest.java
@@ -57,10 +57,9 @@ import java.util.concurrent.Executor;
public class SharedConnectivityManagerTest {
private static final long DEVICE_ID = 11L;
private static final NetworkProviderInfo NETWORK_PROVIDER_INFO =
- new NetworkProviderInfo.Builder()
- .setDeviceType(DEVICE_TYPE_TABLET).setDeviceName("TEST_NAME").setModelName(
- "TEST_MODEL")
- .setConnectionStrength(2).setBatteryPercentage(50).build();
+ new NetworkProviderInfo.Builder("TEST_NAME", "TEST_MODEL")
+ .setDeviceType(DEVICE_TYPE_TABLET).setConnectionStrength(2)
+ .setBatteryPercentage(50).build();
private static final int NETWORK_TYPE = NETWORK_TYPE_CELLULAR;
private static final String NETWORK_NAME = "TEST_NETWORK";
private static final String HOTSPOT_SSID = "TEST_SSID";
diff --git a/wifi/tests/src/android/net/wifi/sharedconnectivity/service/SharedConnectivityServiceTest.java b/wifi/tests/src/android/net/wifi/sharedconnectivity/service/SharedConnectivityServiceTest.java
index cf437b7ea4fe..19effe5d6f14 100644
--- a/wifi/tests/src/android/net/wifi/sharedconnectivity/service/SharedConnectivityServiceTest.java
+++ b/wifi/tests/src/android/net/wifi/sharedconnectivity/service/SharedConnectivityServiceTest.java
@@ -56,10 +56,9 @@ import java.util.List;
@SmallTest
public class SharedConnectivityServiceTest {
private static final NetworkProviderInfo NETWORK_PROVIDER_INFO =
- new NetworkProviderInfo.Builder()
- .setDeviceType(DEVICE_TYPE_TABLET).setDeviceName("TEST_NAME").setModelName(
- "TEST_MODEL")
- .setConnectionStrength(2).setBatteryPercentage(50).build();
+ new NetworkProviderInfo.Builder("TEST_NAME", "TEST_MODEL")
+ .setDeviceType(DEVICE_TYPE_TABLET).setConnectionStrength(2)
+ .setBatteryPercentage(50).build();
private static final HotspotNetwork HOTSPOT_NETWORK =
new HotspotNetwork.Builder().setDeviceId(1).setNetworkProviderInfo(
NETWORK_PROVIDER_INFO)