Merge "Stop calling IMM#isActive() from TextView#onDraw()" into main
diff --git a/AconfigFlags.bp b/AconfigFlags.bp
index fd92979b..16170d9 100644
--- a/AconfigFlags.bp
+++ b/AconfigFlags.bp
@@ -23,6 +23,7 @@
":camera_platform_flags_core_java_lib{.generated_srcjars}",
":com.android.window.flags.window-aconfig-java{.generated_srcjars}",
":com.android.text.flags-aconfig-java{.generated_srcjars}",
+ ":android.companion.virtual.flags-aconfig-java{.generated_srcjars}",
],
}
@@ -80,6 +81,14 @@
defaults: ["framework-minus-apex-aconfig-java-defaults"],
}
+java_aconfig_library {
+ name: "android.security.flags-aconfig-java-host",
+ aconfig_declarations: "android.security.flags-aconfig",
+ host_supported: true,
+ test: true,
+ defaults: ["framework-minus-apex-aconfig-java-defaults"],
+}
+
// OS
aconfig_declarations {
name: "android.os.flags-aconfig",
@@ -92,3 +101,16 @@
aconfig_declarations: "android.os.flags-aconfig",
defaults: ["framework-minus-apex-aconfig-java-defaults"],
}
+
+// VirtualDeviceManager
+java_aconfig_library {
+ name: "android.companion.virtual.flags-aconfig-java",
+ aconfig_declarations: "android.companion.virtual.flags-aconfig",
+ defaults: ["framework-minus-apex-aconfig-java-defaults"],
+}
+
+aconfig_declarations {
+ name: "android.companion.virtual.flags-aconfig",
+ package: "android.companion.virtual.flags",
+ srcs: ["core/java/android/companion/virtual/*.aconfig"],
+}
diff --git a/cmds/idmap2/libidmap2/XmlParser.cpp b/cmds/idmap2/libidmap2/XmlParser.cpp
index 1d78460..7807155 100644
--- a/cmds/idmap2/libidmap2/XmlParser.cpp
+++ b/cmds/idmap2/libidmap2/XmlParser.cpp
@@ -130,11 +130,14 @@
}
Result<Res_value> XmlParser::Node::GetAttributeValue(const std::string& name) const {
+ String16 name16;
return FindAttribute(parser_, name, [&](size_t index) -> bool {
- size_t len;
- const String16 key16(parser_.getAttributeName(index, &len));
- std::string key = String8(key16).c_str();
- return key == name;
+ if (name16.empty()) {
+ name16 = String16(name.c_str(), name.size());
+ }
+ size_t key_len;
+ const auto key16 = parser_.getAttributeName(index, &key_len);
+ return key16 && name16.size() == key_len && name16 == key16;
});
}
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index adbd06c..adf1da9 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -17321,7 +17321,6 @@
field public static final int NT_RADIO_TECHNOLOGY_NR_NTN = 2; // 0x2
field public static final int NT_RADIO_TECHNOLOGY_PROPRIETARY = 4; // 0x4
field public static final int NT_RADIO_TECHNOLOGY_UNKNOWN = 0; // 0x0
- field public static final int SATELLITE_ACCESS_BARRED = 16; // 0x10
field public static final int SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE = 0; // 0x0
field public static final int SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_FAILED = 7; // 0x7
field public static final int SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_NONE = 6; // 0x6
@@ -17331,13 +17330,6 @@
field public static final int SATELLITE_DATAGRAM_TRANSFER_STATE_SEND_FAILED = 3; // 0x3
field public static final int SATELLITE_DATAGRAM_TRANSFER_STATE_SEND_SUCCESS = 2; // 0x2
field public static final int SATELLITE_DATAGRAM_TRANSFER_STATE_UNKNOWN = -1; // 0xffffffff
- field public static final int SATELLITE_ERROR = 1; // 0x1
- field public static final int SATELLITE_ERROR_NONE = 0; // 0x0
- field public static final int SATELLITE_INVALID_ARGUMENTS = 8; // 0x8
- field public static final int SATELLITE_INVALID_MODEM_STATE = 7; // 0x7
- field public static final int SATELLITE_INVALID_TELEPHONY_STATE = 6; // 0x6
- field public static final int SATELLITE_MODEM_BUSY = 22; // 0x16
- field public static final int SATELLITE_MODEM_ERROR = 4; // 0x4
field public static final int SATELLITE_MODEM_STATE_DATAGRAM_RETRYING = 3; // 0x3
field public static final int SATELLITE_MODEM_STATE_DATAGRAM_TRANSFERRING = 2; // 0x2
field public static final int SATELLITE_MODEM_STATE_IDLE = 0; // 0x0
@@ -17345,21 +17337,29 @@
field public static final int SATELLITE_MODEM_STATE_OFF = 4; // 0x4
field public static final int SATELLITE_MODEM_STATE_UNAVAILABLE = 5; // 0x5
field public static final int SATELLITE_MODEM_STATE_UNKNOWN = -1; // 0xffffffff
- field public static final int SATELLITE_NETWORK_ERROR = 5; // 0x5
- field public static final int SATELLITE_NETWORK_TIMEOUT = 17; // 0x11
- field public static final int SATELLITE_NOT_AUTHORIZED = 19; // 0x13
- field public static final int SATELLITE_NOT_REACHABLE = 18; // 0x12
- field public static final int SATELLITE_NOT_SUPPORTED = 20; // 0x14
- field public static final int SATELLITE_NO_RESOURCES = 12; // 0xc
- field public static final int SATELLITE_RADIO_NOT_AVAILABLE = 10; // 0xa
- field public static final int SATELLITE_REQUEST_ABORTED = 15; // 0xf
- field public static final int SATELLITE_REQUEST_FAILED = 9; // 0x9
- field public static final int SATELLITE_REQUEST_IN_PROGRESS = 21; // 0x15
- field public static final int SATELLITE_REQUEST_NOT_SUPPORTED = 11; // 0xb
- field public static final int SATELLITE_SERVER_ERROR = 2; // 0x2
- field public static final int SATELLITE_SERVICE_ERROR = 3; // 0x3
- field public static final int SATELLITE_SERVICE_NOT_PROVISIONED = 13; // 0xd
- field public static final int SATELLITE_SERVICE_PROVISION_IN_PROGRESS = 14; // 0xe
+ field public static final int SATELLITE_RESULT_ACCESS_BARRED = 16; // 0x10
+ field public static final int SATELLITE_RESULT_ERROR = 1; // 0x1
+ field public static final int SATELLITE_RESULT_INVALID_ARGUMENTS = 8; // 0x8
+ field public static final int SATELLITE_RESULT_INVALID_MODEM_STATE = 7; // 0x7
+ field public static final int SATELLITE_RESULT_INVALID_TELEPHONY_STATE = 6; // 0x6
+ field public static final int SATELLITE_RESULT_MODEM_BUSY = 22; // 0x16
+ field public static final int SATELLITE_RESULT_MODEM_ERROR = 4; // 0x4
+ field public static final int SATELLITE_RESULT_NETWORK_ERROR = 5; // 0x5
+ field public static final int SATELLITE_RESULT_NETWORK_TIMEOUT = 17; // 0x11
+ field public static final int SATELLITE_RESULT_NOT_AUTHORIZED = 19; // 0x13
+ field public static final int SATELLITE_RESULT_NOT_REACHABLE = 18; // 0x12
+ field public static final int SATELLITE_RESULT_NOT_SUPPORTED = 20; // 0x14
+ field public static final int SATELLITE_RESULT_NO_RESOURCES = 12; // 0xc
+ field public static final int SATELLITE_RESULT_RADIO_NOT_AVAILABLE = 10; // 0xa
+ field public static final int SATELLITE_RESULT_REQUEST_ABORTED = 15; // 0xf
+ field public static final int SATELLITE_RESULT_REQUEST_FAILED = 9; // 0x9
+ field public static final int SATELLITE_RESULT_REQUEST_IN_PROGRESS = 21; // 0x15
+ field public static final int SATELLITE_RESULT_REQUEST_NOT_SUPPORTED = 11; // 0xb
+ field public static final int SATELLITE_RESULT_SERVER_ERROR = 2; // 0x2
+ field public static final int SATELLITE_RESULT_SERVICE_ERROR = 3; // 0x3
+ field public static final int SATELLITE_RESULT_SERVICE_NOT_PROVISIONED = 13; // 0xd
+ field public static final int SATELLITE_RESULT_SERVICE_PROVISION_IN_PROGRESS = 14; // 0xe
+ field public static final int SATELLITE_RESULT_SUCCESS = 0; // 0x0
}
public static class SatelliteManager.SatelliteException extends java.lang.Exception {
diff --git a/core/java/android/companion/virtual/VirtualDeviceManager.java b/core/java/android/companion/virtual/VirtualDeviceManager.java
index 060a5c8..af41370 100644
--- a/core/java/android/companion/virtual/VirtualDeviceManager.java
+++ b/core/java/android/companion/virtual/VirtualDeviceManager.java
@@ -32,6 +32,7 @@
import android.companion.AssociationInfo;
import android.companion.virtual.audio.VirtualAudioDevice;
import android.companion.virtual.audio.VirtualAudioDevice.AudioConfigurationChangeCallback;
+import android.companion.virtual.flags.Flags;
import android.companion.virtual.sensor.VirtualSensor;
import android.content.ComponentName;
import android.content.Context;
@@ -173,6 +174,9 @@
int associationId,
@NonNull VirtualDeviceParams params) {
Objects.requireNonNull(params, "params must not be null");
+ if (Flags.moreLogs()) {
+ Log.i(TAG, "Creating VirtualDevice");
+ }
try {
return new VirtualDevice(mService, mContext, associationId, params);
} catch (RemoteException e) {
diff --git a/core/java/android/companion/virtual/flags.aconfig b/core/java/android/companion/virtual/flags.aconfig
new file mode 100644
index 0000000..39b99c6
--- /dev/null
+++ b/core/java/android/companion/virtual/flags.aconfig
@@ -0,0 +1,8 @@
+package: "android.companion.virtual.flags"
+
+flag {
+ name: "more_logs"
+ namespace: "virtual_devices"
+ description: "More logs to test flags with"
+ bug: "291725823"
+}
diff --git a/core/java/android/content/pm/parsing/ApkLite.java b/core/java/android/content/pm/parsing/ApkLite.java
index 0127adc..71cfd1b 100644
--- a/core/java/android/content/pm/parsing/ApkLite.java
+++ b/core/java/android/content/pm/parsing/ApkLite.java
@@ -139,6 +139,39 @@
*/
private final boolean mIsSdkLibrary;
+ /**
+ * Indicates whether this application's data will be cleared on a failed restore.
+ */
+ private final boolean mClearUserDataAllowed;
+
+ /**
+ * Set to <code>false</code> if the application does not wish to permit any OS-driven
+ * backups of its data; <code>true</code> otherwise.
+ */
+ private final boolean mBackupAllowed;
+
+ /**
+ * When set, the default data storage directory for this app is pointed at
+ * the device-protected location.
+ */
+ private final boolean mDefaultToDeviceProtectedStorage;
+
+ /**
+ * If {@code true} this app requests full external storage access.
+ */
+ private final boolean mRequestLegacyExternalStorage;
+
+ /**
+ * Indicates whether this application has declared its user data as fragile, causing the
+ * system to prompt the user on whether to keep the user data on uninstall.
+ */
+ private final boolean mUserDataFragile;
+
+ /**
+ * Indicates whether this application's data will be cleared on a failed restore.
+ */
+ private final boolean mClearUserDataOnFailedRestoreAllowed;
+
public ApkLite(String path, String packageName, String splitName, boolean isFeatureSplit,
String configForSplit, String usesSplitName, boolean isSplitRequired, int versionCode,
int versionCodeMajor, int revisionCode, int installLocation,
@@ -149,7 +182,10 @@
String requiredSystemPropertyName, String requiredSystemPropertyValue,
int minSdkVersion, int targetSdkVersion, int rollbackDataPolicy,
Set<String> requiredSplitTypes, Set<String> splitTypes,
- boolean hasDeviceAdminReceiver, boolean isSdkLibrary) {
+ boolean hasDeviceAdminReceiver, boolean isSdkLibrary, boolean clearUserDataAllowed,
+ boolean backupAllowed, boolean defaultToDeviceProtectedStorage,
+ boolean requestLegacyExternalStorage, boolean userDataFragile,
+ boolean clearUserDataOnFailedRestoreAllowed) {
mPath = path;
mPackageName = packageName;
mSplitName = splitName;
@@ -183,6 +219,12 @@
mRollbackDataPolicy = rollbackDataPolicy;
mHasDeviceAdminReceiver = hasDeviceAdminReceiver;
mIsSdkLibrary = isSdkLibrary;
+ mClearUserDataAllowed = clearUserDataAllowed;
+ mBackupAllowed = backupAllowed;
+ mDefaultToDeviceProtectedStorage = defaultToDeviceProtectedStorage;
+ mRequestLegacyExternalStorage = requestLegacyExternalStorage;
+ mUserDataFragile = userDataFragile;
+ mClearUserDataOnFailedRestoreAllowed = clearUserDataOnFailedRestoreAllowed;
}
public ApkLite(String path, ArchivedPackageParcel archivedPackage) {
@@ -219,6 +261,12 @@
mRollbackDataPolicy = 0;
mHasDeviceAdminReceiver = false;
mIsSdkLibrary = false;
+ mClearUserDataAllowed = archivedPackage.clearUserDataAllowed;
+ mBackupAllowed = archivedPackage.backupAllowed;
+ mDefaultToDeviceProtectedStorage = archivedPackage.defaultToDeviceProtectedStorage;
+ mRequestLegacyExternalStorage = archivedPackage.requestLegacyExternalStorage;
+ mUserDataFragile = archivedPackage.userDataFragile;
+ mClearUserDataOnFailedRestoreAllowed = archivedPackage.clearUserDataOnFailedRestoreAllowed;
}
/**
@@ -511,6 +559,9 @@
return mRollbackDataPolicy;
}
+ /**
+ * Indicates if this app contains a {@link android.app.admin.DeviceAdminReceiver}.
+ */
@DataClass.Generated.Member
public boolean isHasDeviceAdminReceiver() {
return mHasDeviceAdminReceiver;
@@ -524,11 +575,62 @@
return mIsSdkLibrary;
}
+ /**
+ * Indicates whether this application's data will be cleared on a failed restore.
+ */
+ @DataClass.Generated.Member
+ public boolean isClearUserDataAllowed() {
+ return mClearUserDataAllowed;
+ }
+
+ /**
+ * Set to <code>false</code> if the application does not wish to permit any OS-driven
+ * backups of its data; <code>true</code> otherwise.
+ */
+ @DataClass.Generated.Member
+ public boolean isBackupAllowed() {
+ return mBackupAllowed;
+ }
+
+ /**
+ * When set, the default data storage directory for this app is pointed at
+ * the device-protected location.
+ */
+ @DataClass.Generated.Member
+ public boolean isDefaultToDeviceProtectedStorage() {
+ return mDefaultToDeviceProtectedStorage;
+ }
+
+ /**
+ * If {@code true} this app requests full external storage access.
+ */
+ @DataClass.Generated.Member
+ public boolean isRequestLegacyExternalStorage() {
+ return mRequestLegacyExternalStorage;
+ }
+
+ /**
+ * Indicates whether this application has declared its user data as fragile, causing the
+ * system to prompt the user on whether to keep the user data on uninstall.
+ */
+ @DataClass.Generated.Member
+ public boolean isUserDataFragile() {
+ return mUserDataFragile;
+ }
+
+ /**
+ * Indicates whether this application's data will be cleared on a failed restore.
+ */
+ @DataClass.Generated.Member
+ public boolean isClearUserDataOnFailedRestoreAllowed() {
+ return mClearUserDataOnFailedRestoreAllowed;
+ }
+
@DataClass.Generated(
- time = 1643063342990L,
+ time = 1693422809896L,
codegenVersion = "1.0.23",
sourceFile = "frameworks/base/core/java/android/content/pm/parsing/ApkLite.java",
- inputSignatures = "private final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.NonNull java.lang.String mPath\nprivate final @android.annotation.Nullable java.lang.String mSplitName\nprivate final @android.annotation.Nullable java.lang.String mUsesSplitName\nprivate final @android.annotation.Nullable java.lang.String mConfigForSplit\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mSplitTypes\nprivate final int mVersionCodeMajor\nprivate final int mVersionCode\nprivate final int mRevisionCode\nprivate final int mInstallLocation\nprivate final int mMinSdkVersion\nprivate final int mTargetSdkVersion\nprivate final @android.annotation.NonNull android.content.pm.VerifierInfo[] mVerifiers\nprivate final @android.annotation.NonNull android.content.pm.SigningDetails mSigningDetails\nprivate final boolean mFeatureSplit\nprivate final boolean mIsolatedSplits\nprivate final boolean mSplitRequired\nprivate final boolean mCoreApp\nprivate final boolean mDebuggable\nprivate final boolean mProfileableByShell\nprivate final boolean mMultiArch\nprivate final boolean mUse32bitAbi\nprivate final boolean mExtractNativeLibs\nprivate final boolean mUseEmbeddedDex\nprivate final @android.annotation.Nullable java.lang.String mTargetPackageName\nprivate final boolean mOverlayIsStatic\nprivate final int mOverlayPriority\nprivate final @android.annotation.Nullable java.lang.String mRequiredSystemPropertyName\nprivate final @android.annotation.Nullable java.lang.String mRequiredSystemPropertyValue\nprivate final int mRollbackDataPolicy\nprivate final boolean mHasDeviceAdminReceiver\nprivate final boolean mIsSdkLibrary\npublic long getLongVersionCode()\nprivate boolean hasAnyRequiredSplitTypes()\nclass ApkLite extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genConstDefs=false)")
+ inputSignatures = "private final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.NonNull java.lang.String mPath\nprivate final @android.annotation.Nullable java.lang.String mSplitName\nprivate final @android.annotation.Nullable java.lang.String mUsesSplitName\nprivate final @android.annotation.Nullable java.lang.String mConfigForSplit\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mSplitTypes\nprivate final int mVersionCodeMajor\nprivate final int mVersionCode\nprivate final int mRevisionCode\nprivate final int mInstallLocation\nprivate final int mMinSdkVersion\nprivate final int mTargetSdkVersion\nprivate final @android.annotation.NonNull android.content.pm.VerifierInfo[] mVerifiers\nprivate final @android.annotation.NonNull android.content.pm.SigningDetails mSigningDetails\nprivate final boolean mFeatureSplit\nprivate final boolean mIsolatedSplits\nprivate final boolean mSplitRequired\nprivate final boolean mCoreApp\nprivate final boolean mDebuggable\nprivate final boolean mProfileableByShell\nprivate final boolean mMultiArch\nprivate final boolean mUse32bitAbi\nprivate final boolean mExtractNativeLibs\nprivate final boolean mUseEmbeddedDex\nprivate final @android.annotation.Nullable java.lang.String mTargetPackageName\nprivate final boolean mOverlayIsStatic\nprivate final int mOverlayPriority\nprivate final @android.annotation.Nullable java.lang.String mRequiredSystemPropertyName\nprivate final @android.annotation.Nullable java.lang.String mRequiredSystemPropertyValue\nprivate final int mRollbackDataPolicy\nprivate final boolean mHasDeviceAdminReceiver\nprivate final boolean mIsSdkLibrary\nprivate final boolean mClearUserDataAllowed\nprivate final boolean mBackupAllowed\nprivate final boolean mDefaultToDeviceProtectedStorage\nprivate final boolean mRequestLegacyExternalStorage\nprivate final boolean mUserDataFragile\nprivate final boolean mClearUserDataOnFailedRestoreAllowed\npublic long getLongVersionCode()\nprivate boolean hasAnyRequiredSplitTypes()\nclass ApkLite extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genConstDefs=false)")
@Deprecated
private void __metadata() {}
diff --git a/core/java/android/content/pm/parsing/ApkLiteParseUtils.java b/core/java/android/content/pm/parsing/ApkLiteParseUtils.java
index 7e67396..066ff689 100644
--- a/core/java/android/content/pm/parsing/ApkLiteParseUtils.java
+++ b/core/java/android/content/pm/parsing/ApkLiteParseUtils.java
@@ -40,6 +40,7 @@
import android.util.Slog;
import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.XmlUtils;
import libcore.io.IoUtils;
@@ -446,6 +447,13 @@
int overlayPriority = 0;
int rollbackDataPolicy = 0;
+ boolean clearUserDataAllowed = true;
+ boolean backupAllowed = true;
+ boolean defaultToDeviceProtectedStorage = false;
+ String requestLegacyExternalStorage = null;
+ boolean userDataFragile = false;
+ boolean clearUserDataOnFailedRestoreAllowed = true;
+
String requiredSystemPropertyName = null;
String requiredSystemPropertyValue = null;
@@ -484,6 +492,23 @@
"extractNativeLibs", true);
useEmbeddedDex = parser.getAttributeBooleanValue(ANDROID_RES_NAMESPACE,
"useEmbeddedDex", false);
+
+ clearUserDataAllowed = parser.getAttributeBooleanValue(ANDROID_RES_NAMESPACE,
+ "allowClearUserDataOnFailedRestore", true);
+ backupAllowed = parser.getAttributeBooleanValue(ANDROID_RES_NAMESPACE,
+ "allowBackup", true);
+ defaultToDeviceProtectedStorage = parser.getAttributeBooleanValue(
+ ANDROID_RES_NAMESPACE,
+ "defaultToDeviceProtectedStorage", false);
+ userDataFragile = parser.getAttributeBooleanValue(ANDROID_RES_NAMESPACE,
+ "hasFragileUserData", false);
+ clearUserDataOnFailedRestoreAllowed = parser.getAttributeBooleanValue(
+ ANDROID_RES_NAMESPACE,
+ "allowClearUserDataOnFailedRestore", true);
+
+ requestLegacyExternalStorage = parser.getAttributeValue(ANDROID_RES_NAMESPACE,
+ "requestLegacyExternalStorage");
+
rollbackDataPolicy = parser.getAttributeIntValue(ANDROID_RES_NAMESPACE,
"rollbackDataPolicy", 0);
String permission = parser.getAttributeValue(ANDROID_RES_NAMESPACE,
@@ -604,6 +629,9 @@
return input.skip(message);
}
+ boolean isRequestLegacyExternalStorage = XmlUtils.convertValueToBoolean(
+ requestLegacyExternalStorage, targetSdkVersion < Build.VERSION_CODES.Q);
+
return input.success(
new ApkLite(codePath, packageSplit.first, packageSplit.second, isFeatureSplit,
configForSplit, usesSplitName, isSplitRequired, versionCode,
@@ -613,7 +641,9 @@
overlayIsStatic, overlayPriority, requiredSystemPropertyName,
requiredSystemPropertyValue, minSdkVersion, targetSdkVersion,
rollbackDataPolicy, requiredSplitTypes.first, requiredSplitTypes.second,
- hasDeviceAdminReceiver, isSdkLibrary));
+ hasDeviceAdminReceiver, isSdkLibrary, clearUserDataAllowed, backupAllowed,
+ defaultToDeviceProtectedStorage, isRequestLegacyExternalStorage,
+ userDataFragile, clearUserDataOnFailedRestoreAllowed));
}
private static boolean isDeviceAdminReceiver(
diff --git a/core/java/android/content/pm/parsing/PackageLite.java b/core/java/android/content/pm/parsing/PackageLite.java
index 51dbde3..4638af7 100644
--- a/core/java/android/content/pm/parsing/PackageLite.java
+++ b/core/java/android/content/pm/parsing/PackageLite.java
@@ -112,6 +112,33 @@
* Indicates if this package is a sdk.
*/
private final boolean mIsSdkLibrary;
+ /**
+ * Indicates whether this application's data will be cleared on a failed restore.
+ */
+ private final boolean mClearUserDataAllowed;
+ /**
+ * Set to <code>false</code> if the application does not wish to permit any OS-driven
+ * backups of its data; <code>true</code> otherwise.
+ */
+ private final boolean mBackupAllowed;
+ /**
+ * When set, the default data storage directory for this app is pointed at
+ * the device-protected location.
+ */
+ private final boolean mDefaultToDeviceProtectedStorage;
+ /**
+ * If {@code true} this app requests full external storage access.
+ */
+ private final boolean mRequestLegacyExternalStorage;
+ /**
+ * Indicates whether this application has declared its user data as fragile, causing the
+ * system to prompt the user on whether to keep the user data on uninstall.
+ */
+ private final boolean mUserDataFragile;
+ /**
+ * Indicates whether this application's data will be cleared on a failed restore.
+ */
+ private final boolean mClearUserDataOnFailedRestoreAllowed;
public PackageLite(String path, String baseApkPath, ApkLite baseApk,
String[] splitNames, boolean[] isFeatureSplits, String[] usesSplitNames,
@@ -148,6 +175,12 @@
mSplitApkPaths = splitApkPaths;
mSplitRevisionCodes = splitRevisionCodes;
mTargetSdk = targetSdk;
+ mClearUserDataAllowed = baseApk.isClearUserDataAllowed();
+ mBackupAllowed = baseApk.isBackupAllowed();
+ mDefaultToDeviceProtectedStorage = baseApk.isDefaultToDeviceProtectedStorage();
+ mRequestLegacyExternalStorage = baseApk.isRequestLegacyExternalStorage();
+ mUserDataFragile = baseApk.isUserDataFragile();
+ mClearUserDataOnFailedRestoreAllowed = baseApk.isClearUserDataOnFailedRestoreAllowed();
}
/**
@@ -426,11 +459,62 @@
return mIsSdkLibrary;
}
+ /**
+ * Indicates whether this application's data will be cleared on a failed restore.
+ */
+ @DataClass.Generated.Member
+ public boolean isClearUserDataAllowed() {
+ return mClearUserDataAllowed;
+ }
+
+ /**
+ * Set to <code>false</code> if the application does not wish to permit any OS-driven
+ * backups of its data; <code>true</code> otherwise.
+ */
+ @DataClass.Generated.Member
+ public boolean isBackupAllowed() {
+ return mBackupAllowed;
+ }
+
+ /**
+ * When set, the default data storage directory for this app is pointed at
+ * the device-protected location.
+ */
+ @DataClass.Generated.Member
+ public boolean isDefaultToDeviceProtectedStorage() {
+ return mDefaultToDeviceProtectedStorage;
+ }
+
+ /**
+ * If {@code true} this app requests full external storage access.
+ */
+ @DataClass.Generated.Member
+ public boolean isRequestLegacyExternalStorage() {
+ return mRequestLegacyExternalStorage;
+ }
+
+ /**
+ * Indicates whether this application has declared its user data as fragile, causing the
+ * system to prompt the user on whether to keep the user data on uninstall.
+ */
+ @DataClass.Generated.Member
+ public boolean isUserDataFragile() {
+ return mUserDataFragile;
+ }
+
+ /**
+ * Indicates whether this application's data will be cleared on a failed restore.
+ */
+ @DataClass.Generated.Member
+ public boolean isClearUserDataOnFailedRestoreAllowed() {
+ return mClearUserDataOnFailedRestoreAllowed;
+ }
+
@DataClass.Generated(
- time = 1693264166050L,
+ time = 1693423910860L,
codegenVersion = "1.0.23",
sourceFile = "frameworks/base/core/java/android/content/pm/parsing/PackageLite.java",
- inputSignatures = "private final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.NonNull java.lang.String mPath\nprivate final @android.annotation.NonNull java.lang.String mBaseApkPath\nprivate final @android.annotation.Nullable java.lang.String[] mSplitApkPaths\nprivate final @android.annotation.Nullable java.lang.String[] mSplitNames\nprivate final @android.annotation.Nullable java.lang.String[] mUsesSplitNames\nprivate final @android.annotation.Nullable java.lang.String[] mConfigForSplit\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mBaseRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String>[] mRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String>[] mSplitTypes\nprivate final int mVersionCodeMajor\nprivate final int mVersionCode\nprivate final int mTargetSdk\nprivate final int mBaseRevisionCode\nprivate final @android.annotation.Nullable int[] mSplitRevisionCodes\nprivate final int mInstallLocation\nprivate final @android.annotation.NonNull android.content.pm.VerifierInfo[] mVerifiers\nprivate final @android.annotation.NonNull android.content.pm.SigningDetails mSigningDetails\nprivate final @android.annotation.Nullable boolean[] mIsFeatureSplits\nprivate final boolean mIsolatedSplits\nprivate final boolean mSplitRequired\nprivate final boolean mCoreApp\nprivate final boolean mDebuggable\nprivate final boolean mMultiArch\nprivate final boolean mUse32bitAbi\nprivate final boolean mExtractNativeLibs\nprivate final boolean mProfileableByShell\nprivate final boolean mUseEmbeddedDex\nprivate final boolean mIsSdkLibrary\npublic java.util.List<java.lang.String> getAllApkPaths()\npublic long getLongVersionCode()\nprivate boolean hasAnyRequiredSplitTypes()\nclass PackageLite extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genConstDefs=false)")
+ inputSignatures = "private final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.NonNull java.lang.String mPath\nprivate final @android.annotation.NonNull java.lang.String mBaseApkPath\nprivate final @android.annotation.Nullable java.lang.String[] mSplitApkPaths\nprivate final @android.annotation.Nullable java.lang.String[] mSplitNames\nprivate final @android.annotation.Nullable java.lang.String[] mUsesSplitNames\nprivate final @android.annotation.Nullable java.lang.String[] mConfigForSplit\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mBaseRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String>[] mRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String>[] mSplitTypes\nprivate final int mVersionCodeMajor\nprivate final int mVersionCode\nprivate final int mTargetSdk\nprivate final int mBaseRevisionCode\nprivate final @android.annotation.Nullable int[] mSplitRevisionCodes\nprivate final int mInstallLocation\nprivate final @android.annotation.NonNull android.content.pm.VerifierInfo[] mVerifiers\nprivate final @android.annotation.NonNull android.content.pm.SigningDetails mSigningDetails\nprivate final @android.annotation.Nullable boolean[] mIsFeatureSplits\nprivate final boolean mIsolatedSplits\nprivate final boolean mSplitRequired\nprivate final boolean mCoreApp\nprivate final boolean mDebuggable\nprivate final boolean mMultiArch\nprivate final boolean mUse32bitAbi\nprivate final boolean mExtractNativeLibs\nprivate final boolean mProfileableByShell\nprivate final boolean mUseEmbeddedDex\nprivate final boolean mIsSdkLibrary\nprivate final boolean mClearUserDataAllowed\nprivate final boolean mBackupAllowed\nprivate final boolean mDefaultToDeviceProtectedStorage\nprivate final boolean mRequestLegacyExternalStorage\nprivate final boolean mUserDataFragile\nprivate final boolean mClearUserDataOnFailedRestoreAllowed\npublic java.util.List<java.lang.String> getAllApkPaths()\npublic long getLongVersionCode()\nprivate boolean hasAnyRequiredSplitTypes()\nclass PackageLite extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genConstDefs=false)")
@Deprecated
private void __metadata() {}
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index c0a44b1..f1ae9be 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -890,10 +890,13 @@
mSystemCallingHideSoftInput = true;
mCurHideInputToken = hideInputToken;
mCurStatsToken = statsToken;
- hideSoftInput(flags, resultReceiver);
- mCurStatsToken = null;
- mCurHideInputToken = null;
- mSystemCallingHideSoftInput = false;
+ try {
+ hideSoftInput(flags, resultReceiver);
+ } finally {
+ mCurStatsToken = null;
+ mCurHideInputToken = null;
+ mSystemCallingHideSoftInput = false;
+ }
}
/**
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index bcde31a..c6cb604 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -1002,6 +1002,24 @@
public static final String DISALLOW_ADD_CLONE_PROFILE = "no_add_clone_profile";
/**
+ * Specifies if a user is disallowed from creating a private profile.
+ * <p>The default value for an unmanaged user is <code>false</code>.
+ * For users with a device owner set, the default is <code>true</code>.
+ *
+ * <p>Holders of the permission
+ * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_PROFILES}
+ * can set this restriction using the DevicePolicyManager APIs mentioned below.
+ *
+ * <p>Key for user restrictions.
+ * <p>Type: Boolean
+ * @see DevicePolicyManager#addUserRestriction(ComponentName, String)
+ * @see DevicePolicyManager#clearUserRestriction(ComponentName, String)
+ * @see #getUserRestrictions()
+ * @hide
+ */
+ public static final String DISALLOW_ADD_PRIVATE_PROFILE = "no_add_private_profile";
+
+ /**
* Specifies if a user is disallowed from disabling application verification. The default
* value is <code>false</code>.
*
@@ -1895,6 +1913,7 @@
DISALLOW_ADD_USER,
DISALLOW_ADD_MANAGED_PROFILE,
DISALLOW_ADD_CLONE_PROFILE,
+ DISALLOW_ADD_PRIVATE_PROFILE,
ENSURE_VERIFY_APPS,
DISALLOW_CONFIG_CELL_BROADCASTS,
DISALLOW_CONFIG_MOBILE_NETWORKS,
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index c3c802b..abc0c7a 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -18360,24 +18360,28 @@
* If hotword detection should be enabled.
* @hide
*/
+ @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public static final String HOTWORD_DETECTION_ENABLED = "hotword_detection_enabled";
/**
* Whether Smart Replies are enabled within Wear.
* @hide
*/
+ @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public static final String SMART_REPLIES_ENABLED = "smart_replies_enabled";
/**
* The default vibration pattern.
* @hide
*/
+ @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public static final String DEFAULT_VIBRATION = "default_vibration";
/**
* If FLP should obtain location data from the paired device.
* @hide
*/
+ @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public static final String OBTAIN_PAIRED_DEVICE_LOCATION =
"obtain_paired_device_location";
@@ -18385,6 +18389,7 @@
* The play store availability on companion phone.
* @hide
*/
+ @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public static final String PHONE_PLAY_STORE_AVAILABILITY =
"phone_play_store_availability";
@@ -18400,6 +18405,7 @@
* Whether the bug report is enabled.
* @hide
*/
+ @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public static final String BUG_REPORT = "bug_report";
// Possible bug report states
@@ -18412,12 +18418,14 @@
* The enabled/disabled state of the SmartIlluminate.
* @hide
*/
+ @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public static final String SMART_ILLUMINATE_ENABLED = "smart_illuminate_enabled";
/**
* Whether automatic time is enabled on the watch.
* @hide
*/
+ @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public static final String CLOCKWORK_AUTO_TIME = "clockwork_auto_time";
// Possible clockwork auto time states
@@ -18435,6 +18443,7 @@
* Whether automatic time zone is enabled on the watch.
* @hide
*/
+ @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public static final String CLOCKWORK_AUTO_TIME_ZONE = "clockwork_auto_time_zone";
// Possible clockwork auto time zone states
@@ -18451,12 +18460,14 @@
* Whether 24 hour time format is enabled on the watch.
* @hide
*/
+ @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public static final String CLOCKWORK_24HR_TIME = "clockwork_24hr_time";
/**
* Whether the auto wifi toggle setting is enabled.
* @hide
*/
+ @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public static final String AUTO_WIFI = "auto_wifi";
// Possible force wifi on states
@@ -18476,6 +18487,7 @@
* wifi requirement until this time). The time is in millis since epoch.
* @hide
*/
+ @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public static final String ALT_BYPASS_WIFI_REQUIREMENT_TIME_MILLIS =
"alt_bypass_wifi_requirement_time_millis";
@@ -18483,6 +18495,7 @@
* Whether the setup was skipped.
* @hide
*/
+ @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public static final String SETUP_SKIPPED = "setup_skipped";
// Possible setup_skipped states
@@ -18497,6 +18510,7 @@
* The last requested call forwarding action.
* @hide
*/
+ @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public static final String LAST_CALL_FORWARD_ACTION = "last_call_forward_action";
// Possible call forwarding actions
@@ -18509,22 +18523,31 @@
// Stem button settings.
/** @hide */
+ @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public static final String STEM_1_TYPE = "STEM_1_TYPE";
/** @hide */
+ @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public static final String STEM_1_DATA = "STEM_1_DATA";
/** @hide */
+ @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public static final String STEM_1_DEFAULT_DATA = "STEM_1_DEFAULT_DATA";
/** @hide */
+ @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public static final String STEM_2_TYPE = "STEM_2_TYPE";
/** @hide */
+ @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public static final String STEM_2_DATA = "STEM_2_DATA";
/** @hide */
+ @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public static final String STEM_2_DEFAULT_DATA = "STEM_2_DEFAULT_DATA";
/** @hide */
+ @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public static final String STEM_3_TYPE = "STEM_3_TYPE";
/** @hide */
+ @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public static final String STEM_3_DATA = "STEM_3_DATA";
/** @hide */
+ @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public static final String STEM_3_DEFAULT_DATA = "STEM_3_DEFAULT_DATA";
// Stem types
@@ -18539,12 +18562,14 @@
* If the device should be muted when off body.
* @hide
*/
+ @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public static final String MUTE_WHEN_OFF_BODY_ENABLED = "obtain_mute_when_off_body";
/**
* Wear OS version string.
* @hide
*/
+ @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public static final String WEAR_OS_VERSION_STRING = "wear_os_version_string";
/**
@@ -18557,24 +18582,28 @@
* The android wear system version.
* @hide
*/
+ @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public static final String ANDROID_WEAR_VERSION = "android_wear_version";
/**
* The wear system capabiltiies.
* @hide
*/
+ @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public static final String SYSTEM_CAPABILITIES = "system_capabilities";
/**
* The android wear system edition.
* @hide
*/
+ @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public static final String SYSTEM_EDITION = "android_wear_system_edition";
/**
* The Wear platform MR number.
* @hide
*/
+ @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public static final String WEAR_PLATFORM_MR_NUMBER = "wear_platform_mr_number";
/**
@@ -18588,36 +18617,42 @@
* Whether ambient is currently enabled.
* @hide
*/
+ @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public static final String AMBIENT_ENABLED = "ambient_enabled";
/**
* Whether ambient tilt to wake is enabled.
* @hide
*/
+ @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public static final String AMBIENT_TILT_TO_WAKE = "ambient_tilt_to_wake";
/**
* Whether ambient low bit mode is enabled by developer options.
* @hide
*/
+ @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public static final String AMBIENT_LOW_BIT_ENABLED_DEV = "ambient_low_bit_enabled_dev";
/**
* Whether ambient touch to wake is enabled.
* @hide
*/
+ @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public static final String AMBIENT_TOUCH_TO_WAKE = "ambient_touch_to_wake";
/**
* Whether ambient tilt to bright is enabled.
* @hide
*/
+ @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public static final String AMBIENT_TILT_TO_BRIGHT = "ambient_tilt_to_bright";
/**
* Whether touch and hold to edit WF is enabled
* @hide
*/
+ @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public static final String GESTURE_TOUCH_AND_HOLD_WATCH_FACE_ENABLED =
"gesture_touch_and_hold_watchface_enabled";
@@ -18631,6 +18666,7 @@
* Whether bedtime mode is enabled.
* @hide
*/
+ @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public static final String BEDTIME_MODE = "bedtime_mode";
/**
@@ -18642,31 +18678,35 @@
* Whether the current watchface is decomposable.
* @hide
*/
+ @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public static final String DECOMPOSABLE_WATCHFACE = "current_watchface_decomposable";
/**
* Whether to force ambient when docked.
* @hide
*/
+ @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public static final String AMBIENT_FORCE_WHEN_DOCKED = "ambient_force_when_docked";
/**
* Whether the ambient low bit mode is enabled.
* @hide
*/
+ @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public static final String AMBIENT_LOW_BIT_ENABLED = "ambient_low_bit_enabled";
/**
* The timeout duration in minutes of ambient mode when plugged in.
* @hide
*/
+ @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public static final String AMBIENT_PLUGGED_TIMEOUT_MIN = "ambient_plugged_timeout_min";
/**
* What OS does paired device has.
* @hide
*/
- @Readable
+ @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public static final String PAIRED_DEVICE_OS_TYPE = "paired_device_os_type";
// Possible values of PAIRED_DEVICE_OS_TYPE
@@ -18699,6 +18739,7 @@
* The user's last setting for hfp client.
* @hide
*/
+ @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public static final String USER_HFP_CLIENT_SETTING = "user_hfp_client_setting";
// Possible hfp client user setting values
@@ -18723,6 +18764,7 @@
* The companion App name.
* @hide
*/
+ @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public static final String COMPANION_APP_NAME = "wear_companion_app_name";
/**
@@ -18730,18 +18772,21 @@
* wear. 1 for supporting, 0 for not supporting.
* @hide
*/
+ @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public static final String ENABLE_ALL_LANGUAGES = "enable_all_languages";
/**
* The Locale (as language tag) the user chose at startup.
* @hide
*/
+ @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public static final String SETUP_LOCALE = "setup_locale";
/**
* The version of oem setup present.
* @hide
*/
+ @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public static final String OEM_SETUP_VERSION = "oem_setup_version";
/**
@@ -18787,6 +18832,7 @@
* -{@link BATTERY_SAVER_MODE_CUSTOM}
* @hide
*/
+ @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public static final String BATTERY_SAVER_MODE = "battery_saver_mode";
/**
@@ -18819,6 +18865,7 @@
* The maximum ambient mode duration when an activity is allowed to auto resume.
* @hide
*/
+ @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public static final String WEAR_ACTIVITY_AUTO_RESUME_TIMEOUT_MS =
"wear_activity_auto_resume_timeout_ms";
@@ -18834,6 +18881,7 @@
* If burn in protection is enabled.
* @hide
*/
+ @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public static final String BURN_IN_PROTECTION_ENABLED = "burn_in_protection";
/**
@@ -18852,6 +18900,7 @@
* RIGHT_WRIST_ROTATION_0 = "2", RIGHT_WRIST_ROTATION_180 = "3"
* @hide
*/
+ @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public static final String WRIST_ORIENTATION_MODE = "wear_wrist_orientation_mode";
/**
@@ -18890,6 +18939,7 @@
*
* @hide
*/
+ @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public static final String CLOCKWORK_SYSUI_PACKAGE = "clockwork_sysui_package";
/**
@@ -18919,6 +18969,7 @@
* Whether the device has Wet Mode/ Touch Lock Mode enabled.
* @hide
*/
+ @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public static final String WET_MODE_ON = "wet_mode_on";
/**
@@ -18937,6 +18988,7 @@
* Whether charging sounds are enabled.
* @hide
*/
+ @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public static final String CHARGING_SOUNDS_ENABLED = "wear_charging_sounds_enabled";
/**
@@ -18945,6 +18997,7 @@
*
* @hide
*/
+ @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public static final String DYNAMIC_COLOR_THEME_ENABLED = "dynamic_color_theme_enabled";
/**
@@ -19036,6 +19089,7 @@
* The key to indicate the data migration status on device upgrade in Wear Services.
* @hide
*/
+ @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public static final String UPGRADE_DATA_MIGRATION_STATUS =
"upgrade_data_migration_status";
@@ -19086,17 +19140,20 @@
* The custom foreground color.
* @hide
*/
+ @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public static final String CUSTOM_COLOR_FOREGROUND = "custom_foreground_color";
/**
* The custom background color.
* @hide
*/
+ @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public static final String CUSTOM_COLOR_BACKGROUND = "custom_background_color";
/** The status of the phone switching process.
* @hide
*/
+ @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public static final String PHONE_SWITCHING_STATUS = "phone_switching_status";
/**
@@ -19177,6 +19234,7 @@
* (0 = false, 1 = true)
* @hide
*/
+ @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public static final String REDUCE_MOTION = "reduce_motion";
/**
@@ -19238,6 +19296,7 @@
* Controls the launcher ui mode on wearable devices.
* @hide
*/
+ @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public static final String WEAR_LAUNCHER_UI_MODE = "wear_launcher_ui_mode";
/** Whether Wear Power Anomaly Service is enabled.
diff --git a/core/java/android/service/trust/OWNERS b/core/java/android/service/trust/OWNERS
index 16eb19a..d352525 100644
--- a/core/java/android/service/trust/OWNERS
+++ b/core/java/android/service/trust/OWNERS
@@ -1,3 +1,4 @@
# Bug component: 36824
jacobhobbie@google.com
+dlm@google.com
diff --git a/core/java/android/view/HandwritingInitiator.java b/core/java/android/view/HandwritingInitiator.java
index 23afb03..a208d1f 100644
--- a/core/java/android/view/HandwritingInitiator.java
+++ b/core/java/android/view/HandwritingInitiator.java
@@ -81,6 +81,8 @@
private int mConnectionCount = 0;
private final InputMethodManager mImm;
+ private final Rect mTempRect = new Rect();
+
private final RectF mTempRectF = new RectF();
private final Region mTempRegion = new Region();
@@ -401,8 +403,9 @@
final View cachedHoverTarget = getCachedHoverTarget();
if (cachedHoverTarget != null) {
- final Rect handwritingArea = getViewHandwritingArea(cachedHoverTarget);
- if (isInHandwritingArea(handwritingArea, hoverX, hoverY, cachedHoverTarget,
+ final Rect handwritingArea = mTempRect;
+ if (getViewHandwritingArea(cachedHoverTarget, handwritingArea)
+ && isInHandwritingArea(handwritingArea, hoverX, hoverY, cachedHoverTarget,
/* isHover */ true)
&& shouldTriggerStylusHandwritingForView(cachedHoverTarget)) {
return cachedHoverTarget;
@@ -445,8 +448,9 @@
// directly return the connectedView.
final View connectedView = getConnectedView();
if (connectedView != null) {
- Rect handwritingArea = getViewHandwritingArea(connectedView);
- if (isInHandwritingArea(handwritingArea, x, y, connectedView, isHover)
+ Rect handwritingArea = mTempRect;
+ if (getViewHandwritingArea(connectedView, handwritingArea)
+ && isInHandwritingArea(handwritingArea, x, y, connectedView, isHover)
&& shouldTriggerStylusHandwritingForView(connectedView)) {
return connectedView;
}
@@ -528,28 +532,30 @@
/**
* Return the handwriting area of the given view, represented in the window's coordinate.
* If the view didn't set any handwriting area, it will return the view's boundary.
- * It will return null if the view or its handwriting area is not visible.
*
- * The handwriting area is clipped to its visible part.
+ * <p> The handwriting area is clipped to its visible part.
* Notice that the returned rectangle is the view's original handwriting area without the
- * view's handwriting area extends.
+ * view's handwriting area extends. </p>
+ *
+ * @param view the {@link View} whose handwriting area we want to compute.
+ * @param rect the {@link Rect} to receive the result.
+ *
+ * @return true if the view's handwriting area is still visible, or false if it's clipped and
+ * fully invisible. This method only consider the clip by given view's parents, but not the case
+ * where a view is covered by its sibling view.
*/
- @Nullable
- private static Rect getViewHandwritingArea(@NonNull View view) {
+ private static boolean getViewHandwritingArea(@NonNull View view, @NonNull Rect rect) {
final ViewParent viewParent = view.getParent();
if (viewParent != null && view.isAttachedToWindow() && view.isAggregatedVisible()) {
final Rect localHandwritingArea = view.getHandwritingArea();
- final Rect globalHandwritingArea = new Rect();
if (localHandwritingArea != null) {
- globalHandwritingArea.set(localHandwritingArea);
+ rect.set(localHandwritingArea);
} else {
- globalHandwritingArea.set(0, 0, view.getWidth(), view.getHeight());
+ rect.set(0, 0, view.getWidth(), view.getHeight());
}
- if (viewParent.getChildVisibleRect(view, globalHandwritingArea, null)) {
- return globalHandwritingArea;
- }
+ return viewParent.getChildVisibleRect(view, rect, null);
}
- return null;
+ return false;
}
/**
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 62e37a4..b8385c6 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -1318,8 +1318,8 @@
* that have the ignore orientation request display setting enabled by OEMs
* (enables compatibility mode for fixed orientation on Android 12 (API
* level 31) or higher; see
- * <a href="https://developer.android.com/guide/topics/large-screens/large-screen-app-compatibility">
- * Large screen app compatibility</a>
+ * <a href="https://developer.android.com/guide/topics/large-screens/large-screen-compatibility-mode">
+ * Large screen compatibility mode</a>
* for more details).
*
* <p>To opt out of the user aspect ratio compatibility override, add this property
@@ -1358,8 +1358,8 @@
* that have the ignore orientation request display setting enabled by OEMs
* (enables compatibility mode for fixed orientation on Android 12 (API
* level 31) or higher; see
- * <a href="https://developer.android.com/guide/topics/large-screens/large-screen-app-compatibility">
- * Large screen app compatibility</a>
+ * <a href="https://developer.android.com/guide/topics/large-screens/large-screen-compatibility-mode">
+ * Large screen compatibility mode</a>
* for more details).
*
* <p>To opt out of the full-screen option of the user aspect ratio compatibility
diff --git a/core/java/android/window/DisplayWindowPolicyController.java b/core/java/android/window/DisplayWindowPolicyController.java
index c270053..2747233a 100644
--- a/core/java/android/window/DisplayWindowPolicyController.java
+++ b/core/java/android/window/DisplayWindowPolicyController.java
@@ -17,8 +17,10 @@
package android.window;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
+import static android.view.Display.INVALID_DISPLAY;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.WindowConfiguration;
import android.content.ComponentName;
@@ -107,18 +109,38 @@
}
/**
- * Returns {@code true} if the given activities can be displayed on this virtual display and
- * the windowing mode is supported.
+ * Returns {@code true} if all of the given activities can be launched on this virtual display
+ * in the configuration defined by the rest of the arguments.
+ *
+ * @see #canContainActivity
*/
- public abstract boolean canContainActivities(@NonNull List<ActivityInfo> activities,
- @WindowConfiguration.WindowingMode int windowingMode);
+ public boolean canContainActivities(@NonNull List<ActivityInfo> activities,
+ @WindowConfiguration.WindowingMode int windowingMode) {
+ for (int i = 0; i < activities.size(); i++) {
+ if (!canContainActivity(activities.get(i), windowingMode,
+ /*launchingFromDisplayId=*/ INVALID_DISPLAY, /*isNewTask=*/ false)) {
+ return false;
+ }
+ }
+ return true;
+ }
/**
- * Returns {@code true} if the given new task can be launched on this virtual display.
+ * Returns {@code true} if the given activity can be launched on this virtual display in the
+ * configuration defined by the rest of the arguments. If the given intent would be intercepted
+ * by the display owner then this means that the activity cannot be launched.
*/
- public abstract boolean canActivityBeLaunched(@NonNull ActivityInfo activityInfo, Intent intent,
- @WindowConfiguration.WindowingMode int windowingMode, int launchingFromDisplayId,
- boolean isNewTask);
+ public abstract boolean canActivityBeLaunched(@NonNull ActivityInfo activityInfo,
+ @Nullable Intent intent, @WindowConfiguration.WindowingMode int windowingMode,
+ int launchingFromDisplayId, boolean isNewTask);
+
+ /**
+ * Returns {@code true} if the given activity can be launched on this virtual display in the
+ * configuration defined by the rest of the arguments.
+ */
+ protected abstract boolean canContainActivity(@NonNull ActivityInfo activityInfo,
+ @WindowConfiguration.WindowingMode int windowingMode,
+ int launchingFromDisplayId, boolean isNewTask);
/**
* Called when an Activity window is layouted with the new changes where contains the
diff --git a/core/res/OWNERS b/core/res/OWNERS
index b46902e..0df7c20 100644
--- a/core/res/OWNERS
+++ b/core/res/OWNERS
@@ -52,3 +52,6 @@
# Telephony
per-file res/values/config_telephony.xml = file:/platform/frameworks/opt/telephony:/OWNERS
per-file res/xml/sms_short_codes.xml = file:/platform/frameworks/opt/telephony:/OWNERS
+
+# TV Input Framework
+per-file res/values/config_tv_external_input_logging.xml = file:/services/core/java/com/android/server/tv/OWNERS
diff --git a/core/tests/coretests/res/layout/viewgroup_test.xml b/core/tests/coretests/res/layout/viewgroup_test.xml
index 04f4f52..9b57047 100644
--- a/core/tests/coretests/res/layout/viewgroup_test.xml
+++ b/core/tests/coretests/res/layout/viewgroup_test.xml
@@ -42,8 +42,8 @@
android:id="@+id/view_translate"
android:layout_width="20dp"
android:layout_height="10dp"
- android:translationX="10dp"
- android:translationY="20dp"
+ android:translationX="10px"
+ android:translationY="20px"
android:text="Hello World!"
android:background="#2F00FF00" />
<FrameLayout
diff --git a/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java b/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java
index a923479..a41fb64 100644
--- a/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java
+++ b/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java
@@ -630,7 +630,7 @@
});
}
- @FlakyTest(bugId = 295234586)
+ @FlakyTest(bugId = 298331121)
@Test
public void testHandleConfigurationChanged_DoesntOverrideActivityConfig() {
final TestActivity activity = mActivityTestRule.launchActivity(new Intent());
@@ -836,8 +836,10 @@
}
private static ClientTransaction newRelaunchResumeTransaction(Activity activity) {
+ final Configuration currentConfig = activity.getResources().getConfiguration();
final ClientTransactionItem callbackItem = ActivityRelaunchItem.obtain(null,
- null, 0, new MergedConfiguration(), false /* preserveWindow */);
+ null, 0, new MergedConfiguration(currentConfig, currentConfig),
+ false /* preserveWindow */);
final ResumeActivityItem resumeStateRequest =
ResumeActivityItem.obtain(true /* isForward */,
false /* shouldSendCompatFakeFocus*/);
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/WindowExtensionsImpl.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/WindowExtensionsImpl.java
index 55eabb0..c3d8f9a 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/WindowExtensionsImpl.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/WindowExtensionsImpl.java
@@ -16,12 +16,14 @@
package androidx.window.extensions;
+import android.app.ActivityTaskManager;
import android.app.ActivityThread;
import android.app.Application;
import android.content.Context;
import android.window.TaskFragmentOrganizer;
import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import androidx.window.common.DeviceStateManagerFoldingFeatureProducer;
import androidx.window.common.RawFoldingFeatureProducer;
import androidx.window.extensions.area.WindowAreaComponent;
@@ -111,9 +113,13 @@
* {@link WindowExtensions#getWindowLayoutComponent()}.
* @return {@link ActivityEmbeddingComponent} OEM implementation.
*/
- @NonNull
+ @Nullable
public ActivityEmbeddingComponent getActivityEmbeddingComponent() {
if (mSplitController == null) {
+ if (!ActivityTaskManager.supportsMultiWindow(getApplication())) {
+ // Disable AE for device that doesn't support multi window.
+ return null;
+ }
synchronized (mLock) {
if (mSplitController == null) {
mSplitController = new SplitController(
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/WindowExtensionsTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/WindowExtensionsTest.java
index d189ae2..45564cb 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/WindowExtensionsTest.java
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/WindowExtensionsTest.java
@@ -16,8 +16,11 @@
package androidx.window.extensions;
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
import static com.google.common.truth.Truth.assertThat;
+import android.app.ActivityTaskManager;
import android.platform.test.annotations.Presubmit;
import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -52,7 +55,11 @@
@Test
public void testGetActivityEmbeddingComponent() {
- assertThat(mExtensions.getActivityEmbeddingComponent()).isNotNull();
+ if (ActivityTaskManager.supportsMultiWindow(getInstrumentation().getContext())) {
+ assertThat(mExtensions.getActivityEmbeddingComponent()).isNotNull();
+ } else {
+ assertThat(mExtensions.getActivityEmbeddingComponent()).isNull();
+ }
}
@Test
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
index e3922d6..018d674 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
@@ -1059,7 +1059,21 @@
private void resetPrevPip(@NonNull TransitionInfo.Change prevPipTaskChange,
@NonNull SurfaceControl.Transaction startTransaction) {
final SurfaceControl leash = prevPipTaskChange.getLeash();
- startTransaction.remove(leash);
+ final Rect bounds = prevPipTaskChange.getEndAbsBounds();
+ final Point offset = prevPipTaskChange.getEndRelOffset();
+ bounds.offset(-offset.x, -offset.y);
+
+ startTransaction.setWindowCrop(leash, null);
+ startTransaction.setMatrix(leash, 1, 0, 0, 1);
+ startTransaction.setCornerRadius(leash, 0);
+ startTransaction.setPosition(leash, bounds.left, bounds.top);
+
+ if (mHasFadeOut && prevPipTaskChange.getTaskInfo().isVisible()) {
+ if (mPipAnimationController.getCurrentAnimator() != null) {
+ mPipAnimationController.getCurrentAnimator().cancel();
+ }
+ startTransaction.setAlpha(leash, 1);
+ }
mHasFadeOut = false;
mCurrentPipTaskToken = null;
diff --git a/packages/SystemUI/animation/Android.bp b/packages/SystemUI/animation/Android.bp
index 8eb012d..6f53b42 100644
--- a/packages/SystemUI/animation/Android.bp
+++ b/packages/SystemUI/animation/Android.bp
@@ -68,5 +68,6 @@
kotlincflags: ["-Xjvm-default=all"],
// sdk_version must be specified, otherwise it compiles against private APIs.
+ min_sdk_version: "33",
sdk_version: "current",
}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt
index b3b44cb..463253b 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt
@@ -102,17 +102,19 @@
longPressViewModel: KeyguardLongPressViewModel,
modifier: Modifier = Modifier,
) {
- var settingsMenu: View? = null
+ fun findSettingsMenu(): View {
+ return viewProvider().requireViewById(R.id.keyguard_settings_button)
+ }
Box(
modifier = modifier,
) {
LongPressSurface(
viewModel = longPressViewModel,
- isSettingsMenuVisible = { settingsMenu?.isVisible == true },
+ isSettingsMenuVisible = { findSettingsMenu().isVisible },
settingsMenuBounds = {
val bounds = android.graphics.Rect()
- settingsMenu?.getHitRect(bounds)
+ findSettingsMenu().getHitRect(bounds)
bounds.toComposeRect()
},
modifier = Modifier.fillMaxSize(),
@@ -124,12 +126,8 @@
// Remove the KeyguardRootView from any parent it might already have in legacy code
// just in case (a view can't have two parents).
(keyguardRootView.parent as? ViewGroup)?.removeView(keyguardRootView)
- settingsMenu = keyguardRootView.requireViewById(R.id.keyguard_settings_button)
keyguardRootView
},
- update = { keyguardRootView ->
- keyguardRootView.requireViewById<View>(R.id.lock_icon_view)
- },
modifier = Modifier.fillMaxSize(),
)
}
diff --git a/packages/SystemUI/src/com/android/keyguard/PinShapeNonHintingView.java b/packages/SystemUI/src/com/android/keyguard/PinShapeNonHintingView.java
index 56c0953..5f33ef9 100644
--- a/packages/SystemUI/src/com/android/keyguard/PinShapeNonHintingView.java
+++ b/packages/SystemUI/src/com/android/keyguard/PinShapeNonHintingView.java
@@ -61,7 +61,7 @@
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
- if (getChildCount() > 0) {
+ if (getChildCount() > 2) {
View firstChild = getChildAt(0);
boolean isVisible = firstChild.getLocalVisibleRect(mFirstChildVisibleRect);
boolean clipped = mFirstChildVisibleRect.left > 0
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
index 845bf25..0fb1b48 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
@@ -768,7 +768,7 @@
/** Enable the share wifi button in Quick Settings internet dialog. */
@JvmField
- val SHARE_WIFI_QS_BUTTON = unreleasedFlag("share_wifi_qs_button")
+ val SHARE_WIFI_QS_BUTTON = unreleasedFlag("share_wifi_qs_button", teamfood = true)
/** Enable haptic slider component in the brightness slider */
@JvmField
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselScrollHandler.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselScrollHandler.kt
index bbb61b4..ec0c40e 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselScrollHandler.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselScrollHandler.kt
@@ -26,6 +26,7 @@
import androidx.core.view.GestureDetectorCompat
import androidx.dynamicanimation.animation.FloatPropertyCompat
import androidx.dynamicanimation.animation.SpringForce
+import com.android.internal.annotations.VisibleForTesting
import com.android.settingslib.Utils
import com.android.systemui.Gefingerpoken
import com.android.systemui.R
@@ -146,7 +147,8 @@
}
/** The touch listener for the scroll view */
- private val touchListener =
+ @VisibleForTesting
+ val touchListener =
object : Gefingerpoken {
override fun onTouchEvent(motionEvent: MotionEvent?) = onTouch(motionEvent!!)
override fun onInterceptTouchEvent(ev: MotionEvent?) = onInterceptTouch(ev!!)
@@ -279,15 +281,14 @@
} else if (isUp || motionEvent.action == MotionEvent.ACTION_CANCEL) {
// It's an up and the fling didn't take it above
val relativePos = scrollView.relativeScrollX % playerWidthPlusPadding
- val scrollXAmount: Int
- if (relativePos > playerWidthPlusPadding / 2) {
- scrollXAmount = playerWidthPlusPadding - relativePos
- } else {
- scrollXAmount = -1 * relativePos
- }
+ val scrollXAmount: Int =
+ if (isRtl xor (relativePos > playerWidthPlusPadding / 2)) {
+ playerWidthPlusPadding - relativePos
+ } else {
+ -1 * relativePos
+ }
if (scrollXAmount != 0) {
- val dx = if (isRtl) -scrollXAmount else scrollXAmount
- val newScrollX = scrollView.relativeScrollX + dx
+ val newScrollX = scrollView.relativeScrollX + scrollXAmount
// Delay the scrolling since scrollView calls springback which cancels
// the animation again..
mainExecutor.execute { scrollView.smoothScrollTo(newScrollX, scrollView.scrollY) }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinator.kt
index 5c2f9a8..62a0d13 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinator.kt
@@ -39,10 +39,7 @@
override fun attach(pipeline: NotifPipeline) {
pipeline.addOnAfterRenderListListener(::onAfterRenderList)
- // TODO(b/282865576): This has an issue where it makes changes to some groups without
- // notifying listeners. To be fixed in QPR, but for now let's comment it out to avoid the
- // group expansion bug.
- // groupExpansionManagerImpl.attach(pipeline)
+ groupExpansionManagerImpl.attach(pipeline)
}
fun onAfterRenderList(entries: List<ListEntry>, controller: NotifStackController) =
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerImpl.java
index 46af03a..eb31bd3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerImpl.java
@@ -67,18 +67,29 @@
* Cleanup entries from mExpandedGroups that no longer exist in the pipeline.
*/
private final OnBeforeRenderListListener mNotifTracker = (entries) -> {
+ if (mExpandedGroups.isEmpty()) {
+ return; // nothing to do
+ }
+
final Set<NotificationEntry> renderingSummaries = new HashSet<>();
for (ListEntry entry : entries) {
if (entry instanceof GroupEntry) {
renderingSummaries.add(entry.getRepresentativeEntry());
}
}
- mExpandedGroups.removeIf(expandedGroup -> !renderingSummaries.contains(expandedGroup));
+
+ // If a group is in mExpandedGroups but not in the pipeline entries, collapse it.
+ final var groupsToRemove = setDifference(mExpandedGroups, renderingSummaries);
+ for (NotificationEntry entry : groupsToRemove) {
+ setGroupExpanded(entry, false);
+ }
};
public void attach(NotifPipeline pipeline) {
- mDumpManager.registerDumpable(this);
- pipeline.addOnBeforeRenderListListener(mNotifTracker);
+ if (mFeatureFlags.isEnabled(Flags.NOTIFICATION_GROUP_EXPANSION_CHANGE)) {
+ mDumpManager.registerDumpable(this);
+ pipeline.addOnBeforeRenderListListener(mNotifTracker);
+ }
}
@Override
@@ -134,4 +145,27 @@
listener.onGroupExpansionChange(entry.getRow(), expanded);
}
}
+
+ /**
+ * Utility method to compute the difference between two sets of NotificationEntry. Unfortunately
+ * {@code Sets.difference} from Guava is not available in this codebase.
+ */
+ @NonNull
+ private Set<NotificationEntry> setDifference(Set<NotificationEntry> set1,
+ Set<NotificationEntry> set2) {
+ if (set1 == null || set1.isEmpty()) {
+ return new HashSet<>();
+ }
+ if (set2 == null || set2.isEmpty()) {
+ return new HashSet<>(set1);
+ }
+
+ final Set<NotificationEntry> difference = new HashSet<>();
+ for (NotificationEntry e : set1) {
+ if (!set2.contains(e)) {
+ difference.add(e);
+ }
+ }
+ return difference;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupMembershipManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupMembershipManager.java
index b9c8f72..c33e8ab 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupMembershipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupMembershipManager.java
@@ -16,6 +16,7 @@
package com.android.systemui.statusbar.notification.collection.render;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import com.android.systemui.statusbar.notification.collection.ListEntry;
@@ -31,13 +32,14 @@
* @return whether a given notification is a top level entry or is the summary in a group which
* has children
*/
- boolean isGroupSummary(NotificationEntry entry);
+ boolean isGroupSummary(@NonNull NotificationEntry entry);
/**
* Get the summary of a specified status bar notification. For an isolated notification this
* returns itself.
*/
- NotificationEntry getGroupSummary(NotificationEntry entry);
+ @Nullable
+ NotificationEntry getGroupSummary(@NonNull NotificationEntry entry);
/**
* Similar to {@link #getGroupSummary(NotificationEntry)} but doesn't get the visual summary
@@ -46,19 +48,20 @@
* TODO: remove this when migrating to the new pipeline, this is taken care of in the
* dismissal logic built into NotifCollection
*/
- default NotificationEntry getLogicalGroupSummary(NotificationEntry entry) {
+ @Nullable
+ default NotificationEntry getLogicalGroupSummary(@NonNull NotificationEntry entry) {
return getGroupSummary(entry);
}
/**
* @return whether a given notification is a child in a group
*/
- boolean isChildInGroup(NotificationEntry entry);
+ boolean isChildInGroup(@NonNull NotificationEntry entry);
/**
* Whether this is the only child in a group
*/
- boolean isOnlyChildInGroup(NotificationEntry entry);
+ boolean isOnlyChildInGroup(@NonNull NotificationEntry entry);
/**
* Get the children that are in the summary's group, not including those isolated.
@@ -67,5 +70,5 @@
* @return list of the children
*/
@Nullable
- List<NotificationEntry> getChildren(ListEntry summary);
+ List<NotificationEntry> getChildren(@NonNull ListEntry summary);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupMembershipManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupMembershipManagerImpl.java
index e784ec6..a6b855f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupMembershipManagerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/GroupMembershipManagerImpl.java
@@ -18,40 +18,65 @@
import static com.android.systemui.statusbar.notification.collection.GroupEntry.ROOT_ENTRY;
+import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.flags.FeatureFlags;
+import com.android.systemui.flags.Flags;
import com.android.systemui.statusbar.notification.collection.GroupEntry;
import com.android.systemui.statusbar.notification.collection.ListEntry;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import java.util.List;
+import javax.inject.Inject;
+
/**
* ShadeListBuilder groups notifications from system server. This manager translates
* ShadeListBuilder's method of grouping to be used within SystemUI.
*/
+@SysUISingleton
public class GroupMembershipManagerImpl implements GroupMembershipManager {
- @Override
- public boolean isGroupSummary(NotificationEntry entry) {
- return getGroupSummary(entry) == entry;
+ FeatureFlags mFeatureFlags;
+
+ @Inject
+ public GroupMembershipManagerImpl(FeatureFlags featureFlags) {
+ mFeatureFlags = featureFlags;
}
@Override
- public NotificationEntry getGroupSummary(NotificationEntry entry) {
- if (isEntryTopLevel(entry) || entry.getParent() == null) {
- return null;
+ public boolean isGroupSummary(@NonNull NotificationEntry entry) {
+ return getGroupSummary(entry) == entry;
+ }
+
+ @Nullable
+ @Override
+ public NotificationEntry getGroupSummary(@NonNull NotificationEntry entry) {
+ if (mFeatureFlags.isEnabled(Flags.NOTIFICATION_GROUP_EXPANSION_CHANGE)) {
+ if (!isChildInGroup(entry)) {
+ return entry.getRepresentativeEntry();
+ }
+ } else {
+ if (isEntryTopLevel(entry) || entry.getParent() == null) {
+ return null;
+ }
}
return entry.getParent().getRepresentativeEntry();
}
@Override
- public boolean isChildInGroup(NotificationEntry entry) {
- return !isEntryTopLevel(entry);
+ public boolean isChildInGroup(@NonNull NotificationEntry entry) {
+ if (mFeatureFlags.isEnabled(Flags.NOTIFICATION_GROUP_EXPANSION_CHANGE)) {
+ return !isEntryTopLevel(entry) && entry.getParent() != null;
+ } else {
+ return !isEntryTopLevel(entry);
+ }
}
@Override
- public boolean isOnlyChildInGroup(NotificationEntry entry) {
+ public boolean isOnlyChildInGroup(@NonNull NotificationEntry entry) {
if (entry.getParent() == null) {
return false;
}
@@ -61,20 +86,24 @@
@Nullable
@Override
- public List<NotificationEntry> getChildren(ListEntry entry) {
+ public List<NotificationEntry> getChildren(@NonNull ListEntry entry) {
if (entry instanceof GroupEntry) {
return ((GroupEntry) entry).getChildren();
}
- if (isGroupSummary(entry.getRepresentativeEntry())) {
+ NotificationEntry representativeEntry = entry.getRepresentativeEntry();
+ if (representativeEntry != null && isGroupSummary(representativeEntry)) {
// maybe we were actually passed the summary
- return entry.getRepresentativeEntry().getParent().getChildren();
+ GroupEntry parent = representativeEntry.getParent();
+ if (parent != null) {
+ return parent.getChildren();
+ }
}
return null;
}
- private boolean isEntryTopLevel(NotificationEntry entry) {
+ private boolean isEntryTopLevel(@NonNull NotificationEntry entry) {
return entry.getParent() == ROOT_ENTRY;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
index 09be41b..5664a2a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
@@ -167,11 +167,8 @@
}
/** Provides an instance of {@link GroupMembershipManager} */
- @SysUISingleton
- @Provides
- static GroupMembershipManager provideGroupMembershipManager() {
- return new GroupMembershipManagerImpl();
- }
+ @Binds
+ GroupMembershipManager provideGroupMembershipManager(GroupMembershipManagerImpl impl);
/** Provides an instance of {@link GroupExpansionManager} */
@Binds
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
index 0ff1a95..67c0c94 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
@@ -44,7 +44,6 @@
import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
import com.android.systemui.qs.QSPanelController;
import com.android.systemui.shared.system.RemoteAnimationRunnerCompat;
-import com.android.systemui.statusbar.NotificationPresenter;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.util.Compile;
@@ -183,8 +182,6 @@
return contextForUser.getPackageManager();
}
- void start();
-
boolean updateIsKeyguard();
boolean updateIsKeyguard(boolean forceStateChange);
@@ -200,8 +197,6 @@
void onKeyguardViewManagerStatesUpdated();
- NotificationPresenter getPresenter();
-
/**
* Used to dispatch initial touch events before crossing the threshold to pull down the
* notification shade. After that, since the launcher window is set to slippery, input
@@ -220,8 +215,6 @@
/** */
boolean getCommandQueuePanelsEnabled();
- BiometricUnlockController getBiometricUnlockController();
-
void showWirelessChargingAnimation(int batteryLevel);
void checkBarModes();
@@ -230,9 +223,6 @@
void setInteracting(int barWindow, boolean interacting);
- @Override
- void dump(PrintWriter pwOriginal, String[] args);
-
/** @deprecated Use {@link DisplayMetricsRepository} instead. */
@Deprecated
float getDisplayWidth();
@@ -281,8 +271,6 @@
void setBouncerShowing(boolean bouncerShowing);
- int getWakefulnessState();
-
boolean isScreenFullyOff();
void showScreenPinningRequest(int taskId, boolean allowCancel);
@@ -323,8 +311,6 @@
boolean isBouncerShowingOverDream();
- boolean isKeyguardSecure();
-
void updateNotificationPanelTouchState();
int getRotation();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesEmptyImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesEmptyImpl.kt
index 37038a3..98ba6d9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesEmptyImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesEmptyImpl.kt
@@ -23,9 +23,7 @@
import com.android.systemui.navigationbar.NavigationBarView
import com.android.systemui.plugins.ActivityStarter.OnDismissAction
import com.android.systemui.qs.QSPanelController
-import com.android.systemui.statusbar.NotificationPresenter
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
-import java.io.PrintWriter
/**
* Empty implementation of [CentralSurfaces] for variants only need to override portions of the
@@ -41,15 +39,12 @@
override fun getKeyguardMessageArea(): AuthKeyguardMessageArea? = null
override fun isLaunchingActivityOverLockscreen() = false
override fun onKeyguardViewManagerStatesUpdated() {}
- override fun getPresenter(): NotificationPresenter? = null
override fun onInputFocusTransfer(start: Boolean, cancel: Boolean, velocity: Float) {}
override fun getCommandQueuePanelsEnabled() = false
- override fun getBiometricUnlockController(): BiometricUnlockController? = null
override fun showWirelessChargingAnimation(batteryLevel: Int) {}
override fun checkBarModes() {}
override fun updateBubblesVisibility() {}
override fun setInteracting(barWindow: Int, interacting: Boolean) {}
- override fun dump(pwOriginal: PrintWriter, args: Array<String>) {}
override fun getDisplayWidth() = 0f
override fun getDisplayHeight() = 0f
override fun showKeyguard() {}
@@ -77,7 +72,6 @@
override fun showPinningEnterExitToast(entering: Boolean) {}
override fun showPinningEscapeToast() {}
override fun setBouncerShowing(bouncerShowing: Boolean) {}
- override fun getWakefulnessState() = 0
override fun isScreenFullyOff() = false
override fun showScreenPinningRequest(taskId: Int, allowCancel: Boolean) {}
override fun getEmergencyActionIntent(): Intent? = null
@@ -95,7 +89,6 @@
override fun isBouncerShowing() = false
override fun isBouncerShowingScrimmed() = false
override fun isBouncerShowingOverDream() = false
- override fun isKeyguardSecure() = false
override fun updateNotificationPanelTouchState() {}
override fun getRotation() = 0
override fun setBarStateForTest(state: Int) {}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
index b32ccbd..0277a36 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
@@ -1649,11 +1649,6 @@
logStateToEventlog();
}
- @Override
- public NotificationPresenter getPresenter() {
- return mPresenter;
- }
-
@VisibleForTesting
@Override
public void setBarStateForTest(int state) {
@@ -1728,11 +1723,6 @@
}
@Override
- public BiometricUnlockController getBiometricUnlockController() {
- return mBiometricUnlockController;
- }
-
- @Override
public void showTransientUnchecked() {
if (!mTransientShown) {
mTransientShown = true;
@@ -2486,7 +2476,7 @@
mStatusBarKeyguardViewManager.reset(true);
} else if (mState == StatusBarState.KEYGUARD
&& !mStatusBarKeyguardViewManager.primaryBouncerIsOrWillBeShowing()
- && isKeyguardSecure()) {
+ && mStatusBarKeyguardViewManager.isSecure()) {
mStatusBarKeyguardViewManager.showBouncer(true /* scrimmed */);
}
}
@@ -2825,11 +2815,6 @@
}
};
- @Override
- public int getWakefulnessState() {
- return mWakefulnessLifecycle.getWakefulness();
- }
-
/**
* @return true if the screen is currently fully off, i.e. has finished turning off and has
* since not started turning on.
@@ -2895,7 +2880,7 @@
if (mDevicePolicyManager.getCameraDisabled(null,
mLockscreenUserManager.getCurrentUserId())) {
return false;
- } else if (isKeyguardShowing() && isKeyguardSecure()) {
+ } else if (isKeyguardShowing() && mStatusBarKeyguardViewManager.isSecure()) {
// Check if the admin has disabled the camera specifically for the keyguard
return (mDevicePolicyManager.getKeyguardDisabledFeatures(null,
mLockscreenUserManager.getCurrentUserId())
@@ -3198,11 +3183,6 @@
return mBouncerShowingOverDream;
}
- @Override
- public boolean isKeyguardSecure() {
- return mStatusBarKeyguardViewManager.isSecure();
- }
-
// End Extra BaseStatusBarMethods.
boolean isTransientShown() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt
index 37f032b..2c15e27 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt
@@ -125,6 +125,7 @@
// FrameCallback used to delay starting the light reveal animation until the next frame
private val startLightRevealCallback = TraceUtils.namedRunnable("startLightReveal") {
+ lightRevealAnimationPlaying = true
lightRevealAnimator.start()
}
@@ -268,7 +269,6 @@
decidedToAnimateGoingToSleep = true
shouldAnimateInKeyguard = true
- lightRevealAnimationPlaying = true
// Start the animation on the next frame. startAnimation() is called after
// PhoneWindowManager makes a binder call to System UI on
@@ -283,7 +283,8 @@
// dispatched, a race condition could make it possible for this callback to be run
// as the device is waking up. That results in the AOD UI being shown while we wake
// up, with unpredictable consequences.
- if (!powerManager.isInteractive(Display.DEFAULT_DISPLAY)) {
+ if (!powerManager.isInteractive(Display.DEFAULT_DISPLAY) &&
+ shouldAnimateInKeyguard) {
aodUiAnimationPlaying = true
// Show AOD. That'll cause the KeyguardVisibilityHelper to call
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaCarouselScrollHandlerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaCarouselScrollHandlerTest.kt
new file mode 100644
index 0000000..49f536e
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaCarouselScrollHandlerTest.kt
@@ -0,0 +1,127 @@
+/*
+ * 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.systemui.media.controls.ui
+
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import android.view.MotionEvent
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.media.controls.util.MediaUiEventLogger
+import com.android.systemui.plugins.FalsingManager
+import com.android.systemui.qs.PageIndicator
+import com.android.systemui.util.concurrency.FakeExecutor
+import com.android.systemui.util.mockito.eq
+import com.android.systemui.util.mockito.whenever
+import com.android.systemui.util.time.FakeSystemClock
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.anyInt
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+@RunWith(AndroidTestingRunner::class)
+class MediaCarouselScrollHandlerTest : SysuiTestCase() {
+
+ private val carouselWidth = 1038
+ private val motionEventUp = MotionEvent.obtain(0, 0, MotionEvent.ACTION_UP, 0f, 0f, 0)
+
+ @Mock lateinit var mediaCarousel: MediaScrollView
+ @Mock lateinit var pageIndicator: PageIndicator
+ @Mock lateinit var dismissCallback: () -> Unit
+ @Mock lateinit var translationChangedListener: () -> Unit
+ @Mock lateinit var seekBarUpdateListener: (visibleToUser: Boolean) -> Unit
+ @Mock lateinit var closeGuts: (immediate: Boolean) -> Unit
+ @Mock lateinit var falsingManager: FalsingManager
+ @Mock lateinit var logSmartspaceImpression: (Boolean) -> Unit
+ @Mock lateinit var logger: MediaUiEventLogger
+
+ lateinit var executor: FakeExecutor
+ private val clock = FakeSystemClock()
+
+ private lateinit var mediaCarouselScrollHandler: MediaCarouselScrollHandler
+
+ @Before
+ fun setup() {
+ MockitoAnnotations.initMocks(this)
+ executor = FakeExecutor(clock)
+ mediaCarouselScrollHandler =
+ MediaCarouselScrollHandler(
+ mediaCarousel,
+ pageIndicator,
+ executor,
+ dismissCallback,
+ translationChangedListener,
+ seekBarUpdateListener,
+ closeGuts,
+ falsingManager,
+ logSmartspaceImpression,
+ logger
+ )
+ mediaCarouselScrollHandler.playerWidthPlusPadding = carouselWidth
+
+ whenever(mediaCarousel.touchListener).thenReturn(mediaCarouselScrollHandler.touchListener)
+ }
+
+ @Test
+ fun testCarouselScroll_shortScroll() {
+ whenever(mediaCarousel.isLayoutRtl).thenReturn(false)
+ whenever(mediaCarousel.relativeScrollX).thenReturn(300)
+
+ mediaCarousel.touchListener?.onTouchEvent(motionEventUp)
+ executor.runAllReady()
+
+ verify(mediaCarousel).smoothScrollTo(eq(0), anyInt())
+ }
+
+ @Test
+ fun testCarouselScroll_shortScroll_isRTL() {
+ whenever(mediaCarousel.isLayoutRtl).thenReturn(true)
+ whenever(mediaCarousel.relativeScrollX).thenReturn(300)
+
+ mediaCarousel.touchListener?.onTouchEvent(motionEventUp)
+ executor.runAllReady()
+
+ verify(mediaCarousel).smoothScrollTo(eq(carouselWidth), anyInt())
+ }
+
+ @Test
+ fun testCarouselScroll_longScroll() {
+ whenever(mediaCarousel.isLayoutRtl).thenReturn(false)
+ whenever(mediaCarousel.relativeScrollX).thenReturn(600)
+
+ mediaCarousel.touchListener?.onTouchEvent(motionEventUp)
+ executor.runAllReady()
+
+ verify(mediaCarousel).smoothScrollTo(eq(carouselWidth), anyInt())
+ }
+
+ @Test
+ fun testCarouselScroll_longScroll_isRTL() {
+ whenever(mediaCarousel.isLayoutRtl).thenReturn(true)
+ whenever(mediaCarousel.relativeScrollX).thenReturn(600)
+
+ mediaCarousel.touchListener?.onTouchEvent(motionEventUp)
+ executor.runAllReady()
+
+ verify(mediaCarousel).smoothScrollTo(eq(0), anyInt())
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ConversationCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ConversationCoordinatorTest.kt
index 55ea3157..65697b73 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ConversationCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ConversationCoordinatorTest.kt
@@ -24,6 +24,7 @@
import android.testing.TestableLooper
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
+import com.android.systemui.flags.FakeFeatureFlagsClassic
import com.android.systemui.statusbar.notification.collection.GroupEntry
import com.android.systemui.statusbar.notification.collection.GroupEntryBuilder
import com.android.systemui.statusbar.notification.collection.NotifPipeline
@@ -77,13 +78,18 @@
private lateinit var coordinator: ConversationCoordinator
+ private val featureFlags = FakeFeatureFlagsClassic()
+
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
coordinator = ConversationCoordinator(
peopleNotificationIdentifier,
conversationIconManager,
- HighPriorityProvider(peopleNotificationIdentifier, GroupMembershipManagerImpl()),
+ HighPriorityProvider(
+ peopleNotificationIdentifier,
+ GroupMembershipManagerImpl(featureFlags)
+ ),
headerController
)
whenever(channel.isImportantConversation).thenReturn(true)
@@ -182,7 +188,7 @@
}
@Test
- fun testInAlertingPeopleSectionWhenThereIsAnImportantChild(){
+ fun testInAlertingPeopleSectionWhenThereIsAnImportantChild() {
// GIVEN
val altChildA = NotificationEntryBuilder().setTag("A")
.setImportance(IMPORTANCE_DEFAULT).build()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerTest.kt
index 4a94dc8..ac2aec6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/GroupExpansionManagerTest.kt
@@ -19,13 +19,23 @@
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.dump.DumpManager
-import com.android.systemui.flags.FakeFeatureFlags
+import com.android.systemui.flags.FakeFeatureFlagsClassic
import com.android.systemui.flags.Flags
+import com.android.systemui.statusbar.notification.collection.GroupEntryBuilder
+import com.android.systemui.statusbar.notification.collection.ListEntry
+import com.android.systemui.statusbar.notification.collection.NotifPipeline
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
+import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeRenderListListener
+import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager.OnGroupExpansionChangeListener
+import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.mock
-import org.junit.Assert
+import com.android.systemui.util.mockito.withArgCaptor
+import com.google.common.truth.Truth.assertThat
import org.junit.Before
import org.junit.Test
+import org.mockito.Mockito.never
+import org.mockito.Mockito.verify
+import org.mockito.Mockito.verifyNoMoreInteractions
import org.mockito.Mockito.`when` as whenever
@SmallTest
@@ -34,15 +44,45 @@
private val dumpManager: DumpManager = mock()
private val groupMembershipManager: GroupMembershipManager = mock()
- private val featureFlags = FakeFeatureFlags()
+ private val featureFlags = FakeFeatureFlagsClassic()
- private val entry1 = NotificationEntryBuilder().build()
- private val entry2 = NotificationEntryBuilder().build()
+ private val pipeline: NotifPipeline = mock()
+ private lateinit var beforeRenderListListener: OnBeforeRenderListListener
+
+ private val summary1 = notificationEntry("foo", 1)
+ private val summary2 = notificationEntry("bar", 1)
+ private val entries =
+ listOf<ListEntry>(
+ GroupEntryBuilder()
+ .setSummary(summary1)
+ .setChildren(
+ listOf(
+ notificationEntry("foo", 2),
+ notificationEntry("foo", 3),
+ notificationEntry("foo", 4)
+ )
+ )
+ .build(),
+ GroupEntryBuilder()
+ .setSummary(summary2)
+ .setChildren(
+ listOf(
+ notificationEntry("bar", 2),
+ notificationEntry("bar", 3),
+ notificationEntry("bar", 4)
+ )
+ )
+ .build(),
+ notificationEntry("baz", 1)
+ )
+
+ private fun notificationEntry(pkg: String, id: Int) =
+ NotificationEntryBuilder().setPkg(pkg).setId(id).build().apply { row = mock() }
@Before
fun setUp() {
- whenever(groupMembershipManager.getGroupSummary(entry1)).thenReturn(entry1)
- whenever(groupMembershipManager.getGroupSummary(entry2)).thenReturn(entry2)
+ whenever(groupMembershipManager.getGroupSummary(summary1)).thenReturn(summary1)
+ whenever(groupMembershipManager.getGroupSummary(summary2)).thenReturn(summary2)
gem = GroupExpansionManagerImpl(dumpManager, groupMembershipManager, featureFlags)
}
@@ -54,16 +94,16 @@
var listenerCalledCount = 0
gem.registerGroupExpansionChangeListener { _, _ -> listenerCalledCount++ }
- gem.setGroupExpanded(entry1, false)
- Assert.assertEquals(0, listenerCalledCount)
- gem.setGroupExpanded(entry1, true)
- Assert.assertEquals(1, listenerCalledCount)
- gem.setGroupExpanded(entry2, true)
- Assert.assertEquals(2, listenerCalledCount)
- gem.setGroupExpanded(entry1, true)
- Assert.assertEquals(2, listenerCalledCount)
- gem.setGroupExpanded(entry2, false)
- Assert.assertEquals(3, listenerCalledCount)
+ gem.setGroupExpanded(summary1, false)
+ assertThat(listenerCalledCount).isEqualTo(0)
+ gem.setGroupExpanded(summary1, true)
+ assertThat(listenerCalledCount).isEqualTo(1)
+ gem.setGroupExpanded(summary2, true)
+ assertThat(listenerCalledCount).isEqualTo(2)
+ gem.setGroupExpanded(summary1, true)
+ assertThat(listenerCalledCount).isEqualTo(2)
+ gem.setGroupExpanded(summary2, false)
+ assertThat(listenerCalledCount).isEqualTo(3)
}
@Test
@@ -73,15 +113,39 @@
var listenerCalledCount = 0
gem.registerGroupExpansionChangeListener { _, _ -> listenerCalledCount++ }
- gem.setGroupExpanded(entry1, false)
- Assert.assertEquals(1, listenerCalledCount)
- gem.setGroupExpanded(entry1, true)
- Assert.assertEquals(2, listenerCalledCount)
- gem.setGroupExpanded(entry2, true)
- Assert.assertEquals(3, listenerCalledCount)
- gem.setGroupExpanded(entry1, true)
- Assert.assertEquals(4, listenerCalledCount)
- gem.setGroupExpanded(entry2, false)
- Assert.assertEquals(5, listenerCalledCount)
+ gem.setGroupExpanded(summary1, false)
+ assertThat(listenerCalledCount).isEqualTo(1)
+ gem.setGroupExpanded(summary1, true)
+ assertThat(listenerCalledCount).isEqualTo(2)
+ gem.setGroupExpanded(summary2, true)
+ assertThat(listenerCalledCount).isEqualTo(3)
+ gem.setGroupExpanded(summary1, true)
+ assertThat(listenerCalledCount).isEqualTo(4)
+ gem.setGroupExpanded(summary2, false)
+ assertThat(listenerCalledCount).isEqualTo(5)
+ }
+
+ @Test
+ fun testSyncWithPipeline() {
+ featureFlags.set(Flags.NOTIFICATION_GROUP_EXPANSION_CHANGE, true)
+ gem.attach(pipeline)
+ beforeRenderListListener = withArgCaptor {
+ verify(pipeline).addOnBeforeRenderListListener(capture())
+ }
+
+ val listener: OnGroupExpansionChangeListener = mock()
+ gem.registerGroupExpansionChangeListener(listener)
+
+ beforeRenderListListener.onBeforeRenderList(entries)
+ verify(listener, never()).onGroupExpansionChange(any(), any())
+
+ // Expand one of the groups.
+ gem.setGroupExpanded(summary1, true)
+ verify(listener).onGroupExpansionChange(summary1.row, true)
+
+ // Empty the pipeline list and verify that the group is no longer expanded.
+ beforeRenderListListener.onBeforeRenderList(emptyList())
+ verify(listener).onGroupExpansionChange(summary1.row, false)
+ verifyNoMoreInteractions(listener)
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/GroupMembershipManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/GroupMembershipManagerTest.kt
new file mode 100644
index 0000000..37ec0e0
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/GroupMembershipManagerTest.kt
@@ -0,0 +1,106 @@
+/*
+ * 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.systemui.statusbar.notification.collection.render
+
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.flags.FakeFeatureFlagsClassic
+import com.android.systemui.flags.Flags
+import com.android.systemui.statusbar.notification.collection.GroupEntry
+import com.android.systemui.statusbar.notification.collection.GroupEntryBuilder
+import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+
+@SmallTest
+class GroupMembershipManagerTest : SysuiTestCase() {
+ private lateinit var gmm: GroupMembershipManagerImpl
+
+ private val featureFlags = FakeFeatureFlagsClassic()
+
+ @Before
+ fun setUp() {
+ gmm = GroupMembershipManagerImpl(featureFlags)
+ }
+
+ @Test
+ fun testIsChildInGroup_topLevel() {
+ featureFlags.set(Flags.NOTIFICATION_GROUP_EXPANSION_CHANGE, false)
+ val topLevelEntry = NotificationEntryBuilder().setParent(GroupEntry.ROOT_ENTRY).build()
+ assertThat(gmm.isChildInGroup(topLevelEntry)).isFalse()
+ }
+
+ @Test
+ fun testIsChildInGroup_noParent_old() {
+ featureFlags.set(Flags.NOTIFICATION_GROUP_EXPANSION_CHANGE, false)
+ val noParentEntry = NotificationEntryBuilder().setParent(null).build()
+ assertThat(gmm.isChildInGroup(noParentEntry)).isTrue()
+ }
+
+ @Test
+ fun testIsChildInGroup_noParent_new() {
+ featureFlags.set(Flags.NOTIFICATION_GROUP_EXPANSION_CHANGE, true)
+ val noParentEntry = NotificationEntryBuilder().setParent(null).build()
+ assertThat(gmm.isChildInGroup(noParentEntry)).isFalse()
+ }
+
+ @Test
+ fun testIsChildInGroup_child() {
+ featureFlags.set(Flags.NOTIFICATION_GROUP_EXPANSION_CHANGE, false)
+ val childEntry = NotificationEntryBuilder().build()
+ assertThat(gmm.isChildInGroup(childEntry)).isTrue()
+ }
+
+ @Test
+ fun testIsGroupSummary() {
+ featureFlags.set(Flags.NOTIFICATION_GROUP_EXPANSION_CHANGE, true)
+ val entry = NotificationEntryBuilder().setGroupSummary(mContext, true).build()
+ assertThat(gmm.isGroupSummary(entry)).isTrue()
+ }
+
+ @Test
+ fun testGetGroupSummary() {
+ featureFlags.set(Flags.NOTIFICATION_GROUP_EXPANSION_CHANGE, true)
+
+ val summary =
+ NotificationEntryBuilder()
+ .setGroup(mContext, "group")
+ .setGroupSummary(mContext, true)
+ .build()
+ val groupEntry =
+ GroupEntryBuilder().setParent(GroupEntry.ROOT_ENTRY).setSummary(summary).build()
+ val entry =
+ NotificationEntryBuilder().setGroup(mContext, "group").setParent(groupEntry).build()
+
+ assertThat(gmm.getGroupSummary(entry)).isEqualTo(summary)
+ }
+
+ @Test
+ fun testGetGroupSummary_isSummary_old() {
+ featureFlags.set(Flags.NOTIFICATION_GROUP_EXPANSION_CHANGE, false)
+ val entry = NotificationEntryBuilder().setGroupSummary(mContext, true).build()
+ assertThat(gmm.getGroupSummary(entry)).isNull()
+ }
+
+ @Test
+ fun testGetGroupSummary_isSummary_new() {
+ featureFlags.set(Flags.NOTIFICATION_GROUP_EXPANSION_CHANGE, true)
+ val entry = NotificationEntryBuilder().setGroupSummary(mContext, true).build()
+ assertThat(gmm.getGroupSummary(entry)).isEqualTo(entry)
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationControllerTest.kt
index e76f26d..e6f8c48 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationControllerTest.kt
@@ -134,6 +134,22 @@
verify(shadeViewController, times(1)).showAodUi()
}
+ @Test
+ fun testAodUiShowNotInvokedIfWakingUp() {
+ `when`(dozeParameters.canControlUnlockedScreenOff()).thenReturn(true)
+ `when`(powerManager.isInteractive).thenReturn(false)
+
+ val callbackCaptor = ArgumentCaptor.forClass(Runnable::class.java)
+ controller.startAnimation()
+ controller.onStartedWakingUp()
+
+ verify(handler).postDelayed(callbackCaptor.capture(), anyLong())
+
+ callbackCaptor.value.run()
+
+ verify(shadeViewController, never()).showAodUi()
+ }
+
/**
* The AOD UI is shown during the screen off animation, after a delay to allow the light reveal
* animation to start. If the device is woken up during the screen off, we should *never* do
diff --git a/services/companion/java/com/android/server/companion/virtual/Android.bp b/services/companion/java/com/android/server/companion/virtual/Android.bp
index 6526c78..7a7d376 100644
--- a/services/companion/java/com/android/server/companion/virtual/Android.bp
+++ b/services/companion/java/com/android/server/companion/virtual/Android.bp
@@ -1,6 +1,9 @@
java_aconfig_library {
name: "virtualdevice_flags_lib",
aconfig_declarations: "virtualdevice_flags",
+ static_libs: [
+ "android.companion.virtual.flags-aconfig-java",
+ ],
}
aconfig_declarations {
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 34033e2..cf6092e 100644
--- a/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java
+++ b/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java
@@ -17,6 +17,7 @@
package com.android.server.companion.virtual;
import static android.content.pm.ActivityInfo.FLAG_CAN_DISPLAY_ON_REMOTE_DEVICES;
+import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowManager.LayoutParams.FLAG_SECURE;
import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
@@ -46,7 +47,6 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.BlockedAppStreamingActivity;
-import java.util.List;
import java.util.Set;
@@ -219,28 +219,37 @@
}
@Override
- public boolean canContainActivities(@NonNull List<ActivityInfo> activities,
- @WindowConfiguration.WindowingMode int windowingMode) {
- if (!isWindowingModeSupported(windowingMode)) {
+ public boolean canActivityBeLaunched(@NonNull ActivityInfo activityInfo,
+ @Nullable Intent intent, @WindowConfiguration.WindowingMode int windowingMode,
+ int launchingFromDisplayId, boolean isNewTask) {
+ if (!canContainActivity(activityInfo, windowingMode, launchingFromDisplayId, isNewTask)) {
+ mActivityBlockedCallback.onActivityBlocked(mDisplayId, activityInfo);
return false;
}
- // Can't display all the activities if any of them don't want to be displayed.
- final int activityCount = activities.size();
- for (int i = 0; i < activityCount; i++) {
- final ActivityInfo aInfo = activities.get(i);
- if (!canContainActivity(aInfo, /* windowFlags= */ 0, /* systemWindowFlags= */ 0)) {
- mActivityBlockedCallback.onActivityBlocked(mDisplayId, aInfo);
- return false;
- }
+ if (mIntentListenerCallback != null && intent != null
+ && mIntentListenerCallback.shouldInterceptIntent(intent)) {
+ Slog.d(TAG, "Virtual device intercepting intent");
+ return false;
}
return true;
}
@Override
- public boolean canActivityBeLaunched(ActivityInfo activityInfo,
- Intent intent, @WindowConfiguration.WindowingMode int windowingMode,
- int launchingFromDisplayId, boolean isNewTask) {
+ public boolean canContainActivity(@NonNull ActivityInfo activityInfo,
+ @WindowConfiguration.WindowingMode int windowingMode, int launchingFromDisplayId,
+ boolean isNewTask) {
if (!isWindowingModeSupported(windowingMode)) {
+ Slog.d(TAG, "Virtual device doesn't support windowing mode " + windowingMode);
+ return false;
+ }
+ if ((activityInfo.flags & FLAG_CAN_DISPLAY_ON_REMOTE_DEVICES) == 0) {
+ Slog.d(TAG, "Virtual device requires android:canDisplayOnRemoteDevices=true");
+ return false;
+ }
+ final UserHandle activityUser =
+ UserHandle.getUserHandleForUid(activityInfo.applicationInfo.uid);
+ if (!mAllowedUsers.contains(activityUser)) {
+ Slog.d(TAG, "Virtual device launch disallowed from user " + activityUser);
return false;
}
@@ -249,40 +258,36 @@
// The error dialog alerting users that streaming is blocked is always allowed.
return true;
}
-
- if (!canContainActivity(activityInfo, /* windowFlags= */ 0, /* systemWindowFlags= */ 0)) {
- mActivityBlockedCallback.onActivityBlocked(mDisplayId, activityInfo);
+ if (!activityMatchesDisplayCategory(activityInfo)) {
+ Slog.d(TAG, "The activity's required display category '"
+ + activityInfo.requiredDisplayCategory
+ + "' not found on virtual display with the following categories: "
+ + mDisplayCategories);
return false;
}
-
- if (launchingFromDisplayId == Display.DEFAULT_DISPLAY) {
- return true;
- }
- if (isNewTask && !mBlockedCrossTaskNavigations.isEmpty()
- && mBlockedCrossTaskNavigations.contains(activityComponent)) {
- Slog.d(TAG, "Virtual device blocking cross task navigation of " + activityComponent);
- mActivityBlockedCallback.onActivityBlocked(mDisplayId, activityInfo);
+ if ((mDefaultActivityPolicy == VirtualDeviceParams.ACTIVITY_POLICY_DEFAULT_ALLOWED
+ && mBlockedActivities.contains(activityComponent))
+ || (mDefaultActivityPolicy == VirtualDeviceParams.ACTIVITY_POLICY_DEFAULT_BLOCKED
+ && !mAllowedActivities.contains(activityComponent))) {
+ Slog.d(TAG, "Virtual device launch disallowed by policy: " + activityComponent);
return false;
}
- if (isNewTask && !mAllowedCrossTaskNavigations.isEmpty()
- && !mAllowedCrossTaskNavigations.contains(activityComponent)) {
- Slog.d(TAG, "Virtual device not allowing cross task navigation of "
- + activityComponent);
- mActivityBlockedCallback.onActivityBlocked(mDisplayId, activityInfo);
- return false;
- }
-
- if (mIntentListenerCallback != null && intent != null
- && mIntentListenerCallback.shouldInterceptIntent(intent)) {
- Slog.d(TAG, "Virtual device has intercepted intent");
- return false;
+ if (isNewTask && launchingFromDisplayId != DEFAULT_DISPLAY) {
+ if ((!mBlockedCrossTaskNavigations.isEmpty()
+ && mBlockedCrossTaskNavigations.contains(activityComponent))
+ || ((!mAllowedCrossTaskNavigations.isEmpty()
+ && !mAllowedCrossTaskNavigations.contains(activityComponent)))) {
+ Slog.d(TAG, "Virtual device cross task navigation disallowed by policy: "
+ + activityComponent);
+ return false;
+ }
}
return true;
}
-
@Override
+ @SuppressWarnings("AndroidFrameworkRequiresPermission")
public boolean keepActivityOnWindowFlagsChanged(ActivityInfo activityInfo, int windowFlags,
int systemWindowFlags) {
// The callback is fired only when windowFlags are changed. To let VirtualDevice owner
@@ -293,10 +298,17 @@
activityInfo.applicationInfo.uid));
}
- if (!canContainActivity(activityInfo, windowFlags, systemWindowFlags)) {
- mActivityBlockedCallback.onActivityBlocked(mDisplayId, activityInfo);
- return false;
+ if (!CompatChanges.isChangeEnabled(ALLOW_SECURE_ACTIVITY_DISPLAY_ON_REMOTE_DEVICE,
+ activityInfo.packageName,
+ UserHandle.getUserHandleForUid(activityInfo.applicationInfo.uid))) {
+ // TODO(b/201712607): Add checks for the apps that use SurfaceView#setSecure.
+ if ((windowFlags & FLAG_SECURE) != 0
+ || (systemWindowFlags & SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS) != 0) {
+ mActivityBlockedCallback.onActivityBlocked(mDisplayId, activityInfo);
+ return false;
+ }
}
+
return true;
}
@@ -368,53 +380,6 @@
}
- private boolean canContainActivity(ActivityInfo activityInfo, int windowFlags,
- int systemWindowFlags) {
- if ((activityInfo.flags & FLAG_CAN_DISPLAY_ON_REMOTE_DEVICES) == 0) {
- return false;
- }
- ComponentName activityComponent = activityInfo.getComponentName();
- if (BLOCKED_APP_STREAMING_COMPONENT.equals(activityComponent)) {
- // The error dialog alerting users that streaming is blocked is always allowed. Need to
- // run before the clauses below to ensure error dialog always shows up.
- return true;
- }
- if (!activityMatchesDisplayCategory(activityInfo)) {
- Slog.d(TAG, String.format(
- "The activity's required display category: %s is not found on virtual display"
- + " with the following categories: %s",
- activityInfo.requiredDisplayCategory, mDisplayCategories.toString()));
- return false;
- }
- final UserHandle activityUser =
- UserHandle.getUserHandleForUid(activityInfo.applicationInfo.uid);
- if (!mAllowedUsers.contains(activityUser)) {
- Slog.d(TAG, "Virtual device activity not allowed from user " + activityUser);
- return false;
- }
- if (mDefaultActivityPolicy == VirtualDeviceParams.ACTIVITY_POLICY_DEFAULT_ALLOWED
- && mBlockedActivities.contains(activityComponent)) {
- Slog.d(TAG, "Virtual device blocking launch of " + activityComponent);
- return false;
- }
- if (mDefaultActivityPolicy == VirtualDeviceParams.ACTIVITY_POLICY_DEFAULT_BLOCKED
- && !mAllowedActivities.contains(activityComponent)) {
- Slog.d(TAG, activityComponent + " is not in the allowed list.");
- return false;
- }
- if (!CompatChanges.isChangeEnabled(ALLOW_SECURE_ACTIVITY_DISPLAY_ON_REMOTE_DEVICE,
- activityInfo.packageName, activityUser)) {
- // TODO(b/201712607): Add checks for the apps that use SurfaceView#setSecure.
- if ((windowFlags & FLAG_SECURE) != 0) {
- return false;
- }
- if ((systemWindowFlags & SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS) != 0) {
- return false;
- }
- }
- return true;
- }
-
@VisibleForTesting
int getRunningAppsChangedListenersSizeForTesting() {
synchronized (mGenericWindowPolicyControllerLock) {
diff --git a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java
index 7429fbe..a135878 100644
--- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java
@@ -34,6 +34,7 @@
import android.companion.virtual.VirtualDevice;
import android.companion.virtual.VirtualDeviceManager;
import android.companion.virtual.VirtualDeviceParams;
+import android.companion.virtual.flags.Flags;
import android.companion.virtual.sensor.VirtualSensor;
import android.content.AttributionSource;
import android.content.Context;
@@ -323,6 +324,15 @@
@NonNull IVirtualDeviceSoundEffectListener soundEffectListener) {
createVirtualDevice_enforcePermission();
attributionSource.enforceCallingUid();
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ if (Flags.moreLogs()) {
+ Slog.i(TAG, "Creating VirtualDevice");
+ }
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+
final int callingUid = getCallingUid();
final String packageName = attributionSource.getPackageName();
if (!PermissionUtils.validateCallingPackageName(getContext(), packageName)) {
diff --git a/services/companion/java/com/android/server/companion/virtual/flags.aconfig b/services/companion/java/com/android/server/companion/virtual/flags.aconfig
index 4fe4c87..6297e91 100644
--- a/services/companion/java/com/android/server/companion/virtual/flags.aconfig
+++ b/services/companion/java/com/android/server/companion/virtual/flags.aconfig
@@ -1,3 +1,5 @@
+# OLD PACKAGE, DO NOT USE: Prefer `flags.aconfig` in core/java/android/companion/virtual
+# (or other custom files) to define your flags
package: "com.android.server.companion.virtual"
flag {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 594712f..0d265a0 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -5446,6 +5446,19 @@
intent = new Intent(Intent.ACTION_MAIN);
}
try {
+ if (allowlistToken != null) {
+ final int callingUid = Binder.getCallingUid();
+ final String packageName;
+ final long token = Binder.clearCallingIdentity();
+ try {
+ packageName = AppGlobals.getPackageManager().getNameForUid(callingUid);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ Slog.wtf(TAG, "Send a non-null allowlistToken to a non-PI target."
+ + " Calling package: " + packageName + "; intent: " + intent
+ + "; options: " + options);
+ }
target.send(code, intent, resolvedType, allowlistToken, null,
requiredPermission, options);
} catch (RemoteException e) {
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index ff35b19..bfccd58 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -3066,7 +3066,8 @@
* <p>This variable controls the retry delay, and is reset when the VPN pass network
* validation.
*/
- private int mValidationFailRetryCount = 0;
+ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
+ int mValidationFailRetryCount = 0;
/**
* The number of attempts since the last successful connection.
@@ -3897,6 +3898,18 @@
// Skip other invalid status if the scheduled recovery exists.
if (mScheduledHandleDataStallFuture != null) return;
+ // Trigger network validation on the underlying network to possibly cause system
+ // switch default network or try recover if the current default network is broken.
+ //
+ // For the same underlying network, the first validation result should clarify if
+ // it's caused by broken underlying network. So only perform underlying network
+ // re-evaluation after first validation failure to prevent extra network resource
+ // costs on sending probes.
+ if (mValidationFailRetryCount == 0) {
+ mConnectivityManager.reportNetworkConnectivity(
+ mActiveNetwork, false /* hasConnectivity */);
+ }
+
if (mValidationFailRetryCount < MAX_MOBIKE_RECOVERY_ATTEMPT) {
Log.d(TAG, "Validation failed");
diff --git a/services/core/java/com/android/server/display/DisplayDeviceConfig.java b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
index c0c60a4..e3dafa4 100644
--- a/services/core/java/com/android/server/display/DisplayDeviceConfig.java
+++ b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
@@ -282,6 +282,8 @@
* <screenBrightnessRampFastIncrease>0.02</screenBrightnessRampFastIncrease>
* <screenBrightnessRampSlowDecrease>0.03</screenBrightnessRampSlowDecrease>
* <screenBrightnessRampSlowIncrease>0.04</screenBrightnessRampSlowIncrease>
+ * <screenBrightnessRampSlowDecreaseIdle>0.05</screenBrightnessRampSlowDecreaseIdle>
+ * <screenBrightnessRampSlowIncreaseIdle>0.06</screenBrightnessRampSlowIncreaseIdle>
*
* <screenBrightnessRampIncreaseMaxMillis>2000</screenBrightnessRampIncreaseMaxMillis>
* <screenBrightnessRampDecreaseMaxMillis>3000</screenBrightnessRampDecreaseMaxMillis>
@@ -597,6 +599,8 @@
private float mBrightnessRampFastIncrease = Float.NaN;
private float mBrightnessRampSlowDecrease = Float.NaN;
private float mBrightnessRampSlowIncrease = Float.NaN;
+ private float mBrightnessRampSlowDecreaseIdle = Float.NaN;
+ private float mBrightnessRampSlowIncreaseIdle = Float.NaN;
private long mBrightnessRampDecreaseMaxMillis = 0;
private long mBrightnessRampIncreaseMaxMillis = 0;
private int mAmbientHorizonLong = AMBIENT_LIGHT_LONG_HORIZON_MILLIS;
@@ -1039,6 +1043,14 @@
return mBrightnessRampSlowIncrease;
}
+ public float getBrightnessRampSlowDecreaseIdle() {
+ return mBrightnessRampSlowDecreaseIdle;
+ }
+
+ public float getBrightnessRampSlowIncreaseIdle() {
+ return mBrightnessRampSlowIncreaseIdle;
+ }
+
public long getBrightnessRampDecreaseMaxMillis() {
return mBrightnessRampDecreaseMaxMillis;
}
@@ -1654,6 +1666,8 @@
+ ", mBrightnessRampFastIncrease=" + mBrightnessRampFastIncrease
+ ", mBrightnessRampSlowDecrease=" + mBrightnessRampSlowDecrease
+ ", mBrightnessRampSlowIncrease=" + mBrightnessRampSlowIncrease
+ + ", mBrightnessRampSlowDecreaseIdle=" + mBrightnessRampSlowDecreaseIdle
+ + ", mBrightnessRampSlowIncreaseIdle=" + mBrightnessRampSlowIncreaseIdle
+ ", mBrightnessRampDecreaseMaxMillis=" + mBrightnessRampDecreaseMaxMillis
+ ", mBrightnessRampIncreaseMaxMillis=" + mBrightnessRampIncreaseMaxMillis
+ "\n"
@@ -1845,6 +1859,8 @@
mBrightnessRampFastIncrease = PowerManager.BRIGHTNESS_MAX;
mBrightnessRampSlowDecrease = PowerManager.BRIGHTNESS_MAX;
mBrightnessRampSlowIncrease = PowerManager.BRIGHTNESS_MAX;
+ mBrightnessRampSlowDecreaseIdle = PowerManager.BRIGHTNESS_MAX;
+ mBrightnessRampSlowIncreaseIdle = PowerManager.BRIGHTNESS_MAX;
mBrightnessRampDecreaseMaxMillis = 0;
mBrightnessRampIncreaseMaxMillis = 0;
setSimpleMappingStrategyValues();
@@ -2665,6 +2681,12 @@
}
private void loadBrightnessRamps(DisplayConfiguration config) {
+ // Interactive must come first, since idle falls back to it when values are unspecified.
+ loadBrightnessRampsInteractive(config);
+ loadBrightnessRampsIdle(config);
+ }
+
+ private void loadBrightnessRampsInteractive(DisplayConfiguration config) {
// Priority 1: Value in the display device config (float)
// Priority 2: Value in the config.xml (int)
final BigDecimal fastDownDecimal = config.getScreenBrightnessRampFastDecrease();
@@ -2697,6 +2719,27 @@
}
}
+ private void loadBrightnessRampsIdle(DisplayConfiguration config) {
+ // Priority 1: Idle value in the display device config (float)
+ // Priority 2: Fallback - Interactive value from wherever.
+ final BigDecimal slowDownDecimalIdle = config.getScreenBrightnessRampSlowDecreaseIdle();
+ final BigDecimal slowUpDecimalIdle = config.getScreenBrightnessRampSlowIncreaseIdle();
+
+ if (slowDownDecimalIdle != null && slowUpDecimalIdle != null) {
+ mBrightnessRampSlowDecreaseIdle = slowDownDecimalIdle.floatValue();
+ mBrightnessRampSlowIncreaseIdle = slowUpDecimalIdle.floatValue();
+ } else {
+ if (slowDownDecimalIdle != null || slowUpDecimalIdle != null) {
+ Slog.w(TAG, "Per display idle brightness ramp values ignored because not all "
+ + "values are present in display device config");
+ }
+ // If these values don't exist, fall back to interactive mode values, since
+ // there are no idle ramp values in config.xml
+ mBrightnessRampSlowDecreaseIdle = mBrightnessRampSlowDecrease;
+ mBrightnessRampSlowIncreaseIdle = mBrightnessRampSlowIncrease;
+ }
+ }
+
private void loadBrightnessRampsFromConfigXml() {
mBrightnessRampFastIncrease = BrightnessSynchronizer.brightnessIntToFloat(
mContext.getResources().getInteger(R.integer.config_brightness_ramp_rate_fast));
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 79b7343..e6b5057 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -430,6 +430,8 @@
private float mBrightnessRampRateFastIncrease;
private float mBrightnessRampRateSlowDecrease;
private float mBrightnessRampRateSlowIncrease;
+ private float mBrightnessRampRateSlowDecreaseIdle;
+ private float mBrightnessRampRateSlowIncreaseIdle;
// Report HBM brightness change to StatsD
private int mDisplayStatsId;
@@ -1312,6 +1314,10 @@
mBrightnessRampRateFastIncrease = mDisplayDeviceConfig.getBrightnessRampFastIncrease();
mBrightnessRampRateSlowDecrease = mDisplayDeviceConfig.getBrightnessRampSlowDecrease();
mBrightnessRampRateSlowIncrease = mDisplayDeviceConfig.getBrightnessRampSlowIncrease();
+ mBrightnessRampRateSlowDecreaseIdle =
+ mDisplayDeviceConfig.getBrightnessRampSlowDecreaseIdle();
+ mBrightnessRampRateSlowIncreaseIdle =
+ mDisplayDeviceConfig.getBrightnessRampSlowIncreaseIdle();
mBrightnessRampDecreaseMaxTimeMillis =
mDisplayDeviceConfig.getBrightnessRampDecreaseMaxMillis();
mBrightnessRampIncreaseMaxTimeMillis =
@@ -1922,12 +1928,16 @@
} else {
boolean isIncreasing = animateValue > currentBrightness;
final float rampSpeed;
+ final boolean idle = mAutomaticBrightnessController != null
+ && mAutomaticBrightnessController.isInIdleMode();
if (isIncreasing && slowChange) {
- rampSpeed = mBrightnessRampRateSlowIncrease;
+ rampSpeed = idle ? mBrightnessRampRateSlowIncreaseIdle
+ : mBrightnessRampRateSlowIncrease;
} else if (isIncreasing && !slowChange) {
rampSpeed = mBrightnessRampRateFastIncrease;
} else if (!isIncreasing && slowChange) {
- rampSpeed = mBrightnessRampRateSlowDecrease;
+ rampSpeed = idle ? mBrightnessRampRateSlowDecreaseIdle
+ : mBrightnessRampRateSlowDecrease;
} else {
rampSpeed = mBrightnessRampRateFastDecrease;
}
diff --git a/services/core/java/com/android/server/display/DisplayPowerController2.java b/services/core/java/com/android/server/display/DisplayPowerController2.java
index 6c2240b..252c29d 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController2.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController2.java
@@ -357,6 +357,8 @@
private float mBrightnessRampRateFastIncrease;
private float mBrightnessRampRateSlowDecrease;
private float mBrightnessRampRateSlowIncrease;
+ private float mBrightnessRampRateSlowDecreaseIdle;
+ private float mBrightnessRampRateSlowIncreaseIdle;
// Report HBM brightness change to StatsD
private int mDisplayStatsId;
@@ -1127,6 +1129,10 @@
mBrightnessRampRateFastIncrease = mDisplayDeviceConfig.getBrightnessRampFastIncrease();
mBrightnessRampRateSlowDecrease = mDisplayDeviceConfig.getBrightnessRampSlowDecrease();
mBrightnessRampRateSlowIncrease = mDisplayDeviceConfig.getBrightnessRampSlowIncrease();
+ mBrightnessRampRateSlowDecreaseIdle =
+ mDisplayDeviceConfig.getBrightnessRampSlowDecreaseIdle();
+ mBrightnessRampRateSlowIncreaseIdle =
+ mDisplayDeviceConfig.getBrightnessRampSlowIncreaseIdle();
mBrightnessRampDecreaseMaxTimeMillis =
mDisplayDeviceConfig.getBrightnessRampDecreaseMaxMillis();
mBrightnessRampIncreaseMaxTimeMillis =
@@ -1535,12 +1541,16 @@
} else {
boolean isIncreasing = animateValue > currentBrightness;
final float rampSpeed;
+ final boolean idle = mAutomaticBrightnessController != null
+ && mAutomaticBrightnessController.isInIdleMode();
if (isIncreasing && slowChange) {
- rampSpeed = mBrightnessRampRateSlowIncrease;
+ rampSpeed = idle ? mBrightnessRampRateSlowIncreaseIdle
+ : mBrightnessRampRateSlowIncrease;
} else if (isIncreasing && !slowChange) {
rampSpeed = mBrightnessRampRateFastIncrease;
} else if (!isIncreasing && slowChange) {
- rampSpeed = mBrightnessRampRateSlowDecrease;
+ rampSpeed = idle ? mBrightnessRampRateSlowDecreaseIdle
+ : mBrightnessRampRateSlowDecrease;
} else {
rampSpeed = mBrightnessRampRateFastDecrease;
}
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index bf88580..1554072 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -2805,9 +2805,18 @@
throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
"Session not sealed");
}
- Objects.requireNonNull(mPackageName);
- Objects.requireNonNull(mSigningDetails);
- Objects.requireNonNull(mResolvedBaseFile);
+ if (mPackageName == null) {
+ throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
+ "Session no package name");
+ }
+ if (mSigningDetails == null) {
+ throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
+ "Session no signing data");
+ }
+ if (mResolvedBaseFile == null) {
+ throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
+ "Session no resolved base file");
+ }
final PackageLite result;
if (!isApexSession()) {
// For mode inherit existing, it would link/copy existing files to stage dir in
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 64e8f7a..8faadba 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -116,7 +116,11 @@
import android.content.pm.VerifierDeviceIdentity;
import android.content.pm.VersionedPackage;
import android.content.pm.overlay.OverlayPaths;
+import android.content.pm.parsing.ApkLite;
+import android.content.pm.parsing.ApkLiteParseUtils;
import android.content.pm.parsing.PackageLite;
+import android.content.pm.parsing.result.ParseResult;
+import android.content.pm.parsing.result.ParseTypeImpl;
import android.content.res.Resources;
import android.database.ContentObserver;
import android.graphics.Bitmap;
@@ -6301,33 +6305,32 @@
@Override
public ArchivedPackageParcel getArchivedPackage(String apkPath) {
- final ParsedPackage parsedPackage;
- try (PackageParser2 pp = mInjector.getPreparingPackageParser()) {
- parsedPackage = pp.parsePackage(new File(apkPath),
- getDefParseFlags() | ParsingPackageUtils.PARSE_COLLECT_CERTIFICATES, false);
- } catch (PackageManagerException e) {
- throw new IllegalArgumentException("Failed parse", e);
+ ParseTypeImpl input = ParseTypeImpl.forDefaultParsing();
+ ParseResult<ApkLite> result = ApkLiteParseUtils.parseApkLite(input.reset(),
+ new File(apkPath), ParsingPackageUtils.PARSE_COLLECT_CERTIFICATES);
+ if (result.isError()) {
+ throw new IllegalArgumentException(result.getErrorMessage(), result.getException());
}
+ final ApkLite apk = result.getResult();
ArchivedPackageParcel archPkg = new ArchivedPackageParcel();
- archPkg.packageName = parsedPackage.getPackageName();
- archPkg.signingDetails = parsedPackage.getSigningDetails();
+ archPkg.packageName = apk.getPackageName();
+ archPkg.signingDetails = apk.getSigningDetails();
- long longVersionCode = parsedPackage.getLongVersionCode();
- archPkg.versionCodeMajor = (int) (longVersionCode >> 32);
- archPkg.versionCode = (int) longVersionCode;
+ archPkg.versionCodeMajor = apk.getVersionCodeMajor();
+ archPkg.versionCode = apk.getVersionCode();
- archPkg.targetSdkVersion = parsedPackage.getTargetSdkVersion();
+ archPkg.targetSdkVersion = apk.getTargetSdkVersion();
// These get translated in flags important for user data management.
- archPkg.clearUserDataAllowed = parsedPackage.isClearUserDataAllowed();
- archPkg.backupAllowed = parsedPackage.isBackupAllowed();
+ archPkg.clearUserDataAllowed = apk.isClearUserDataAllowed();
+ archPkg.backupAllowed = apk.isBackupAllowed();
archPkg.defaultToDeviceProtectedStorage =
- parsedPackage.isDefaultToDeviceProtectedStorage();
- archPkg.requestLegacyExternalStorage = parsedPackage.isRequestLegacyExternalStorage();
- archPkg.userDataFragile = parsedPackage.isUserDataFragile();
+ apk.isDefaultToDeviceProtectedStorage();
+ archPkg.requestLegacyExternalStorage = apk.isRequestLegacyExternalStorage();
+ archPkg.userDataFragile = apk.isUserDataFragile();
archPkg.clearUserDataOnFailedRestoreAllowed =
- parsedPackage.isClearUserDataOnFailedRestoreAllowed();
+ apk.isClearUserDataOnFailedRestoreAllowed();
return archPkg;
}
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index d2adfdd..f740cf4 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -2916,11 +2916,7 @@
StringBuilder sb = new StringBuilder();
for (final PackageSetting ps : mPackages.values()) {
- // TODO(b/135203078): This doesn't handle multiple users
- final String dataPath = PackageInfoUtils.getDataDir(ps, UserHandle.USER_SYSTEM)
- .getAbsolutePath();
-
- if (ps.getPkg() == null || dataPath == null) {
+ if (ps.getPkg() == null) {
if (!"android".equals(ps.getPackageName())) {
Slog.w(TAG, "Skipping " + ps + " due to missing metadata");
}
@@ -2932,6 +2928,10 @@
continue;
}
+ // TODO(b/135203078): This doesn't handle multiple users
+ final File dataDir = PackageInfoUtils.getDataDir(ps, UserHandle.USER_SYSTEM);
+ final String dataPath = dataDir == null ? "null" : dataDir.getAbsolutePath();
+
final boolean isDebug = ps.getPkg().isDebuggable();
final IntArray gids = new IntArray();
for (final int userId : userIds) {
@@ -2973,7 +2973,7 @@
sb.append(ps.getSeInfo());
sb.append(" ");
final int gidsSize = gids.size();
- if (gids != null && gids.size() > 0) {
+ if (gids.size() > 0) {
sb.append(gids.get(0));
for (int i = 1; i < gidsSize; i++) {
sb.append(",");
@@ -4893,6 +4893,8 @@
pw.print("]");
}
pw.println();
+ File dataDir = PackageInfoUtils.getDataDir(ps, UserHandle.myUserId());
+ pw.print(prefix); pw.print(" dataDir="); pw.println(dataDir.getAbsolutePath());
if (pkg != null) {
pw.print(prefix); pw.print(" versionName="); pw.println(pkg.getVersionName());
pw.print(prefix); pw.print(" usesNonSdkApi="); pw.println(pkg.isNonSdkApiRequested());
@@ -5193,10 +5195,6 @@
pw.print(" installReason=");
pw.println(userState.getInstallReason());
- final File dataDir = PackageInfoUtils.getDataDir(ps, user.id);
- pw.print(" dataDir=");
- pw.println(dataDir == null ? "null" : dataDir.getAbsolutePath());
-
final PackageUserStateInternal pus = ps.readUserState(user.id);
pw.print(" firstInstallTime=");
date.setTime(pus.getFirstInstallTimeMillis());
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index f2797eb..259b207 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -4787,11 +4787,14 @@
// default check is for DISALLOW_ADD_USER
// If new user is of type CLONE, check if creation of clone profile is allowed
// If new user is of type MANAGED, check if creation of managed profile is allowed
+ // If new user is of type PRIVATE, check if creation of private profile is allowed
String restriction = UserManager.DISALLOW_ADD_USER;
if (UserManager.isUserTypeCloneProfile(userType)) {
restriction = UserManager.DISALLOW_ADD_CLONE_PROFILE;
} else if (UserManager.isUserTypeManagedProfile(userType)) {
restriction = UserManager.DISALLOW_ADD_MANAGED_PROFILE;
+ } else if (UserManager.isUserTypePrivateProfile(userType)) {
+ restriction = UserManager.DISALLOW_ADD_PRIVATE_PROFILE;
}
enforceUserRestriction(restriction, UserHandle.getCallingUserId(),
diff --git a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
index 4e2ceab..35861d7 100644
--- a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
+++ b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
@@ -103,6 +103,7 @@
UserManager.DISALLOW_ADD_USER,
UserManager.DISALLOW_ADD_MANAGED_PROFILE,
UserManager.DISALLOW_ADD_CLONE_PROFILE,
+ UserManager.DISALLOW_ADD_PRIVATE_PROFILE,
UserManager.ENSURE_VERIFY_APPS,
UserManager.DISALLOW_CONFIG_CELL_BROADCASTS,
UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS,
@@ -212,7 +213,8 @@
private static final Set<String> IMMUTABLE_BY_OWNERS = Sets.newArraySet(
UserManager.DISALLOW_RECORD_AUDIO,
UserManager.DISALLOW_WALLPAPER,
- UserManager.DISALLOW_OEM_UNLOCK
+ UserManager.DISALLOW_OEM_UNLOCK,
+ UserManager.DISALLOW_ADD_PRIVATE_PROFILE
);
/**
diff --git a/services/core/java/com/android/server/pm/dex/ArtManagerService.java b/services/core/java/com/android/server/pm/dex/ArtManagerService.java
index f4f03f4..31856f1 100644
--- a/services/core/java/com/android/server/pm/dex/ArtManagerService.java
+++ b/services/core/java/com/android/server/pm/dex/ArtManagerService.java
@@ -544,6 +544,11 @@
*/
public boolean compileLayouts(@NonNull PackageStateInternal ps, @NonNull AndroidPackage pkg) {
try {
+ final String packageName = pkg.getPackageName();
+ final String apkPath = pkg.getSplits().get(0).getPath();
+ // TODO(b/143971007): Use a cross-user directory
+ File dataDir = PackageInfoUtils.getDataDir(ps, UserHandle.myUserId());
+ final String outDexFile = dataDir.getAbsolutePath() + "/code_cache/compiled_view.dex";
if (ps.isPrivileged() || pkg.isUseEmbeddedDex()
|| pkg.isDefaultToDeviceProtectedStorage()) {
// Privileged apps prefer to load trusted code so they don't use compiled views.
@@ -553,14 +558,6 @@
// selinux permissions required for writing to user_de.
return false;
}
- final String packageName = pkg.getPackageName();
- final String apkPath = pkg.getSplits().get(0).getPath();
- final File dataDir = PackageInfoUtils.getDataDir(ps, UserHandle.myUserId());
- if (dataDir == null) {
- // The app is not installed on the target user and doesn't have a data dir
- return false;
- }
- final String outDexFile = dataDir.getAbsolutePath() + "/code_cache/compiled_view.dex";
Log.i("PackageManager", "Compiling layouts in " + packageName + " (" + apkPath +
") to " + outDexFile);
final long callingId = Binder.clearCallingIdentity();
diff --git a/services/core/java/com/android/server/pm/dex/ViewCompiler.java b/services/core/java/com/android/server/pm/dex/ViewCompiler.java
index c5b65a3..6405ea5 100644
--- a/services/core/java/com/android/server/pm/dex/ViewCompiler.java
+++ b/services/core/java/com/android/server/pm/dex/ViewCompiler.java
@@ -40,11 +40,8 @@
public boolean compileLayouts(PackageStateInternal ps, String apkPath) {
try {
final String packageName = ps.getPackageName();
- final File dataDir = PackageInfoUtils.getDataDir(ps, UserHandle.myUserId());
- if (dataDir == null) {
- // The app is not installed on the target user and doesn't have a data dir
- return false;
- }
+ // TODO(b/143971007): Use a cross-user directory
+ File dataDir = PackageInfoUtils.getDataDir(ps, UserHandle.myUserId());
final String outDexFile = dataDir.getAbsolutePath() + "/code_cache/compiled_view.dex";
Log.i("PackageManager", "Compiling layouts in " + packageName + " (" + apkPath +
") to " + outDexFile);
diff --git a/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java b/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java
index fc07909..27812df 100644
--- a/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java
+++ b/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java
@@ -443,7 +443,7 @@
updateApplicationInfo(info, flags, state);
- initForUser(info, pkg, userId, state);
+ initForUser(info, pkg, userId);
// TODO(b/135203078): Remove PackageParser1/toAppInfoWithoutState and clean all this up
PackageStateUnserialized pkgState = pkgSetting.getTransientState();
@@ -689,7 +689,7 @@
info.splitDependencies = pkg.getSplitDependencies().size() == 0
? null : pkg.getSplitDependencies();
- initForUser(info, pkg, userId, state);
+ initForUser(info, pkg, userId);
info.primaryCpuAbi = pkgSetting.getPrimaryCpuAbi();
info.secondaryCpuAbi = pkgSetting.getSecondaryCpuAbi();
@@ -1001,7 +1001,7 @@
}
private static void initForUser(ApplicationInfo output, AndroidPackage input,
- @UserIdInt int userId, PackageUserStateInternal state) {
+ @UserIdInt int userId) {
PackageImpl pkg = ((PackageImpl) input);
String packageName = input.getPackageName();
output.uid = UserHandle.getUid(userId, UserHandle.getAppId(input.getUid()));
@@ -1011,12 +1011,6 @@
return;
}
- if (!pkg.isSystem() && state.getCeDataInode() <= 0) {
- // The data dir has been deleted
- output.dataDir = null;
- return;
- }
-
// For performance reasons, all these paths are built as strings
if (userId == UserHandle.USER_SYSTEM) {
output.credentialProtectedDataDir =
@@ -1051,7 +1045,7 @@
// This duplicates the ApplicationInfo variant because it uses field assignment and the classes
// don't inherit from each other, unfortunately. Consolidating logic would introduce overhead.
private static void initForUser(InstrumentationInfo output, AndroidPackage input,
- @UserIdInt int userId, PackageUserStateInternal state) {
+ @UserIdInt int userId) {
PackageImpl pkg = ((PackageImpl) input);
String packageName = input.getPackageName();
if ("android".equals(packageName)) {
@@ -1059,12 +1053,6 @@
return;
}
- if (!pkg.isSystem() && state.getCeDataInode() <= 0) {
- // The data dir has been deleted
- output.dataDir = null;
- return;
- }
-
// For performance reasons, all these paths are built as strings
if (userId == UserHandle.USER_SYSTEM) {
output.credentialProtectedDataDir =
@@ -1096,21 +1084,12 @@
}
}
- /**
- * Returns the data dir of the app for the target user. Return null if the app isn't installed
- * on the target user and doesn't have a data dir on the target user.
- */
- @Nullable
+ @NonNull
public static File getDataDir(PackageStateInternal ps, int userId) {
if ("android".equals(ps.getPackageName())) {
return Environment.getDataSystemDirectory();
}
- if (!ps.isSystem() && ps.getUserStateOrDefault(userId).getCeDataInode() <= 0) {
- // The data dir has been deleted
- return null;
- }
-
if (ps.isDefaultToDeviceProtectedStorage()
&& PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) {
return Environment.getDataUserDePackageDirectory(ps.getVolumeUuid(), userId,
diff --git a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java
index d9ad353..2d55b9f 100644
--- a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java
+++ b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java
@@ -513,17 +513,21 @@
// parseBaseAppBasicFlags
pkg
// Default true
- .setBackupAllowed(true)
- .setClearUserDataAllowed(true)
- .setClearUserDataOnFailedRestoreAllowed(true)
+ .setBackupAllowed(lite.isBackupAllowed())
+ .setClearUserDataAllowed(lite.isClearUserDataAllowed())
+ .setClearUserDataOnFailedRestoreAllowed(
+ lite.isClearUserDataOnFailedRestoreAllowed())
.setAllowNativeHeapPointerTagging(true)
.setEnabled(true)
.setExtractNativeLibrariesRequested(true)
// targetSdkVersion gated
.setAllowAudioPlaybackCapture(targetSdk >= Build.VERSION_CODES.Q)
.setHardwareAccelerated(targetSdk >= Build.VERSION_CODES.ICE_CREAM_SANDWICH)
- .setRequestLegacyExternalStorage(targetSdk < Build.VERSION_CODES.Q)
+ .setRequestLegacyExternalStorage(lite.isRequestLegacyExternalStorage())
.setCleartextTrafficAllowed(targetSdk < Build.VERSION_CODES.P)
+ // Default false
+ .setDefaultToDeviceProtectedStorage(lite.isDefaultToDeviceProtectedStorage())
+ .setUserDataFragile(lite.isUserDataFragile())
// Ints
.setCategory(ApplicationInfo.CATEGORY_UNDEFINED)
// Floats Default 0f
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 6085488..90e67df 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -3363,7 +3363,11 @@
// current focused activity could be another activity in the same Task if activities are
// displayed on adjacent TaskFragments.
final ActivityRecord currentFocusedApp = mDisplayContent.mFocusedApp;
- if (currentFocusedApp != null && currentFocusedApp.task == task) {
+ final int topFocusedDisplayId = mRootWindowContainer.getTopFocusedDisplayContent() != null
+ ? mRootWindowContainer.getTopFocusedDisplayContent().getDisplayId()
+ : INVALID_DISPLAY;
+ if (currentFocusedApp != null && currentFocusedApp.task == task
+ && topFocusedDisplayId == mDisplayContent.getDisplayId()) {
final Task topFocusableTask = mDisplayContent.getTask(
(t) -> t.isLeafTask() && t.isFocusable(), true /* traverseTopToBottom */);
if (task == topFocusableTask) {
diff --git a/services/core/java/com/android/server/wm/DisplayWindowPolicyControllerHelper.java b/services/core/java/com/android/server/wm/DisplayWindowPolicyControllerHelper.java
index 2fb9869..6b33746 100644
--- a/services/core/java/com/android/server/wm/DisplayWindowPolicyControllerHelper.java
+++ b/services/core/java/com/android/server/wm/DisplayWindowPolicyControllerHelper.java
@@ -68,19 +68,15 @@
}
/**
- * @see DisplayWindowPolicyController#canContainActivities(List, int)
+ * @see DisplayWindowPolicyController#canContainActivities
*/
public boolean canContainActivities(@NonNull List<ActivityInfo> activities,
@WindowConfiguration.WindowingMode int windowingMode) {
if (mDisplayWindowPolicyController == null) {
- for (int i = activities.size() - 1; i >= 0; i--) {
- final ActivityInfo aInfo = activities.get(i);
- if (aInfo.requiredDisplayCategory != null) {
- Slog.e(TAG,
- String.format("Activity with requiredDisplayCategory='%s' cannot be"
- + " displayed on display %d because that display does"
- + " not have a matching category",
- aInfo.requiredDisplayCategory, mDisplayContent.mDisplayId));
+ for (int i = 0; i < activities.size(); ++i) {
+ // Missing controller means that this display has no categories for activity launch
+ // restriction.
+ if (hasDisplayCategory(activities.get(i))) {
return false;
}
}
@@ -90,26 +86,31 @@
}
/**
- * @see DisplayWindowPolicyController#canActivityBeLaunched(ActivityInfo, int, int, boolean)
+ * @see DisplayWindowPolicyController#canActivityBeLaunched
*/
public boolean canActivityBeLaunched(ActivityInfo activityInfo,
Intent intent, @WindowConfiguration.WindowingMode int windowingMode,
int launchingFromDisplayId, boolean isNewTask) {
if (mDisplayWindowPolicyController == null) {
- if (activityInfo.requiredDisplayCategory != null) {
- Slog.e(TAG,
- String.format("Activity with requiredDisplayCategory='%s' cannot be"
- + " launched on display %d because that display does"
- + " not have a matching category",
- activityInfo.requiredDisplayCategory, mDisplayContent.mDisplayId));
- return false;
- }
- return true;
+ // Missing controller means that this display has no categories for activity launch
+ // restriction.
+ return !hasDisplayCategory(activityInfo);
}
return mDisplayWindowPolicyController.canActivityBeLaunched(activityInfo, intent,
windowingMode, launchingFromDisplayId, isNewTask);
}
+ private boolean hasDisplayCategory(ActivityInfo aInfo) {
+ if (aInfo.requiredDisplayCategory != null) {
+ Slog.d(TAG,
+ String.format("Checking activity launch with requiredDisplayCategory='%s' on"
+ + " display %d, which doesn't have a matching category.",
+ aInfo.requiredDisplayCategory, mDisplayContent.mDisplayId));
+ return true;
+ }
+ return false;
+ }
+
/**
* @see DisplayWindowPolicyController#keepActivityOnWindowFlagsChanged(ActivityInfo, int, int)
*/
@@ -199,7 +200,6 @@
return mDisplayWindowPolicyController.isEnteringPipAllowed(uid);
}
-
void dump(String prefix, PrintWriter pw) {
if (mDisplayWindowPolicyController != null) {
pw.println();
diff --git a/services/core/xsd/display-device-config/display-device-config.xsd b/services/core/xsd/display-device-config/display-device-config.xsd
index d833fbd..d22e02e 100644
--- a/services/core/xsd/display-device-config/display-device-config.xsd
+++ b/services/core/xsd/display-device-config/display-device-config.xsd
@@ -67,6 +67,18 @@
<xs:element type="nonNegativeDecimal" name="screenBrightnessRampSlowIncrease">
<xs:annotation name="final"/>
</xs:element>
+ <!-- Ramp speed used to decrease the screen brightness when in idle mode.
+ In framework brightness units per second. Must exist with
+ screenBrightnessRampSlowIncreaseIdle-->
+ <xs:element type="nonNegativeDecimal" name="screenBrightnessRampSlowDecreaseIdle">
+ <xs:annotation name="final"/>
+ </xs:element>
+ <!-- Ramp speed used to decrease the screen brightness when in idle mode.
+ In framework brightness units per second. Must exist with
+ screenBrightnessRampSlowDecreaseIdle-->
+ <xs:element type="nonNegativeDecimal" name="screenBrightnessRampSlowIncreaseIdle">
+ <xs:annotation name="final"/>
+ </xs:element>
<!-- Maximum time in milliseconds that a brightness increase animation
can take. -->
<xs:element type="xs:nonNegativeInteger" name="screenBrightnessRampIncreaseMaxMillis">
diff --git a/services/core/xsd/display-device-config/schema/current.txt b/services/core/xsd/display-device-config/schema/current.txt
index d2ac1aae..6364c1f 100644
--- a/services/core/xsd/display-device-config/schema/current.txt
+++ b/services/core/xsd/display-device-config/schema/current.txt
@@ -115,7 +115,9 @@
method public final java.math.BigDecimal getScreenBrightnessRampFastIncrease();
method public final java.math.BigInteger getScreenBrightnessRampIncreaseMaxMillis();
method public final java.math.BigDecimal getScreenBrightnessRampSlowDecrease();
+ method public final java.math.BigDecimal getScreenBrightnessRampSlowDecreaseIdle();
method public final java.math.BigDecimal getScreenBrightnessRampSlowIncrease();
+ method public final java.math.BigDecimal getScreenBrightnessRampSlowIncreaseIdle();
method public final com.android.server.display.config.SensorDetails getScreenOffBrightnessSensor();
method public final com.android.server.display.config.IntegerArray getScreenOffBrightnessSensorValueToLux();
method @NonNull public final com.android.server.display.config.ThermalThrottling getThermalThrottling();
@@ -142,7 +144,9 @@
method public final void setScreenBrightnessRampFastIncrease(java.math.BigDecimal);
method public final void setScreenBrightnessRampIncreaseMaxMillis(java.math.BigInteger);
method public final void setScreenBrightnessRampSlowDecrease(java.math.BigDecimal);
+ method public final void setScreenBrightnessRampSlowDecreaseIdle(java.math.BigDecimal);
method public final void setScreenBrightnessRampSlowIncrease(java.math.BigDecimal);
+ method public final void setScreenBrightnessRampSlowIncreaseIdle(java.math.BigDecimal);
method public final void setScreenOffBrightnessSensor(com.android.server.display.config.SensorDetails);
method public final void setScreenOffBrightnessSensorValueToLux(com.android.server.display.config.IntegerArray);
method public final void setThermalThrottling(@NonNull com.android.server.display.config.ThermalThrottling);
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index af1bac8..2be2bb9 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -2594,6 +2594,12 @@
mUserManager.setUserRestriction(UserManager.DISALLOW_ADD_CLONE_PROFILE, true,
userHandle);
}
+ // Enforcing the restriction of private profile creation in case device owner is set.
+ if (!mUserManager.hasUserRestriction(
+ UserManager.DISALLOW_ADD_PRIVATE_PROFILE, userHandle)) {
+ mUserManager.setUserRestriction(UserManager.DISALLOW_ADD_PRIVATE_PROFILE, true,
+ userHandle);
+ }
// Creation of managed profile is restricted in case device owner is set, enforcing this
// restriction by setting user level restriction at time of device owner setup.
if (!mUserManager.hasUserRestriction(
@@ -4036,6 +4042,15 @@
mUserManager.setUserRestriction(UserManager.DISALLOW_ADD_CLONE_PROFILE,
false, user);
}
+
+ // When a device owner is set, the system automatically restricts adding a
+ // private profile.
+ // Remove this restriction when the device owner is cleared.
+ if (mUserManager.hasUserRestriction(UserManager.DISALLOW_ADD_PRIVATE_PROFILE,
+ user)) {
+ mUserManager.setUserRestriction(UserManager.DISALLOW_ADD_PRIVATE_PROFILE,
+ false, user);
+ }
}
} else {
// ManagedProvisioning/DPC sets DISALLOW_ADD_USER. Clear to recover to the original state
@@ -4061,6 +4076,15 @@
false,
userHandle);
}
+
+ // When a device owner is set, the system automatically restricts adding a
+ // private profile.
+ // Remove this restriction when the device owner is cleared.
+ if (mUserManager.hasUserRestriction(UserManager.DISALLOW_ADD_PRIVATE_PROFILE,
+ userHandle)) {
+ mUserManager.setUserRestriction(UserManager.DISALLOW_ADD_PRIVATE_PROFILE,
+ false, userHandle);
+ }
}
}
@@ -9423,6 +9447,11 @@
mUserManager.setUserRestriction(UserManager.DISALLOW_ADD_CLONE_PROFILE,
true,
UserHandle.of(u));
+
+ // Restrict adding a private profile when a device owner is set.
+ mUserManager.setUserRestriction(UserManager.DISALLOW_ADD_PRIVATE_PROFILE,
+ true,
+ UserHandle.of(u));
}
} else {
mUserManager.setUserRestriction(UserManager.DISALLOW_ADD_MANAGED_PROFILE,
@@ -9435,6 +9464,9 @@
mUserManager.setUserRestriction(UserManager.DISALLOW_ADD_CLONE_PROFILE,
true,
UserHandle.of(userId));
+ mUserManager.setUserRestriction(UserManager.DISALLOW_ADD_PRIVATE_PROFILE,
+ true,
+ UserHandle.of(userId));
}
// TODO Send to system too?
sendOwnerChangedBroadcast(DevicePolicyManager.ACTION_DEVICE_OWNER_CHANGED, userId);
@@ -13200,6 +13232,8 @@
USER_RESTRICTION_PERMISSIONS.put(
UserManager.DISALLOW_ADD_CLONE_PROFILE, new String[]{MANAGE_DEVICE_POLICY_PROFILES});
USER_RESTRICTION_PERMISSIONS.put(
+ UserManager.DISALLOW_ADD_PRIVATE_PROFILE, new String[]{MANAGE_DEVICE_POLICY_PROFILES});
+ USER_RESTRICTION_PERMISSIONS.put(
UserManager.DISALLOW_ADD_USER, new String[]{MANAGE_DEVICE_POLICY_MODIFY_USERS});
USER_RESTRICTION_PERMISSIONS.put(
UserManager.DISALLOW_ADD_WIFI_CONFIG, new String[]{MANAGE_DEVICE_POLICY_WIFI});
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java
index 7a877b9..0fc8c5e 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java
@@ -426,6 +426,7 @@
USER_RESTRICTION_FLAGS.put(UserManager.DISALLOW_ADD_USER, /* flags= */ 0);
USER_RESTRICTION_FLAGS.put(UserManager.DISALLOW_ADD_MANAGED_PROFILE, /* flags= */ 0);
USER_RESTRICTION_FLAGS.put(UserManager.DISALLOW_ADD_CLONE_PROFILE, /* flags= */ 0);
+ USER_RESTRICTION_FLAGS.put(UserManager.DISALLOW_ADD_PRIVATE_PROFILE, /* flags= */ 0);
USER_RESTRICTION_FLAGS.put(UserManager.ENSURE_VERIFY_APPS, POLICY_FLAG_GLOBAL_ONLY_POLICY);
USER_RESTRICTION_FLAGS.put(UserManager.DISALLOW_CONFIG_CELL_BROADCASTS, /* flags= */ 0);
USER_RESTRICTION_FLAGS.put(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS, /* flags= */ 0);
diff --git a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/ScanTests.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/ScanTests.java
index 98c6c42..e2939c1 100644
--- a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/ScanTests.java
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/ScanTests.java
@@ -612,9 +612,6 @@
final PackageSetting pkgSetting = scanResult.mPkgSetting;
assertBasicPackageSetting(scanResult, packageName, isInstant, pkgSetting);
- // pretend that the data dir has been set up already, so that the generated applicationInfo
- // includes the expected data dir string
- pkgSetting.setCeDataInode(/* ceDataInode= */100, /* userId= */0);
final ApplicationInfo applicationInfo = PackageInfoUtils.generateApplicationInfo(
pkgSetting.getPkg(), 0, pkgSetting.getUserStateOrDefault(0), 0, pkgSetting);
diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerController2Test.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerController2Test.java
index 4cbdd09..0195ff7 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerController2Test.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerController2Test.java
@@ -101,6 +101,8 @@
private static final float BRIGHTNESS_RAMP_RATE_FAST_INCREASE = 0.4f;
private static final float BRIGHTNESS_RAMP_RATE_SLOW_DECREASE = 0.1f;
private static final float BRIGHTNESS_RAMP_RATE_SLOW_INCREASE = 0.2f;
+ private static final float BRIGHTNESS_RAMP_RATE_SLOW_INCREASE_IDLE = 0.5f;
+ private static final float BRIGHTNESS_RAMP_RATE_SLOW_DECREASE_IDLE = 0.6f;
private OffsettableClock mClock;
private TestLooper mTestLooper;
@@ -1116,6 +1118,48 @@
verify(mDisplayWhiteBalanceControllerMock, times(1)).setStrongModeEnabled(true);
}
+ @Test
+ public void testRampRatesIdle() {
+ Settings.System.putInt(mContext.getContentResolver(),
+ Settings.System.SCREEN_BRIGHTNESS_MODE,
+ Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
+ float brightness = 0.6f;
+ when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_ON);
+ when(mHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
+ when(mHolder.automaticBrightnessController.isInIdleMode()).thenReturn(true);
+ when(mHolder.automaticBrightnessController.getAutomaticScreenBrightness(
+ any(BrightnessEvent.class))).thenReturn(brightness);
+
+ DisplayPowerRequest dpr = new DisplayPowerRequest();
+ mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+ advanceTime(1); // Run updatePowerState
+
+ verify(mHolder.animator).animateTo(eq(brightness), anyFloat(),
+ eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
+
+ when(mHolder.displayPowerState.getScreenBrightness()).thenReturn(brightness);
+ brightness = 0.05f;
+ when(mHolder.automaticBrightnessController.getAutomaticScreenBrightness(
+ any(BrightnessEvent.class))).thenReturn(brightness);
+
+ mHolder.dpc.updateBrightness();
+ advanceTime(1); // Run updatePowerState
+
+ // The second time, the animation rate should be slow
+ verify(mHolder.animator).animateTo(eq(brightness), anyFloat(),
+ eq(BRIGHTNESS_RAMP_RATE_SLOW_DECREASE_IDLE));
+
+ brightness = 0.9f;
+ when(mHolder.automaticBrightnessController.getAutomaticScreenBrightness(
+ any(BrightnessEvent.class))).thenReturn(brightness);
+
+ mHolder.dpc.updateBrightness();
+ advanceTime(1); // Run updatePowerState
+ // The third time, the animation rate should be slow
+ verify(mHolder.animator).animateTo(eq(brightness), anyFloat(),
+ eq(BRIGHTNESS_RAMP_RATE_SLOW_INCREASE_IDLE));
+ }
+
/**
* Creates a mock and registers it to {@link LocalServices}.
*/
@@ -1187,6 +1231,10 @@
.thenReturn(BRIGHTNESS_RAMP_RATE_SLOW_DECREASE);
when(displayDeviceConfigMock.getBrightnessRampSlowIncrease())
.thenReturn(BRIGHTNESS_RAMP_RATE_SLOW_INCREASE);
+ when(displayDeviceConfigMock.getBrightnessRampSlowIncreaseIdle())
+ .thenReturn(BRIGHTNESS_RAMP_RATE_SLOW_INCREASE_IDLE);
+ when(displayDeviceConfigMock.getBrightnessRampSlowDecreaseIdle())
+ .thenReturn(BRIGHTNESS_RAMP_RATE_SLOW_DECREASE_IDLE);
}
private DisplayPowerControllerHolder createDisplayPowerController(int displayId,
diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java
index 68bbcbc..f499ac5 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java
@@ -101,6 +101,8 @@
private static final float BRIGHTNESS_RAMP_RATE_FAST_INCREASE = 0.4f;
private static final float BRIGHTNESS_RAMP_RATE_SLOW_DECREASE = 0.1f;
private static final float BRIGHTNESS_RAMP_RATE_SLOW_INCREASE = 0.2f;
+ private static final float BRIGHTNESS_RAMP_RATE_SLOW_INCREASE_IDLE = 0.5f;
+ private static final float BRIGHTNESS_RAMP_RATE_SLOW_DECREASE_IDLE = 0.6f;
private OffsettableClock mClock;
private TestLooper mTestLooper;
@@ -1123,6 +1125,48 @@
verify(mDisplayWhiteBalanceControllerMock, times(1)).setStrongModeEnabled(true);
}
+ @Test
+ public void testRampRatesIdle() {
+ Settings.System.putInt(mContext.getContentResolver(),
+ Settings.System.SCREEN_BRIGHTNESS_MODE,
+ Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
+ float brightness = 0.6f;
+ when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_ON);
+ when(mHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
+ when(mHolder.automaticBrightnessController.isInIdleMode()).thenReturn(true);
+ when(mHolder.automaticBrightnessController.getAutomaticScreenBrightness(
+ any(BrightnessEvent.class))).thenReturn(brightness);
+
+ DisplayPowerRequest dpr = new DisplayPowerRequest();
+ mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+ advanceTime(1); // Run updatePowerState
+
+ verify(mHolder.animator).animateTo(eq(brightness), anyFloat(),
+ eq(BRIGHTNESS_RAMP_RATE_FAST_INCREASE));
+
+ when(mHolder.displayPowerState.getScreenBrightness()).thenReturn(brightness);
+ brightness = 0.05f;
+ when(mHolder.automaticBrightnessController.getAutomaticScreenBrightness(
+ any(BrightnessEvent.class))).thenReturn(brightness);
+
+ mHolder.dpc.updateBrightness();
+ advanceTime(1); // Run updatePowerState
+
+ // The second time, the animation rate should be slow
+ verify(mHolder.animator).animateTo(eq(brightness), anyFloat(),
+ eq(BRIGHTNESS_RAMP_RATE_SLOW_DECREASE_IDLE));
+
+ brightness = 0.9f;
+ when(mHolder.automaticBrightnessController.getAutomaticScreenBrightness(
+ any(BrightnessEvent.class))).thenReturn(brightness);
+
+ mHolder.dpc.updateBrightness();
+ advanceTime(1); // Run updatePowerState
+ // The third time, the animation rate should be slow
+ verify(mHolder.animator).animateTo(eq(brightness), anyFloat(),
+ eq(BRIGHTNESS_RAMP_RATE_SLOW_INCREASE_IDLE));
+ }
+
private void advanceTime(long timeMs) {
mClock.fastForward(timeMs);
mTestLooper.dispatchAll();
@@ -1186,6 +1230,10 @@
.thenReturn(BRIGHTNESS_RAMP_RATE_SLOW_DECREASE);
when(displayDeviceConfigMock.getBrightnessRampSlowIncrease())
.thenReturn(BRIGHTNESS_RAMP_RATE_SLOW_INCREASE);
+ when(displayDeviceConfigMock.getBrightnessRampSlowDecreaseIdle())
+ .thenReturn(BRIGHTNESS_RAMP_RATE_SLOW_DECREASE_IDLE);
+ when(displayDeviceConfigMock.getBrightnessRampSlowIncreaseIdle())
+ .thenReturn(BRIGHTNESS_RAMP_RATE_SLOW_INCREASE_IDLE);
}
private DisplayPowerControllerHolder createDisplayPowerController(int displayId,
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 00e35ec..41af9e3 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
@@ -129,7 +129,6 @@
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.Set;
import java.util.function.Consumer;
@@ -296,19 +295,20 @@
DISPLAY_ID_1);
doNothing().when(mContext).startActivityAsUser(any(), any(), any());
- ArrayList<ActivityInfo> activityInfos = getActivityInfoList(
+ ActivityInfo activityInfo = getActivityInfo(
NONBLOCKED_APP_PACKAGE_NAME,
NONBLOCKED_APP_PACKAGE_NAME,
/* displayOnRemoveDevices= */ true,
targetDisplayCategory);
Intent blockedAppIntent = BlockedAppStreamingActivity.createIntent(
- activityInfos.get(0), mAssociationInfo.getDisplayName());
- gwpc.canContainActivities(activityInfos, WindowConfiguration.WINDOWING_MODE_FULLSCREEN);
+ activityInfo, mAssociationInfo.getDisplayName());
+ gwpc.canActivityBeLaunched(activityInfo, blockedAppIntent,
+ WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /*isNewTask=*/false);
return blockedAppIntent;
}
- private ArrayList<ActivityInfo> getActivityInfoList(
+ private ActivityInfo getActivityInfo(
String packageName, String name, boolean displayOnRemoveDevices,
String requiredDisplayCategory) {
ActivityInfo activityInfo = new ActivityInfo();
@@ -318,7 +318,7 @@
? FLAG_CAN_DISPLAY_ON_REMOTE_DEVICES : FLAG_CANNOT_DISPLAY_ON_REMOTE_DEVICES;
activityInfo.applicationInfo = mApplicationInfoMock;
activityInfo.requiredDisplayCategory = requiredDisplayCategory;
- return new ArrayList<>(Arrays.asList(activityInfo));
+ return activityInfo;
}
@Before
@@ -1414,14 +1414,15 @@
DISPLAY_ID_1);
doNothing().when(mContext).startActivityAsUser(any(), any(), any());
- ArrayList<ActivityInfo> activityInfos = getActivityInfoList(
+ ActivityInfo activityInfo = getActivityInfo(
NONBLOCKED_APP_PACKAGE_NAME,
NONBLOCKED_APP_PACKAGE_NAME,
/* displayOnRemoveDevices */ true,
/* targetDisplayCategory */ null);
Intent blockedAppIntent = BlockedAppStreamingActivity.createIntent(
- activityInfos.get(0), mAssociationInfo.getDisplayName());
- gwpc.canContainActivities(activityInfos, WindowConfiguration.WINDOWING_MODE_FULLSCREEN);
+ activityInfo, mAssociationInfo.getDisplayName());
+ gwpc.canActivityBeLaunched(activityInfo, blockedAppIntent,
+ WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /*isNewTask=*/false);
verify(mContext, never()).startActivityAsUser(argThat(intent ->
intent.filterEquals(blockedAppIntent)), any(), any());
@@ -1434,14 +1435,15 @@
DISPLAY_ID_1);
doNothing().when(mContext).startActivityAsUser(any(), any(), any());
- ArrayList<ActivityInfo> activityInfos = getActivityInfoList(
+ ActivityInfo activityInfo = getActivityInfo(
PERMISSION_CONTROLLER_PACKAGE_NAME,
PERMISSION_CONTROLLER_PACKAGE_NAME,
/* displayOnRemoveDevices */ false,
/* targetDisplayCategory */ null);
Intent blockedAppIntent = BlockedAppStreamingActivity.createIntent(
- activityInfos.get(0), mAssociationInfo.getDisplayName());
- gwpc.canContainActivities(activityInfos, WindowConfiguration.WINDOWING_MODE_FULLSCREEN);
+ activityInfo, mAssociationInfo.getDisplayName());
+ gwpc.canActivityBeLaunched(activityInfo, blockedAppIntent,
+ WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /*isNewTask=*/false);
verify(mContext).startActivityAsUser(argThat(intent ->
intent.filterEquals(blockedAppIntent)), any(), any());
@@ -1454,14 +1456,15 @@
DISPLAY_ID_1);
doNothing().when(mContext).startActivityAsUser(any(), any(), any());
- ArrayList<ActivityInfo> activityInfos = getActivityInfoList(
+ ActivityInfo activityInfo = getActivityInfo(
SETTINGS_PACKAGE_NAME,
SETTINGS_PACKAGE_NAME,
/* displayOnRemoveDevices */ true,
/* targetDisplayCategory */ null);
Intent blockedAppIntent = BlockedAppStreamingActivity.createIntent(
- activityInfos.get(0), mAssociationInfo.getDisplayName());
- gwpc.canContainActivities(activityInfos, WindowConfiguration.WINDOWING_MODE_FULLSCREEN);
+ activityInfo, mAssociationInfo.getDisplayName());
+ gwpc.canActivityBeLaunched(activityInfo, blockedAppIntent,
+ WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /*isNewTask=*/false);
verify(mContext).startActivityAsUser(argThat(intent ->
intent.filterEquals(blockedAppIntent)), any(), any());
@@ -1474,14 +1477,15 @@
DISPLAY_ID_1);
doNothing().when(mContext).startActivityAsUser(any(), any(), any());
- ArrayList<ActivityInfo> activityInfos = getActivityInfoList(
+ ActivityInfo activityInfo = getActivityInfo(
VENDING_PACKAGE_NAME,
VENDING_PACKAGE_NAME,
/* displayOnRemoveDevices */ true,
/* targetDisplayCategory */ null);
Intent blockedAppIntent = BlockedAppStreamingActivity.createIntent(
- activityInfos.get(0), mAssociationInfo.getDisplayName());
- gwpc.canContainActivities(activityInfos, WindowConfiguration.WINDOWING_MODE_FULLSCREEN);
+ activityInfo, mAssociationInfo.getDisplayName());
+ gwpc.canActivityBeLaunched(activityInfo, blockedAppIntent,
+ WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /*isNewTask=*/false);
verify(mContext).startActivityAsUser(argThat(intent ->
intent.filterEquals(blockedAppIntent)), any(), any());
@@ -1494,14 +1498,15 @@
DISPLAY_ID_1);
doNothing().when(mContext).startActivityAsUser(any(), any(), any());
- ArrayList<ActivityInfo> activityInfos = getActivityInfoList(
+ ActivityInfo activityInfo = getActivityInfo(
GOOGLE_DIALER_PACKAGE_NAME,
GOOGLE_DIALER_PACKAGE_NAME,
/* displayOnRemoveDevices */ true,
/* targetDisplayCategory */ null);
Intent blockedAppIntent = BlockedAppStreamingActivity.createIntent(
- activityInfos.get(0), mAssociationInfo.getDisplayName());
- gwpc.canContainActivities(activityInfos, WindowConfiguration.WINDOWING_MODE_FULLSCREEN);
+ activityInfo, mAssociationInfo.getDisplayName());
+ gwpc.canActivityBeLaunched(activityInfo, blockedAppIntent,
+ WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /*isNewTask=*/false);
verify(mContext).startActivityAsUser(argThat(intent ->
intent.filterEquals(blockedAppIntent)), any(), any());
@@ -1514,14 +1519,15 @@
DISPLAY_ID_1);
doNothing().when(mContext).startActivityAsUser(any(), any(), any());
- ArrayList<ActivityInfo> activityInfos = getActivityInfoList(
+ ActivityInfo activityInfo = getActivityInfo(
GOOGLE_MAPS_PACKAGE_NAME,
GOOGLE_MAPS_PACKAGE_NAME,
/* displayOnRemoveDevices */ true,
/* targetDisplayCategory */ null);
Intent blockedAppIntent = BlockedAppStreamingActivity.createIntent(
- activityInfos.get(0), mAssociationInfo.getDisplayName());
- gwpc.canContainActivities(activityInfos, WindowConfiguration.WINDOWING_MODE_FULLSCREEN);
+ activityInfo, mAssociationInfo.getDisplayName());
+ gwpc.canActivityBeLaunched(activityInfo, blockedAppIntent,
+ WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /*isNewTask=*/false);
verify(mContext).startActivityAsUser(argThat(intent ->
intent.filterEquals(blockedAppIntent)), any(), any());
@@ -1561,12 +1567,12 @@
addVirtualDisplay(mDeviceImpl, DISPLAY_ID_1);
GenericWindowPolicyController gwpc = mDeviceImpl.getDisplayWindowPolicyControllerForTest(
DISPLAY_ID_1);
- ArrayList<ActivityInfo> activityInfos = getActivityInfoList(
+ ActivityInfo activityInfo = getActivityInfo(
NONBLOCKED_APP_PACKAGE_NAME,
NONBLOCKED_APP_PACKAGE_NAME,
/* displayOnRemoveDevices */ true,
/* targetDisplayCategory */ null);
- assertThat(gwpc.canActivityBeLaunched(activityInfos.get(0), intent,
+ assertThat(gwpc.canActivityBeLaunched(activityInfo, intent,
WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /*isNewTask=*/false))
.isTrue();
}
@@ -1585,7 +1591,7 @@
addVirtualDisplay(mDeviceImpl, DISPLAY_ID_1);
GenericWindowPolicyController gwpc = mDeviceImpl.getDisplayWindowPolicyControllerForTest(
DISPLAY_ID_1);
- ArrayList<ActivityInfo> activityInfos = getActivityInfoList(
+ ActivityInfo activityInfo = getActivityInfo(
NONBLOCKED_APP_PACKAGE_NAME,
NONBLOCKED_APP_PACKAGE_NAME,
/* displayOnRemoveDevices */ true,
@@ -1597,7 +1603,7 @@
// register interceptor and intercept intent
mDeviceImpl.registerIntentInterceptor(interceptor, intentFilter);
- assertThat(gwpc.canActivityBeLaunched(activityInfos.get(0), intent,
+ assertThat(gwpc.canActivityBeLaunched(activityInfo, intent,
WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /*isNewTask=*/false))
.isFalse();
ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
@@ -1609,7 +1615,7 @@
// unregister interceptor and launch activity
mDeviceImpl.unregisterIntentInterceptor(interceptor);
- assertThat(gwpc.canActivityBeLaunched(activityInfos.get(0), intent,
+ assertThat(gwpc.canActivityBeLaunched(activityInfo, intent,
WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /*isNewTask=*/false))
.isTrue();
}
@@ -1628,7 +1634,7 @@
addVirtualDisplay(mDeviceImpl, DISPLAY_ID_1);
GenericWindowPolicyController gwpc = mDeviceImpl.getDisplayWindowPolicyControllerForTest(
DISPLAY_ID_1);
- ArrayList<ActivityInfo> activityInfos = getActivityInfoList(
+ ActivityInfo activityInfo = getActivityInfo(
NONBLOCKED_APP_PACKAGE_NAME,
NONBLOCKED_APP_PACKAGE_NAME,
/* displayOnRemoveDevices */ true,
@@ -1640,7 +1646,7 @@
// register interceptor with different filter
mDeviceImpl.registerIntentInterceptor(interceptor, intentFilter);
- assertThat(gwpc.canActivityBeLaunched(activityInfos.get(0), intent,
+ assertThat(gwpc.canActivityBeLaunched(activityInfo, intent,
WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /*isNewTask=*/false))
.isTrue();
}
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
index f408ef0..f4dac2c 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -1144,6 +1144,10 @@
eq(UserManager.DISALLOW_ADD_CLONE_PROFILE),
eq(true), eq(UserHandle.SYSTEM));
+ verify(getServices().userManager, times(1)).setUserRestriction(
+ eq(UserManager.DISALLOW_ADD_PRIVATE_PROFILE),
+ eq(true), eq(UserHandle.SYSTEM));
+
verify(mContext.spiedContext, times(1)).sendBroadcastAsUser(
MockUtils.checkIntentAction(DevicePolicyManager.ACTION_DEVICE_OWNER_CHANGED),
MockUtils.checkUserHandle(UserHandle.USER_SYSTEM));
@@ -1422,6 +1426,10 @@
.setUserRestriction(eq(UserManager.DISALLOW_ADD_CLONE_PROFILE), eq(false),
MockUtils.checkUserHandle(UserHandle.USER_SYSTEM));
+ verify(getServices().userManager)
+ .setUserRestriction(eq(UserManager.DISALLOW_ADD_PRIVATE_PROFILE), eq(false),
+ MockUtils.checkUserHandle(UserHandle.USER_SYSTEM));
+
verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
eq(UserHandle.USER_SYSTEM), MockUtils.checkUserRestrictions(),
MockUtils.checkUserRestrictions(UserHandle.USER_SYSTEM), eq(true));
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
index ecd35a5..b22798e 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
@@ -1174,6 +1174,24 @@
}
}
+ // Make sure the creation of a private profile fails if DISALLOW_ADD_PRIVATE_PROFILE is true.
+ @MediumTest
+ @Test
+ public void testCreateProfileForUser_disallowAddPrivateProfile() {
+ final int mainUserId = ActivityManager.getCurrentUser();
+ final UserHandle mainUserHandle = asHandle(mainUserId);
+ mUserManager.setUserRestriction(UserManager.DISALLOW_ADD_PRIVATE_PROFILE,
+ true, mainUserHandle);
+ try {
+ UserInfo privateProfileInfo = createProfileForUser("Private",
+ UserManager.USER_TYPE_PROFILE_PRIVATE, mainUserId);
+ assertThat(privateProfileInfo).isNull();
+ } finally {
+ mUserManager.setUserRestriction(UserManager.DISALLOW_ADD_PRIVATE_PROFILE, false,
+ mainUserHandle);
+ }
+ }
+
@MediumTest
@Test
public void testAddRestrictedProfile() throws Exception {
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserRestrictionsUtilsTest.java b/services/tests/servicestests/src/com/android/server/pm/UserRestrictionsUtilsTest.java
index a387d4a..9907bd6 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserRestrictionsUtilsTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserRestrictionsUtilsTest.java
@@ -72,6 +72,8 @@
public void testCanDeviceOwnerChange() {
assertFalse(UserRestrictionsUtils.canDeviceOwnerChange(UserManager.DISALLOW_RECORD_AUDIO));
assertFalse(UserRestrictionsUtils.canDeviceOwnerChange(UserManager.DISALLOW_WALLPAPER));
+ assertFalse(UserRestrictionsUtils.canDeviceOwnerChange(
+ UserManager.DISALLOW_ADD_PRIVATE_PROFILE));
assertTrue(UserRestrictionsUtils.canDeviceOwnerChange(UserManager.DISALLOW_ADD_USER));
assertTrue(UserRestrictionsUtils.canDeviceOwnerChange(UserManager.DISALLOW_USER_SWITCH));
}
@@ -83,6 +85,8 @@
UserManager.DISALLOW_WALLPAPER, true));
assertFalse(UserRestrictionsUtils.canProfileOwnerChange(
UserManager.DISALLOW_USER_SWITCH, true));
+ assertFalse(UserRestrictionsUtils.canProfileOwnerChange(
+ UserManager.DISALLOW_ADD_PRIVATE_PROFILE, true));
assertTrue(UserRestrictionsUtils.canProfileOwnerChange(
UserManager.DISALLOW_ADD_USER, true));
assertTrue(UserRestrictionsUtils.canProfileOwnerChange(
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowPolicyControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowPolicyControllerTests.java
index 5dfb901..30a8941 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowPolicyControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowPolicyControllerTests.java
@@ -44,7 +44,6 @@
import org.junit.Test;
import org.junit.runner.RunWith;
-import java.util.List;
import java.util.Set;
/**
@@ -106,7 +105,6 @@
assertEquals(uidAmount, mDwpc.mRunningUids.size());
assertTrue(mDwpc.mRunningUids.contains(TEST_USER_0_ID) == expectedUid0);
assertTrue(mDwpc.mRunningUids.contains(TEST_USER_1_ID) == expectedUid1);
-
}
private ActivityRecord launchActivityOnDisplay(DisplayContent display, int uid) {
@@ -197,6 +195,11 @@
@Test
public void testCanActivityBeLaunched_requiredDisplayCategory() {
+ doReturn(null).when(mWm.mDisplayManagerInternal)
+ .getDisplayWindowPolicyController(anyInt());
+ mSecondaryDisplay = createNewDisplay();
+ assertFalse(mSecondaryDisplay.mDwpcHelper.hasController());
+
ActivityStarter starter = new ActivityStarter(mock(ActivityStartController.class), mAtm,
mSupervisor, mock(ActivityStartInterceptor.class));
final Task task = new TaskBuilder(mSupervisor).setDisplay(mSecondaryDisplay).build();
@@ -233,20 +236,14 @@
public boolean canActivityBeLaunched(@NonNull ActivityInfo activity, Intent intent,
@WindowConfiguration.WindowingMode int windowingMode, int launchingFromDisplayId,
boolean isNewTask) {
- return false;
+ return canContainActivity(activity, windowingMode, launchingFromDisplayId, isNewTask);
}
@Override
- public boolean canContainActivities(@NonNull List<ActivityInfo> activities,
- @WindowConfiguration.WindowingMode int windowingMode) {
- final int activityCount = activities.size();
- for (int i = 0; i < activityCount; i++) {
- final ActivityInfo aInfo = activities.get(i);
- if (aInfo.getComponentName().equals(DISALLOWED_ACTIVITY)) {
- return false;
- }
- }
- return true;
+ protected boolean canContainActivity(@NonNull ActivityInfo activity,
+ @WindowConfiguration.WindowingMode int windowingMode, int launchingFromDisplayId,
+ boolean isNewTask) {
+ return !activity.getComponentName().equals(DISALLOWED_ACTIVITY);
}
@Override
diff --git a/telephony/java/android/telephony/satellite/SatelliteManager.java b/telephony/java/android/telephony/satellite/SatelliteManager.java
index 9994002a..75b5f55 100644
--- a/telephony/java/android/telephony/satellite/SatelliteManager.java
+++ b/telephony/java/android/telephony/satellite/SatelliteManager.java
@@ -101,26 +101,26 @@
}
/**
- * Exception from the satellite service containing the {@link SatelliteError} error code.
+ * Exception from the satellite service containing the {@link SatelliteResult} error code.
*/
public static class SatelliteException extends Exception {
- @SatelliteError private final int mErrorCode;
+ @SatelliteResult private final int mErrorCode;
/**
* Create a SatelliteException with a given error code.
*
- * @param errorCode The {@link SatelliteError}.
+ * @param errorCode The {@link SatelliteResult}.
*/
- public SatelliteException(@SatelliteError int errorCode) {
+ public SatelliteException(@SatelliteResult int errorCode) {
mErrorCode = errorCode;
}
/**
* Get the error code returned from the satellite service.
*
- * @return The {@link SatelliteError}.
+ * @return The {@link SatelliteResult}.
*/
- @SatelliteError public int getErrorCode() {
+ @SatelliteResult public int getErrorCode() {
return mErrorCode;
}
}
@@ -185,134 +185,134 @@
/**
* The request was successfully processed.
*/
- public static final int SATELLITE_ERROR_NONE = 0;
+ public static final int SATELLITE_RESULT_SUCCESS = 0;
/**
* A generic error which should be used only when other specific errors cannot be used.
*/
- public static final int SATELLITE_ERROR = 1;
+ public static final int SATELLITE_RESULT_ERROR = 1;
/**
* Error received from the satellite server.
*/
- public static final int SATELLITE_SERVER_ERROR = 2;
+ public static final int SATELLITE_RESULT_SERVER_ERROR = 2;
/**
* Error received from the vendor service. This generic error code should be used
* only when the error cannot be mapped to other specific service error codes.
*/
- public static final int SATELLITE_SERVICE_ERROR = 3;
+ public static final int SATELLITE_RESULT_SERVICE_ERROR = 3;
/**
* Error received from satellite modem. This generic error code should be used only when
* the error cannot be mapped to other specific modem error codes.
*/
- public static final int SATELLITE_MODEM_ERROR = 4;
+ public static final int SATELLITE_RESULT_MODEM_ERROR = 4;
/**
* Error received from the satellite network. This generic error code should be used only when
* the error cannot be mapped to other specific network error codes.
*/
- public static final int SATELLITE_NETWORK_ERROR = 5;
+ public static final int SATELLITE_RESULT_NETWORK_ERROR = 5;
/**
* Telephony is not in a valid state to receive requests from clients.
*/
- public static final int SATELLITE_INVALID_TELEPHONY_STATE = 6;
+ public static final int SATELLITE_RESULT_INVALID_TELEPHONY_STATE = 6;
/**
* Satellite modem is not in a valid state to receive requests from clients.
*/
- public static final int SATELLITE_INVALID_MODEM_STATE = 7;
+ public static final int SATELLITE_RESULT_INVALID_MODEM_STATE = 7;
/**
* Either vendor service, or modem, or Telephony framework has received a request with
* invalid arguments from its clients.
*/
- public static final int SATELLITE_INVALID_ARGUMENTS = 8;
+ public static final int SATELLITE_RESULT_INVALID_ARGUMENTS = 8;
/**
* Telephony framework failed to send a request or receive a response from the vendor service
* or satellite modem due to internal error.
*/
- public static final int SATELLITE_REQUEST_FAILED = 9;
+ public static final int SATELLITE_RESULT_REQUEST_FAILED = 9;
/**
* Radio did not start or is resetting.
*/
- public static final int SATELLITE_RADIO_NOT_AVAILABLE = 10;
+ public static final int SATELLITE_RESULT_RADIO_NOT_AVAILABLE = 10;
/**
* The request is not supported by either the satellite modem or the network.
*/
- public static final int SATELLITE_REQUEST_NOT_SUPPORTED = 11;
+ public static final int SATELLITE_RESULT_REQUEST_NOT_SUPPORTED = 11;
/**
* Satellite modem or network has no resources available to handle requests from clients.
*/
- public static final int SATELLITE_NO_RESOURCES = 12;
+ public static final int SATELLITE_RESULT_NO_RESOURCES = 12;
/**
* Satellite service is not provisioned yet.
*/
- public static final int SATELLITE_SERVICE_NOT_PROVISIONED = 13;
+ public static final int SATELLITE_RESULT_SERVICE_NOT_PROVISIONED = 13;
/**
* Satellite service provision is already in progress.
*/
- public static final int SATELLITE_SERVICE_PROVISION_IN_PROGRESS = 14;
+ public static final int SATELLITE_RESULT_SERVICE_PROVISION_IN_PROGRESS = 14;
/**
* The ongoing request was aborted by either the satellite modem or the network.
* This error is also returned when framework decides to abort current send request as one
* of the previous send request failed.
*/
- public static final int SATELLITE_REQUEST_ABORTED = 15;
+ public static final int SATELLITE_RESULT_REQUEST_ABORTED = 15;
/**
* The device/subscriber is barred from accessing the satellite service.
*/
- public static final int SATELLITE_ACCESS_BARRED = 16;
+ public static final int SATELLITE_RESULT_ACCESS_BARRED = 16;
/**
* Satellite modem timeout to receive ACK or response from the satellite network after
* sending a request to the network.
*/
- public static final int SATELLITE_NETWORK_TIMEOUT = 17;
+ public static final int SATELLITE_RESULT_NETWORK_TIMEOUT = 17;
/**
* Satellite network is not reachable from the modem.
*/
- public static final int SATELLITE_NOT_REACHABLE = 18;
+ public static final int SATELLITE_RESULT_NOT_REACHABLE = 18;
/**
* The device/subscriber is not authorized to register with the satellite service provider.
*/
- public static final int SATELLITE_NOT_AUTHORIZED = 19;
+ public static final int SATELLITE_RESULT_NOT_AUTHORIZED = 19;
/**
* The device does not support satellite.
*/
- public static final int SATELLITE_NOT_SUPPORTED = 20;
+ public static final int SATELLITE_RESULT_NOT_SUPPORTED = 20;
/**
* The current request is already in-progress.
*/
- public static final int SATELLITE_REQUEST_IN_PROGRESS = 21;
+ public static final int SATELLITE_RESULT_REQUEST_IN_PROGRESS = 21;
/**
* Satellite modem is currently busy due to which current request cannot be processed.
*/
- public static final int SATELLITE_MODEM_BUSY = 22;
+ public static final int SATELLITE_RESULT_MODEM_BUSY = 22;
/** @hide */
- @IntDef(prefix = {"SATELLITE_"}, value = {
- SATELLITE_ERROR_NONE,
- SATELLITE_ERROR,
- SATELLITE_SERVER_ERROR,
- SATELLITE_SERVICE_ERROR,
- SATELLITE_MODEM_ERROR,
- SATELLITE_NETWORK_ERROR,
- SATELLITE_INVALID_TELEPHONY_STATE,
- SATELLITE_INVALID_MODEM_STATE,
- SATELLITE_INVALID_ARGUMENTS,
- SATELLITE_REQUEST_FAILED,
- SATELLITE_RADIO_NOT_AVAILABLE,
- SATELLITE_REQUEST_NOT_SUPPORTED,
- SATELLITE_NO_RESOURCES,
- SATELLITE_SERVICE_NOT_PROVISIONED,
- SATELLITE_SERVICE_PROVISION_IN_PROGRESS,
- SATELLITE_REQUEST_ABORTED,
- SATELLITE_ACCESS_BARRED,
- SATELLITE_NETWORK_TIMEOUT,
- SATELLITE_NOT_REACHABLE,
- SATELLITE_NOT_AUTHORIZED,
- SATELLITE_NOT_SUPPORTED,
- SATELLITE_REQUEST_IN_PROGRESS,
- SATELLITE_MODEM_BUSY
+ @IntDef(prefix = {"SATELLITE_RESULT_"}, value = {
+ SATELLITE_RESULT_SUCCESS,
+ SATELLITE_RESULT_ERROR,
+ SATELLITE_RESULT_SERVER_ERROR,
+ SATELLITE_RESULT_SERVICE_ERROR,
+ SATELLITE_RESULT_MODEM_ERROR,
+ SATELLITE_RESULT_NETWORK_ERROR,
+ SATELLITE_RESULT_INVALID_TELEPHONY_STATE,
+ SATELLITE_RESULT_INVALID_MODEM_STATE,
+ SATELLITE_RESULT_INVALID_ARGUMENTS,
+ SATELLITE_RESULT_REQUEST_FAILED,
+ SATELLITE_RESULT_RADIO_NOT_AVAILABLE,
+ SATELLITE_RESULT_REQUEST_NOT_SUPPORTED,
+ SATELLITE_RESULT_NO_RESOURCES,
+ SATELLITE_RESULT_SERVICE_NOT_PROVISIONED,
+ SATELLITE_RESULT_SERVICE_PROVISION_IN_PROGRESS,
+ SATELLITE_RESULT_REQUEST_ABORTED,
+ SATELLITE_RESULT_ACCESS_BARRED,
+ SATELLITE_RESULT_NETWORK_TIMEOUT,
+ SATELLITE_RESULT_NOT_REACHABLE,
+ SATELLITE_RESULT_NOT_AUTHORIZED,
+ SATELLITE_RESULT_NOT_SUPPORTED,
+ SATELLITE_RESULT_REQUEST_IN_PROGRESS,
+ SATELLITE_RESULT_MODEM_BUSY
})
@Retention(RetentionPolicy.SOURCE)
- public @interface SatelliteError {}
+ public @interface SatelliteResult {}
/**
* Unknown Non-Terrestrial radio technology. This generic radio technology should be used
@@ -403,7 +403,7 @@
* {@code false} to disable.
* @param enableDemoMode {@code true} to enable demo mode and {@code false} to disable.
* @param executor The executor on which the error code listener will be called.
- * @param resultListener Listener for the {@link SatelliteError} result of the operation.
+ * @param resultListener Listener for the {@link SatelliteResult} result of the operation.
*
* @throws SecurityException if the caller doesn't have required permission.
* @throws IllegalStateException if the Telephony process is not currently available.
@@ -412,7 +412,7 @@
public void requestSatelliteEnabled(boolean enableSatellite, boolean enableDemoMode,
@NonNull @CallbackExecutor Executor executor,
- @SatelliteError @NonNull Consumer<Integer> resultListener) {
+ @SatelliteResult @NonNull Consumer<Integer> resultListener) {
Objects.requireNonNull(executor);
Objects.requireNonNull(resultListener);
@@ -446,7 +446,7 @@
* will return a {@code boolean} with value {@code true} if the satellite modem
* is enabled and {@code false} otherwise.
* If the request is not successful, {@link OutcomeReceiver#onError(Throwable)}
- * will return a {@link SatelliteException} with the {@link SatelliteError}.
+ * will return a {@link SatelliteException} with the {@link SatelliteResult}.
*
* @throws SecurityException if the caller doesn't have required permission.
* @throws IllegalStateException if the Telephony process is not currently available.
@@ -464,7 +464,7 @@
ResultReceiver receiver = new ResultReceiver(null) {
@Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
- if (resultCode == SATELLITE_ERROR_NONE) {
+ if (resultCode == SATELLITE_RESULT_SUCCESS) {
if (resultData.containsKey(KEY_SATELLITE_ENABLED)) {
boolean isSatelliteEnabled =
resultData.getBoolean(KEY_SATELLITE_ENABLED);
@@ -473,8 +473,8 @@
} else {
loge("KEY_SATELLITE_ENABLED does not exist.");
executor.execute(() -> Binder.withCleanCallingIdentity(() ->
- callback.onError(
- new SatelliteException(SATELLITE_REQUEST_FAILED))));
+ callback.onError(new SatelliteException(
+ SATELLITE_RESULT_REQUEST_FAILED))));
}
} else {
executor.execute(() -> Binder.withCleanCallingIdentity(() ->
@@ -501,7 +501,7 @@
* will return a {@code boolean} with value {@code true} if demo mode is enabled
* and {@code false} otherwise.
* If the request is not successful, {@link OutcomeReceiver#onError(Throwable)}
- * will return a {@link SatelliteException} with the {@link SatelliteError}.
+ * will return a {@link SatelliteException} with the {@link SatelliteResult}.
*
* @throws SecurityException if the caller doesn't have required permission.
* @throws IllegalStateException if the Telephony process is not currently available.
@@ -519,7 +519,7 @@
ResultReceiver receiver = new ResultReceiver(null) {
@Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
- if (resultCode == SATELLITE_ERROR_NONE) {
+ if (resultCode == SATELLITE_RESULT_SUCCESS) {
if (resultData.containsKey(KEY_DEMO_MODE_ENABLED)) {
boolean isDemoModeEnabled =
resultData.getBoolean(KEY_DEMO_MODE_ENABLED);
@@ -528,8 +528,8 @@
} else {
loge("KEY_DEMO_MODE_ENABLED does not exist.");
executor.execute(() -> Binder.withCleanCallingIdentity(() ->
- callback.onError(
- new SatelliteException(SATELLITE_REQUEST_FAILED))));
+ callback.onError(new SatelliteException(
+ SATELLITE_RESULT_REQUEST_FAILED))));
}
} else {
executor.execute(() -> Binder.withCleanCallingIdentity(() ->
@@ -556,7 +556,7 @@
* will return a {@code boolean} with value {@code true} if the satellite
* service is supported on the device and {@code false} otherwise.
* If the request is not successful, {@link OutcomeReceiver#onError(Throwable)}
- * will return a {@link SatelliteException} with the {@link SatelliteError}.
+ * will return a {@link SatelliteException} with the {@link SatelliteResult}.
*
* @throws IllegalStateException if the Telephony process is not currently available.
*/
@@ -572,7 +572,7 @@
ResultReceiver receiver = new ResultReceiver(null) {
@Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
- if (resultCode == SATELLITE_ERROR_NONE) {
+ if (resultCode == SATELLITE_RESULT_SUCCESS) {
if (resultData.containsKey(KEY_SATELLITE_SUPPORTED)) {
boolean isSatelliteSupported =
resultData.getBoolean(KEY_SATELLITE_SUPPORTED);
@@ -581,8 +581,8 @@
} else {
loge("KEY_SATELLITE_SUPPORTED does not exist.");
executor.execute(() -> Binder.withCleanCallingIdentity(() ->
- callback.onError(
- new SatelliteException(SATELLITE_REQUEST_FAILED))));
+ callback.onError(new SatelliteException(
+ SATELLITE_RESULT_REQUEST_FAILED))));
}
} else {
executor.execute(() -> Binder.withCleanCallingIdentity(() ->
@@ -608,7 +608,7 @@
* If the request is successful, {@link OutcomeReceiver#onResult(Object)}
* will return the {@link SatelliteCapabilities} of the satellite service.
* If the request is not successful, {@link OutcomeReceiver#onError(Throwable)}
- * will return a {@link SatelliteException} with the {@link SatelliteError}.
+ * will return a {@link SatelliteException} with the {@link SatelliteResult}.
*
* @throws SecurityException if the caller doesn't have required permission.
* @throws IllegalStateException if the Telephony process is not currently available.
@@ -626,7 +626,7 @@
ResultReceiver receiver = new ResultReceiver(null) {
@Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
- if (resultCode == SATELLITE_ERROR_NONE) {
+ if (resultCode == SATELLITE_RESULT_SUCCESS) {
if (resultData.containsKey(KEY_SATELLITE_CAPABILITIES)) {
SatelliteCapabilities capabilities =
resultData.getParcelable(KEY_SATELLITE_CAPABILITIES,
@@ -636,8 +636,8 @@
} else {
loge("KEY_SATELLITE_CAPABILITIES does not exist.");
executor.execute(() -> Binder.withCleanCallingIdentity(() ->
- callback.onError(
- new SatelliteException(SATELLITE_REQUEST_FAILED))));
+ callback.onError(new SatelliteException(
+ SATELLITE_RESULT_REQUEST_FAILED))));
}
} else {
executor.execute(() -> Binder.withCleanCallingIdentity(() ->
@@ -794,13 +794,13 @@
* Start receiving satellite transmission updates.
* This can be called by the pointing UI when the user starts pointing to the satellite.
* Modem should continue to report the pointing input as the device or satellite moves.
- * Satellite transmission updates are started only on {@link #SATELLITE_ERROR_NONE}.
+ * Satellite transmission updates are started only on {@link #SATELLITE_RESULT_SUCCESS}.
* All other results indicate that this operation failed.
* Once satellite transmission updates begin, position and datagram transfer state updates
* will be sent through {@link SatelliteTransmissionUpdateCallback}.
*
* @param executor The executor on which the callback and error code listener will be called.
- * @param resultListener Listener for the {@link SatelliteError} result of the operation.
+ * @param resultListener Listener for the {@link SatelliteResult} result of the operation.
* @param callback The callback to notify of satellite transmission updates.
*
* @throws SecurityException if the caller doesn't have required permission.
@@ -809,7 +809,7 @@
@RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
public void startSatelliteTransmissionUpdates(@NonNull @CallbackExecutor Executor executor,
- @SatelliteError @NonNull Consumer<Integer> resultListener,
+ @SatelliteResult @NonNull Consumer<Integer> resultListener,
@NonNull SatelliteTransmissionUpdateCallback callback) {
Objects.requireNonNull(executor);
Objects.requireNonNull(resultListener);
@@ -866,12 +866,12 @@
* Stop receiving satellite transmission updates.
* This can be called by the pointing UI when the user stops pointing to the satellite.
* Satellite transmission updates are stopped and the callback is unregistered only on
- * {@link #SATELLITE_ERROR_NONE}. All other results that this operation failed.
+ * {@link #SATELLITE_RESULT_SUCCESS}. All other results that this operation failed.
*
* @param callback The callback that was passed to {@link
* #startSatelliteTransmissionUpdates(Executor, Consumer, SatelliteTransmissionUpdateCallback)}.
* @param executor The executor on which the error code listener will be called.
- * @param resultListener Listener for the {@link SatelliteError} result of the operation.
+ * @param resultListener Listener for the {@link SatelliteResult} result of the operation.
*
* @throws SecurityException if the caller doesn't have required permission.
* @throws IllegalStateException if the Telephony process is not currently available.
@@ -881,7 +881,7 @@
public void stopSatelliteTransmissionUpdates(
@NonNull SatelliteTransmissionUpdateCallback callback,
@NonNull @CallbackExecutor Executor executor,
- @SatelliteError @NonNull Consumer<Integer> resultListener) {
+ @SatelliteResult @NonNull Consumer<Integer> resultListener) {
Objects.requireNonNull(callback);
Objects.requireNonNull(executor);
Objects.requireNonNull(resultListener);
@@ -905,7 +905,7 @@
} else {
loge("stopSatelliteTransmissionUpdates: No internal callback.");
executor.execute(() -> Binder.withCleanCallingIdentity(
- () -> resultListener.accept(SATELLITE_INVALID_ARGUMENTS)));
+ () -> resultListener.accept(SATELLITE_RESULT_INVALID_ARGUMENTS)));
}
} else {
throw new IllegalStateException("telephony service is null.");
@@ -927,7 +927,7 @@
* request. Even when the cancellation is signaled, Telephony will
* still trigger the callback to return the result of this request.
* @param executor The executor on which the error code listener will be called.
- * @param resultListener Listener for the {@link SatelliteError} result of the operation.
+ * @param resultListener Listener for the {@link SatelliteResult} result of the operation.
*
* @throws SecurityException if the caller doesn't have required permission.
* @throws IllegalStateException if the Telephony process is not currently available.
@@ -937,7 +937,7 @@
public void provisionSatelliteService(@NonNull String token, @NonNull byte[] provisionData,
@Nullable CancellationSignal cancellationSignal,
@NonNull @CallbackExecutor Executor executor,
- @SatelliteError @NonNull Consumer<Integer> resultListener) {
+ @SatelliteResult @NonNull Consumer<Integer> resultListener) {
Objects.requireNonNull(token);
Objects.requireNonNull(executor);
Objects.requireNonNull(resultListener);
@@ -980,7 +980,7 @@
* This should match with the token passed as input in
* {@link #provisionSatelliteService(String, byte[], CancellationSignal, Executor,
* Consumer)}
- * @param resultListener Listener for the {@link SatelliteError} result of the operation.
+ * @param resultListener Listener for the {@link SatelliteResult} result of the operation.
*
* @throws SecurityException if the caller doesn't have required permission.
* @throws IllegalStateException if the Telephony process is not currently available.
@@ -989,7 +989,7 @@
public void deprovisionSatelliteService(@NonNull String token,
@NonNull @CallbackExecutor Executor executor,
- @SatelliteError @NonNull Consumer<Integer> resultListener) {
+ @SatelliteResult @NonNull Consumer<Integer> resultListener) {
Objects.requireNonNull(token);
Objects.requireNonNull(executor);
Objects.requireNonNull(resultListener);
@@ -1020,14 +1020,14 @@
* @param executor The executor on which the callback will be called.
* @param callback The callback to handle the satellite provision state changed event.
*
- * @return The {@link SatelliteError} result of the operation.
+ * @return The {@link SatelliteResult} result of the operation.
*
* @throws SecurityException if the caller doesn't have required permission.
* @throws IllegalStateException if the Telephony process is not currently available.
*/
@RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
- @SatelliteError public int registerForSatelliteProvisionStateChanged(
+ @SatelliteResult public int registerForSatelliteProvisionStateChanged(
@NonNull @CallbackExecutor Executor executor,
@NonNull SatelliteProvisionStateCallback callback) {
Objects.requireNonNull(executor);
@@ -1055,7 +1055,7 @@
loge("registerForSatelliteProvisionStateChanged() RemoteException: " + ex);
ex.rethrowFromSystemServer();
}
- return SATELLITE_REQUEST_FAILED;
+ return SATELLITE_RESULT_REQUEST_FAILED;
}
/**
@@ -1102,7 +1102,7 @@
* will return a {@code boolean} with value {@code true} if the device is
* provisioned with a satellite provider and {@code false} otherwise.
* If the request is not successful, {@link OutcomeReceiver#onError(Throwable)}
- * will return a {@link SatelliteException} with the {@link SatelliteError}.
+ * will return a {@link SatelliteException} with the {@link SatelliteResult}.
*
* @throws SecurityException if the caller doesn't have required permission.
* @throws IllegalStateException if the Telephony process is not currently available.
@@ -1120,7 +1120,7 @@
ResultReceiver receiver = new ResultReceiver(null) {
@Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
- if (resultCode == SATELLITE_ERROR_NONE) {
+ if (resultCode == SATELLITE_RESULT_SUCCESS) {
if (resultData.containsKey(KEY_SATELLITE_PROVISIONED)) {
boolean isSatelliteProvisioned =
resultData.getBoolean(KEY_SATELLITE_PROVISIONED);
@@ -1129,8 +1129,8 @@
} else {
loge("KEY_SATELLITE_PROVISIONED does not exist.");
executor.execute(() -> Binder.withCleanCallingIdentity(() ->
- callback.onError(
- new SatelliteException(SATELLITE_REQUEST_FAILED))));
+ callback.onError(new SatelliteException(
+ SATELLITE_RESULT_REQUEST_FAILED))));
}
} else {
executor.execute(() -> Binder.withCleanCallingIdentity(() ->
@@ -1154,14 +1154,14 @@
* @param executor The executor on which the callback will be called.
* @param callback The callback to handle the satellite modem state changed event.
*
- * @return The {@link SatelliteError} result of the operation.
+ * @return The {@link SatelliteResult} result of the operation.
*
* @throws SecurityException if the caller doesn't have required permission.
* @throws IllegalStateException if the Telephony process is not currently available.
*/
@RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
- @SatelliteError public int registerForSatelliteModemStateChanged(
+ @SatelliteResult public int registerForSatelliteModemStateChanged(
@NonNull @CallbackExecutor Executor executor,
@NonNull SatelliteStateCallback callback) {
Objects.requireNonNull(executor);
@@ -1186,7 +1186,7 @@
loge("registerForSatelliteModemStateChanged() RemoteException:" + ex);
ex.rethrowFromSystemServer();
}
- return SATELLITE_REQUEST_FAILED;
+ return SATELLITE_RESULT_REQUEST_FAILED;
}
/**
@@ -1232,14 +1232,14 @@
* @param callback The callback to handle incoming datagrams over satellite.
* This callback with be invoked when a new datagram is received from satellite.
*
- * @return The {@link SatelliteError} result of the operation.
+ * @return The {@link SatelliteResult} result of the operation.
*
* @throws SecurityException if the caller doesn't have required permission.
* @throws IllegalStateException if the Telephony process is not currently available.
*/
@RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
- @SatelliteError public int registerForSatelliteDatagram(
+ @SatelliteResult public int registerForSatelliteDatagram(
@NonNull @CallbackExecutor Executor executor,
@NonNull SatelliteDatagramCallback callback) {
Objects.requireNonNull(executor);
@@ -1280,7 +1280,7 @@
loge("registerForSatelliteDatagram() RemoteException:" + ex);
ex.rethrowFromSystemServer();
}
- return SATELLITE_REQUEST_FAILED;
+ return SATELLITE_RESULT_REQUEST_FAILED;
}
/**
@@ -1327,7 +1327,7 @@
* Consumer)} )}
*
* @param executor The executor on which the result listener will be called.
- * @param resultListener Listener for the {@link SatelliteError} result of the operation.
+ * @param resultListener Listener for the {@link SatelliteResult} result of the operation.
*
* @throws SecurityException if the caller doesn't have required permission.
* @throws IllegalStateException if the Telephony process is not currently available.
@@ -1335,7 +1335,7 @@
@RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
public void pollPendingSatelliteDatagrams(@NonNull @CallbackExecutor Executor executor,
- @SatelliteError @NonNull Consumer<Integer> resultListener) {
+ @SatelliteResult @NonNull Consumer<Integer> resultListener) {
Objects.requireNonNull(executor);
Objects.requireNonNull(resultListener);
@@ -1380,7 +1380,7 @@
* user activity and the application's ability to determine the
* best possible UX experience for the user.
* @param executor The executor on which the result listener will be called.
- * @param resultListener Listener for the {@link SatelliteError} result of the operation.
+ * @param resultListener Listener for the {@link SatelliteResult} result of the operation.
*
* @throws SecurityException if the caller doesn't have required permission.
* @throws IllegalStateException if the Telephony process is not currently available.
@@ -1390,7 +1390,7 @@
public void sendSatelliteDatagram(@DatagramType int datagramType,
@NonNull SatelliteDatagram datagram, boolean needFullScreenPointingUI,
@NonNull @CallbackExecutor Executor executor,
- @SatelliteError @NonNull Consumer<Integer> resultListener) {
+ @SatelliteResult @NonNull Consumer<Integer> resultListener) {
Objects.requireNonNull(datagram);
Objects.requireNonNull(executor);
Objects.requireNonNull(resultListener);
@@ -1426,7 +1426,7 @@
* communication is allowed for the current location and
* {@code false} otherwise.
* If the request is not successful, {@link OutcomeReceiver#onError(Throwable)}
- * will return a {@link SatelliteException} with the {@link SatelliteError}.
+ * will return a {@link SatelliteException} with the {@link SatelliteResult}.
*
* @throws SecurityException if the caller doesn't have required permission.
* @throws IllegalStateException if the Telephony process is not currently available.
@@ -1445,7 +1445,7 @@
ResultReceiver receiver = new ResultReceiver(null) {
@Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
- if (resultCode == SATELLITE_ERROR_NONE) {
+ if (resultCode == SATELLITE_RESULT_SUCCESS) {
if (resultData.containsKey(KEY_SATELLITE_COMMUNICATION_ALLOWED)) {
boolean isSatelliteCommunicationAllowed =
resultData.getBoolean(KEY_SATELLITE_COMMUNICATION_ALLOWED);
@@ -1454,8 +1454,8 @@
} else {
loge("KEY_SATELLITE_COMMUNICATION_ALLOWED does not exist.");
executor.execute(() -> Binder.withCleanCallingIdentity(() ->
- callback.onError(
- new SatelliteException(SATELLITE_REQUEST_FAILED))));
+ callback.onError(new SatelliteException(
+ SATELLITE_RESULT_REQUEST_FAILED))));
}
} else {
executor.execute(() -> Binder.withCleanCallingIdentity(() ->
@@ -1484,7 +1484,7 @@
* If the request is successful, {@link OutcomeReceiver#onResult(Object)}
* will return the time after which the satellite will be visible.
* If the request is not successful, {@link OutcomeReceiver#onError(Throwable)}
- * will return a {@link SatelliteException} with the {@link SatelliteError}.
+ * will return a {@link SatelliteException} with the {@link SatelliteResult}.
*
* @throws SecurityException if the caller doesn't have required permission.
* @throws IllegalStateException if the Telephony process is not currently available.
@@ -1502,7 +1502,7 @@
ResultReceiver receiver = new ResultReceiver(null) {
@Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
- if (resultCode == SATELLITE_ERROR_NONE) {
+ if (resultCode == SATELLITE_RESULT_SUCCESS) {
if (resultData.containsKey(KEY_SATELLITE_NEXT_VISIBILITY)) {
int nextVisibilityDuration =
resultData.getInt(KEY_SATELLITE_NEXT_VISIBILITY);
@@ -1512,8 +1512,8 @@
} else {
loge("KEY_SATELLITE_NEXT_VISIBILITY does not exist.");
executor.execute(() -> Binder.withCleanCallingIdentity(() ->
- callback.onError(
- new SatelliteException(SATELLITE_REQUEST_FAILED))));
+ callback.onError(new SatelliteException(
+ SATELLITE_RESULT_REQUEST_FAILED))));
}
} else {
executor.execute(() -> Binder.withCleanCallingIdentity(() ->
diff --git a/telephony/java/android/telephony/satellite/SatelliteTransmissionUpdateCallback.java b/telephony/java/android/telephony/satellite/SatelliteTransmissionUpdateCallback.java
index d7d892a..7ac06b0 100644
--- a/telephony/java/android/telephony/satellite/SatelliteTransmissionUpdateCallback.java
+++ b/telephony/java/android/telephony/satellite/SatelliteTransmissionUpdateCallback.java
@@ -43,7 +43,7 @@
*/
void onSendDatagramStateChanged(
@SatelliteManager.SatelliteDatagramTransferState int state, int sendPendingCount,
- @SatelliteManager.SatelliteError int errorCode);
+ @SatelliteManager.SatelliteResult int errorCode);
/**
* Called when satellite datagram receive state changed.
@@ -54,5 +54,5 @@
*/
void onReceiveDatagramStateChanged(
@SatelliteManager.SatelliteDatagramTransferState int state, int receivePendingCount,
- @SatelliteManager.SatelliteError int errorCode);
+ @SatelliteManager.SatelliteResult int errorCode);
}
diff --git a/telephony/java/android/telephony/satellite/stub/ISatelliteListener.aidl b/telephony/java/android/telephony/satellite/stub/ISatelliteListener.aidl
index 5e69215..d687162 100644
--- a/telephony/java/android/telephony/satellite/stub/ISatelliteListener.aidl
+++ b/telephony/java/android/telephony/satellite/stub/ISatelliteListener.aidl
@@ -19,7 +19,6 @@
import android.telephony.satellite.stub.NTRadioTechnology;
import android.telephony.satellite.stub.PointingInfo;
import android.telephony.satellite.stub.SatelliteDatagram;
-import android.telephony.satellite.stub.SatelliteError;
import android.telephony.satellite.stub.SatelliteModemState;
/**
diff --git a/telephony/java/android/telephony/satellite/stub/SatelliteError.aidl b/telephony/java/android/telephony/satellite/stub/SatelliteResult.aidl
similarity index 77%
rename from telephony/java/android/telephony/satellite/stub/SatelliteError.aidl
rename to telephony/java/android/telephony/satellite/stub/SatelliteResult.aidl
index 6a110a9..639b483 100644
--- a/telephony/java/android/telephony/satellite/stub/SatelliteError.aidl
+++ b/telephony/java/android/telephony/satellite/stub/SatelliteResult.aidl
@@ -20,91 +20,87 @@
* {@hide}
*/
@Backing(type="int")
-enum SatelliteError {
+enum SatelliteResult {
/**
* The request was successfully processed.
*/
- ERROR_NONE = 0,
+ SATELLITE_RESULT_SUCCESS = 0,
/**
* A generic error which should be used only when other specific errors cannot be used.
*/
- SATELLITE_ERROR = 1,
+ SATELLITE_RESULT_ERROR = 1,
/**
* Error received from the satellite server.
*/
- SERVER_ERROR = 2,
+ SATELLITE_RESULT_SERVER_ERROR = 2,
/**
* Error received from the vendor service. This generic error code should be used
* only when the error cannot be mapped to other specific service error codes.
*/
- SERVICE_ERROR = 3,
+ SATELLITE_RESULT_SERVICE_ERROR = 3,
/**
* Error received from satellite modem. This generic error code should be used only when
* the error cannot be mapped to other specific modem error codes.
*/
- MODEM_ERROR = 4,
+ SATELLITE_RESULT_MODEM_ERROR = 4,
/**
* Error received from the satellite network. This generic error code should be used only when
* the error cannot be mapped to other specific network error codes.
*/
- NETWORK_ERROR = 5,
- /**
- * Telephony is not in a valid state to receive requests from clients.
- */
- INVALID_TELEPHONY_STATE = 6,
+ SATELLITE_RESULT_NETWORK_ERROR = 5,
/**
* Satellite modem is not in a valid state to receive requests from clients.
*/
- INVALID_MODEM_STATE = 7,
+ SATELLITE_RESULT_INVALID_MODEM_STATE = 6,
/**
* Either vendor service, or modem, or Telephony framework has received a request with
* invalid arguments from its clients.
*/
- INVALID_ARGUMENTS = 8,
+ SATELLITE_RESULT_INVALID_ARGUMENTS = 7,
/**
* Telephony framework failed to send a request or receive a response from the vendor service
* or satellite modem due to internal error.
*/
- REQUEST_FAILED = 9,
+ SATELLITE_RESULT_REQUEST_FAILED = 8,
/**
* Radio did not start or is resetting.
*/
- RADIO_NOT_AVAILABLE = 10,
+ SATELLITE_RESULT_RADIO_NOT_AVAILABLE = 9,
/**
* The request is not supported by either the satellite modem or the network.
*/
- REQUEST_NOT_SUPPORTED = 11,
+ SATELLITE_RESULT_REQUEST_NOT_SUPPORTED = 10,
/**
* Satellite modem or network has no resources available to handle requests from clients.
*/
- NO_RESOURCES = 12,
+ SATELLITE_RESULT_NO_RESOURCES = 11,
/**
* Satellite service is not provisioned yet.
*/
- SERVICE_NOT_PROVISIONED = 13,
+ SATELLITE_RESULT_SERVICE_NOT_PROVISIONED = 12,
/**
* Satellite service provision is already in progress.
*/
- SERVICE_PROVISION_IN_PROGRESS = 14,
+ SATELLITE_RESULT_SERVICE_PROVISION_IN_PROGRESS = 13,
/**
* The ongoing request was aborted by either the satellite modem or the network.
*/
- REQUEST_ABORTED = 15,
+ SATELLITE_RESULT_REQUEST_ABORTED = 14,
/**
* The device/subscriber is barred from accessing the satellite service.
*/
- SATELLITE_ACCESS_BARRED = 16,
+ SATELLITE_RESULT_ACCESS_BARRED = 15,
/**
* Satellite modem timeout to receive ACK or response from the satellite network after
* sending a request to the network.
*/
- NETWORK_TIMEOUT = 17,
+ SATELLITE_RESULT_NETWORK_TIMEOUT = 16,
/**
* Satellite network is not reachable from the modem.
*/
- SATELLITE_NOT_REACHABLE = 18,
+ SATELLITE_RESULT_NOT_REACHABLE = 17,
/**
* The device/subscriber is not authorized to register with the satellite service provider.
*/
- NOT_AUTHORIZED = 19
+ SATELLITE_RESULT_NOT_AUTHORIZED = 18
}