diff --git a/AconfigFlags.bp b/AconfigFlags.bp
index 7977d73599e8f618e5a6e880ba1d336aed18e070..45e33ce4b6e93c9096b56bc273c4b3cc7f62024a 100644
--- a/AconfigFlags.bp
+++ b/AconfigFlags.bp
@@ -56,7 +56,6 @@ aconfig_declarations_group {
"android.media.tv.flags-aconfig-java",
"android.multiuser.flags-aconfig-java",
"android.net.platform.flags-aconfig-java",
- "android.net.vcn.flags-aconfig-java-export",
"android.net.wifi.flags-aconfig-java",
"android.nfc.flags-aconfig-java",
"android.os.flags-aconfig-java",
@@ -96,6 +95,7 @@ aconfig_declarations_group {
"com.android.internal.foldables.flags-aconfig-java",
"com.android.internal.os.flags-aconfig-java",
"com.android.internal.pm.pkg.component.flags-aconfig-java",
+ "com.android.internal.widget.flags-aconfig-java",
"com.android.media.flags.bettertogether-aconfig-java",
"com.android.media.flags.editing-aconfig-java",
"com.android.media.flags.performance-aconfig-java",
@@ -280,6 +280,19 @@ java_aconfig_library {
defaults: ["framework-minus-apex-aconfig-java-defaults"],
}
+aconfig_declarations {
+ name: "com.android.internal.widget.flags-aconfig",
+ package: "com.android.internal.widget.flags",
+ container: "system",
+ srcs: ["core/java/com/android/internal/widget/*.aconfig"],
+}
+
+java_aconfig_library {
+ name: "com.android.internal.widget.flags-aconfig-java",
+ aconfig_declarations: "com.android.internal.widget.flags-aconfig",
+ defaults: ["framework-minus-apex-aconfig-java-defaults"],
+}
+
// Text
aconfig_declarations {
name: "com.android.text.flags-aconfig",
@@ -623,6 +636,11 @@ java_aconfig_library {
defaults: ["framework-minus-apex-aconfig-java-defaults"],
}
+cc_aconfig_library {
+ name: "aconfig_hardware_flags_c_lib",
+ aconfig_declarations: "android.hardware.flags-aconfig",
+}
+
// Widget
aconfig_declarations {
name: "android.widget.flags-aconfig",
@@ -790,21 +808,6 @@ java_aconfig_library {
defaults: ["framework-minus-apex-aconfig-java-defaults"],
}
-// OnDeviceIntelligence
-aconfig_declarations {
- name: "android.app.ondeviceintelligence-aconfig",
- exportable: true,
- package: "android.app.ondeviceintelligence.flags",
- container: "system",
- srcs: ["core/java/android/app/ondeviceintelligence/flags/ondevice_intelligence.aconfig"],
-}
-
-java_aconfig_library {
- name: "android.app.ondeviceintelligence-aconfig-java",
- aconfig_declarations: "android.app.ondeviceintelligence-aconfig",
- defaults: ["framework-minus-apex-aconfig-java-defaults"],
-}
-
// Permissions
aconfig_declarations {
name: "android.permission.flags-aconfig",
@@ -986,6 +989,11 @@ aconfig_declarations {
java_aconfig_library {
name: "android.app.flags-aconfig-java",
aconfig_declarations: "android.app.flags-aconfig",
+ min_sdk_version: "34",
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.nfcservices",
+ ],
defaults: ["framework-minus-apex-aconfig-java-defaults"],
}
@@ -1204,25 +1212,6 @@ java_aconfig_library {
defaults: ["framework-minus-apex-aconfig-java-defaults"],
}
-// VCN
-// TODO:376339506 Move the VCN code, the flag declaration and
-// java_aconfig_library to framework-connectivity-b
-aconfig_declarations {
- name: "android.net.vcn.flags-aconfig",
- package: "android.net.vcn",
- container: "com.android.tethering",
- exportable: true,
- srcs: ["core/java/android/net/vcn/*.aconfig"],
-}
-
-java_aconfig_library {
- name: "android.net.vcn.flags-aconfig-java-export",
- aconfig_declarations: "android.net.vcn.flags-aconfig",
- mode: "exported",
- min_sdk_version: "35",
- defaults: ["framework-minus-apex-aconfig-java-defaults"],
-}
-
// DevicePolicy
aconfig_declarations {
name: "device_policy_aconfig_flags",
@@ -1239,6 +1228,17 @@ java_aconfig_library {
defaults: ["framework-minus-apex-aconfig-java-defaults"],
}
+java_aconfig_library {
+ name: "device_policy_aconfig_flags_java_export",
+ aconfig_declarations: "device_policy_aconfig_flags",
+ defaults: ["framework-minus-apex-aconfig-java-defaults"],
+ min_sdk_version: "30",
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.permission",
+ ],
+}
+
java_aconfig_library {
name: "device_policy_aconfig_flags_lib_host",
aconfig_declarations: "device_policy_aconfig_flags",
@@ -1467,6 +1467,13 @@ java_aconfig_library {
defaults: ["framework-minus-apex-aconfig-java-defaults"],
}
+java_aconfig_library {
+ name: "android.appwidget.flags-aconfig-java-host",
+ aconfig_declarations: "android.appwidget.flags-aconfig",
+ host_supported: true,
+ defaults: ["framework-minus-apex-aconfig-java-defaults"],
+}
+
// App
aconfig_declarations {
name: "android.server.app.flags-aconfig",
diff --git a/Android.bp b/Android.bp
index 42028e010e8432de5a5b0e534034c5a958758f6b..529da53e58f72a2ee3277e0b42c0e9301e382b66 100644
--- a/Android.bp
+++ b/Android.bp
@@ -87,6 +87,7 @@ filegroup {
":framework-wifi-non-updatable-sources",
":PacProcessor-aidl-sources",
":ProxyHandler-aidl-sources",
+ ":vcn-utils-platform-sources",
":net-utils-framework-common-srcs",
// AIDL from frameworks/base/native/
@@ -314,6 +315,7 @@ java_defaults {
":framework-telephony-sources",
":framework-wifi-annotations",
":framework-wifi-non-updatable-sources",
+ ":vcn-utils-platform-sources",
":PacProcessor-aidl-sources",
":ProxyHandler-aidl-sources",
":net-utils-framework-common-srcs",
@@ -444,6 +446,9 @@ java_library {
default: [
"framework-platformcrashrecovery.impl",
],
+ }) + select(release_flag("RELEASE_ONDEVICE_INTELLIGENCE_MODULE"), {
+ true: [],
+ default: ["framework-ondeviceintelligence-platform.impl"],
}),
sdk_version: "core_platform",
installable: false,
@@ -487,6 +492,7 @@ java_library {
apex_available: ["//apex_available:platform"],
visibility: [
"//frameworks/base:__subpackages__",
+ "//packages/modules/NeuralNetworks:__subpackages__",
],
compile_dex: false,
headers_only: true,
@@ -582,6 +588,9 @@ java_library {
default: [
"framework-platformcrashrecovery-compat-config",
],
+ }) + select(release_flag("RELEASE_ONDEVICE_INTELLIGENCE_MODULE"), {
+ true: [],
+ default: ["framework-ondeviceintelligence-platform-compat-config"],
}),
}
@@ -596,7 +605,7 @@ filegroup {
srcs: [
"core/java/com/android/internal/util/HexDump.java",
"core/java/com/android/internal/util/WakeupMessage.java",
- "core/java/android/net/vcn/util/PersistableBundleUtils.java",
+ "packages/Vcn/framework-b/src/android/net/vcn/util/PersistableBundleUtils.java",
"telephony/java/android/telephony/Annotation.java",
],
}
diff --git a/apex/jobscheduler/service/aconfig/job.aconfig b/apex/jobscheduler/service/aconfig/job.aconfig
index 810be8fc4220ef40157f2871e2433e34c7846c1a..fe95a59622f46febcedfda77e640a2601874b618 100644
--- a/apex/jobscheduler/service/aconfig/job.aconfig
+++ b/apex/jobscheduler/service/aconfig/job.aconfig
@@ -63,7 +63,7 @@ flag {
name: "remove_user_during_user_switch"
namespace: "backstage_power"
description: "Remove started user if user will be stopped due to user switch"
- bug: "321598070"
+ bug: "337077643"
}
flag {
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
index a5a08fb9997c926570ce440e06a9a3d450b938d6..8fad79a845b4f93daac5e625acbdeb5c6f91e7db 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
@@ -1981,7 +1981,12 @@ public class JobSchedulerService extends com.android.server.SystemService
jobStatus.getNumAppliedFlexibleConstraints(),
jobStatus.getNumDroppedFlexibleConstraints(),
jobStatus.getFilteredTraceTag(),
- jobStatus.getFilteredDebugTags());
+ jobStatus.getFilteredDebugTags(),
+ jobStatus.getNumAbandonedFailures(),
+ /* 0 is reserved for UNKNOWN_POLICY */
+ jobStatus.getJob().getBackoffPolicy() + 1,
+ shouldUseAggressiveBackoff(jobStatus.getNumAbandonedFailures()));
+
// If the job is immediately ready to run, then we can just immediately
// put it in the pending list and try to schedule it. This is especially
@@ -2422,7 +2427,11 @@ public class JobSchedulerService extends com.android.server.SystemService
cancelled.getNumAppliedFlexibleConstraints(),
cancelled.getNumDroppedFlexibleConstraints(),
cancelled.getFilteredTraceTag(),
- cancelled.getFilteredDebugTags());
+ cancelled.getFilteredDebugTags(),
+ cancelled.getNumAbandonedFailures(),
+ /* 0 is reserved for UNKNOWN_POLICY */
+ cancelled.getJob().getBackoffPolicy() + 1,
+ shouldUseAggressiveBackoff(cancelled.getNumAbandonedFailures()));
}
// If this is a replacement, bring in the new version of the job
if (incomingJob != null) {
@@ -5917,9 +5926,6 @@ public class JobSchedulerService extends com.android.server.SystemService
pw.print(Flags.FLAG_DO_NOT_FORCE_RUSH_EXECUTION_AT_BOOT,
Flags.doNotForceRushExecutionAtBoot());
pw.println();
- pw.print(android.app.job.Flags.FLAG_BACKUP_JOBS_EXEMPTION,
- android.app.job.Flags.backupJobsExemption());
- pw.println();
pw.print(android.app.job.Flags.FLAG_IGNORE_IMPORTANT_WHILE_FOREGROUND,
android.app.job.Flags.ignoreImportantWhileForeground());
pw.println();
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerShellCommand.java b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerShellCommand.java
index f3bc9c747f170a020f6968d6e12cdf03b7941fba..42c8250a6185f33479403d33ac5650ba8b956556 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerShellCommand.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerShellCommand.java
@@ -433,9 +433,6 @@ public final class JobSchedulerShellCommand extends BasicShellCommandHandler {
case com.android.server.job.Flags.FLAG_DO_NOT_FORCE_RUSH_EXECUTION_AT_BOOT:
pw.println(com.android.server.job.Flags.doNotForceRushExecutionAtBoot());
break;
- case android.app.job.Flags.FLAG_BACKUP_JOBS_EXEMPTION:
- pw.println(android.app.job.Flags.backupJobsExemption());
- break;
case android.app.job.Flags.FLAG_IGNORE_IMPORTANT_WHILE_FOREGROUND:
pw.println(android.app.job.Flags.ignoreImportantWhileForeground());
break;
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java b/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java
index 909a9b30ada46e5a880abef20ff78c2c42dbc5eb..2b401c8ff6b1581a37c48f4c767b468ef87e54c6 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java
@@ -546,7 +546,11 @@ public final class JobServiceContext implements ServiceConnection {
job.getNumAppliedFlexibleConstraints(),
job.getNumDroppedFlexibleConstraints(),
job.getFilteredTraceTag(),
- job.getFilteredDebugTags());
+ job.getFilteredDebugTags(),
+ job.getNumAbandonedFailures(),
+ /* 0 is reserved for UNKNOWN_POLICY */
+ job.getJob().getBackoffPolicy() + 1,
+ mService.shouldUseAggressiveBackoff(job.getNumAbandonedFailures()));
sEnqueuedJwiAtJobStart.logSampleWithUid(job.getUid(), job.getWorkCount());
final String sourcePackage = job.getSourcePackageName();
if (Trace.isTagEnabled(Trace.TRACE_TAG_SYSTEM_SERVER)) {
@@ -1681,7 +1685,11 @@ public final class JobServiceContext implements ServiceConnection {
completedJob.getNumAppliedFlexibleConstraints(),
completedJob.getNumDroppedFlexibleConstraints(),
completedJob.getFilteredTraceTag(),
- completedJob.getFilteredDebugTags());
+ completedJob.getFilteredDebugTags(),
+ completedJob.getNumAbandonedFailures(),
+ /* 0 is reserved for UNKNOWN_POLICY */
+ completedJob.getJob().getBackoffPolicy() + 1,
+ mService.shouldUseAggressiveBackoff(completedJob.getNumAbandonedFailures()));
if (Trace.isTagEnabled(Trace.TRACE_TAG_SYSTEM_SERVER)) {
Trace.asyncTraceForTrackEnd(Trace.TRACE_TAG_SYSTEM_SERVER,
JobSchedulerService.TRACE_TRACK_NAME, getId());
diff --git a/api/Android.bp b/api/Android.bp
index 73262030ee379d63a9111deb0d3740efafca938e..14c2766d8887e393c58b21597489995afc77a1d8 100644
--- a/api/Android.bp
+++ b/api/Android.bp
@@ -105,6 +105,13 @@ combined_apis {
default: [
"framework-platformcrashrecovery",
],
+ }) + select(release_flag("RELEASE_ONDEVICE_INTELLIGENCE_MODULE"), {
+ true: [
+ "framework-ondeviceintelligence",
+ ],
+ default: [
+ "framework-ondeviceintelligence-platform",
+ ],
}) + select(release_flag("RELEASE_RANGING_STACK"), {
true: [
"framework-ranging",
@@ -119,7 +126,12 @@ combined_apis {
"service-permission",
"service-rkp",
"service-sdksandbox",
- ] + select(soong_config_variable("ANDROID", "release_crashrecovery_module"), {
+ ] + select(release_flag("RELEASE_ONDEVICE_INTELLIGENCE_MODULE"), {
+ true: [
+ "service-ondeviceintelligence",
+ ],
+ default: [],
+ }) + select(soong_config_variable("ANDROID", "release_crashrecovery_module"), {
"true": [
"service-crashrecovery",
],
@@ -478,6 +490,7 @@ java_defaults {
"//frameworks/base/location",
"//frameworks/base/packages/CrashRecovery/framework",
"//frameworks/base/nfc",
+ "//packages/modules/NeuralNetworks:__subpackages__",
],
plugins: ["error_prone_android_framework"],
errorprone: {
diff --git a/api/api.go b/api/api.go
index 5ca24de1b46acb29603439978194363f411eaeb7..e4d783eba4c335fc5080894c2d789f5576d6b985 100644
--- a/api/api.go
+++ b/api/api.go
@@ -29,6 +29,7 @@ const i18n = "i18n.module.public.api"
const virtualization = "framework-virtualization"
const location = "framework-location"
const platformCrashrecovery = "framework-platformcrashrecovery"
+const ondeviceintelligence = "framework-ondeviceintelligence-platform"
var core_libraries_modules = []string{art, conscrypt, i18n}
@@ -40,7 +41,7 @@ var core_libraries_modules = []string{art, conscrypt, i18n}
// APIs.
// In addition, the modules in this list are allowed to contribute to test APIs
// stubs.
-var non_updatable_modules = []string{virtualization, location, platformCrashrecovery}
+var non_updatable_modules = []string{virtualization, location, platformCrashrecovery, ondeviceintelligence}
// The intention behind this soong plugin is to generate a number of "merged"
// API-related modules that would otherwise require a large amount of very
diff --git a/boot/Android.bp b/boot/Android.bp
index 6eead42a4d30e631bd79263d57f7787aba44ba58..eaa984ac0cddd6b11837b2c254393cc3a578ca05 100644
--- a/boot/Android.bp
+++ b/boot/Android.bp
@@ -31,6 +31,7 @@ soong_config_module_type {
"car_bootclasspath_fragment",
"nfc_apex_bootclasspath_fragment",
"release_crashrecovery_module",
+ "release_ondevice_intelligence_module",
"release_package_profiling_module",
],
properties: [
@@ -176,6 +177,15 @@ custom_platform_bootclasspath {
},
],
},
+ release_ondevice_intelligence_module: {
+ fragments: [
+ // only used when ondeviceintelligence is moved to neuralnetworks module
+ {
+ apex: "com.android.neuralnetworks",
+ module: "com.android.ondeviceintelligence-bootclasspath-fragment",
+ },
+ ],
+ },
release_package_profiling_module: {
fragments: [
// only used if profiling is enabled.
diff --git a/cmds/idmap2/Android.bp b/cmds/idmap2/Android.bp
index 58763a7f9aca07a550be705e8541f91ff090c37f..d9ff19051de9fbe70ef6de239b3d53e3dac73490 100644
--- a/cmds/idmap2/Android.bp
+++ b/cmds/idmap2/Android.bp
@@ -165,6 +165,7 @@ cc_test {
],
host_supported: true,
test_suites: ["general-tests"],
+ require_root: true,
srcs: [
"tests/BinaryStreamVisitorTests.cpp",
"tests/CommandLineOptionsTests.cpp",
diff --git a/cmds/idmap2/libidmap2/ResourceContainer.cpp b/cmds/idmap2/libidmap2/ResourceContainer.cpp
index 57ae3548123b738971ff1c70394e40f244fdd52a..f22a481c1f28f29a355bacdcbc3da25e67350759 100644
--- a/cmds/idmap2/libidmap2/ResourceContainer.cpp
+++ b/cmds/idmap2/libidmap2/ResourceContainer.cpp
@@ -22,6 +22,7 @@
#include
#include
+#include "android-base/scopeguard.h"
#include "androidfw/ApkAssets.h"
#include "androidfw/AssetManager.h"
#include "androidfw/Util.h"
@@ -269,27 +270,40 @@ struct ResState {
std::unique_ptr am;
ZipAssetsProvider* zip_assets;
- static Result Initialize(std::unique_ptr zip,
+ static Result Initialize(std::unique_ptr&& zip,
package_property_t flags) {
ResState state;
state.zip_assets = zip.get();
if ((state.apk_assets = ApkAssets::Load(std::move(zip), flags)) == nullptr) {
- return Error("failed to load apk asset");
+ return Error("failed to load apk asset for '%s'",
+ state.zip_assets->GetDebugName().c_str());
}
+ // Make sure we put ZipAssetsProvider where we took it if initialization fails, so the
+ // original object stays valid for any next call it may get.
+ auto scoped_restore_zip_assets = android::base::ScopeGuard([&zip, &state]() {
+ zip = std::unique_ptr(
+ static_cast(
+ std::move(const_cast(*state.apk_assets)).TakeAssetsProvider().release()));
+ });
+
if ((state.arsc = state.apk_assets->GetLoadedArsc()) == nullptr) {
- return Error("failed to retrieve loaded arsc");
+ return Error("failed to retrieve loaded arsc for '%s'",
+ state.zip_assets->GetDebugName().c_str());
}
if ((state.package = GetPackageAtIndex0(state.arsc)) == nullptr) {
- return Error("failed to retrieve loaded package at index 0");
+ return Error("failed to retrieve loaded package at index 0 for '%s'",
+ state.zip_assets->GetDebugName().c_str());
}
state.am = std::make_unique();
if (!state.am->SetApkAssets({state.apk_assets}, false)) {
- return Error("failed to create asset manager");
+ return Error("failed to create asset manager for '%s'",
+ state.zip_assets->GetDebugName().c_str());
}
+ scoped_restore_zip_assets.Disable();
return state;
}
};
diff --git a/cmds/idmap2/tests/IdmapTests.cpp b/cmds/idmap2/tests/IdmapTests.cpp
index 1b656e8c2088f3480b7251a5783ddb813b6ca7e5..7093614f40472811e7f9af1895c49eea562fc569 100644
--- a/cmds/idmap2/tests/IdmapTests.cpp
+++ b/cmds/idmap2/tests/IdmapTests.cpp
@@ -214,6 +214,20 @@ TEST(IdmapTests, CreateIdmapHeaderFromApkAssets) {
ASSERT_EQ(idmap->GetHeader()->GetOverlayName(), TestConstants::OVERLAY_NAME_ALL_POLICIES);
}
+TEST(IdmapTests, TargetContainerWorksAfterError) {
+ auto target = TargetResourceContainer::FromPath(GetTestDataPath() + "/target/target-bad.apk");
+ ASSERT_TRUE(target);
+
+ auto crc = target->get()->GetCrc();
+ ASSERT_TRUE(crc);
+
+ // This call tries to construct the full ApkAssets state, and fails.
+ ASSERT_FALSE(target->get()->DefinesOverlayable());
+ auto crc2 = target->get()->GetCrc();
+ ASSERT_TRUE(crc2);
+ EXPECT_EQ(*crc, *crc2);
+}
+
TEST(IdmapTests, CreateIdmapDataFromApkAssets) {
std::string target_apk_path = GetTestDataPath() + "/target/target.apk";
std::string overlay_apk_path = GetTestDataPath() + "/overlay/overlay.apk";
diff --git a/cmds/idmap2/tests/data/target/target-bad.apk b/cmds/idmap2/tests/data/target/target-bad.apk
new file mode 100644
index 0000000000000000000000000000000000000000..fd8678238c4d53383d12536df34e1e448a2d1332
Binary files /dev/null and b/cmds/idmap2/tests/data/target/target-bad.apk differ
diff --git a/core/api/current.txt b/core/api/current.txt
index d9338a5798299d2d63aa0fec181ab3af956518b1..5efa74779c06908da025e5eb3ab6c827371d6a6f 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -140,6 +140,7 @@ package android {
field public static final String MANAGE_DEVICE_POLICY_ACROSS_USERS_SECURITY_CRITICAL = "android.permission.MANAGE_DEVICE_POLICY_ACROSS_USERS_SECURITY_CRITICAL";
field public static final String MANAGE_DEVICE_POLICY_AIRPLANE_MODE = "android.permission.MANAGE_DEVICE_POLICY_AIRPLANE_MODE";
field public static final String MANAGE_DEVICE_POLICY_APPS_CONTROL = "android.permission.MANAGE_DEVICE_POLICY_APPS_CONTROL";
+ field @FlaggedApi("android.app.appfunctions.flags.enable_app_function_manager") public static final String MANAGE_DEVICE_POLICY_APP_FUNCTIONS = "android.permission.MANAGE_DEVICE_POLICY_APP_FUNCTIONS";
field public static final String MANAGE_DEVICE_POLICY_APP_RESTRICTIONS = "android.permission.MANAGE_DEVICE_POLICY_APP_RESTRICTIONS";
field public static final String MANAGE_DEVICE_POLICY_APP_USER_DATA = "android.permission.MANAGE_DEVICE_POLICY_APP_USER_DATA";
field public static final String MANAGE_DEVICE_POLICY_ASSIST_CONTENT = "android.permission.MANAGE_DEVICE_POLICY_ASSIST_CONTENT";
@@ -247,6 +248,7 @@ package android {
field public static final String READ_BASIC_PHONE_STATE = "android.permission.READ_BASIC_PHONE_STATE";
field public static final String READ_CALENDAR = "android.permission.READ_CALENDAR";
field public static final String READ_CALL_LOG = "android.permission.READ_CALL_LOG";
+ field @FlaggedApi("android.media.tv.flags.media_quality_fw") public static final String READ_COLOR_ZONES = "android.permission.READ_COLOR_ZONES";
field public static final String READ_CONTACTS = "android.permission.READ_CONTACTS";
field @FlaggedApi("com.android.server.feature.flags.enable_read_dropbox_permission") public static final String READ_DROPBOX_DATA = "android.permission.READ_DROPBOX_DATA";
field public static final String READ_EXTERNAL_STORAGE = "android.permission.READ_EXTERNAL_STORAGE";
@@ -2199,6 +2201,11 @@ package android {
field @FlaggedApi("android.os.material_motion_tokens") public static final int config_motionStandardFastSpatialDamping;
field @FlaggedApi("android.os.material_motion_tokens") public static final int config_motionStandardSlowEffectDamping;
field @FlaggedApi("android.os.material_motion_tokens") public static final int config_motionStandardSlowSpatialDamping;
+ field @FlaggedApi("android.os.material_shape_tokens") public static final int config_shapeCornerRadiusLarge;
+ field @FlaggedApi("android.os.material_shape_tokens") public static final int config_shapeCornerRadiusMedium;
+ field @FlaggedApi("android.os.material_shape_tokens") public static final int config_shapeCornerRadiusSmall;
+ field @FlaggedApi("android.os.material_shape_tokens") public static final int config_shapeCornerRadiusXlarge;
+ field @FlaggedApi("android.os.material_shape_tokens") public static final int config_shapeCornerRadiusXsmall;
field public static final int dialog_min_width_major = 17104899; // 0x1050003
field public static final int dialog_min_width_minor = 17104900; // 0x1050004
field public static final int notification_large_icon_height = 17104902; // 0x1050006
@@ -6475,6 +6482,7 @@ package android.app {
method public String getSortKey();
method public long getTimeoutAfter();
method public boolean hasImage();
+ method @FlaggedApi("android.app.api_rich_ongoing") public boolean hasPromotableCharacteristics();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.media.AudioAttributes AUDIO_ATTRIBUTES_DEFAULT;
field public static final int BADGE_ICON_LARGE = 2; // 0x2
@@ -8073,6 +8081,7 @@ package android.app.admin {
field public static final String ACCOUNT_MANAGEMENT_DISABLED_POLICY = "accountManagementDisabled";
field public static final String APPLICATION_HIDDEN_POLICY = "applicationHidden";
field public static final String APPLICATION_RESTRICTIONS_POLICY = "applicationRestrictions";
+ field @FlaggedApi("android.app.appfunctions.flags.enable_app_function_manager") public static final String APP_FUNCTIONS_POLICY = "appFunctions";
field public static final String AUTO_TIMEZONE_POLICY = "autoTimezone";
field public static final String AUTO_TIME_POLICY = "autoTime";
field public static final String BACKUP_SERVICE_POLICY = "backupService";
@@ -8122,6 +8131,7 @@ package android.app.admin {
method @NonNull public java.util.Set getAffiliationIds(@NonNull android.content.ComponentName);
method @Nullable public java.util.Set getAlwaysOnVpnLockdownWhitelist(@NonNull android.content.ComponentName);
method @Nullable public String getAlwaysOnVpnPackage(@NonNull android.content.ComponentName);
+ method @FlaggedApi("android.app.appfunctions.flags.enable_app_function_manager") @RequiresPermission(value=android.Manifest.permission.MANAGE_DEVICE_POLICY_APP_FUNCTIONS, conditional=true) public int getAppFunctionsPolicy();
method @NonNull @WorkerThread public android.os.Bundle getApplicationRestrictions(@Nullable android.content.ComponentName, String);
method @Deprecated @Nullable public String getApplicationRestrictionsManagingPackage(@NonNull android.content.ComponentName);
method @RequiresPermission(anyOf={android.Manifest.permission.SET_TIME, "android.permission.QUERY_ADMIN_POLICY"}, conditional=true) public boolean getAutoTimeEnabled(@Nullable android.content.ComponentName);
@@ -8280,6 +8290,7 @@ package android.app.admin {
method public void setAffiliationIds(@NonNull android.content.ComponentName, @NonNull java.util.Set);
method public void setAlwaysOnVpnPackage(@NonNull android.content.ComponentName, @Nullable String, boolean) throws android.content.pm.PackageManager.NameNotFoundException;
method public void setAlwaysOnVpnPackage(@NonNull android.content.ComponentName, @Nullable String, boolean, @Nullable java.util.Set) throws android.content.pm.PackageManager.NameNotFoundException;
+ method @FlaggedApi("android.app.appfunctions.flags.enable_app_function_manager") @RequiresPermission(value=android.Manifest.permission.MANAGE_DEVICE_POLICY_APP_FUNCTIONS, conditional=true) public void setAppFunctionsPolicy(int);
method @RequiresPermission(value=android.Manifest.permission.MANAGE_DEVICE_POLICY_PACKAGE_STATE, conditional=true) public boolean setApplicationHidden(@Nullable android.content.ComponentName, String, boolean);
method @WorkerThread public void setApplicationRestrictions(@Nullable android.content.ComponentName, String, android.os.Bundle);
method @Deprecated public void setApplicationRestrictionsManagingPackage(@NonNull android.content.ComponentName, @Nullable String) throws android.content.pm.PackageManager.NameNotFoundException;
@@ -8406,6 +8417,9 @@ package android.app.admin {
field public static final String ACTION_SET_NEW_PASSWORD = "android.app.action.SET_NEW_PASSWORD";
field public static final String ACTION_START_ENCRYPTION = "android.app.action.START_ENCRYPTION";
field public static final String ACTION_SYSTEM_UPDATE_POLICY_CHANGED = "android.app.action.SYSTEM_UPDATE_POLICY_CHANGED";
+ field @FlaggedApi("android.app.appfunctions.flags.enable_app_function_manager") public static final int APP_FUNCTIONS_DISABLED = 1; // 0x1
+ field @FlaggedApi("android.app.appfunctions.flags.enable_app_function_manager") public static final int APP_FUNCTIONS_DISABLED_CROSS_PROFILE = 2; // 0x2
+ field @FlaggedApi("android.app.appfunctions.flags.enable_app_function_manager") public static final int APP_FUNCTIONS_NOT_CONTROLLED_BY_POLICY = 0; // 0x0
field @FlaggedApi("android.app.admin.flags.set_auto_time_enabled_coexistence") public static final int AUTO_TIME_DISABLED = 1; // 0x1
field @FlaggedApi("android.app.admin.flags.set_auto_time_enabled_coexistence") public static final int AUTO_TIME_ENABLED = 2; // 0x2
field @FlaggedApi("android.app.admin.flags.set_auto_time_enabled_coexistence") public static final int AUTO_TIME_NOT_CONTROLLED_BY_POLICY = 0; // 0x0
@@ -8870,6 +8884,7 @@ package android.app.appfunctions {
field public static final int ERROR_CATEGORY_UNKNOWN = 0; // 0x0
field public static final int ERROR_DENIED = 1000; // 0x3e8
field public static final int ERROR_DISABLED = 1002; // 0x3ea
+ field public static final int ERROR_ENTERPRISE_POLICY_DISALLOWED = 2002; // 0x7d2
field public static final int ERROR_FUNCTION_NOT_FOUND = 1003; // 0x3eb
field public static final int ERROR_INVALID_ARGUMENT = 1001; // 0x3e9
field public static final int ERROR_SYSTEM_ERROR = 2000; // 0x7d0
@@ -17082,7 +17097,7 @@ package android.graphics {
method public void arcTo(@NonNull android.graphics.RectF, float, float);
method public void arcTo(float, float, float, float, float, float, boolean);
method public void close();
- method @Deprecated public void computeBounds(@NonNull android.graphics.RectF, boolean);
+ method public void computeBounds(@NonNull android.graphics.RectF, boolean);
method @FlaggedApi("com.android.graphics.flags.exact_compute_bounds") public void computeBounds(@NonNull android.graphics.RectF);
method public void conicTo(float, float, float, float, float);
method public void cubicTo(float, float, float, float, float, float);
@@ -20809,6 +20824,7 @@ package android.hardware.display {
method public int describeContents();
method @FlaggedApi("android.companion.virtualdevice.flags.device_aware_display_power") @FloatRange(from=0.0f, to=1.0f) public float getDefaultBrightness();
method public int getDensityDpi();
+ method @FlaggedApi("android.companion.virtualdevice.flags.device_aware_display_power") @FloatRange(from=0.0f, to=1.0f) public float getDimBrightness();
method @NonNull public java.util.Set getDisplayCategories();
method public int getFlags();
method public int getHeight();
@@ -20830,6 +20846,7 @@ package android.hardware.display {
method @NonNull public android.hardware.display.VirtualDisplayConfig build();
method @FlaggedApi("android.companion.virtualdevice.flags.device_aware_display_power") @NonNull public android.hardware.display.VirtualDisplayConfig.Builder setBrightnessListener(@NonNull java.util.concurrent.Executor, @NonNull android.hardware.display.VirtualDisplayConfig.BrightnessListener);
method @FlaggedApi("android.companion.virtualdevice.flags.device_aware_display_power") @NonNull public android.hardware.display.VirtualDisplayConfig.Builder setDefaultBrightness(@FloatRange(from=0.0f, to=1.0f) float);
+ method @FlaggedApi("android.companion.virtualdevice.flags.device_aware_display_power") @NonNull public android.hardware.display.VirtualDisplayConfig.Builder setDimBrightness(@FloatRange(from=0.0f, to=1.0f) float);
method @NonNull public android.hardware.display.VirtualDisplayConfig.Builder setDisplayCategories(@NonNull java.util.Set);
method @NonNull public android.hardware.display.VirtualDisplayConfig.Builder setFlags(int);
method @NonNull public android.hardware.display.VirtualDisplayConfig.Builder setRequestedRefreshRate(@FloatRange(from=0.0f) float);
@@ -21778,6 +21795,18 @@ package android.media {
field public static final int ENCODING_DTS_UHD_P2 = 30; // 0x1e
field public static final int ENCODING_E_AC3 = 6; // 0x6
field public static final int ENCODING_E_AC3_JOC = 18; // 0x12
+ field @FlaggedApi("android.media.audio.iamf_definitions_api") public static final int ENCODING_IAMF_BASE_ENHANCED_PROFILE_AAC = 42; // 0x2a
+ field @FlaggedApi("android.media.audio.iamf_definitions_api") public static final int ENCODING_IAMF_BASE_ENHANCED_PROFILE_FLAC = 43; // 0x2b
+ field @FlaggedApi("android.media.audio.iamf_definitions_api") public static final int ENCODING_IAMF_BASE_ENHANCED_PROFILE_OPUS = 41; // 0x29
+ field @FlaggedApi("android.media.audio.iamf_definitions_api") public static final int ENCODING_IAMF_BASE_ENHANCED_PROFILE_PCM = 44; // 0x2c
+ field @FlaggedApi("android.media.audio.iamf_definitions_api") public static final int ENCODING_IAMF_BASE_PROFILE_AAC = 38; // 0x26
+ field @FlaggedApi("android.media.audio.iamf_definitions_api") public static final int ENCODING_IAMF_BASE_PROFILE_FLAC = 39; // 0x27
+ field @FlaggedApi("android.media.audio.iamf_definitions_api") public static final int ENCODING_IAMF_BASE_PROFILE_OPUS = 37; // 0x25
+ field @FlaggedApi("android.media.audio.iamf_definitions_api") public static final int ENCODING_IAMF_BASE_PROFILE_PCM = 40; // 0x28
+ field @FlaggedApi("android.media.audio.iamf_definitions_api") public static final int ENCODING_IAMF_SIMPLE_PROFILE_AAC = 34; // 0x22
+ field @FlaggedApi("android.media.audio.iamf_definitions_api") public static final int ENCODING_IAMF_SIMPLE_PROFILE_FLAC = 35; // 0x23
+ field @FlaggedApi("android.media.audio.iamf_definitions_api") public static final int ENCODING_IAMF_SIMPLE_PROFILE_OPUS = 33; // 0x21
+ field @FlaggedApi("android.media.audio.iamf_definitions_api") public static final int ENCODING_IAMF_SIMPLE_PROFILE_PCM = 36; // 0x24
field public static final int ENCODING_IEC61937 = 13; // 0xd
field public static final int ENCODING_INVALID = 0; // 0x0
field public static final int ENCODING_MP3 = 9; // 0x9
@@ -24899,7 +24928,7 @@ package android.media {
method @Nullable public android.net.Uri getIconUri();
method @NonNull public String getId();
method @NonNull public CharSequence getName();
- method @FlaggedApi("com.android.media.flags.enable_route_visibility_control_api") @NonNull public java.util.Set getRequiredPermissions();
+ method @FlaggedApi("com.android.media.flags.enable_route_visibility_control_api") @NonNull public java.util.List> getRequiredPermissions();
method @FlaggedApi("com.android.media.flags.enable_built_in_speaker_route_suitability_statuses") public int getSuitabilityStatus();
method @FlaggedApi("com.android.media.flags.enable_mirroring_in_media_router_2") public int getSupportedRoutingTypes();
method public int getType();
@@ -24969,6 +24998,7 @@ package android.media {
method @NonNull public android.media.MediaRoute2Info.Builder setExtras(@Nullable android.os.Bundle);
method @NonNull public android.media.MediaRoute2Info.Builder setIconUri(@Nullable android.net.Uri);
method @FlaggedApi("com.android.media.flags.enable_route_visibility_control_api") @NonNull public android.media.MediaRoute2Info.Builder setRequiredPermissions(@NonNull java.util.Set);
+ method @FlaggedApi("com.android.media.flags.enable_route_visibility_control_api") @NonNull public android.media.MediaRoute2Info.Builder setRequiredPermissions(@NonNull java.util.List>);
method @FlaggedApi("com.android.media.flags.enable_built_in_speaker_route_suitability_statuses") @NonNull public android.media.MediaRoute2Info.Builder setSuitabilityStatus(int);
method @FlaggedApi("com.android.media.flags.enable_mirroring_in_media_router_2") @NonNull public android.media.MediaRoute2Info.Builder setSupportedRoutingTypes(int);
method @NonNull public android.media.MediaRoute2Info.Builder setType(int);
@@ -27140,6 +27170,15 @@ package android.media.projection {
package android.media.quality {
+ @FlaggedApi("android.media.tv.flags.media_quality_fw") public final class ActiveProcessingPicture implements android.os.Parcelable {
+ ctor public ActiveProcessingPicture(int, @NonNull String);
+ method public int describeContents();
+ method public int getId();
+ method @NonNull public String getProfileId();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator CREATOR;
+ }
+
@FlaggedApi("android.media.tv.flags.media_quality_fw") public final class AmbientBacklightEvent implements android.os.Parcelable {
ctor public AmbientBacklightEvent(int, @Nullable android.media.quality.AmbientBacklightMetadata);
method public int describeContents();
@@ -27158,10 +27197,10 @@ package android.media.quality {
method public int describeContents();
method public int getColorFormat();
method public int getCompressAlgorithm();
- method @IntRange(from=0) public int getHorizontalZonesNumber();
+ method @IntRange(from=0, to=128) public int getHorizontalZonesNumber();
method @NonNull public String getPackageName();
method public int getSource();
- method @IntRange(from=0) public int getVerticalZonesNumber();
+ method @IntRange(from=0, to=80) public int getVerticalZonesNumber();
method @NonNull public int[] getZonesColors();
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator CREATOR;
@@ -27191,8 +27230,30 @@ package android.media.quality {
}
public static final class MediaQualityContract.PictureQuality {
+ field public static final String PARAMETER_AUTO_PICTURE_QUALITY_ENABLED = "auto_picture_quality_enabled";
+ field public static final String PARAMETER_AUTO_SUPER_RESOLUTION_ENABLED = "auto_super_resolution_enabled";
+ field public static final String PARAMETER_BLUE_STRETCH = "blue_stretch";
field public static final String PARAMETER_BRIGHTNESS = "brightness";
+ field public static final String PARAMETER_COLOR_TEMPERATURE = "color_temperature";
+ field public static final String PARAMETER_COLOR_TUNE = "color_tune";
+ field public static final String PARAMETER_COLOR_TUNER_BLUE_GAIN = "color_tuner_blue_gain";
+ field public static final String PARAMETER_COLOR_TUNER_BLUE_OFFSET = "color_tuner_blue_offset";
+ field public static final String PARAMETER_COLOR_TUNER_BRIGHTNESS = "color_tuner_brightness";
+ field public static final String PARAMETER_COLOR_TUNER_GREEN_GAIN = "color_tuner_green_gain";
+ field public static final String PARAMETER_COLOR_TUNER_GREEN_OFFSET = "color_tuner_green_offset";
+ field public static final String PARAMETER_COLOR_TUNER_HUE = "color_tuner_hue";
+ field public static final String PARAMETER_COLOR_TUNER_RED_GAIN = "color_tuner_red_gain";
+ field public static final String PARAMETER_COLOR_TUNER_RED_OFFSET = "color_tuner_red_offset";
+ field public static final String PARAMETER_COLOR_TUNER_SATURATION = "color_tuner_saturation";
field public static final String PARAMETER_CONTRAST = "contrast";
+ field public static final String PARAMETER_DECONTOUR = "decontour";
+ field public static final String PARAMETER_DYNAMIC_LUMA_CONTROL = "dynamic_luma_control";
+ field public static final String PARAMETER_FILM_MODE = "film_mode";
+ field public static final String PARAMETER_FLESH_TONE = "flesh_tone";
+ field public static final String PARAMETER_GLOBAL_DIMMING = "global_dimming";
+ field public static final String PARAMETER_HUE = "hue";
+ field public static final String PARAMETER_MPEG_NOISE_REDUCTION = "mpeg_noise_reduction";
+ field public static final String PARAMETER_NOISE_REDUCTION = "noise_reduction";
field public static final String PARAMETER_SATURATION = "saturation";
field public static final String PARAMETER_SHARPNESS = "sharpness";
}
@@ -27204,13 +27265,14 @@ package android.media.quality {
}
@FlaggedApi("android.media.tv.flags.media_quality_fw") public final class MediaQualityManager {
+ method public void addActiveProcessingPictureListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.quality.MediaQualityManager.ActiveProcessingPictureListener);
method public void createPictureProfile(@NonNull android.media.quality.PictureProfile);
method public void createSoundProfile(@NonNull android.media.quality.SoundProfile);
- method @NonNull public java.util.List getAvailablePictureProfiles();
- method @NonNull public java.util.List getAvailableSoundProfiles();
+ method @NonNull public java.util.List getAvailablePictureProfiles(boolean);
+ method @NonNull public java.util.List getAvailableSoundProfiles(boolean);
method @NonNull public java.util.List getParamCapabilities(@NonNull java.util.List);
- method @Nullable public android.media.quality.PictureProfile getPictureProfile(int, @NonNull String);
- method @Nullable public android.media.quality.SoundProfile getSoundProfile(int, @NonNull String);
+ method @Nullable public android.media.quality.PictureProfile getPictureProfile(int, @NonNull String, boolean);
+ method @Nullable public android.media.quality.SoundProfile getSoundProfile(int, @NonNull String, boolean);
method public boolean isAmbientBacklightEnabled();
method public boolean isAutoPictureQualityEnabled();
method public boolean isAutoSoundQualityEnabled();
@@ -27218,6 +27280,7 @@ package android.media.quality {
method public void registerAmbientBacklightCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.quality.MediaQualityManager.AmbientBacklightCallback);
method public void registerPictureProfileCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.quality.MediaQualityManager.PictureProfileCallback);
method public void registerSoundProfileCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.quality.MediaQualityManager.SoundProfileCallback);
+ method public void removeActiveProcessingPictureListener(@NonNull android.media.quality.MediaQualityManager.ActiveProcessingPictureListener);
method public void removePictureProfile(@NonNull String);
method public void removeSoundProfile(@NonNull String);
method public void setAmbientBacklightEnabled(boolean);
@@ -27229,6 +27292,10 @@ package android.media.quality {
method public void updateSoundProfile(@NonNull String, @NonNull android.media.quality.SoundProfile);
}
+ public static interface MediaQualityManager.ActiveProcessingPictureListener {
+ method public void onActiveProcessingPicturesChanged(@NonNull java.util.List);
+ }
+
public abstract static class MediaQualityManager.AmbientBacklightCallback {
ctor public MediaQualityManager.AmbientBacklightCallback();
method public void onAmbientBacklightEvent(@NonNull android.media.quality.AmbientBacklightEvent);
@@ -27236,7 +27303,7 @@ package android.media.quality {
public abstract static class MediaQualityManager.PictureProfileCallback {
ctor public MediaQualityManager.PictureProfileCallback();
- method public void onError(int);
+ method public void onError(@Nullable String, int);
method public void onParamCapabilitiesChanged(@Nullable String, @NonNull java.util.List);
method public void onPictureProfileAdded(@NonNull String, @NonNull android.media.quality.PictureProfile);
method public void onPictureProfileRemoved(@NonNull String, @NonNull android.media.quality.PictureProfile);
@@ -27245,7 +27312,7 @@ package android.media.quality {
public abstract static class MediaQualityManager.SoundProfileCallback {
ctor public MediaQualityManager.SoundProfileCallback();
- method public void onError(int);
+ method public void onError(@Nullable String, int);
method public void onParamCapabilitiesChanged(@Nullable String, @NonNull java.util.List);
method public void onSoundProfileAdded(@NonNull String, @NonNull android.media.quality.SoundProfile);
method public void onSoundProfileRemoved(@NonNull String, @NonNull android.media.quality.SoundProfile);
@@ -30132,128 +30199,6 @@ package android.net.sip {
}
-package android.net.vcn {
-
- public final class VcnCellUnderlyingNetworkTemplate extends android.net.vcn.VcnUnderlyingNetworkTemplate {
- method public int getCbs();
- method public int getDun();
- method public int getIms();
- method public int getInternet();
- method public int getMms();
- method @NonNull public java.util.Set getOperatorPlmnIds();
- method public int getOpportunistic();
- method public int getRcs();
- method public int getRoaming();
- method @NonNull public java.util.Set getSimSpecificCarrierIds();
- }
-
- public static final class VcnCellUnderlyingNetworkTemplate.Builder {
- ctor public VcnCellUnderlyingNetworkTemplate.Builder();
- method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate build();
- method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setCbs(int);
- method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setDun(int);
- method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setIms(int);
- method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setInternet(int);
- method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setMetered(int);
- method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setMinDownstreamBandwidthKbps(int, int);
- method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setMinUpstreamBandwidthKbps(int, int);
- method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setMms(int);
- method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setOperatorPlmnIds(@NonNull java.util.Set);
- method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setOpportunistic(int);
- method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setRcs(int);
- method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setRoaming(int);
- method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setSimSpecificCarrierIds(@NonNull java.util.Set);
- }
-
- public final class VcnConfig implements android.os.Parcelable {
- method public int describeContents();
- method @NonNull public java.util.Set getGatewayConnectionConfigs();
- method @NonNull public java.util.Set getRestrictedUnderlyingNetworkTransports();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator CREATOR;
- }
-
- public static final class VcnConfig.Builder {
- ctor public VcnConfig.Builder(@NonNull android.content.Context);
- method @NonNull public android.net.vcn.VcnConfig.Builder addGatewayConnectionConfig(@NonNull android.net.vcn.VcnGatewayConnectionConfig);
- method @NonNull public android.net.vcn.VcnConfig build();
- method @NonNull public android.net.vcn.VcnConfig.Builder setRestrictedUnderlyingNetworkTransports(@NonNull java.util.Set);
- }
-
- public final class VcnGatewayConnectionConfig {
- method @NonNull public int[] getExposedCapabilities();
- method @NonNull public String getGatewayConnectionName();
- method @IntRange(from=0x500) public int getMaxMtu();
- method public int getMinUdpPort4500NatTimeoutSeconds();
- method @NonNull public long[] getRetryIntervalsMillis();
- method @NonNull public java.util.List getVcnUnderlyingNetworkPriorities();
- method public boolean hasGatewayOption(int);
- method @FlaggedApi("android.net.vcn.safe_mode_config") public boolean isSafeModeEnabled();
- field @FlaggedApi("android.net.vcn.mainline_vcn_module_api") public static final int MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET = -1; // 0xffffffff
- field public static final int VCN_GATEWAY_OPTION_ENABLE_DATA_STALL_RECOVERY_WITH_MOBILITY = 0; // 0x0
- }
-
- public static final class VcnGatewayConnectionConfig.Builder {
- ctor public VcnGatewayConnectionConfig.Builder(@NonNull String, @NonNull android.net.ipsec.ike.IkeTunnelConnectionParams);
- method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder addExposedCapability(int);
- method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder addGatewayOption(int);
- method @NonNull public android.net.vcn.VcnGatewayConnectionConfig build();
- method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder removeExposedCapability(int);
- method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder removeGatewayOption(int);
- method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder setMaxMtu(@IntRange(from=0x500) int);
- method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder setMinUdpPort4500NatTimeoutSeconds(@IntRange(from=0x78) int);
- method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder setRetryIntervalsMillis(@NonNull long[]);
- method @FlaggedApi("android.net.vcn.safe_mode_config") @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder setSafeModeEnabled(boolean);
- method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder setVcnUnderlyingNetworkPriorities(@NonNull java.util.List);
- }
-
- public class VcnManager {
- method @RequiresPermission("carrier privileges") public void clearVcnConfig(@NonNull android.os.ParcelUuid) throws java.io.IOException;
- method @NonNull public java.util.List getConfiguredSubscriptionGroups();
- method public void registerVcnStatusCallback(@NonNull android.os.ParcelUuid, @NonNull java.util.concurrent.Executor, @NonNull android.net.vcn.VcnManager.VcnStatusCallback);
- method @RequiresPermission("carrier privileges") public void setVcnConfig(@NonNull android.os.ParcelUuid, @NonNull android.net.vcn.VcnConfig) throws java.io.IOException;
- method public void unregisterVcnStatusCallback(@NonNull android.net.vcn.VcnManager.VcnStatusCallback);
- field public static final int VCN_ERROR_CODE_CONFIG_ERROR = 1; // 0x1
- field public static final int VCN_ERROR_CODE_INTERNAL_ERROR = 0; // 0x0
- field public static final int VCN_ERROR_CODE_NETWORK_ERROR = 2; // 0x2
- field public static final int VCN_STATUS_CODE_ACTIVE = 2; // 0x2
- field public static final int VCN_STATUS_CODE_INACTIVE = 1; // 0x1
- field public static final int VCN_STATUS_CODE_NOT_CONFIGURED = 0; // 0x0
- field public static final int VCN_STATUS_CODE_SAFE_MODE = 3; // 0x3
- }
-
- public abstract static class VcnManager.VcnStatusCallback {
- ctor public VcnManager.VcnStatusCallback();
- method public abstract void onGatewayConnectionError(@NonNull String, int, @Nullable Throwable);
- method public abstract void onStatusChanged(int);
- }
-
- public abstract class VcnUnderlyingNetworkTemplate {
- method public int getMetered();
- method public int getMinEntryDownstreamBandwidthKbps();
- method public int getMinEntryUpstreamBandwidthKbps();
- method public int getMinExitDownstreamBandwidthKbps();
- method public int getMinExitUpstreamBandwidthKbps();
- field public static final int MATCH_ANY = 0; // 0x0
- field public static final int MATCH_FORBIDDEN = 2; // 0x2
- field public static final int MATCH_REQUIRED = 1; // 0x1
- }
-
- public final class VcnWifiUnderlyingNetworkTemplate extends android.net.vcn.VcnUnderlyingNetworkTemplate {
- method @NonNull public java.util.Set getSsids();
- }
-
- public static final class VcnWifiUnderlyingNetworkTemplate.Builder {
- ctor public VcnWifiUnderlyingNetworkTemplate.Builder();
- method @NonNull public android.net.vcn.VcnWifiUnderlyingNetworkTemplate build();
- method @NonNull public android.net.vcn.VcnWifiUnderlyingNetworkTemplate.Builder setMetered(int);
- method @NonNull public android.net.vcn.VcnWifiUnderlyingNetworkTemplate.Builder setMinDownstreamBandwidthKbps(int, int);
- method @NonNull public android.net.vcn.VcnWifiUnderlyingNetworkTemplate.Builder setMinUpstreamBandwidthKbps(int, int);
- method @NonNull public android.net.vcn.VcnWifiUnderlyingNetworkTemplate.Builder setSsids(@NonNull java.util.Set);
- }
-
-}
-
package android.opengl {
public class EGL14 {
@@ -34820,7 +34765,10 @@ package android.os {
method public android.os.MessageQueue getMessageQueue();
method public boolean hasMessages(android.os.Handler, Object, int);
method public boolean hasMessages(android.os.Handler, Object, Runnable);
+ method @FlaggedApi("android.os.message_queue_testability") public boolean isBlockedOnSyncBarrier();
method public android.os.Message next();
+ method @FlaggedApi("android.os.message_queue_testability") @Nullable public Long peekWhen();
+ method @FlaggedApi("android.os.message_queue_testability") @Nullable public android.os.Message poll();
method public void recycle(android.os.Message);
method public void release();
}
@@ -40873,8 +40821,10 @@ package android.security.keystore {
method @NonNull public java.util.List getGrantedCertificateChainFromId(long) throws android.security.keystore.KeyPermanentlyInvalidatedException, java.security.UnrecoverableKeyException;
method @NonNull public java.security.Key getGrantedKeyFromId(long) throws android.security.keystore.KeyPermanentlyInvalidatedException, java.security.UnrecoverableKeyException;
method @NonNull public java.security.KeyPair getGrantedKeyPairFromId(long) throws android.security.keystore.KeyPermanentlyInvalidatedException, java.security.UnrecoverableKeyException;
+ method @FlaggedApi("android.security.keystore2.attest_modules") @NonNull public byte[] getSupplementaryAttestationInfo(int) throws android.security.KeyStoreException;
method public long grantKeyAccess(@NonNull String, int) throws android.security.KeyStoreException, java.security.UnrecoverableKeyException;
method public void revokeKeyAccess(@NonNull String, int) throws android.security.KeyStoreException, java.security.UnrecoverableKeyException;
+ field public static final int MODULE_HASH = -1879047468; // 0x900002d4
}
public class SecureKeyImportUnavailableException extends java.security.ProviderException {
@@ -40930,13 +40880,14 @@ package android.service.autofill {
public abstract class AutofillService extends android.app.Service {
ctor public AutofillService();
- method @Nullable public final android.service.autofill.FillEventHistory getFillEventHistory();
+ method @Deprecated @FlaggedApi("android.service.autofill.autofill_session_destroyed") @Nullable public final android.service.autofill.FillEventHistory getFillEventHistory();
method public final android.os.IBinder onBind(android.content.Intent);
method public void onConnected();
method public void onDisconnected();
method public abstract void onFillRequest(@NonNull android.service.autofill.FillRequest, @NonNull android.os.CancellationSignal, @NonNull android.service.autofill.FillCallback);
method public abstract void onSaveRequest(@NonNull android.service.autofill.SaveRequest, @NonNull android.service.autofill.SaveCallback);
method public void onSavedDatasetsInfoRequest(@NonNull android.service.autofill.SavedDatasetsInfoCallback);
+ method @FlaggedApi("android.service.autofill.autofill_session_destroyed") public void onSessionDestroyed(@Nullable android.service.autofill.FillEventHistory);
field public static final String EXTRA_FILL_RESPONSE = "android.service.autofill.extra.FILL_RESPONSE";
field public static final String SERVICE_INTERFACE = "android.service.autofill.AutofillService";
field public static final String SERVICE_META_DATA = "android.autofill";
@@ -41097,7 +41048,7 @@ package android.service.autofill {
field public static final int TYPE_DATASET_SELECTED = 0; // 0x0
field public static final int TYPE_SAVE_SHOWN = 3; // 0x3
field public static final int TYPE_VIEW_REQUESTED_AUTOFILL = 6; // 0x6
- field @FlaggedApi("android.service.autofill.autofill_w_metrics") public static final int UI_TYPE_CREDMAN = 4; // 0x4
+ field @FlaggedApi("android.service.autofill.autofill_w_metrics") public static final int UI_TYPE_CREDENTIAL_MANAGER = 4; // 0x4
field public static final int UI_TYPE_DIALOG = 3; // 0x3
field public static final int UI_TYPE_INLINE = 2; // 0x2
field public static final int UI_TYPE_MENU = 1; // 0x1
@@ -42666,9 +42617,10 @@ package android.service.settings.preferences {
method public boolean isWritable();
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator CREATOR;
- field public static final int INTENT_ONLY = 2; // 0x2
- field public static final int NOT_SENSITIVE = 0; // 0x0
- field public static final int SENSITIVE = 1; // 0x1
+ field public static final int EXPECT_POST_CONFIRMATION = 1; // 0x1
+ field public static final int EXPECT_PRE_CONFIRMATION = 2; // 0x2
+ field public static final int NO_DIRECT_ACCESS = 3; // 0x3
+ field public static final int NO_SENSITIVITY = 0; // 0x0
}
public static final class SettingsPreferenceMetadata.Builder {
@@ -44936,11 +44888,11 @@ package android.telephony {
field public static final String KEY_CARRIER_VVM_PACKAGE_NAME_STRING_ARRAY = "carrier_vvm_package_name_string_array";
field public static final String KEY_CARRIER_WFC_IMS_AVAILABLE_BOOL = "carrier_wfc_ims_available_bool";
field public static final String KEY_CARRIER_WFC_SUPPORTS_WIFI_ONLY_BOOL = "carrier_wfc_supports_wifi_only_bool";
- field public static final String KEY_CDMA_3WAYCALL_FLASH_DELAY_INT = "cdma_3waycall_flash_delay_int";
- field public static final String KEY_CDMA_DTMF_TONE_DELAY_INT = "cdma_dtmf_tone_delay_int";
- field public static final String KEY_CDMA_NONROAMING_NETWORKS_STRING_ARRAY = "cdma_nonroaming_networks_string_array";
- field public static final String KEY_CDMA_ROAMING_MODE_INT = "cdma_roaming_mode_int";
- field public static final String KEY_CDMA_ROAMING_NETWORKS_STRING_ARRAY = "cdma_roaming_networks_string_array";
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final String KEY_CDMA_3WAYCALL_FLASH_DELAY_INT = "cdma_3waycall_flash_delay_int";
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final String KEY_CDMA_DTMF_TONE_DELAY_INT = "cdma_dtmf_tone_delay_int";
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final String KEY_CDMA_NONROAMING_NETWORKS_STRING_ARRAY = "cdma_nonroaming_networks_string_array";
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final String KEY_CDMA_ROAMING_MODE_INT = "cdma_roaming_mode_int";
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final String KEY_CDMA_ROAMING_NETWORKS_STRING_ARRAY = "cdma_roaming_networks_string_array";
field public static final String KEY_CELLULAR_SERVICE_CAPABILITIES_INT_ARRAY = "cellular_service_capabilities_int_array";
field public static final String KEY_CELLULAR_USAGE_SETTING_INT = "cellular_usage_setting_int";
field public static final String KEY_CHECK_PRICING_WITH_CARRIER_FOR_DATA_ROAMING_BOOL = "check_pricing_with_carrier_data_roaming_bool";
@@ -44967,7 +44919,7 @@ package android.telephony {
field public static final String KEY_DEFAULT_VM_NUMBER_ROAMING_AND_IMS_UNREGISTERED_STRING = "default_vm_number_roaming_and_ims_unregistered_string";
field public static final String KEY_DEFAULT_VM_NUMBER_STRING = "default_vm_number_string";
field public static final String KEY_DIAL_STRING_REPLACE_STRING_ARRAY = "dial_string_replace_string_array";
- field public static final String KEY_DISABLE_CDMA_ACTIVATION_CODE_BOOL = "disable_cdma_activation_code_bool";
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final String KEY_DISABLE_CDMA_ACTIVATION_CODE_BOOL = "disable_cdma_activation_code_bool";
field public static final String KEY_DISABLE_CHARGE_INDICATION_BOOL = "disable_charge_indication_bool";
field @FlaggedApi("com.android.internal.telephony.flags.satellite_system_apis") public static final String KEY_DISABLE_DUN_APN_WHILE_ROAMING_WITH_PRESET_APN_BOOL = "disable_dun_apn_while_roaming_with_preset_apn_bool";
field public static final String KEY_DISABLE_SUPPLEMENTARY_SERVICES_IN_AIRPLANE_MODE_BOOL = "disable_supplementary_services_in_airplane_mode_bool";
@@ -45088,6 +45040,7 @@ package android.telephony {
field public static final String KEY_RCS_CONFIG_SERVER_URL_STRING = "rcs_config_server_url_string";
field public static final String KEY_READ_ONLY_APN_FIELDS_STRING_ARRAY = "read_only_apn_fields_string_array";
field public static final String KEY_READ_ONLY_APN_TYPES_STRING_ARRAY = "read_only_apn_types_string_array";
+ field @FlaggedApi("com.android.internal.telephony.flags.satellite_system_apis") public static final String KEY_REGIONAL_SATELLITE_EARFCN_BUNDLE = "regional_satellite_earfcn_bundle";
field @FlaggedApi("com.android.internal.telephony.flags.satellite_system_apis") public static final String KEY_REMOVE_SATELLITE_PLMN_IN_MANUAL_NETWORK_SCAN_BOOL = "remove_satellite_plmn_in_manual_network_scan_bool";
field public static final String KEY_REQUIRE_ENTITLEMENT_CHECKS_BOOL = "require_entitlement_checks_bool";
field @Deprecated public static final String KEY_RESTART_RADIO_ON_PDP_FAIL_REGULAR_DEACTIVATION_BOOL = "restart_radio_on_pdp_fail_regular_deactivation_bool";
@@ -45101,6 +45054,7 @@ package android.telephony {
field @FlaggedApi("com.android.internal.telephony.flags.carrier_enabled_satellite_flag") public static final String KEY_SATELLITE_ATTACH_SUPPORTED_BOOL = "satellite_attach_supported_bool";
field @FlaggedApi("com.android.internal.telephony.flags.carrier_enabled_satellite_flag") public static final String KEY_SATELLITE_CONNECTION_HYSTERESIS_SEC_INT = "satellite_connection_hysteresis_sec_int";
field @FlaggedApi("com.android.internal.telephony.flags.satellite_system_apis") public static final String KEY_SATELLITE_DATA_SUPPORT_MODE_INT = "satellite_data_support_mode_int";
+ field @FlaggedApi("com.android.internal.telephony.flags.satellite_system_apis") public static final String KEY_SATELLITE_DISPLAY_NAME_STRING = "satellite_display_name_string";
field @FlaggedApi("com.android.internal.telephony.flags.satellite_system_apis") public static final String KEY_SATELLITE_ENTITLEMENT_APP_NAME_STRING = "satellite_entitlement_app_name_string";
field @FlaggedApi("com.android.internal.telephony.flags.carrier_enabled_satellite_flag") public static final String KEY_SATELLITE_ENTITLEMENT_STATUS_REFRESH_DAYS_INT = "satellite_entitlement_status_refresh_days_int";
field @FlaggedApi("com.android.internal.telephony.flags.carrier_enabled_satellite_flag") public static final String KEY_SATELLITE_ENTITLEMENT_SUPPORTED_BOOL = "satellite_entitlement_supported_bool";
@@ -45112,12 +45066,14 @@ package android.telephony {
field @FlaggedApi("com.android.internal.telephony.flags.carrier_roaming_nb_iot_ntn") public static final String KEY_SATELLITE_ROAMING_P2P_SMS_SUPPORTED_BOOL = "satellite_roaming_p2p_sms_supported_bool";
field @FlaggedApi("com.android.internal.telephony.flags.carrier_roaming_nb_iot_ntn") public static final String KEY_SATELLITE_ROAMING_SCREEN_OFF_INACTIVITY_TIMEOUT_SEC_INT = "satellite_roaming_screen_off_inactivity_timeout_sec_int";
field @FlaggedApi("com.android.internal.telephony.flags.satellite_system_apis") public static final String KEY_SATELLITE_ROAMING_TURN_OFF_SESSION_FOR_EMERGENCY_CALL_BOOL = "satellite_roaming_turn_off_session_for_emergency_call_bool";
+ field @FlaggedApi("com.android.internal.telephony.flags.satellite_system_apis") public static final String KEY_SATELLITE_SOS_MAX_DATAGRAM_SIZE_BYTES_INT = "satellite_sos_max_datagram_size_bytes_int";
+ field @FlaggedApi("com.android.internal.telephony.flags.satellite_system_apis") public static final String KEY_SATELLITE_SUPPORTED_MSG_APPS_STRING_ARRAY = "satellite_supported_msg_apps_string_array";
field public static final String KEY_SHOW_4G_FOR_3G_DATA_ICON_BOOL = "show_4g_for_3g_data_icon_bool";
field public static final String KEY_SHOW_4G_FOR_LTE_DATA_ICON_BOOL = "show_4g_for_lte_data_icon_bool";
- field public static final String KEY_SHOW_APN_SETTING_CDMA_BOOL = "show_apn_setting_cdma_bool";
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final String KEY_SHOW_APN_SETTING_CDMA_BOOL = "show_apn_setting_cdma_bool";
field public static final String KEY_SHOW_BLOCKING_PAY_PHONE_OPTION_BOOL = "show_blocking_pay_phone_option_bool";
field public static final String KEY_SHOW_CALL_BLOCKING_DISABLED_NOTIFICATION_ALWAYS_BOOL = "show_call_blocking_disabled_notification_always_bool";
- field public static final String KEY_SHOW_CDMA_CHOICES_BOOL = "show_cdma_choices_bool";
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final String KEY_SHOW_CDMA_CHOICES_BOOL = "show_cdma_choices_bool";
field public static final String KEY_SHOW_FORWARDED_NUMBER_BOOL = "show_forwarded_number_bool";
field public static final String KEY_SHOW_ICCID_IN_SIM_STATUS_BOOL = "show_iccid_in_sim_status_bool";
field public static final String KEY_SHOW_IMS_REGISTRATION_STATUS_BOOL = "show_ims_registration_status_bool";
@@ -45147,7 +45103,7 @@ package android.telephony {
field public static final String KEY_SUPPORT_ENHANCED_CALL_BLOCKING_BOOL = "support_enhanced_call_blocking_bool";
field public static final String KEY_SUPPORT_IMS_CONFERENCE_EVENT_PACKAGE_BOOL = "support_ims_conference_event_package_bool";
field public static final String KEY_SUPPORT_PAUSE_IMS_VIDEO_CALLS_BOOL = "support_pause_ims_video_calls_bool";
- field public static final String KEY_SUPPORT_SWAP_AFTER_MERGE_BOOL = "support_swap_after_merge_bool";
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final String KEY_SUPPORT_SWAP_AFTER_MERGE_BOOL = "support_swap_after_merge_bool";
field public static final String KEY_SUPPORT_TDSCDMA_BOOL = "support_tdscdma_bool";
field public static final String KEY_SUPPORT_TDSCDMA_ROAMING_NETWORKS_STRING_ARRAY = "support_tdscdma_roaming_networks_string_array";
field public static final String KEY_SWITCH_DATA_TO_PRIMARY_IF_PRIMARY_IS_OOS_BOOL = "switch_data_to_primary_if_primary_is_oos_bool";
@@ -45157,7 +45113,7 @@ package android.telephony {
field public static final String KEY_USE_ACS_FOR_RCS_BOOL = "use_acs_for_rcs_bool";
field public static final String KEY_USE_HFA_FOR_PROVISIONING_BOOL = "use_hfa_for_provisioning_bool";
field public static final String KEY_USE_IP_FOR_CALLING_INDICATOR_BOOL = "use_ip_for_calling_indicator_bool";
- field public static final String KEY_USE_OTASP_FOR_PROVISIONING_BOOL = "use_otasp_for_provisioning_bool";
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final String KEY_USE_OTASP_FOR_PROVISIONING_BOOL = "use_otasp_for_provisioning_bool";
field @Deprecated public static final String KEY_USE_RCS_PRESENCE_BOOL = "use_rcs_presence_bool";
field public static final String KEY_USE_RCS_SIP_OPTIONS_BOOL = "use_rcs_sip_options_bool";
field public static final String KEY_USE_WFC_HOME_NETWORK_MODE_IN_ROAMING_NETWORK_BOOL = "use_wfc_home_network_mode_in_roaming_network_bool";
@@ -45593,13 +45549,13 @@ package android.telephony {
field @NonNull public static final android.os.Parcelable.Creator CREATOR;
}
- public final class CellIdentityCdma extends android.telephony.CellIdentity {
- method public int getBasestationId();
- method public int getLatitude();
- method public int getLongitude();
- method public int getNetworkId();
- method public int getSystemId();
- field @NonNull public static final android.os.Parcelable.Creator CREATOR;
+ @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public final class CellIdentityCdma extends android.telephony.CellIdentity {
+ method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public int getBasestationId();
+ method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public int getLatitude();
+ method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public int getLongitude();
+ method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public int getNetworkId();
+ method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public int getSystemId();
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") @NonNull public static final android.os.Parcelable.Creator CREATOR;
}
public final class CellIdentityGsm extends android.telephony.CellIdentity {
@@ -45691,11 +45647,11 @@ package android.telephony {
field public static final long UNAVAILABLE_LONG = 9223372036854775807L; // 0x7fffffffffffffffL
}
- public final class CellInfoCdma extends android.telephony.CellInfo implements android.os.Parcelable {
- method @NonNull public android.telephony.CellIdentityCdma getCellIdentity();
- method @NonNull public android.telephony.CellSignalStrengthCdma getCellSignalStrength();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator CREATOR;
+ @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public final class CellInfoCdma extends android.telephony.CellInfo implements android.os.Parcelable {
+ method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") @NonNull public android.telephony.CellIdentityCdma getCellIdentity();
+ method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") @NonNull public android.telephony.CellSignalStrengthCdma getCellSignalStrength();
+ method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public void writeToParcel(android.os.Parcel, int);
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") @NonNull public static final android.os.Parcelable.Creator CREATOR;
}
public final class CellInfoGsm extends android.telephony.CellInfo implements android.os.Parcelable {
@@ -47274,11 +47230,11 @@ package android.telephony {
method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public String getImei(int);
method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PHONE_STATE, android.Manifest.permission.READ_SMS, android.Manifest.permission.READ_PHONE_NUMBERS}) public String getLine1Number();
method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public String getManualNetworkSelectionPlmn();
- method @Nullable public String getManufacturerCode();
- method @Nullable public String getManufacturerCode(int);
+ method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") @Nullable public String getManufacturerCode();
+ method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") @Nullable public String getManufacturerCode(int);
method public static long getMaximumCallComposerPictureSize();
- method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public String getMeid();
- method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public String getMeid(int);
+ method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public String getMeid();
+ method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public String getMeid(int);
method public String getMmsUAProfUrl();
method public String getMmsUserAgent();
method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public String getNai();
@@ -47424,10 +47380,10 @@ package android.telephony {
field public static final int CARRIER_RESTRICTION_STATUS_RESTRICTED = 2; // 0x2
field public static final int CARRIER_RESTRICTION_STATUS_RESTRICTED_TO_CALLER = 3; // 0x3
field public static final int CARRIER_RESTRICTION_STATUS_UNKNOWN = 0; // 0x0
- field public static final int CDMA_ROAMING_MODE_AFFILIATED = 1; // 0x1
- field public static final int CDMA_ROAMING_MODE_ANY = 2; // 0x2
- field public static final int CDMA_ROAMING_MODE_HOME = 0; // 0x0
- field public static final int CDMA_ROAMING_MODE_RADIO_DEFAULT = -1; // 0xffffffff
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CDMA_ROAMING_MODE_AFFILIATED = 1; // 0x1
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CDMA_ROAMING_MODE_ANY = 2; // 0x2
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CDMA_ROAMING_MODE_HOME = 0; // 0x0
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CDMA_ROAMING_MODE_RADIO_DEFAULT = -1; // 0xffffffff
field public static final int DATA_ACTIVITY_DORMANT = 4; // 0x4
field public static final int DATA_ACTIVITY_IN = 1; // 0x1
field public static final int DATA_ACTIVITY_INOUT = 3; // 0x3
@@ -47447,9 +47403,9 @@ package android.telephony {
field public static final int DATA_SUSPENDED = 3; // 0x3
field public static final int DATA_UNKNOWN = -1; // 0xffffffff
field public static final int DEFAULT_PORT_INDEX = 0; // 0x0
- field public static final int ERI_FLASH = 2; // 0x2
- field public static final int ERI_OFF = 1; // 0x1
- field public static final int ERI_ON = 0; // 0x0
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int ERI_FLASH = 2; // 0x2
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int ERI_OFF = 1; // 0x1
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int ERI_ON = 0; // 0x0
field @FlaggedApi("com.android.internal.telephony.flags.oem_enabled_satellite_flag") public static final String EVENT_DISPLAY_EMERGENCY_MESSAGE = "android.telephony.event.DISPLAY_EMERGENCY_MESSAGE";
field public static final String EXTRA_ACTIVE_SIM_SUPPORTED_COUNT = "android.telephony.extra.ACTIVE_SIM_SUPPORTED_COUNT";
field public static final String EXTRA_APN_PROTOCOL = "android.telephony.extra.APN_PROTOCOL";
@@ -47490,11 +47446,11 @@ package android.telephony {
field public static final int NETWORK_SELECTION_MODE_AUTO = 1; // 0x1
field public static final int NETWORK_SELECTION_MODE_MANUAL = 2; // 0x2
field public static final int NETWORK_SELECTION_MODE_UNKNOWN = 0; // 0x0
- field public static final int NETWORK_TYPE_1xRTT = 7; // 0x7
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int NETWORK_TYPE_1xRTT = 7; // 0x7
field public static final long NETWORK_TYPE_BITMASK_1xRTT = 64L; // 0x40L
- field public static final long NETWORK_TYPE_BITMASK_CDMA = 8L; // 0x8L
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final long NETWORK_TYPE_BITMASK_CDMA = 8L; // 0x8L
field public static final long NETWORK_TYPE_BITMASK_EDGE = 2L; // 0x2L
- field public static final long NETWORK_TYPE_BITMASK_EHRPD = 8192L; // 0x2000L
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final long NETWORK_TYPE_BITMASK_EHRPD = 8192L; // 0x2000L
field public static final long NETWORK_TYPE_BITMASK_EVDO_0 = 16L; // 0x10L
field public static final long NETWORK_TYPE_BITMASK_EVDO_A = 32L; // 0x20L
field public static final long NETWORK_TYPE_BITMASK_EVDO_B = 2048L; // 0x800L
@@ -47507,16 +47463,17 @@ package android.telephony {
field public static final long NETWORK_TYPE_BITMASK_IWLAN = 131072L; // 0x20000L
field public static final long NETWORK_TYPE_BITMASK_LTE = 4096L; // 0x1000L
field @Deprecated public static final long NETWORK_TYPE_BITMASK_LTE_CA = 262144L; // 0x40000L
+ field @FlaggedApi("com.android.internal.telephony.flags.satellite_system_apis") public static final long NETWORK_TYPE_BITMASK_NB_IOT_NTN = 1048576L; // 0x100000L
field public static final long NETWORK_TYPE_BITMASK_NR = 524288L; // 0x80000L
field public static final long NETWORK_TYPE_BITMASK_TD_SCDMA = 65536L; // 0x10000L
field public static final long NETWORK_TYPE_BITMASK_UMTS = 4L; // 0x4L
field public static final long NETWORK_TYPE_BITMASK_UNKNOWN = 0L; // 0x0L
- field public static final int NETWORK_TYPE_CDMA = 4; // 0x4
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int NETWORK_TYPE_CDMA = 4; // 0x4
field public static final int NETWORK_TYPE_EDGE = 2; // 0x2
- field public static final int NETWORK_TYPE_EHRPD = 14; // 0xe
- field public static final int NETWORK_TYPE_EVDO_0 = 5; // 0x5
- field public static final int NETWORK_TYPE_EVDO_A = 6; // 0x6
- field public static final int NETWORK_TYPE_EVDO_B = 12; // 0xc
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int NETWORK_TYPE_EHRPD = 14; // 0xe
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int NETWORK_TYPE_EVDO_0 = 5; // 0x5
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int NETWORK_TYPE_EVDO_A = 6; // 0x6
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int NETWORK_TYPE_EVDO_B = 12; // 0xc
field public static final int NETWORK_TYPE_GPRS = 1; // 0x1
field public static final int NETWORK_TYPE_GSM = 16; // 0x10
field public static final int NETWORK_TYPE_HSDPA = 8; // 0x8
@@ -47526,11 +47483,12 @@ package android.telephony {
field @Deprecated public static final int NETWORK_TYPE_IDEN = 11; // 0xb
field public static final int NETWORK_TYPE_IWLAN = 18; // 0x12
field public static final int NETWORK_TYPE_LTE = 13; // 0xd
+ field @FlaggedApi("com.android.internal.telephony.flags.satellite_system_apis") public static final int NETWORK_TYPE_NB_IOT_NTN = 21; // 0x15
field public static final int NETWORK_TYPE_NR = 20; // 0x14
field public static final int NETWORK_TYPE_TD_SCDMA = 17; // 0x11
field public static final int NETWORK_TYPE_UMTS = 3; // 0x3
field public static final int NETWORK_TYPE_UNKNOWN = 0; // 0x0
- field public static final int PHONE_TYPE_CDMA = 2; // 0x2
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int PHONE_TYPE_CDMA = 2; // 0x2
field public static final int PHONE_TYPE_GSM = 1; // 0x1
field public static final int PHONE_TYPE_NONE = 0; // 0x0
field public static final int PHONE_TYPE_SIP = 3; // 0x3
@@ -53515,6 +53473,7 @@ package android.view {
field @NonNull public static final android.os.Parcelable.Creator CREATOR;
field public static final int FRAME_RATE_COMPATIBILITY_DEFAULT = 0; // 0x0
field public static final int FRAME_RATE_COMPATIBILITY_FIXED_SOURCE = 1; // 0x1
+ field @FlaggedApi("com.android.graphics.surfaceflinger.flags.arr_setframerate_gte_enum") public static final int FRAME_RATE_COMPATIBILITY_GTE = 2; // 0x2
field public static final int ROTATION_0 = 0; // 0x0
field public static final int ROTATION_180 = 2; // 0x2
field public static final int ROTATION_270 = 3; // 0x3
@@ -55293,8 +55252,8 @@ package android.view {
method public abstract void setTransformation(android.graphics.Matrix);
method public abstract void setVisibility(int);
method public abstract void setWebDomain(@Nullable String);
- field @FlaggedApi("android.service.autofill.autofill_w_metrics") public static final String EXTRA_VIRTUAL_STRUCTURE_TYPE = "android.view.ViewStructure.extra.VIRTUAL_STRUCTURE_TYPE";
- field @FlaggedApi("android.service.autofill.autofill_w_metrics") public static final String EXTRA_VIRTUAL_STRUCTURE_VERSION_NUMBER = "android.view.ViewStructure.extra.VIRTUAL_STRUCTURE_VERSION_NUMBER";
+ field @FlaggedApi("android.service.autofill.autofill_w_metrics") public static final String EXTRA_VIRTUAL_STRUCTURE_TYPE = "android.view.extra.VIRTUAL_STRUCTURE_TYPE";
+ field @FlaggedApi("android.service.autofill.autofill_w_metrics") public static final String EXTRA_VIRTUAL_STRUCTURE_VERSION_NUMBER = "android.view.extra.VIRTUAL_STRUCTURE_VERSION_NUMBER";
}
public abstract static class ViewStructure.HtmlInfo {
@@ -58407,6 +58366,7 @@ package android.view.textclassifier {
method @NonNull @WorkerThread public default android.view.textclassifier.TextSelection suggestSelection(@NonNull android.view.textclassifier.TextSelection.Request);
method @NonNull @WorkerThread public default android.view.textclassifier.TextSelection suggestSelection(@NonNull CharSequence, @IntRange(from=0) int, @IntRange(from=0) int, @Nullable android.os.LocaleList);
field public static final String EXTRA_FROM_TEXT_CLASSIFIER = "android.view.textclassifier.extra.FROM_TEXT_CLASSIFIER";
+ field @FlaggedApi("android.permission.flags.text_classifier_choice_api_enabled") public static final String EXTRA_TEXT_ORIGIN_PACKAGE = "android.view.textclassifier.extra.TEXT_ORIGIN_PACKAGE";
field public static final String HINT_TEXT_IS_EDITABLE = "android.text_is_editable";
field public static final String HINT_TEXT_IS_NOT_EDITABLE = "android.text_is_not_editable";
field public static final android.view.textclassifier.TextClassifier NO_OP;
@@ -58416,6 +58376,7 @@ package android.view.textclassifier {
field public static final String TYPE_EMAIL = "email";
field public static final String TYPE_FLIGHT_NUMBER = "flight";
field public static final String TYPE_OTHER = "other";
+ field @FlaggedApi("android.permission.flags.text_classifier_choice_api_enabled") public static final String TYPE_OTP = "otp";
field public static final String TYPE_PHONE = "phone";
field public static final String TYPE_UNKNOWN = "";
field public static final String TYPE_URL = "url";
diff --git a/core/api/lint-baseline.txt b/core/api/lint-baseline.txt
index ad5bd31828e030f0a9d97b242b02ebd7766c5e0d..e71dffaf152d4ff00878f4275081f459a9754166 100644
--- a/core/api/lint-baseline.txt
+++ b/core/api/lint-baseline.txt
@@ -1,10 +1,4 @@
// Baseline format: 1.0
-ActionValue: android.view.ViewStructure#EXTRA_VIRTUAL_STRUCTURE_TYPE:
- Inconsistent extra value; expected `android.view.extra.VIRTUAL_STRUCTURE_TYPE`, was `android.view.ViewStructure.extra.VIRTUAL_STRUCTURE_TYPE`
-ActionValue: android.view.ViewStructure#EXTRA_VIRTUAL_STRUCTURE_VERSION_NUMBER:
- Inconsistent extra value; expected `android.view.extra.VIRTUAL_STRUCTURE_VERSION_NUMBER`, was `android.view.ViewStructure.extra.VIRTUAL_STRUCTURE_VERSION_NUMBER`
-
-
BroadcastBehavior: android.app.AlarmManager#ACTION_NEXT_ALARM_CLOCK_CHANGED:
Field 'ACTION_NEXT_ALARM_CLOCK_CHANGED' is missing @BroadcastBehavior
BroadcastBehavior: android.app.AlarmManager#ACTION_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED:
@@ -1191,10 +1185,6 @@ UnflaggedApi: android.R.dimen#system_corner_radius_xlarge:
New API must be flagged with @FlaggedApi: field android.R.dimen.system_corner_radius_xlarge
UnflaggedApi: android.R.dimen#system_corner_radius_xsmall:
New API must be flagged with @FlaggedApi: field android.R.dimen.system_corner_radius_xsmall
-UnflaggedApi: android.R.integer#status_bar_notification_info_maxnum:
- Changes from not deprecated to deprecated must be flagged with @FlaggedApi: field android.R.integer.status_bar_notification_info_maxnum
-UnflaggedApi: android.R.string#status_bar_notification_info_overflow:
- Changes from not deprecated to deprecated must be flagged with @FlaggedApi: field android.R.string.status_bar_notification_info_overflow
UnflaggedApi: android.accessibilityservice.AccessibilityService#OVERLAY_RESULT_INTERNAL_ERROR:
New API must be flagged with @FlaggedApi: field android.accessibilityservice.AccessibilityService.OVERLAY_RESULT_INTERNAL_ERROR
UnflaggedApi: android.accessibilityservice.AccessibilityService#OVERLAY_RESULT_INVALID:
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt
index 804210fe3bb5b44d39899517e9908180d3a17b72..bca2ce2473c5989014012c4e4d39f55606dd5193 100644
--- a/core/api/module-lib-current.txt
+++ b/core/api/module-lib-current.txt
@@ -265,10 +265,6 @@ package android.media.session {
package android.net {
- @FlaggedApi("android.net.vcn.mainline_vcn_module_api") public final class ConnectivityFrameworkInitializerBaklava {
- method @FlaggedApi("android.net.vcn.mainline_vcn_module_api") public static void registerServiceWrappers();
- }
-
public class LocalSocket implements java.io.Closeable {
ctor public LocalSocket(@NonNull java.io.FileDescriptor);
}
@@ -328,25 +324,6 @@ package android.net.netstats {
}
-package android.net.vcn {
-
- @FlaggedApi("android.net.vcn.mainline_vcn_module_api") public final class VcnTransportInfo implements android.os.Parcelable android.net.TransportInfo {
- method @FlaggedApi("android.net.vcn.mainline_vcn_module_api") public int describeContents();
- method @FlaggedApi("android.net.vcn.mainline_vcn_module_api") public long getApplicableRedactions();
- method @FlaggedApi("android.net.vcn.mainline_vcn_module_api") public int getMinUdpPort4500NatTimeoutSeconds();
- method @FlaggedApi("android.net.vcn.mainline_vcn_module_api") @NonNull public android.net.TransportInfo makeCopy(long);
- method @FlaggedApi("android.net.vcn.mainline_vcn_module_api") public void writeToParcel(@NonNull android.os.Parcel, int);
- field @FlaggedApi("android.net.vcn.mainline_vcn_module_api") @NonNull public static final android.os.Parcelable.Creator CREATOR;
- }
-
- @FlaggedApi("android.net.vcn.mainline_vcn_module_api") public static final class VcnTransportInfo.Builder {
- ctor @FlaggedApi("android.net.vcn.mainline_vcn_module_api") public VcnTransportInfo.Builder();
- method @FlaggedApi("android.net.vcn.mainline_vcn_module_api") @NonNull public android.net.vcn.VcnTransportInfo build();
- method @FlaggedApi("android.net.vcn.mainline_vcn_module_api") @NonNull public android.net.vcn.VcnTransportInfo.Builder setMinUdpPort4500NatTimeoutSeconds(@IntRange(from=0x78) int);
- }
-
-}
-
package android.net.wifi {
public final class WifiMigration {
@@ -505,6 +482,10 @@ package android.os {
field public static final long TRACE_TAG_NETWORK = 2097152L; // 0x200000L
}
+ public class UpdateEngine {
+ method @FlaggedApi("android.os.update_engine_api") public void triggerPostinstall(@NonNull String);
+ }
+
}
package android.os.storage {
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 612a48ac00a7bb57f2d219bde85fb4ebe9ae3949..9590e1ab19c90ccb1d53f88ca5c2d9cb16b3eb7a 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -10,6 +10,7 @@ package android {
field @FlaggedApi("android.app.contextualsearch.flags.enable_service") public static final String ACCESS_CONTEXTUAL_SEARCH = "android.permission.ACCESS_CONTEXTUAL_SEARCH";
field public static final String ACCESS_CONTEXT_HUB = "android.permission.ACCESS_CONTEXT_HUB";
field public static final String ACCESS_DRM_CERTIFICATES = "android.permission.ACCESS_DRM_CERTIFICATES";
+ field @FlaggedApi("android.permission.flags.fine_power_monitor_permission") public static final String ACCESS_FINE_POWER_MONITORS = "android.permission.ACCESS_FINE_POWER_MONITORS";
field @Deprecated public static final String ACCESS_FM_RADIO = "android.permission.ACCESS_FM_RADIO";
field public static final String ACCESS_FPS_COUNTER = "android.permission.ACCESS_FPS_COUNTER";
field @FlaggedApi("android.multiuser.enable_permission_to_access_hidden_profiles") public static final String ACCESS_HIDDEN_PROFILES_FULL = "android.permission.ACCESS_HIDDEN_PROFILES_FULL";
@@ -26,6 +27,7 @@ package android {
field public static final String ACCESS_SHORTCUTS = "android.permission.ACCESS_SHORTCUTS";
field @FlaggedApi("android.app.smartspace.flags.access_smartspace") public static final String ACCESS_SMARTSPACE = "android.permission.ACCESS_SMARTSPACE";
field public static final String ACCESS_SURFACE_FLINGER = "android.permission.ACCESS_SURFACE_FLINGER";
+ field @FlaggedApi("android.permission.flags.text_classifier_choice_api_enabled") public static final String ACCESS_TEXT_CLASSIFIER_BY_TYPE = "android.permission.ACCESS_TEXT_CLASSIFIER_BY_TYPE";
field public static final String ACCESS_TUNED_INFO = "android.permission.ACCESS_TUNED_INFO";
field public static final String ACCESS_TV_DESCRAMBLER = "android.permission.ACCESS_TV_DESCRAMBLER";
field public static final String ACCESS_TV_SHARED_FILTER = "android.permission.ACCESS_TV_SHARED_FILTER";
@@ -78,6 +80,7 @@ package android {
field @FlaggedApi("android.app.ondeviceintelligence.flags.enable_on_device_intelligence") public static final String BIND_ON_DEVICE_INTELLIGENCE_SERVICE = "android.permission.BIND_ON_DEVICE_INTELLIGENCE_SERVICE";
field @FlaggedApi("android.app.ondeviceintelligence.flags.enable_on_device_intelligence") public static final String BIND_ON_DEVICE_SANDBOXED_INFERENCE_SERVICE = "android.permission.BIND_ON_DEVICE_SANDBOXED_INFERENCE_SERVICE";
field public static final String BIND_PHONE_ACCOUNT_SUGGESTION_SERVICE = "android.permission.BIND_PHONE_ACCOUNT_SUGGESTION_SERVICE";
+ field @FlaggedApi("android.location.flags.population_density_provider") public static final String BIND_POPULATION_DENSITY_PROVIDER_SERVICE = "android.permission.BIND_POPULATION_DENSITY_PROVIDER_SERVICE";
field public static final String BIND_PRINT_RECOMMENDATION_SERVICE = "android.permission.BIND_PRINT_RECOMMENDATION_SERVICE";
field public static final String BIND_REMOTE_LOCKSCREEN_VALIDATION_SERVICE = "android.permission.BIND_REMOTE_LOCKSCREEN_VALIDATION_SERVICE";
field public static final String BIND_RESOLVER_RANKER_SERVICE = "android.permission.BIND_RESOLVER_RANKER_SERVICE";
@@ -327,6 +330,7 @@ package android {
field public static final String READ_RUNTIME_PROFILES = "android.permission.READ_RUNTIME_PROFILES";
field public static final String READ_SAFETY_CENTER_STATUS = "android.permission.READ_SAFETY_CENTER_STATUS";
field public static final String READ_SEARCH_INDEXABLES = "android.permission.READ_SEARCH_INDEXABLES";
+ field @FlaggedApi("com.android.internal.telephony.flags.subscription_plan_allow_status_and_end_date") public static final String READ_SUBSCRIPTION_PLANS = "android.permission.READ_SUBSCRIPTION_PLANS";
field @FlaggedApi("android.app.system_terms_of_address_enabled") public static final String READ_SYSTEM_GRAMMATICAL_GENDER = "android.permission.READ_SYSTEM_GRAMMATICAL_GENDER";
field public static final String READ_SYSTEM_UPDATE_INFO = "android.permission.READ_SYSTEM_UPDATE_INFO";
field public static final String READ_WALLPAPER_INTERNAL = "android.permission.READ_WALLPAPER_INTERNAL";
@@ -549,6 +553,7 @@ package android {
field public static final int config_systemTextIntelligence = 17039414; // 0x1040036
field public static final int config_systemUi = 17039418; // 0x104003a
field public static final int config_systemUiIntelligence = 17039410; // 0x1040032
+ field @FlaggedApi("android.permission.flags.system_vendor_intelligence_role_enabled") public static final int config_systemVendorIntelligence;
field public static final int config_systemVisualIntelligence = 17039415; // 0x1040037
field public static final int config_systemWearHealthService = 17039428; // 0x1040044
field public static final int config_systemWellbeing = 17039408; // 0x1040030
@@ -1290,6 +1295,7 @@ package android.app {
method @FlaggedApi("android.app.live_wallpaper_content_handling") @Nullable @RequiresPermission(android.Manifest.permission.READ_WALLPAPER_INTERNAL) public android.app.wallpaper.WallpaperInstance getWallpaperInstance(int);
method public void setDisplayOffset(android.os.IBinder, int, int);
method @FlaggedApi("com.android.window.flags.multi_crop") @RequiresPermission(android.Manifest.permission.SET_WALLPAPER) public int setStreamWithCrops(@NonNull java.io.InputStream, @NonNull android.util.SparseArray, boolean, int) throws java.io.IOException;
+ method @FlaggedApi("android.app.live_wallpaper_content_handling") @RequiresPermission(android.Manifest.permission.SET_WALLPAPER) public int setStreamWithDescription(@NonNull java.io.InputStream, @NonNull android.app.wallpaper.WallpaperDescription, boolean, int) throws java.io.IOException;
method @RequiresPermission(android.Manifest.permission.SET_WALLPAPER_COMPONENT) public boolean setWallpaperComponent(android.content.ComponentName);
method @FlaggedApi("android.app.live_wallpaper_content_handling") @RequiresPermission(allOf={android.Manifest.permission.SET_WALLPAPER_COMPONENT, android.Manifest.permission.INTERACT_ACROSS_USERS_FULL}, conditional=true) public boolean setWallpaperComponentWithDescription(@NonNull android.app.wallpaper.WallpaperDescription, int);
method @RequiresPermission(android.Manifest.permission.SET_WALLPAPER_COMPONENT) public boolean setWallpaperComponentWithFlags(@NonNull android.content.ComponentName, int);
@@ -2273,149 +2279,6 @@ package android.app.job {
}
-package android.app.ondeviceintelligence {
-
- @FlaggedApi("android.app.ondeviceintelligence.flags.enable_on_device_intelligence") public interface DownloadCallback {
- method public void onDownloadCompleted(@NonNull android.os.PersistableBundle);
- method public void onDownloadFailed(int, @Nullable String, @NonNull android.os.PersistableBundle);
- method public default void onDownloadProgress(long);
- method public default void onDownloadStarted(long);
- field public static final int DOWNLOAD_FAILURE_STATUS_DOWNLOADING = 3; // 0x3
- field public static final int DOWNLOAD_FAILURE_STATUS_NETWORK_FAILURE = 2; // 0x2
- field public static final int DOWNLOAD_FAILURE_STATUS_NOT_ENOUGH_DISK_SPACE = 1; // 0x1
- field public static final int DOWNLOAD_FAILURE_STATUS_UNAVAILABLE = 4; // 0x4
- field public static final int DOWNLOAD_FAILURE_STATUS_UNKNOWN = 0; // 0x0
- }
-
- @FlaggedApi("android.app.ondeviceintelligence.flags.enable_on_device_intelligence") public final class Feature implements android.os.Parcelable {
- method public int describeContents();
- method @NonNull public android.os.PersistableBundle getFeatureParams();
- method public int getId();
- method @Nullable public String getModelName();
- method @Nullable public String getName();
- method public int getType();
- method public int getVariant();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator CREATOR;
- }
-
- public static final class Feature.Builder {
- ctor public Feature.Builder(int);
- method @NonNull public android.app.ondeviceintelligence.Feature build();
- method @NonNull public android.app.ondeviceintelligence.Feature.Builder setFeatureParams(@NonNull android.os.PersistableBundle);
- method @NonNull public android.app.ondeviceintelligence.Feature.Builder setModelName(@NonNull String);
- method @NonNull public android.app.ondeviceintelligence.Feature.Builder setName(@NonNull String);
- method @NonNull public android.app.ondeviceintelligence.Feature.Builder setType(int);
- method @NonNull public android.app.ondeviceintelligence.Feature.Builder setVariant(int);
- }
-
- @FlaggedApi("android.app.ondeviceintelligence.flags.enable_on_device_intelligence") public final class FeatureDetails implements android.os.Parcelable {
- ctor public FeatureDetails(int, @NonNull android.os.PersistableBundle);
- ctor public FeatureDetails(int);
- method public int describeContents();
- method @NonNull public android.os.PersistableBundle getFeatureDetailParams();
- method public int getFeatureStatus();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator CREATOR;
- field public static final int FEATURE_STATUS_AVAILABLE = 3; // 0x3
- field public static final int FEATURE_STATUS_DOWNLOADABLE = 1; // 0x1
- field public static final int FEATURE_STATUS_DOWNLOADING = 2; // 0x2
- field public static final int FEATURE_STATUS_SERVICE_UNAVAILABLE = 4; // 0x4
- field public static final int FEATURE_STATUS_UNAVAILABLE = 0; // 0x0
- }
-
- @FlaggedApi("android.app.ondeviceintelligence.flags.enable_on_device_intelligence_module") public final class InferenceInfo implements android.os.Parcelable {
- method public int describeContents();
- method public long getEndTimeMillis();
- method public long getStartTimeMillis();
- method public long getSuspendedTimeMillis();
- method public int getUid();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator CREATOR;
- }
-
- public static final class InferenceInfo.Builder {
- ctor public InferenceInfo.Builder(int);
- method @NonNull public android.app.ondeviceintelligence.InferenceInfo build();
- method @NonNull public android.app.ondeviceintelligence.InferenceInfo.Builder setEndTimeMillis(long);
- method @NonNull public android.app.ondeviceintelligence.InferenceInfo.Builder setStartTimeMillis(long);
- method @NonNull public android.app.ondeviceintelligence.InferenceInfo.Builder setSuspendedTimeMillis(long);
- }
-
- @FlaggedApi("android.app.ondeviceintelligence.flags.enable_on_device_intelligence") public class OnDeviceIntelligenceException extends java.lang.Exception {
- ctor public OnDeviceIntelligenceException(int, @NonNull String, @NonNull android.os.PersistableBundle);
- ctor public OnDeviceIntelligenceException(int, @NonNull android.os.PersistableBundle);
- ctor public OnDeviceIntelligenceException(int, @NonNull String);
- ctor public OnDeviceIntelligenceException(int);
- method public int getErrorCode();
- method @NonNull public android.os.PersistableBundle getErrorParams();
- field public static final int ON_DEVICE_INTELLIGENCE_SERVICE_UNAVAILABLE = 100; // 0x64
- field public static final int PROCESSING_ERROR_BAD_DATA = 2; // 0x2
- field public static final int PROCESSING_ERROR_BAD_REQUEST = 3; // 0x3
- field public static final int PROCESSING_ERROR_BUSY = 9; // 0x9
- field public static final int PROCESSING_ERROR_CANCELLED = 7; // 0x7
- field public static final int PROCESSING_ERROR_COMPUTE_ERROR = 5; // 0x5
- field public static final int PROCESSING_ERROR_INTERNAL = 14; // 0xe
- field public static final int PROCESSING_ERROR_IPC_ERROR = 6; // 0x6
- field public static final int PROCESSING_ERROR_NOT_AVAILABLE = 8; // 0x8
- field public static final int PROCESSING_ERROR_REQUEST_NOT_SAFE = 4; // 0x4
- field public static final int PROCESSING_ERROR_REQUEST_TOO_LARGE = 12; // 0xc
- field public static final int PROCESSING_ERROR_RESPONSE_NOT_SAFE = 11; // 0xb
- field public static final int PROCESSING_ERROR_SAFETY_ERROR = 10; // 0xa
- field public static final int PROCESSING_ERROR_SERVICE_UNAVAILABLE = 15; // 0xf
- field public static final int PROCESSING_ERROR_SUSPENDED = 13; // 0xd
- field public static final int PROCESSING_ERROR_UNKNOWN = 1; // 0x1
- field public static final int PROCESSING_UPDATE_STATUS_CONNECTION_FAILED = 200; // 0xc8
- }
-
- @FlaggedApi("android.app.ondeviceintelligence.flags.enable_on_device_intelligence") public final class OnDeviceIntelligenceManager {
- method @RequiresPermission(android.Manifest.permission.USE_ON_DEVICE_INTELLIGENCE) public void getFeature(int, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver);
- method @RequiresPermission(android.Manifest.permission.USE_ON_DEVICE_INTELLIGENCE) public void getFeatureDetails(@NonNull android.app.ondeviceintelligence.Feature, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver);
- method @FlaggedApi("android.app.ondeviceintelligence.flags.enable_on_device_intelligence_module") @NonNull @RequiresPermission(android.Manifest.permission.DUMP) public java.util.List getLatestInferenceInfo(long);
- method @Nullable @RequiresPermission(android.Manifest.permission.USE_ON_DEVICE_INTELLIGENCE) public String getRemoteServicePackageName();
- method @RequiresPermission(android.Manifest.permission.USE_ON_DEVICE_INTELLIGENCE) public void getVersion(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.LongConsumer);
- method @RequiresPermission(android.Manifest.permission.USE_ON_DEVICE_INTELLIGENCE) public void listFeatures(@NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver,android.app.ondeviceintelligence.OnDeviceIntelligenceException>);
- method @RequiresPermission(android.Manifest.permission.USE_ON_DEVICE_INTELLIGENCE) public void processRequest(@NonNull android.app.ondeviceintelligence.Feature, @NonNull android.os.Bundle, int, @Nullable android.os.CancellationSignal, @Nullable android.app.ondeviceintelligence.ProcessingSignal, @NonNull java.util.concurrent.Executor, @NonNull android.app.ondeviceintelligence.ProcessingCallback);
- method @RequiresPermission(android.Manifest.permission.USE_ON_DEVICE_INTELLIGENCE) public void processRequestStreaming(@NonNull android.app.ondeviceintelligence.Feature, @NonNull android.os.Bundle, int, @Nullable android.os.CancellationSignal, @Nullable android.app.ondeviceintelligence.ProcessingSignal, @NonNull java.util.concurrent.Executor, @NonNull android.app.ondeviceintelligence.StreamingProcessingCallback);
- method @RequiresPermission(android.Manifest.permission.USE_ON_DEVICE_INTELLIGENCE) public void requestFeatureDownload(@NonNull android.app.ondeviceintelligence.Feature, @Nullable android.os.CancellationSignal, @NonNull java.util.concurrent.Executor, @NonNull android.app.ondeviceintelligence.DownloadCallback);
- method @RequiresPermission(android.Manifest.permission.USE_ON_DEVICE_INTELLIGENCE) public void requestTokenInfo(@NonNull android.app.ondeviceintelligence.Feature, @NonNull android.os.Bundle, @Nullable android.os.CancellationSignal, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver);
- field public static final int REQUEST_TYPE_EMBEDDINGS = 2; // 0x2
- field public static final int REQUEST_TYPE_INFERENCE = 0; // 0x0
- field public static final int REQUEST_TYPE_PREPARE = 1; // 0x1
- }
-
- @FlaggedApi("android.app.ondeviceintelligence.flags.enable_on_device_intelligence") public interface ProcessingCallback {
- method public default void onDataAugmentRequest(@NonNull android.os.Bundle, @NonNull java.util.function.Consumer);
- method public void onError(@NonNull android.app.ondeviceintelligence.OnDeviceIntelligenceException);
- method public void onResult(@NonNull android.os.Bundle);
- }
-
- @FlaggedApi("android.app.ondeviceintelligence.flags.enable_on_device_intelligence") public final class ProcessingSignal {
- ctor public ProcessingSignal();
- method public void sendSignal(@NonNull android.os.PersistableBundle);
- method public void setOnProcessingSignalCallback(@NonNull java.util.concurrent.Executor, @Nullable android.app.ondeviceintelligence.ProcessingSignal.OnProcessingSignalCallback);
- }
-
- public static interface ProcessingSignal.OnProcessingSignalCallback {
- method public void onSignalReceived(@NonNull android.os.PersistableBundle);
- }
-
- @FlaggedApi("android.app.ondeviceintelligence.flags.enable_on_device_intelligence") public interface StreamingProcessingCallback extends android.app.ondeviceintelligence.ProcessingCallback {
- method public void onPartialResult(@NonNull android.os.Bundle);
- }
-
- @FlaggedApi("android.app.ondeviceintelligence.flags.enable_on_device_intelligence") public final class TokenInfo implements android.os.Parcelable {
- ctor public TokenInfo(long, @NonNull android.os.PersistableBundle);
- ctor public TokenInfo(long);
- method public int describeContents();
- method public long getCount();
- method @NonNull public android.os.PersistableBundle getInfoParams();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator CREATOR;
- }
-
-}
-
package android.app.people {
public final class PeopleManager {
@@ -3301,6 +3164,14 @@ package android.app.usage {
}
+package android.app.wallpaper {
+
+ @FlaggedApi("android.app.live_wallpaper_content_handling") public final class WallpaperDescription implements android.os.Parcelable {
+ method @NonNull public android.util.SparseArray getCropHints();
+ }
+
+}
+
package android.app.wallpapereffectsgeneration {
public final class CameraAttributes implements android.os.Parcelable {
@@ -5254,9 +5125,9 @@ package android.hardware.contexthub {
}
@FlaggedApi("android.chre.flags.offload_api") public class HubEndpointSession implements java.lang.AutoCloseable {
- method public void close();
- method @Nullable public android.hardware.contexthub.HubServiceInfo getServiceInfo();
- method @NonNull public android.hardware.location.ContextHubTransaction sendMessage(@NonNull android.hardware.contexthub.HubMessage);
+ method @RequiresPermission(android.Manifest.permission.ACCESS_CONTEXT_HUB) public void close();
+ method @Nullable public String getServiceDescriptor();
+ method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_CONTEXT_HUB) public android.hardware.location.ContextHubTransaction sendMessage(@NonNull android.hardware.contexthub.HubMessage);
}
@FlaggedApi("android.chre.flags.offload_api") public class HubEndpointSessionResult {
@@ -5308,7 +5179,7 @@ package android.hardware.contexthub {
@FlaggedApi("android.chre.flags.offload_api") public interface IHubEndpointLifecycleCallback {
method public void onSessionClosed(@NonNull android.hardware.contexthub.HubEndpointSession, int);
- method @NonNull public android.hardware.contexthub.HubEndpointSessionResult onSessionOpenRequest(@NonNull android.hardware.contexthub.HubEndpointInfo, @Nullable android.hardware.contexthub.HubServiceInfo);
+ method @NonNull public android.hardware.contexthub.HubEndpointSessionResult onSessionOpenRequest(@NonNull android.hardware.contexthub.HubEndpointInfo, @Nullable String);
method public void onSessionOpened(@NonNull android.hardware.contexthub.HubEndpointSession);
}
@@ -6314,7 +6185,7 @@ package android.hardware.location {
method @Deprecated @RequiresPermission(android.Manifest.permission.ACCESS_CONTEXT_HUB) public int loadNanoApp(int, @NonNull android.hardware.location.NanoApp);
method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_CONTEXT_HUB) public android.hardware.location.ContextHubTransaction loadNanoApp(@NonNull android.hardware.location.ContextHubInfo, @NonNull android.hardware.location.NanoAppBinary);
method @FlaggedApi("android.chre.flags.offload_api") @RequiresPermission(android.Manifest.permission.ACCESS_CONTEXT_HUB) public void openSession(@NonNull android.hardware.contexthub.HubEndpoint, @NonNull android.hardware.contexthub.HubEndpointInfo);
- method @FlaggedApi("android.chre.flags.offload_api") @RequiresPermission(android.Manifest.permission.ACCESS_CONTEXT_HUB) public void openSession(@NonNull android.hardware.contexthub.HubEndpoint, @NonNull android.hardware.contexthub.HubEndpointInfo, @NonNull android.hardware.contexthub.HubServiceInfo);
+ method @FlaggedApi("android.chre.flags.offload_api") @RequiresPermission(android.Manifest.permission.ACCESS_CONTEXT_HUB) public void openSession(@NonNull android.hardware.contexthub.HubEndpoint, @NonNull android.hardware.contexthub.HubEndpointInfo, @NonNull String);
method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_CONTEXT_HUB) public android.hardware.location.ContextHubTransaction> queryNanoApps(@NonNull android.hardware.location.ContextHubInfo);
method @Deprecated public int registerCallback(@NonNull android.hardware.location.ContextHubManager.Callback);
method @Deprecated public int registerCallback(android.hardware.location.ContextHubManager.Callback, android.os.Handler);
@@ -8118,14 +7989,17 @@ package android.media.musicrecognition {
package android.media.quality {
@FlaggedApi("android.media.tv.flags.media_quality_fw") public final class MediaQualityManager {
+ method public void addGlobalActiveProcessingPictureListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.quality.MediaQualityManager.ActiveProcessingPictureListener);
method @NonNull public java.util.List getPictureProfileAllowList();
method @NonNull public java.util.List getPictureProfilePackageNames();
- method @NonNull public java.util.List getPictureProfilesByPackage(@NonNull String);
+ method @NonNull public java.util.List getPictureProfilesByPackage(@NonNull String, boolean);
method @NonNull public java.util.List getSoundProfileAllowList();
method @NonNull public java.util.List getSoundProfilePackageNames();
- method @NonNull public java.util.List getSoundProfilesByPackage(@NonNull String);
+ method @NonNull public java.util.List getSoundProfilesByPackage(@NonNull String, boolean);
method public void setAutoPictureQualityEnabled(boolean);
method public void setAutoSoundQualityEnabled(boolean);
+ method public boolean setDefaultPictureProfile(@Nullable String);
+ method public boolean setDefaultSoundProfile(@Nullable String);
method public void setPictureProfileAllowList(@NonNull java.util.List);
method public void setSoundProfileAllowList(@NonNull java.util.List);
method public void setSuperResolutionEnabled(boolean);
@@ -10614,28 +10488,6 @@ package android.net.util {
}
-package android.net.vcn {
-
- public class VcnManager {
- method @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public void addVcnNetworkPolicyChangeListener(@NonNull java.util.concurrent.Executor, @NonNull android.net.vcn.VcnManager.VcnNetworkPolicyChangeListener);
- method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public android.net.vcn.VcnNetworkPolicyResult applyVcnNetworkPolicy(@NonNull android.net.NetworkCapabilities, @NonNull android.net.LinkProperties);
- method @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public void removeVcnNetworkPolicyChangeListener(@NonNull android.net.vcn.VcnManager.VcnNetworkPolicyChangeListener);
- }
-
- public static interface VcnManager.VcnNetworkPolicyChangeListener {
- method public void onPolicyChanged();
- }
-
- public final class VcnNetworkPolicyResult implements android.os.Parcelable {
- method public int describeContents();
- method @NonNull public android.net.NetworkCapabilities getNetworkCapabilities();
- method public boolean isTeardownRequested();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator CREATOR;
- }
-
-}
-
package android.net.wifi {
public final class WifiKeystore {
@@ -12625,6 +12477,7 @@ package android.provider {
field public static final String ACTION_REQUEST_ENABLE_CONTENT_CAPTURE = "android.settings.REQUEST_ENABLE_CONTENT_CAPTURE";
field public static final String ACTION_SHOW_ADMIN_SUPPORT_DETAILS = "android.settings.SHOW_ADMIN_SUPPORT_DETAILS";
field public static final String ACTION_SHOW_RESTRICTED_SETTING_DIALOG = "android.settings.SHOW_RESTRICTED_SETTING_DIALOG";
+ field @FlaggedApi("com.android.internal.telephony.flags.action_sim_preference_settings") public static final String ACTION_SIM_PREFERENCE_SETTINGS = "android.settings.SIM_PREFERENCE_SETTINGS";
field public static final String ACTION_TETHER_PROVISIONING_UI = "android.settings.TETHER_PROVISIONING_UI";
field public static final String ACTION_TETHER_SETTINGS = "android.settings.TETHER_SETTINGS";
field public static final String ACTION_TETHER_UNSUPPORTED_CARRIER_UI = "android.settings.TETHER_UNSUPPORTED_CARRIER_UI";
@@ -12860,14 +12713,14 @@ package android.security.authenticationpolicy {
}
@FlaggedApi("android.security.secure_lockdown") public final class DisableSecureLockDeviceParams implements android.os.Parcelable {
- ctor public DisableSecureLockDeviceParams(@NonNull String);
+ ctor public DisableSecureLockDeviceParams(@NonNull CharSequence);
method public int describeContents();
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator CREATOR;
}
@FlaggedApi("android.security.secure_lockdown") public final class EnableSecureLockDeviceParams implements android.os.Parcelable {
- ctor public EnableSecureLockDeviceParams(@NonNull String);
+ ctor public EnableSecureLockDeviceParams(@NonNull CharSequence);
method public int describeContents();
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator CREATOR;
@@ -13799,39 +13652,6 @@ package android.service.oemlock {
}
-package android.service.ondeviceintelligence {
-
- @FlaggedApi("android.app.ondeviceintelligence.flags.enable_on_device_intelligence") public abstract class OnDeviceIntelligenceService extends android.app.Service {
- ctor public OnDeviceIntelligenceService();
- method @Nullable public final android.os.IBinder onBind(@NonNull android.content.Intent);
- method public abstract void onDownloadFeature(int, @NonNull android.app.ondeviceintelligence.Feature, @Nullable android.os.CancellationSignal, @NonNull android.app.ondeviceintelligence.DownloadCallback);
- method public abstract void onGetFeature(int, int, @NonNull android.os.OutcomeReceiver);
- method public abstract void onGetFeatureDetails(int, @NonNull android.app.ondeviceintelligence.Feature, @NonNull android.os.OutcomeReceiver);
- method public abstract void onGetReadOnlyFeatureFileDescriptorMap(@NonNull android.app.ondeviceintelligence.Feature, @NonNull java.util.function.Consumer>);
- method public abstract void onGetVersion(@NonNull java.util.function.LongConsumer);
- method public abstract void onInferenceServiceConnected();
- method public abstract void onInferenceServiceDisconnected();
- method public abstract void onListFeatures(int, @NonNull android.os.OutcomeReceiver,android.app.ondeviceintelligence.OnDeviceIntelligenceException>);
- method public final void updateProcessingState(@NonNull android.os.Bundle, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver);
- field public static final String SERVICE_INTERFACE = "android.service.ondeviceintelligence.OnDeviceIntelligenceService";
- }
-
- @FlaggedApi("android.app.ondeviceintelligence.flags.enable_on_device_intelligence") public abstract class OnDeviceSandboxedInferenceService extends android.app.Service {
- ctor public OnDeviceSandboxedInferenceService();
- method public final void fetchFeatureFileDescriptorMap(@NonNull android.app.ondeviceintelligence.Feature, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer>);
- method @NonNull public java.util.concurrent.Executor getCallbackExecutor();
- method public final void getReadOnlyFileDescriptor(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer) throws java.io.FileNotFoundException;
- method @Nullable public final android.os.IBinder onBind(@NonNull android.content.Intent);
- method @NonNull public abstract void onProcessRequest(int, @NonNull android.app.ondeviceintelligence.Feature, @NonNull android.os.Bundle, int, @Nullable android.os.CancellationSignal, @Nullable android.app.ondeviceintelligence.ProcessingSignal, @NonNull android.app.ondeviceintelligence.ProcessingCallback);
- method @NonNull public abstract void onProcessRequestStreaming(int, @NonNull android.app.ondeviceintelligence.Feature, @NonNull android.os.Bundle, int, @Nullable android.os.CancellationSignal, @Nullable android.app.ondeviceintelligence.ProcessingSignal, @NonNull android.app.ondeviceintelligence.StreamingProcessingCallback);
- method @NonNull public abstract void onTokenInfoRequest(int, @NonNull android.app.ondeviceintelligence.Feature, @NonNull android.os.Bundle, @Nullable android.os.CancellationSignal, @NonNull android.os.OutcomeReceiver);
- method public abstract void onUpdateProcessingState(@NonNull android.os.Bundle, @NonNull android.os.OutcomeReceiver);
- method public final java.io.FileInputStream openFileInput(@NonNull String) throws java.io.FileNotFoundException;
- field public static final String SERVICE_INTERFACE = "android.service.ondeviceintelligence.OnDeviceSandboxedInferenceService";
- }
-
-}
-
package android.service.persistentdata {
@FlaggedApi("android.security.frp_enforcement") public class PersistentDataBlockManager {
@@ -14812,7 +14632,7 @@ package android.telecom {
field public static final int CALLTYPE_INCOMING = 1; // 0x1
field public static final int CALLTYPE_OUTGOING = 2; // 0x2
field public static final int CALLTYPE_UNKNOWN = 0; // 0x0
- field public static final int CDMA_PHONE = 1; // 0x1
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CDMA_PHONE = 1; // 0x1
field @NonNull public static final android.os.Parcelable.Creator CREATOR;
field public static final int GSM_PHONE = 2; // 0x2
field public static final int IMS_PHONE = 4; // 0x4
@@ -15193,7 +15013,7 @@ package android.telephony {
field public static final String KEY_GBA_UA_SECURITY_ORGANIZATION_INT = "gba_ua_security_organization_int";
field public static final String KEY_GBA_UA_SECURITY_PROTOCOL_INT = "gba_ua_security_protocol_int";
field public static final String KEY_GBA_UA_TLS_CIPHER_SUITE_INT = "gba_ua_tls_cipher_suite_int";
- field public static final String KEY_SUPPORT_CDMA_1X_VOICE_CALLS_BOOL = "support_cdma_1x_voice_calls_bool";
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final String KEY_SUPPORT_CDMA_1X_VOICE_CALLS_BOOL = "support_cdma_1x_voice_calls_bool";
}
public static final class CarrierConfigManager.Wifi {
@@ -15280,8 +15100,8 @@ package android.telephony {
ctor public CellBroadcastService();
method @NonNull @WorkerThread public abstract CharSequence getCellBroadcastAreaInfo(int);
method @CallSuper public android.os.IBinder onBind(@Nullable android.content.Intent);
- method public abstract void onCdmaCellBroadcastSms(int, @NonNull byte[], int);
- method public abstract void onCdmaScpMessage(int, @NonNull java.util.List, @NonNull String, @NonNull java.util.function.Consumer);
+ method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public void onCdmaCellBroadcastSms(int, @NonNull byte[], int);
+ method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public void onCdmaScpMessage(int, @NonNull java.util.List, @NonNull String, @NonNull java.util.function.Consumer);
method public abstract void onGsmCellBroadcastSms(int, @NonNull byte[]);
field public static final String CELL_BROADCAST_SERVICE_INTERFACE = "android.telephony.CellBroadcastService";
}
@@ -15291,9 +15111,9 @@ package android.telephony {
method @NonNull public abstract android.telephony.CellIdentity sanitizeLocationInfo();
}
- public final class CellIdentityCdma extends android.telephony.CellIdentity {
- method @NonNull public android.telephony.cdma.CdmaCellLocation asCellLocation();
- method @NonNull public android.telephony.CellIdentityCdma sanitizeLocationInfo();
+ @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public final class CellIdentityCdma extends android.telephony.CellIdentity {
+ method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") @NonNull public android.telephony.cdma.CdmaCellLocation asCellLocation();
+ method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") @NonNull public android.telephony.CellIdentityCdma sanitizeLocationInfo();
}
public final class CellIdentityGsm extends android.telephony.CellIdentity {
@@ -15709,16 +15529,16 @@ package android.telephony {
field public static final int BUSY = 17; // 0x11
field public static final int CALL_BARRED = 240; // 0xf0
field public static final int CALL_REJECTED = 21; // 0x15
- field public static final int CDMA_ACCESS_BLOCKED = 1009; // 0x3f1
- field public static final int CDMA_ACCESS_FAILURE = 1006; // 0x3ee
- field public static final int CDMA_DROP = 1001; // 0x3e9
- field public static final int CDMA_INTERCEPT = 1002; // 0x3ea
- field public static final int CDMA_LOCKED_UNTIL_POWER_CYCLE = 1000; // 0x3e8
- field public static final int CDMA_NOT_EMERGENCY = 1008; // 0x3f0
- field public static final int CDMA_PREEMPTED = 1007; // 0x3ef
- field public static final int CDMA_REORDER = 1003; // 0x3eb
- field public static final int CDMA_RETRY_ORDER = 1005; // 0x3ed
- field public static final int CDMA_SO_REJECT = 1004; // 0x3ec
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CDMA_ACCESS_BLOCKED = 1009; // 0x3f1
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CDMA_ACCESS_FAILURE = 1006; // 0x3ee
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CDMA_DROP = 1001; // 0x3e9
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CDMA_INTERCEPT = 1002; // 0x3ea
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CDMA_LOCKED_UNTIL_POWER_CYCLE = 1000; // 0x3e8
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CDMA_NOT_EMERGENCY = 1008; // 0x3f0
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CDMA_PREEMPTED = 1007; // 0x3ef
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CDMA_REORDER = 1003; // 0x3eb
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CDMA_RETRY_ORDER = 1005; // 0x3ed
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CDMA_SO_REJECT = 1004; // 0x3ec
field public static final int CHANNEL_NOT_AVAIL = 44; // 0x2c
field public static final int CHANNEL_UNACCEPTABLE = 6; // 0x6
field public static final int CONDITIONAL_IE_ERROR = 100; // 0x64
@@ -16252,14 +16072,14 @@ package android.telephony {
method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public android.telephony.CarrierRestrictionRules getCarrierRestrictionRules();
method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getCarrierServicePackageName();
method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getCarrierServicePackageNameForLogicalSlot(int);
- method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getCdmaEnhancedRoamingIndicatorDisplayNumber();
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String getCdmaMdn();
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String getCdmaMdn(int);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String getCdmaMin();
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String getCdmaMin(int);
- method public String getCdmaPrlVersion();
- method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getCdmaRoamingMode();
- method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getCdmaSubscriptionMode();
+ method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getCdmaEnhancedRoamingIndicatorDisplayNumber();
+ method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String getCdmaMdn();
+ method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String getCdmaMdn(int);
+ method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String getCdmaMin();
+ method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String getCdmaMin(int);
+ method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public String getCdmaPrlVersion();
+ method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getCdmaRoamingMode();
+ method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getCdmaSubscriptionMode();
method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_CELL_BROADCASTS) public java.util.List getCellBroadcastIdRanges();
method public int getCurrentPhoneType();
method public int getCurrentPhoneType(int);
@@ -16349,7 +16169,7 @@ package android.telephony {
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void resetCarrierKeysForImsiEncryption();
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public void resetIms(int);
method @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public void resetOtaEmergencyNumberDbFilePath();
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean resetRadioConfig();
+ method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean resetRadioConfig();
method @RequiresPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL) public void resetSettings();
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int sendThermalMitigationRequest(@NonNull android.telephony.ThermalMitigationRequest);
method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int setAllowedCarriers(int, java.util.List);
@@ -16358,8 +16178,8 @@ package android.telephony {
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setCallWaitingEnabled(boolean, @Nullable java.util.concurrent.Executor, @Nullable java.util.function.Consumer);
method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setCarrierDataEnabled(boolean);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int setCarrierRestrictionRules(@NonNull android.telephony.CarrierRestrictionRules);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setCdmaRoamingMode(int);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setCdmaSubscriptionMode(int);
+ method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setCdmaRoamingMode(int);
+ method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setCdmaSubscriptionMode(int);
method @RequiresPermission(android.Manifest.permission.MODIFY_CELL_BROADCASTS) public void setCellBroadcastIdRanges(@NonNull java.util.List, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDataActivationState(int);
method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDataEnabled(int, boolean);
@@ -16423,9 +16243,9 @@ package android.telephony {
field public static final int CARRIER_PRIVILEGE_STATUS_HAS_ACCESS = 1; // 0x1
field public static final int CARRIER_PRIVILEGE_STATUS_NO_ACCESS = 0; // 0x0
field public static final int CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED = -1; // 0xffffffff
- field public static final int CDMA_SUBSCRIPTION_NV = 1; // 0x1
- field public static final int CDMA_SUBSCRIPTION_RUIM_SIM = 0; // 0x0
- field public static final int CDMA_SUBSCRIPTION_UNKNOWN = -1; // 0xffffffff
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CDMA_SUBSCRIPTION_NV = 1; // 0x1
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CDMA_SUBSCRIPTION_RUIM_SIM = 0; // 0x0
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CDMA_SUBSCRIPTION_UNKNOWN = -1; // 0xffffffff
field public static final int CELL_BROADCAST_RESULT_FAIL_ACTIVATION = 3; // 0x3
field public static final int CELL_BROADCAST_RESULT_FAIL_CONFIG = 2; // 0x2
field public static final int CELL_BROADCAST_RESULT_SUCCESS = 0; // 0x0
@@ -16642,21 +16462,21 @@ package android.telephony {
package android.telephony.cdma {
- public final class CdmaSmsCbProgramData implements android.os.Parcelable {
- method public int describeContents();
- method public int getCategory();
- method public int getOperation();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final int CATEGORY_CMAS_CHILD_ABDUCTION_EMERGENCY = 4099; // 0x1003
- field public static final int CATEGORY_CMAS_EXTREME_THREAT = 4097; // 0x1001
- field public static final int CATEGORY_CMAS_LAST_RESERVED_VALUE = 4351; // 0x10ff
- field public static final int CATEGORY_CMAS_PRESIDENTIAL_LEVEL_ALERT = 4096; // 0x1000
- field public static final int CATEGORY_CMAS_SEVERE_THREAT = 4098; // 0x1002
- field public static final int CATEGORY_CMAS_TEST_MESSAGE = 4100; // 0x1004
- field @NonNull public static final android.os.Parcelable.Creator CREATOR;
- field public static final int OPERATION_ADD_CATEGORY = 1; // 0x1
- field public static final int OPERATION_CLEAR_CATEGORIES = 2; // 0x2
- field public static final int OPERATION_DELETE_CATEGORY = 0; // 0x0
+ @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public final class CdmaSmsCbProgramData implements android.os.Parcelable {
+ method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public int describeContents();
+ method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public int getCategory();
+ method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public int getOperation();
+ method @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public void writeToParcel(android.os.Parcel, int);
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CATEGORY_CMAS_CHILD_ABDUCTION_EMERGENCY = 4099; // 0x1003
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CATEGORY_CMAS_EXTREME_THREAT = 4097; // 0x1001
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CATEGORY_CMAS_LAST_RESERVED_VALUE = 4351; // 0x10ff
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CATEGORY_CMAS_PRESIDENTIAL_LEVEL_ALERT = 4096; // 0x1000
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CATEGORY_CMAS_SEVERE_THREAT = 4098; // 0x1002
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CATEGORY_CMAS_TEST_MESSAGE = 4100; // 0x1004
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") @NonNull public static final android.os.Parcelable.Creator CREATOR;
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int OPERATION_ADD_CATEGORY = 1; // 0x1
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int OPERATION_CLEAR_CATEGORIES = 2; // 0x2
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int OPERATION_DELETE_CATEGORY = 0; // 0x0
}
}
@@ -17984,7 +17804,7 @@ package android.telephony.ims {
field public static final int CAPABILITY_UPDATE_TRIGGER_ETAG_EXPIRED = 1; // 0x1
field public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_2G = 7; // 0x7
field public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_3G = 6; // 0x6
- field public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_EHRPD = 4; // 0x4
+ field @Deprecated @FlaggedApi("com.android.internal.telephony.flags.deprecate_cdma") public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_EHRPD = 4; // 0x4
field public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_HSPAPLUS = 5; // 0x5
field public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_INTERNET_PDN = 12; // 0xc
field public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_IWLAN = 9; // 0x9
@@ -18833,6 +18653,10 @@ package android.telephony.satellite {
method @FlaggedApi("com.android.internal.telephony.flags.oem_enabled_satellite_flag") public void onSatelliteDatagramReceived(long, @NonNull android.telephony.satellite.SatelliteDatagram, int, @NonNull java.util.function.Consumer);
}
+ @FlaggedApi("com.android.internal.telephony.flags.satellite_system_apis") public interface SatelliteDisallowedReasonsCallback {
+ method public void onSatelliteDisallowedReasonsChanged(@NonNull int[]);
+ }
+
@FlaggedApi("com.android.internal.telephony.flags.satellite_system_apis") public final class SatelliteInfo implements android.os.Parcelable {
method public int describeContents();
method @NonNull public java.util.List getBands();
@@ -18848,6 +18672,7 @@ package android.telephony.satellite {
method @FlaggedApi("com.android.internal.telephony.flags.satellite_system_apis") @RequiresPermission(android.Manifest.permission.SATELLITE_COMMUNICATION) public void deprovisionSatellite(@NonNull java.util.List, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver);
method @FlaggedApi("com.android.internal.telephony.flags.oem_enabled_satellite_flag") @RequiresPermission(android.Manifest.permission.SATELLITE_COMMUNICATION) public void deprovisionService(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer);
method @FlaggedApi("com.android.internal.telephony.flags.carrier_enabled_satellite_flag") @NonNull @RequiresPermission(android.Manifest.permission.SATELLITE_COMMUNICATION) public java.util.Set getAttachRestrictionReasonsForCarrier(int);
+ method @FlaggedApi("com.android.internal.telephony.flags.satellite_system_apis") @NonNull @RequiresPermission(android.Manifest.permission.SATELLITE_COMMUNICATION) public int[] getSatelliteDisallowedReasons();
method @FlaggedApi("com.android.internal.telephony.flags.carrier_enabled_satellite_flag") @NonNull @RequiresPermission(android.Manifest.permission.SATELLITE_COMMUNICATION) public java.util.List getSatellitePlmnsForCarrier(int);
method @FlaggedApi("com.android.internal.telephony.flags.oem_enabled_satellite_flag") @RequiresPermission(android.Manifest.permission.SATELLITE_COMMUNICATION) public void pollPendingDatagrams(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer);
method @FlaggedApi("com.android.internal.telephony.flags.satellite_system_apis") @RequiresPermission(android.Manifest.permission.SATELLITE_COMMUNICATION) public void provisionSatellite(@NonNull java.util.List, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver);
@@ -18858,6 +18683,8 @@ package android.telephony.satellite {
method @FlaggedApi("com.android.internal.telephony.flags.oem_enabled_satellite_flag") @RequiresPermission(android.Manifest.permission.SATELLITE_COMMUNICATION) public int registerForModemStateChanged(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.satellite.SatelliteModemStateCallback);
method @FlaggedApi("com.android.internal.telephony.flags.oem_enabled_satellite_flag") @RequiresPermission(android.Manifest.permission.SATELLITE_COMMUNICATION) public void registerForNtnSignalStrengthChanged(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.satellite.NtnSignalStrengthCallback);
method @FlaggedApi("com.android.internal.telephony.flags.oem_enabled_satellite_flag") @RequiresPermission(android.Manifest.permission.SATELLITE_COMMUNICATION) public int registerForProvisionStateChanged(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.satellite.SatelliteProvisionStateCallback);
+ method @FlaggedApi("com.android.internal.telephony.flags.satellite_system_apis") @RequiresPermission(android.Manifest.permission.SATELLITE_COMMUNICATION) public void registerForSatelliteDisallowedReasonsChanged(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.satellite.SatelliteDisallowedReasonsCallback);
+ method @FlaggedApi("com.android.internal.telephony.flags.satellite_system_apis") @RequiresPermission(android.Manifest.permission.SATELLITE_COMMUNICATION) public int registerForSelectedNbIotSatelliteSubscriptionChanged(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.satellite.SelectedNbIotSatelliteSubscriptionCallback);
method @FlaggedApi("com.android.internal.telephony.flags.satellite_system_apis") @RequiresPermission(android.Manifest.permission.SATELLITE_COMMUNICATION) public int registerForSupportedStateChanged(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.satellite.SatelliteSupportedStateCallback);
method @FlaggedApi("com.android.internal.telephony.flags.carrier_enabled_satellite_flag") @RequiresPermission(android.Manifest.permission.SATELLITE_COMMUNICATION) public void removeAttachRestrictionForCarrier(int, int, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer);
method @FlaggedApi("com.android.internal.telephony.flags.carrier_enabled_satellite_flag") @RequiresPermission(android.Manifest.permission.SATELLITE_COMMUNICATION) public void requestAttachEnabledForCarrier(int, boolean, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer);
@@ -18871,7 +18698,10 @@ package android.telephony.satellite {
method @FlaggedApi("com.android.internal.telephony.flags.oem_enabled_satellite_flag") @RequiresPermission(android.Manifest.permission.SATELLITE_COMMUNICATION) public void requestIsProvisioned(@NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver);
method @FlaggedApi("com.android.internal.telephony.flags.oem_enabled_satellite_flag") public void requestIsSupported(@NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver);
method @FlaggedApi("com.android.internal.telephony.flags.oem_enabled_satellite_flag") @RequiresPermission(android.Manifest.permission.SATELLITE_COMMUNICATION) public void requestNtnSignalStrength(@NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver);
+ method @FlaggedApi("com.android.internal.telephony.flags.satellite_system_apis") @RequiresPermission(android.Manifest.permission.SATELLITE_COMMUNICATION) public void requestSatelliteAccessConfigurationForCurrentLocation(@NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver);
+ method @FlaggedApi("com.android.internal.telephony.flags.satellite_system_apis") @RequiresPermission(android.Manifest.permission.SATELLITE_COMMUNICATION) public void requestSatelliteDisplayName(@NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver);
method @FlaggedApi("com.android.internal.telephony.flags.satellite_system_apis") @RequiresPermission(android.Manifest.permission.SATELLITE_COMMUNICATION) public void requestSatelliteSubscriberProvisionStatus(@NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver,android.telephony.satellite.SatelliteManager.SatelliteException>);
+ method @FlaggedApi("com.android.internal.telephony.flags.satellite_system_apis") @RequiresPermission(android.Manifest.permission.SATELLITE_COMMUNICATION) public void requestSelectedNbIotSatelliteSubscriptionId(@NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver);
method @FlaggedApi("com.android.internal.telephony.flags.oem_enabled_satellite_flag") @RequiresPermission(android.Manifest.permission.SATELLITE_COMMUNICATION) public void requestTimeForNextSatelliteVisibility(@NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver);
method @FlaggedApi("com.android.internal.telephony.flags.oem_enabled_satellite_flag") @RequiresPermission(android.Manifest.permission.SATELLITE_COMMUNICATION) public void sendDatagram(int, @NonNull android.telephony.satellite.SatelliteDatagram, boolean, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer);
method @FlaggedApi("com.android.internal.telephony.flags.oem_enabled_satellite_flag") @RequiresPermission(android.Manifest.permission.SATELLITE_COMMUNICATION) public void setDeviceAlignedWithSatellite(boolean);
@@ -18883,6 +18713,8 @@ package android.telephony.satellite {
method @FlaggedApi("com.android.internal.telephony.flags.oem_enabled_satellite_flag") @RequiresPermission(android.Manifest.permission.SATELLITE_COMMUNICATION) public void unregisterForModemStateChanged(@NonNull android.telephony.satellite.SatelliteModemStateCallback);
method @FlaggedApi("com.android.internal.telephony.flags.oem_enabled_satellite_flag") @RequiresPermission(android.Manifest.permission.SATELLITE_COMMUNICATION) public void unregisterForNtnSignalStrengthChanged(@NonNull android.telephony.satellite.NtnSignalStrengthCallback);
method @FlaggedApi("com.android.internal.telephony.flags.oem_enabled_satellite_flag") @RequiresPermission(android.Manifest.permission.SATELLITE_COMMUNICATION) public void unregisterForProvisionStateChanged(@NonNull android.telephony.satellite.SatelliteProvisionStateCallback);
+ method @FlaggedApi("com.android.internal.telephony.flags.satellite_system_apis") @RequiresPermission(android.Manifest.permission.SATELLITE_COMMUNICATION) public void unregisterForSatelliteDisallowedReasonsChanged(@NonNull android.telephony.satellite.SatelliteDisallowedReasonsCallback);
+ method @FlaggedApi("com.android.internal.telephony.flags.satellite_system_apis") @RequiresPermission(android.Manifest.permission.SATELLITE_COMMUNICATION) public void unregisterForSelectedNbIotSatelliteSubscriptionChanged(@NonNull android.telephony.satellite.SelectedNbIotSatelliteSubscriptionCallback);
method @FlaggedApi("com.android.internal.telephony.flags.satellite_system_apis") @RequiresPermission(android.Manifest.permission.SATELLITE_COMMUNICATION) public void unregisterForSupportedStateChanged(@NonNull android.telephony.satellite.SatelliteSupportedStateCallback);
field @FlaggedApi("com.android.internal.telephony.flags.satellite_system_apis") public static final String ACTION_SATELLITE_START_NON_EMERGENCY_SESSION = "android.telephony.satellite.action.SATELLITE_START_NON_EMERGENCY_SESSION";
field @FlaggedApi("com.android.internal.telephony.flags.satellite_system_apis") public static final String ACTION_SATELLITE_SUBSCRIBER_ID_LIST_CHANGED = "android.telephony.satellite.action.SATELLITE_SUBSCRIBER_ID_LIST_CHANGED";
@@ -18954,6 +18786,7 @@ package android.telephony.satellite {
field @FlaggedApi("com.android.internal.telephony.flags.oem_enabled_satellite_flag") public static final int SATELLITE_RESULT_NOT_REACHABLE = 18; // 0x12
field @FlaggedApi("com.android.internal.telephony.flags.oem_enabled_satellite_flag") public static final int SATELLITE_RESULT_NOT_SUPPORTED = 20; // 0x14
field @FlaggedApi("com.android.internal.telephony.flags.oem_enabled_satellite_flag") public static final int SATELLITE_RESULT_NO_RESOURCES = 12; // 0xc
+ field @FlaggedApi("com.android.internal.telephony.flags.satellite_system_apis") public static final int SATELLITE_RESULT_NO_VALID_SATELLITE_SUBSCRIPTION = 30; // 0x1e
field @FlaggedApi("com.android.internal.telephony.flags.oem_enabled_satellite_flag") public static final int SATELLITE_RESULT_RADIO_NOT_AVAILABLE = 10; // 0xa
field @FlaggedApi("com.android.internal.telephony.flags.oem_enabled_satellite_flag") public static final int SATELLITE_RESULT_REQUEST_ABORTED = 15; // 0xf
field @FlaggedApi("com.android.internal.telephony.flags.oem_enabled_satellite_flag") public static final int SATELLITE_RESULT_REQUEST_FAILED = 9; // 0x9
@@ -19056,6 +18889,10 @@ package android.telephony.satellite {
method @FlaggedApi("com.android.internal.telephony.flags.satellite_system_apis") public default void onSendDatagramStateChanged(int, int, int, int);
}
+ @FlaggedApi("com.android.internal.telephony.flags.satellite_system_apis") public interface SelectedNbIotSatelliteSubscriptionCallback {
+ method public void onSelectedNbIotSatelliteSubscriptionChanged(int);
+ }
+
@FlaggedApi("com.android.internal.telephony.flags.satellite_system_apis") public final class SystemSelectionSpecifier implements android.os.Parcelable {
method public int describeContents();
method @NonNull public int[] getBands();
@@ -19172,8 +19009,10 @@ package android.view {
public static class WindowManager.LayoutParams extends android.view.ViewGroup.LayoutParams implements android.os.Parcelable {
method public final long getUserActivityTimeout();
+ method @FlaggedApi("com.android.hardware.input.override_power_key_behavior_in_focused_window") @RequiresPermission(android.Manifest.permission.OVERRIDE_SYSTEM_KEY_BEHAVIOR_IN_FOCUSED_WINDOW) public boolean isReceivePowerKeyDoublePressEnabled();
method public boolean isSystemApplicationOverlay();
method @FlaggedApi("android.companion.virtualdevice.flags.status_bar_and_insets") public void setInsetsParams(@NonNull java.util.List);
+ method @FlaggedApi("com.android.hardware.input.override_power_key_behavior_in_focused_window") @RequiresPermission(android.Manifest.permission.OVERRIDE_SYSTEM_KEY_BEHAVIOR_IN_FOCUSED_WINDOW) public void setReceivePowerKeyDoublePressEnabled(boolean);
method @RequiresPermission(android.Manifest.permission.SYSTEM_APPLICATION_OVERLAY) public void setSystemApplicationOverlay(boolean);
method public final void setUserActivityTimeout(long);
field @RequiresPermission(android.Manifest.permission.HIDE_NON_SYSTEM_OVERLAY_WINDOWS) public static final int SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS = 524288; // 0x80000
@@ -19299,6 +19138,20 @@ package android.view.inputmethod {
}
+package android.view.textclassifier {
+
+ public final class TextClassificationManager {
+ method @FlaggedApi("android.permission.flags.text_classifier_choice_api_enabled") @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_TEXT_CLASSIFIER_BY_TYPE) public android.view.textclassifier.TextClassifier getClassifier(int);
+ }
+
+ public interface TextClassifier {
+ field @FlaggedApi("android.permission.flags.text_classifier_choice_api_enabled") public static final int CLASSIFIER_TYPE_ANDROID_DEFAULT = 2; // 0x2
+ field @FlaggedApi("android.permission.flags.text_classifier_choice_api_enabled") public static final int CLASSIFIER_TYPE_DEVICE_DEFAULT = 1; // 0x1
+ field @FlaggedApi("android.permission.flags.text_classifier_choice_api_enabled") public static final int CLASSIFIER_TYPE_SELF_PROVIDED = 0; // 0x0
+ }
+
+}
+
package android.view.translation {
public final class TranslationCapability implements android.os.Parcelable {
diff --git a/core/api/system-lint-baseline.txt b/core/api/system-lint-baseline.txt
index 7c43891f13f28527f0abe7841497ea8cdaeab004..3b9ef959e797d1d3a07417b9435e095edbeef5c9 100644
--- a/core/api/system-lint-baseline.txt
+++ b/core/api/system-lint-baseline.txt
@@ -505,6 +505,8 @@ DeprecationMismatch: javax.microedition.khronos.egl.EGL10#eglCreatePixmapSurface
FlaggedApiLiteral: android.Manifest.permission#ACCESS_LAST_KNOWN_CELL_ID:
@FlaggedApi contains a string literal, but should reference the field generated by aconfig (com.android.server.telecom.flags.Flags.FLAG_TELECOM_RESOLVE_HIDDEN_DEPENDENCIES).
+FlaggedApiLiteral: android.Manifest.permission#ACCESS_TEXT_CLASSIFIER_BY_TYPE:
+ @FlaggedApi contains a string literal, but should reference the field generated by aconfig (android.permission.flags.Flags.FLAG_TEXT_CLASSIFIER_CHOICE_API_ENABLED).
FlaggedApiLiteral: android.Manifest.permission#BACKUP_HEALTH_CONNECT_DATA_AND_SETTINGS:
@FlaggedApi contains a string literal, but should reference the field generated by aconfig (android.permission.flags.Flags.FLAG_HEALTH_CONNECT_BACKUP_RESTORE_PERMISSION_ENABLED).
FlaggedApiLiteral: android.Manifest.permission#BIND_VERIFICATION_AGENT:
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 603677e89240a5a0cf66db070875ac5d17b75d64..6230a59a62c0b1f1b77ef5863145efb1e700237f 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -543,7 +543,6 @@ package android.app {
method @FlaggedApi("com.android.window.flags.multi_crop") @RequiresPermission(android.Manifest.permission.SET_WALLPAPER) public int setBitmapWithCrops(@Nullable android.graphics.Bitmap, @NonNull java.util.Map, boolean, int) throws java.io.IOException;
method @FlaggedApi("android.app.live_wallpaper_content_handling") @RequiresPermission(android.Manifest.permission.SET_WALLPAPER) public int setBitmapWithDescription(@Nullable android.graphics.Bitmap, @NonNull android.app.wallpaper.WallpaperDescription, boolean, int) throws java.io.IOException;
method @FlaggedApi("com.android.window.flags.multi_crop") @RequiresPermission(android.Manifest.permission.SET_WALLPAPER) public int setStreamWithCrops(@NonNull java.io.InputStream, @NonNull java.util.Map, boolean, int) throws java.io.IOException;
- method @FlaggedApi("android.app.live_wallpaper_content_handling") @RequiresPermission(android.Manifest.permission.SET_WALLPAPER) public int setStreamWithDescription(@NonNull java.io.InputStream, @NonNull android.app.wallpaper.WallpaperDescription, boolean, int) throws java.io.IOException;
method public void setWallpaperZoomOut(@NonNull android.os.IBinder, float);
method public boolean shouldEnableWideColorGamut();
method public boolean wallpaperSupportsWcg(int);
@@ -658,6 +657,7 @@ package android.app.admin {
field public static final int OPERATION_SET_ALWAYS_ON_VPN_PACKAGE = 30; // 0x1e
field public static final int OPERATION_SET_APPLICATION_HIDDEN = 15; // 0xf
field public static final int OPERATION_SET_APPLICATION_RESTRICTIONS = 16; // 0x10
+ field @FlaggedApi("android.app.appfunctions.flags.enable_app_function_manager") public static final int OPERATION_SET_APP_FUNCTIONS_POLICY = 42; // 0x2a
field public static final int OPERATION_SET_CAMERA_DISABLED = 31; // 0x1f
field @FlaggedApi("android.view.contentprotection.flags.manage_device_policy_enabled") public static final int OPERATION_SET_CONTENT_PROTECTION_POLICY = 41; // 0x29
field public static final int OPERATION_SET_FACTORY_RESET_PROTECTION_POLICY = 32; // 0x20
@@ -3247,14 +3247,6 @@ package android.service.notification {
}
-package android.service.ondeviceintelligence {
-
- @FlaggedApi("android.app.ondeviceintelligence.flags.enable_on_device_intelligence") public abstract class OnDeviceIntelligenceService extends android.app.Service {
- method public void onReady();
- }
-
-}
-
package android.service.quickaccesswallet {
public interface QuickAccessWalletClient extends java.io.Closeable {
diff --git a/core/api/test-lint-baseline.txt b/core/api/test-lint-baseline.txt
index 9140bdf4fba790251139e9e4424fbec60acde3e6..349b4edffc32e2b07c53b9bf60bd1149b3a4c007 100644
--- a/core/api/test-lint-baseline.txt
+++ b/core/api/test-lint-baseline.txt
@@ -1,10 +1,4 @@
// Baseline format: 1.0
-ActionValue: android.view.contentcapture.ViewNode.ViewStructureImpl#EXTRA_VIRTUAL_STRUCTURE_TYPE:
- Inconsistent extra value; expected `android.view.contentcapture.extra.VIRTUAL_STRUCTURE_TYPE`, was `android.view.ViewStructure.extra.VIRTUAL_STRUCTURE_TYPE`
-ActionValue: android.view.contentcapture.ViewNode.ViewStructureImpl#EXTRA_VIRTUAL_STRUCTURE_VERSION_NUMBER:
- Inconsistent extra value; expected `android.view.contentcapture.extra.VIRTUAL_STRUCTURE_VERSION_NUMBER`, was `android.view.ViewStructure.extra.VIRTUAL_STRUCTURE_VERSION_NUMBER`
-
-
BannedThrow: android.os.vibrator.persistence.VibrationXmlSerializer#serialize(android.os.VibrationEffect, java.io.Writer):
Methods must not throw unchecked exceptions
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 38aea64386a0e32b32f400afeda298df8b63d6f8..03ef669c067520b6d7841cb97a21d4ddac5a5f4c 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -1279,7 +1279,24 @@ public class Activity extends ContextThemeWrapper
*
*
This method should be utilized when an activity wants to nudge the user to switch
* to the web application in cases where the web may provide the user with a better
- * experience. Note that this method does not guarantee that the education will be shown.
+ * experience. Note that this method does not guarantee that the education will be shown.
+ *
+ *
The number of times that the "Open in browser" education can be triggered by this method
+ * is limited per application, and, when shown, the education appears above the app's content.
+ * For these reasons, developers should use this method sparingly when it is least
+ * disruptive to the user to show the education and when it is optimal to switch the user to a
+ * browser session. Before requesting to show the education, developers should assert that they
+ * have set a link that can be used by the "Open in browser" feature through either
+ * {@link AssistContent#EXTRA_AUTHENTICATING_USER_WEB_URI} or
+ * {@link AssistContent#setWebUri} so that users are navigated to a relevant page if they choose
+ * to switch to the browser. If a URI is not set using either method, "Open in browser" will
+ * utilize a generic link if available which will direct users to the homepage of the site
+ * associated with the app. The generic link is provided for a limited number of applications by
+ * the system and cannot be edited by developers. If none of these options contains a valid URI,
+ * the user will not be provided with the option to switch to the browser and the education will
+ * not be shown if requested.
+ *
+ * @see android.app.assist.AssistContent#EXTRA_SESSION_TRANSFER_WEB_URI
*/
@FlaggedApi(com.android.window.flags.Flags.FLAG_ENABLE_DESKTOP_WINDOWING_APP_TO_WEB_EDUCATION)
public final void requestOpenInBrowserEducation() {
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 33ba0586504243a3fee4fd5bdc7f5ea2390565a9..69d3e8d4c0d2ef693984473fc4997993460c1a45 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -1189,6 +1189,18 @@ public class ActivityManager {
return procState == PROCESS_STATE_FOREGROUND_SERVICE;
}
+ /** @hide Should this process state be considered jank perceptible? */
+ public static final boolean isProcStateJankPerceptible(int procState) {
+ if (Flags.jankPerceptibleNarrow()) {
+ return procState == PROCESS_STATE_PERSISTENT_UI
+ || procState == PROCESS_STATE_TOP
+ || procState == PROCESS_STATE_IMPORTANT_FOREGROUND
+ || procState == PROCESS_STATE_TOP_SLEEPING;
+ } else {
+ return !isProcStateCached(procState);
+ }
+ }
+
/** @hide requestType for assist context: only basic information. */
public static final int ASSIST_CONTEXT_BASIC = 0;
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index eccb6ffb281c34866fa8c8efe34c78fbdbf6f969..abdfb53537f89e1eb3046fff140ae2da44548256 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -44,6 +44,8 @@ import android.os.PowerExemptionManager.ReasonCode;
import android.os.PowerExemptionManager.TempAllowListType;
import android.os.TransactionTooLargeException;
import android.os.WorkSource;
+import android.os.instrumentation.IOffsetCallback;
+import android.os.instrumentation.MethodDescriptor;
import android.util.ArraySet;
import android.util.Pair;
@@ -1351,6 +1353,14 @@ public abstract class ActivityManagerInternal {
public abstract void killApplicationSync(String pkgName, int appId, int userId,
String reason, int exitInfoReason);
+ /**
+ * Queries the offset data for a given method on a process.
+ * @hide
+ */
+ public abstract void getExecutableMethodFileOffsets(@NonNull String processName,
+ int pid, int uid, @NonNull MethodDescriptor methodDescriptor,
+ @NonNull IOffsetCallback callback);
+
/**
* Add a creator token for all embedded intents (stored as extra) of the given intent.
*
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 3c1cce973b3a2fc5617505e0b7c8abcc960b7ad5..48b74f2d07767eeaf43893f028028f6caa3d2ab8 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -165,6 +165,10 @@ import android.os.TelephonyServiceManager;
import android.os.Trace;
import android.os.UserHandle;
import android.os.UserManager;
+import android.os.instrumentation.ExecutableMethodFileOffsets;
+import android.os.instrumentation.IOffsetCallback;
+import android.os.instrumentation.MethodDescriptor;
+import android.os.instrumentation.MethodDescriptorParser;
import android.permission.IPermissionManager;
import android.provider.BlockedNumberContract;
import android.provider.CalendarContract;
@@ -1372,7 +1376,8 @@ public final class ActivityThread extends ClientTransactionHandler
data.startRequestedElapsedTime = startRequestedElapsedTime;
data.startRequestedUptime = startRequestedUptime;
updateCompatOverrideScale(compatInfo);
- CompatibilityInfo.applyOverrideScaleIfNeeded(config);
+ updateCompatOverrideDisplayRotation(compatInfo);
+ CompatibilityInfo.applyOverrideIfNeeded(config);
sendMessage(H.BIND_APPLICATION, data);
}
@@ -1386,6 +1391,15 @@ public final class ActivityThread extends ClientTransactionHandler
}
}
+ private void updateCompatOverrideDisplayRotation(@NonNull CompatibilityInfo info) {
+ if (info.isOverrideDisplayRotationRequired()) {
+ CompatibilityInfo.setOverrideDisplayRotation(info.applicationDisplayRotation);
+ } else {
+ CompatibilityInfo.setOverrideDisplayRotation(
+ WindowConfiguration.ROTATION_UNDEFINED);
+ }
+ }
+
public final void runIsolatedEntryPoint(String entryPoint, String[] entryPointArgs) {
SomeArgs args = SomeArgs.obtain();
args.arg1 = entryPoint;
@@ -2036,6 +2050,7 @@ public final class ActivityThread extends ClientTransactionHandler
ucd.pkg = pkg;
ucd.info = info;
updateCompatOverrideScale(info);
+ updateCompatOverrideDisplayRotation(info);
sendMessage(H.UPDATE_PACKAGE_COMPATIBILITY_INFO, ucd);
}
@@ -2225,6 +2240,29 @@ public final class ActivityThread extends ClientTransactionHandler
args.arg6 = uiTranslationSpec;
sendMessage(H.UPDATE_UI_TRANSLATION_STATE, args);
}
+
+ @Override
+ public void getExecutableMethodFileOffsets(
+ @NonNull MethodDescriptor methodDescriptor,
+ @NonNull IOffsetCallback resultCallback) {
+ Method method = MethodDescriptorParser.parseMethodDescriptor(
+ getClass().getClassLoader(), methodDescriptor);
+ VMDebug.ExecutableMethodFileOffsets location =
+ VMDebug.getExecutableMethodFileOffsets(method);
+ try {
+ if (location == null) {
+ resultCallback.onResult(null);
+ return;
+ }
+ ExecutableMethodFileOffsets ret = new ExecutableMethodFileOffsets();
+ ret.containerPath = location.getContainerPath();
+ ret.containerOffset = location.getContainerOffset();
+ ret.methodOffset = location.getMethodOffset();
+ resultCallback.onResult(ret);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
}
private @NonNull SafeCancellationTransport createSafeCancellationTransport(
@@ -3907,12 +3945,7 @@ public final class ActivityThread extends ClientTransactionHandler
if (mLastProcessState == processState) {
return;
}
- // Do not issue a transitional GC if we are transitioning between 2 cached states.
- // Only update if the state flips between cached and uncached or vice versa
- if (ActivityManager.isProcStateCached(mLastProcessState)
- != ActivityManager.isProcStateCached(processState)) {
- updateVmProcessState(processState);
- }
+ updateVmProcessState(mLastProcessState, processState);
mLastProcessState = processState;
if (localLOGV) {
Slog.i(TAG, "******************* PROCESS STATE CHANGED TO: " + processState
@@ -3921,18 +3954,21 @@ public final class ActivityThread extends ClientTransactionHandler
}
}
+ /** Converts a process state to a VM process state. */
+ private static int toVmProcessState(int processState) {
+ final int state = ActivityManager.isProcStateJankPerceptible(processState)
+ ? VM_PROCESS_STATE_JANK_PERCEPTIBLE
+ : VM_PROCESS_STATE_JANK_IMPERCEPTIBLE;
+ return state;
+ }
+
/** Update VM state based on ActivityManager.PROCESS_STATE_* constants. */
- // Currently ART VM only uses state updates for Transitional GC, and thus
- // this function initiates a Transitional GC for transitions into Cached apps states.
- private void updateVmProcessState(int processState) {
- // Only a transition into Cached state should result in a Transitional GC request
- // to the ART runtime. Update VM state to JANK_IMPERCEPTIBLE in that case.
- // Note that there are 4 possible cached states currently, all of which are
- // JANK_IMPERCEPTIBLE from GC point of view.
- final int state = ActivityManager.isProcStateCached(processState)
- ? VM_PROCESS_STATE_JANK_IMPERCEPTIBLE
- : VM_PROCESS_STATE_JANK_PERCEPTIBLE;
- VMRuntime.getRuntime().updateProcessState(state);
+ private void updateVmProcessState(int lastProcessState, int newProcessState) {
+ final int state = toVmProcessState(newProcessState);
+ if (lastProcessState == PROCESS_STATE_UNKNOWN
+ || state != toVmProcessState(lastProcessState)) {
+ VMRuntime.getRuntime().updateProcessState(state);
+ }
}
@Override
@@ -5159,7 +5195,7 @@ public final class ActivityThread extends ClientTransactionHandler
try {
if (doRebind) {
ActivityManager.getService().unbindFinished(
- data.token, data.intent, doRebind);
+ data.token, data.intent);
} else {
ActivityManager.getService().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_UNBIND, 0, 0, data.intent);
diff --git a/core/java/android/app/BroadcastStickyCache.java b/core/java/android/app/BroadcastStickyCache.java
index fe2e1075235545c504d5e160383b5913df3a8f6c..1f627794a0f46a4e6628c524c1ab80d5fa17c0c8 100644
--- a/core/java/android/app/BroadcastStickyCache.java
+++ b/core/java/android/app/BroadcastStickyCache.java
@@ -35,6 +35,7 @@ import android.telephony.TelephonyManager;
import android.util.ArrayMap;
import android.view.WindowManagerPolicyConstants;
+import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
@@ -71,8 +72,10 @@ public class BroadcastStickyCache {
@VisibleForTesting
public static final ArrayMap sActionApiNameMap = new ArrayMap<>();
+ @GuardedBy("BroadcastStickyCache.class")
private static final ArrayMap sActionConfigMap = new ArrayMap<>();
+ @GuardedBy("BroadcastStickyCache.class")
private static final ArrayMap>
sFilterCacheMap = new ArrayMap<>();
@@ -154,37 +157,44 @@ public class BroadcastStickyCache {
@Nullable String broadcastPermission,
@UserIdInt int userId,
@RegisterReceiverFlags int flags) {
- IpcDataCache intentDataCache = findIpcDataCache(filter);
-
- if (intentDataCache == null) {
- final String action = filter.getAction(0);
- final StickyBroadcastFilter stickyBroadcastFilter =
- new StickyBroadcastFilter(filter, action);
- final Config config = getConfig(action);
-
- intentDataCache =
- new IpcDataCache<>(config,
- (query) -> ActivityManager.getService().registerReceiverWithFeature(
- applicationThread,
- mBasePackageName,
- attributionTag,
- /* receiverId= */ "null",
- /* receiver= */ null,
- filter,
- broadcastPermission,
- userId,
- flags));
- sFilterCacheMap.put(stickyBroadcastFilter, intentDataCache);
+ IpcDataCache intentDataCache;
+
+ synchronized (BroadcastStickyCache.class) {
+ intentDataCache = findIpcDataCache(filter);
+
+ if (intentDataCache == null) {
+ final String action = filter.getAction(0);
+ final StickyBroadcastFilter stickyBroadcastFilter =
+ new StickyBroadcastFilter(filter, action);
+ final Config config = getConfig(action);
+
+ intentDataCache =
+ new IpcDataCache<>(config,
+ (query) -> ActivityManager.getService().registerReceiverWithFeature(
+ applicationThread,
+ mBasePackageName,
+ attributionTag,
+ /* receiverId= */ "null",
+ /* receiver= */ null,
+ filter,
+ broadcastPermission,
+ userId,
+ flags));
+ sFilterCacheMap.put(stickyBroadcastFilter, intentDataCache);
+ }
}
return intentDataCache.query(null);
}
@VisibleForTesting
public static void clearCacheForTest() {
- sFilterCacheMap.clear();
+ synchronized (BroadcastStickyCache.class) {
+ sFilterCacheMap.clear();
+ }
}
@Nullable
+ @GuardedBy("BroadcastStickyCache.class")
private static IpcDataCache findIpcDataCache(
@NonNull IntentFilter filter) {
for (int i = sFilterCacheMap.size() - 1; i >= 0; i--) {
@@ -198,12 +208,14 @@ public class BroadcastStickyCache {
}
@NonNull
+ @GuardedBy("BroadcastStickyCache.class")
private static IpcDataCache.Config getConfig(@NonNull String action) {
if (!sActionConfigMap.containsKey(action)) {
// We only need 1 entry per cache but just to be on the safer side we are choosing 32
// although we don't expect more than 1.
sActionConfigMap.put(action,
- new Config(32, IpcDataCache.MODULE_SYSTEM, sActionApiNameMap.get(action)));
+ new Config(32, IpcDataCache.MODULE_SYSTEM,
+ sActionApiNameMap.get(action)).cacheNulls(true));
}
return sActionConfigMap.get(action);
diff --git a/core/java/android/app/CameraCompatTaskInfo.java b/core/java/android/app/CameraCompatTaskInfo.java
index 432a0da15a47289f040b04c7ece9be1f8749fcb1..845d2acbaf9d05b36f80528fcccc5c4d0aa8ca10 100644
--- a/core/java/android/app/CameraCompatTaskInfo.java
+++ b/core/java/android/app/CameraCompatTaskInfo.java
@@ -16,11 +16,16 @@
package android.app;
+import static android.app.WindowConfiguration.ROTATION_UNDEFINED;
+import static android.view.Surface.ROTATION_0;
+import static android.view.Surface.ROTATION_90;
+
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.Parcel;
import android.os.Parcelable;
+import android.view.Surface;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -153,6 +158,27 @@ public class CameraCompatTaskInfo implements Parcelable {
+ "}";
}
+ /**
+ * Returns the sandboxed display rotation based on the given {@code cameraCompatMode}.
+ *
+ *
This will be what the app likely expects in its requested orientation while running on a
+ * device with portrait natural orientation: `CAMERA_COMPAT_FREEFORM_PORTRAIT_*` is 0, and
+ * `CAMERA_COMPAT_FREEFORM_LANDSCAPE_*` is 90.
+ *
+ * @return {@link WindowConfiguration#ROTATION_UNDEFINED} if not in camera compat mode.
+ */
+ @Surface.Rotation
+ public static int getDisplayRotationFromCameraCompatMode(@FreeformCameraCompatMode int
+ cameraCompatMode) {
+ return switch (cameraCompatMode) {
+ case CAMERA_COMPAT_FREEFORM_PORTRAIT_DEVICE_IN_LANDSCAPE,
+ CAMERA_COMPAT_FREEFORM_PORTRAIT_DEVICE_IN_PORTRAIT -> ROTATION_0;
+ case CAMERA_COMPAT_FREEFORM_LANDSCAPE_DEVICE_IN_LANDSCAPE,
+ CAMERA_COMPAT_FREEFORM_LANDSCAPE_DEVICE_IN_PORTRAIT -> ROTATION_90;
+ default -> ROTATION_UNDEFINED;
+ };
+ }
+
/** Human readable version of the freeform camera compat mode. */
@NonNull
public static String freeformCameraCompatModeToString(
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index 50486611a5a9553678c8749930ffc927077b62a9..ad01ad57b2d880238f385b2f50418f7d6ba4ae82 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -321,7 +321,7 @@ interface IActivityManager {
oneway void removeContentProvider(in IBinder connection, boolean stable);
@UnsupportedAppUsage
void setRequestedOrientation(in IBinder token, int requestedOrientation);
- void unbindFinished(in IBinder token, in Intent service, boolean doRebind);
+ void unbindFinished(in IBinder token, in Intent service);
@UnsupportedAppUsage
void setProcessImportant(in IBinder token, int pid, boolean isForeground, String reason);
void setServiceForeground(in ComponentName className, in IBinder token,
diff --git a/core/java/android/app/IApplicationThread.aidl b/core/java/android/app/IApplicationThread.aidl
index 06d01ecfcf06c0a2b4a63a7e4c3b0a53c074eda1..063501bf82a20874670877dbe0833704a240639e 100644
--- a/core/java/android/app/IApplicationThread.aidl
+++ b/core/java/android/app/IApplicationThread.aidl
@@ -46,6 +46,8 @@ import android.os.ParcelFileDescriptor;
import android.os.PersistableBundle;
import android.os.RemoteCallback;
import android.os.SharedMemory;
+import android.os.instrumentation.IOffsetCallback;
+import android.os.instrumentation.MethodDescriptor;
import android.view.autofill.AutofillId;
import android.view.translation.TranslationSpec;
import android.view.translation.UiTranslationSpec;
@@ -183,4 +185,6 @@ oneway interface IApplicationThread {
void scheduleTimeoutService(IBinder token, int startId);
void scheduleTimeoutServiceForType(IBinder token, int startId, int fgsType);
void schedulePing(in RemoteCallback pong);
+ void getExecutableMethodFileOffsets(in MethodDescriptor methodDescriptor,
+ in IOffsetCallback resultCallback);
}
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index a4d8a5cd4673834e27f63dc2858a1fffd087d9af..f2d6c6ad81e5c6b6a2672007018997495c40e19c 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -3221,7 +3221,6 @@ public class Notification implements Parcelable
/**
* @hide
*/
- @FlaggedApi(Flags.FLAG_UI_RICH_ONGOING)
public boolean containsCustomViews() {
return contentView != null
|| bigContentView != null
@@ -3235,7 +3234,6 @@ public class Notification implements Parcelable
/**
* @hide
*/
- @FlaggedApi(Flags.FLAG_UI_RICH_ONGOING)
public boolean hasTitle() {
return extras != null
&& (!TextUtils.isEmpty(extras.getCharSequence(EXTRA_TITLE))
@@ -3245,7 +3243,7 @@ public class Notification implements Parcelable
/**
* @hide
*/
- @FlaggedApi(Flags.FLAG_UI_RICH_ONGOING)
+ @FlaggedApi(Flags.FLAG_API_RICH_ONGOING)
public boolean hasPromotableStyle() {
final Class extends Style> notificationStyle = getNotificationStyle();
@@ -3257,11 +3255,16 @@ public class Notification implements Parcelable
}
/**
- * @hide
+ * Returns whether the notification has all the characteristics that make it eligible for
+ * {@link #FLAG_PROMOTED_ONGOING}. This method does not factor in other criteria such user
+ * preferences for the app or channel. If this returns true, it does not guarantee that the
+ * notification will be assigned FLAG_PROMOTED_ONGOING by the system, but if this returns false,
+ * it will not.
*/
- @FlaggedApi(Flags.FLAG_UI_RICH_ONGOING)
+ @FlaggedApi(Flags.FLAG_API_RICH_ONGOING)
public boolean hasPromotableCharacteristics() {
return isColorizedRequested()
+ && isOngoingEvent()
&& hasTitle()
&& !isGroupSummary()
&& !containsCustomViews()
@@ -4155,6 +4158,13 @@ public class Notification implements Parcelable
return extras.getString(EXTRA_SHORT_CRITICAL_TEXT);
}
+ /**
+ * @hide
+ */
+ public boolean isOngoingEvent() {
+ return (flags & FLAG_ONGOING_EVENT) != 0;
+ }
+
/**
* @hide
*/
@@ -14829,10 +14839,7 @@ public class Notification implements Parcelable
if (isColorized) {
if (rawColor == COLOR_DEFAULT) {
- int[] attrs = {R.attr.materialColorSecondary};
- try (TypedArray ta = obtainDayNightAttributes(ctx, attrs)) {
- mBackgroundColor = getColor(ta, 0, Color.WHITE);
- }
+ mBackgroundColor = ctx.getColor(R.color.materialColorSecondary);
} else {
mBackgroundColor = rawColor;
}
@@ -14864,30 +14871,25 @@ public class Notification implements Parcelable
mRippleAlpha = 0x33;
} else {
int[] attrs = {
- R.attr.materialColorSurfaceContainerHigh,
- R.attr.materialColorOnSurface,
- R.attr.materialColorOnSurfaceVariant,
- R.attr.materialColorPrimary,
- R.attr.materialColorSecondary,
- R.attr.materialColorTertiary,
- R.attr.materialColorOnTertiary,
- R.attr.materialColorTertiaryFixedDim,
- R.attr.materialColorOnTertiaryFixed,
R.attr.colorError,
R.attr.colorControlHighlight
};
+
+ mBackgroundColor = ctx.getColor(R.color.materialColorSurfaceContainerHigh);
+ mPrimaryTextColor = ctx.getColor(R.color.materialColorOnSurface);
+ mSecondaryTextColor = ctx.getColor(R.color.materialColorOnSurfaceVariant);
+ mPrimaryAccentColor = ctx.getColor(R.color.materialColorPrimary);
+ mSecondaryAccentColor = ctx.getColor(R.color.materialColorSecondary);
+ mTertiaryAccentColor = ctx.getColor(R.color.materialColorTertiary);
+ mOnTertiaryAccentTextColor = ctx.getColor(R.color.materialColorOnTertiary);
+ mTertiaryFixedDimAccentColor = ctx.getColor(
+ R.color.materialColorTertiaryFixedDim);
+ mOnTertiaryFixedAccentTextColor = ctx.getColor(
+ R.color.materialColorOnTertiaryFixed);
+
try (TypedArray ta = obtainDayNightAttributes(ctx, attrs)) {
- mBackgroundColor = getColor(ta, 0, nightMode ? Color.BLACK : Color.WHITE);
- mPrimaryTextColor = getColor(ta, 1, COLOR_INVALID);
- mSecondaryTextColor = getColor(ta, 2, COLOR_INVALID);
- mPrimaryAccentColor = getColor(ta, 3, COLOR_INVALID);
- mSecondaryAccentColor = getColor(ta, 4, COLOR_INVALID);
- mTertiaryAccentColor = getColor(ta, 5, COLOR_INVALID);
- mOnTertiaryAccentTextColor = getColor(ta, 6, COLOR_INVALID);
- mTertiaryFixedDimAccentColor = getColor(ta, 7, COLOR_INVALID);
- mOnTertiaryFixedAccentTextColor = getColor(ta, 8, COLOR_INVALID);
- mErrorColor = getColor(ta, 9, COLOR_INVALID);
- mRippleAlpha = Color.alpha(getColor(ta, 10, 0x33ffffff));
+ mErrorColor = getColor(ta, 0, COLOR_INVALID);
+ mRippleAlpha = Color.alpha(getColor(ta, 1, 0x33ffffff));
}
mContrastColor = calculateContrastColor(ctx, rawColor, mPrimaryAccentColor,
mBackgroundColor, nightMode);
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index 87c86191203671df6699433524dd187930f70009..8ed66eb7e6c0fb206ea9570bf42269a45234b1be 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -49,7 +49,6 @@ import android.net.Uri;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
-import android.os.Handler;
import android.os.IBinder;
import android.os.Parcel;
import android.os.Parcelable;
@@ -61,15 +60,18 @@ import android.provider.Settings;
import android.provider.Settings.Global;
import android.service.notification.Adjustment;
import android.service.notification.Condition;
+import android.service.notification.RateEstimator;
import android.service.notification.StatusBarNotification;
import android.service.notification.ZenDeviceEffects;
import android.service.notification.ZenModeConfig;
import android.service.notification.ZenPolicy;
import android.util.Log;
+import android.util.LruCache;
import android.util.proto.ProtoOutputStream;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.time.InstantSource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
@@ -643,9 +645,17 @@ public class NotificationManager {
*/
public static int MAX_SERVICE_COMPONENT_NAME_LENGTH = 500;
+ private static final float MAX_NOTIFICATION_ENQUEUE_RATE = 5f;
+
+ private final Context mContext;
private final Map
mCallNotificationEventCallbacks = new HashMap<>();
+ private final InstantSource mClock;
+ private final RateEstimator mEnqueueRateEstimator = new RateEstimator();
+ private final LruCache mEnqueuedNotificationKeys = new LruCache<>(10);
+ private final Object mEnqueueThrottleLock = new Object();
+
@UnsupportedAppUsage
private static INotificationManager sService;
@@ -661,10 +671,17 @@ public class NotificationManager {
return sService;
}
+ /** @hide */
+ protected INotificationManager service() {
+ return getService();
+ }
+
+ /** {@hide} */
@UnsupportedAppUsage
- /*package*/ NotificationManager(Context context, Handler handler)
+ public NotificationManager(Context context, InstantSource clock)
{
mContext = context;
+ mClock = clock;
}
/** {@hide} */
@@ -736,7 +753,7 @@ public class NotificationManager {
*/
public void notifyAsPackage(@NonNull String targetPackage, @Nullable String tag, int id,
@NonNull Notification notification) {
- INotificationManager service = getService();
+ INotificationManager service = service();
String sender = mContext.getPackageName();
try {
@@ -752,13 +769,12 @@ public class NotificationManager {
* @hide
*/
@UnsupportedAppUsage
- public void notifyAsUser(String tag, int id, Notification notification, UserHandle user)
+ public void notifyAsUser(@Nullable String tag, int id, Notification notification,
+ UserHandle user)
{
- INotificationManager service = getService();
+ INotificationManager service = service();
String pkg = mContext.getPackageName();
-
- if (notificationClassification()
- && NotificationChannel.SYSTEM_RESERVED_IDS.contains(notification.getChannelId())) {
+ if (discardNotify(tag, id, notification)) {
return;
}
@@ -771,6 +787,37 @@ public class NotificationManager {
}
}
+ /**
+ * Determines whether a {@link #notify} call should be skipped. If the notification is not
+ * skipped, updates tracking metadata to use in future decisions.
+ */
+ private boolean discardNotify(@Nullable String tag, int id, Notification notification) {
+ if (notificationClassification()
+ && NotificationChannel.SYSTEM_RESERVED_IDS.contains(notification.getChannelId())) {
+ return true;
+ }
+
+ if (Flags.nmBinderPerfThrottleNotify()) {
+ String key = toEnqueuedNotificationKey(tag, id);
+ long now = mClock.millis();
+ synchronized (mEnqueueThrottleLock) {
+ if (mEnqueuedNotificationKeys.get(key) != null
+ && !notification.hasCompletedProgress()
+ && mEnqueueRateEstimator.getRate(now) > MAX_NOTIFICATION_ENQUEUE_RATE) {
+ return true;
+ }
+
+ mEnqueueRateEstimator.update(now);
+ mEnqueuedNotificationKeys.put(key, Boolean.TRUE);
+ }
+ }
+
+ return false;
+ }
+ private static String toEnqueuedNotificationKey(@Nullable String tag, int id) {
+ return tag + "," + id;
+ }
+
private Notification fixNotification(Notification notification) {
String pkg = mContext.getPackageName();
// Fix the notification as best we can.
@@ -852,7 +899,7 @@ public class NotificationManager {
* @param id An identifier for this notification.
*/
public void cancelAsPackage(@NonNull String targetPackage, @Nullable String tag, int id) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
service.cancelNotificationWithTag(targetPackage, mContext.getOpPackageName(),
tag, id, mContext.getUser().getIdentifier());
@@ -865,9 +912,15 @@ public class NotificationManager {
* @hide
*/
@UnsupportedAppUsage
- public void cancelAsUser(String tag, int id, UserHandle user)
+ public void cancelAsUser(@Nullable String tag, int id, UserHandle user)
{
- INotificationManager service = getService();
+ if (Flags.nmBinderPerfThrottleNotify()) {
+ synchronized (mEnqueueThrottleLock) {
+ mEnqueuedNotificationKeys.remove(toEnqueuedNotificationKey(tag, id));
+ }
+ }
+
+ INotificationManager service = service();
String pkg = mContext.getPackageName();
if (localLOGV) Log.v(TAG, pkg + ": cancel(" + id + ")");
try {
@@ -884,7 +937,13 @@ public class NotificationManager {
*/
public void cancelAll()
{
- INotificationManager service = getService();
+ if (Flags.nmBinderPerfThrottleNotify()) {
+ synchronized (mEnqueueThrottleLock) {
+ mEnqueuedNotificationKeys.evictAll();
+ }
+ }
+
+ INotificationManager service = service();
String pkg = mContext.getPackageName();
if (localLOGV) Log.v(TAG, pkg + ": cancelAll()");
try {
@@ -907,7 +966,7 @@ public class NotificationManager {
* @param delegate Package name of the app which can send notifications on your behalf.
*/
public void setNotificationDelegate(@Nullable String delegate) {
- INotificationManager service = getService();
+ INotificationManager service = service();
String pkg = mContext.getPackageName();
if (localLOGV) Log.v(TAG, pkg + ": cancelAll()");
try {
@@ -922,7 +981,7 @@ public class NotificationManager {
* your behalf, if there currently is one.
*/
public @Nullable String getNotificationDelegate() {
- INotificationManager service = getService();
+ INotificationManager service = service();
String pkg = mContext.getPackageName();
try {
return service.getNotificationDelegate(pkg);
@@ -938,7 +997,7 @@ public class NotificationManager {
* See {@link #setNotificationDelegate(String)}.
*/
public boolean canNotifyAsPackage(@NonNull String pkg) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.canNotifyAsPackage(mContext.getPackageName(), pkg, mContext.getUserId());
} catch (RemoteException e) {
@@ -956,7 +1015,7 @@ public class NotificationManager {
* {@link android.provider.Settings#ACTION_MANAGE_APP_USE_FULL_SCREEN_INTENT}.
*/
public boolean canUseFullScreenIntent() {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.canUseFullScreenIntent(mContext.getAttributionSource());
} catch (RemoteException e) {
@@ -974,7 +1033,7 @@ public class NotificationManager {
*/
@FlaggedApi(android.app.Flags.FLAG_API_RICH_ONGOING)
public boolean canPostPromotedNotifications() {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.canBePromoted(mContext.getPackageName());
} catch (RemoteException e) {
@@ -989,7 +1048,7 @@ public class NotificationManager {
@TestApi
@FlaggedApi(android.app.Flags.FLAG_API_RICH_ONGOING)
public void setCanPostPromotedNotifications(@NonNull String pkg, int uid, boolean allowed) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
service.setCanBePromoted(pkg, uid, allowed, true);
} catch (RemoteException e) {
@@ -1024,7 +1083,7 @@ public class NotificationManager {
* @param groups The list of groups to create
*/
public void createNotificationChannelGroups(@NonNull List groups) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
service.createNotificationChannelGroups(mContext.getPackageName(),
new ParceledListSlice(groups));
@@ -1067,7 +1126,7 @@ public class NotificationManager {
* @param channels the list of channels to attempt to create.
*/
public void createNotificationChannels(@NonNull List channels) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
service.createNotificationChannels(mContext.getPackageName(),
new ParceledListSlice(channels));
@@ -1085,7 +1144,7 @@ public class NotificationManager {
* package (see {@link Context#createPackageContext(String, int)}).
*/
public NotificationChannel getNotificationChannel(String channelId) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.getNotificationChannel(mContext.getOpPackageName(),
mContext.getUserId(), mContext.getPackageName(), channelId);
@@ -1105,7 +1164,7 @@ public class NotificationManager {
*/
public @Nullable NotificationChannel getNotificationChannel(@NonNull String channelId,
@NonNull String conversationId) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.getConversationNotificationChannel(mContext.getOpPackageName(),
mContext.getUserId(), mContext.getPackageName(), channelId, true,
@@ -1124,7 +1183,7 @@ public class NotificationManager {
* {@link Context#createPackageContext(String, int)}).
*/
public List getNotificationChannels() {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.getNotificationChannels(mContext.getOpPackageName(),
mContext.getPackageName(), mContext.getUserId()).getList();
@@ -1145,7 +1204,7 @@ public class NotificationManager {
&& NotificationChannel.SYSTEM_RESERVED_IDS.contains(channelId)) {
return;
}
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
service.deleteNotificationChannel(mContext.getPackageName(), channelId);
} catch (RemoteException e) {
@@ -1159,7 +1218,7 @@ public class NotificationManager {
* The channel group must belong to your package, or null will be returned.
*/
public NotificationChannelGroup getNotificationChannelGroup(String channelGroupId) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.getNotificationChannelGroup(mContext.getPackageName(), channelGroupId);
} catch (RemoteException e) {
@@ -1171,7 +1230,7 @@ public class NotificationManager {
* Returns all notification channel groups belonging to the calling app.
*/
public List getNotificationChannelGroups() {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
final ParceledListSlice parceledList =
service.getNotificationChannelGroups(mContext.getPackageName());
@@ -1189,7 +1248,7 @@ public class NotificationManager {
* belong to it.
*/
public void deleteNotificationChannelGroup(String groupId) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
service.deleteNotificationChannelGroup(mContext.getPackageName(), groupId);
} catch (RemoteException e) {
@@ -1203,7 +1262,7 @@ public class NotificationManager {
@TestApi
public void updateNotificationChannel(@NonNull String pkg, int uid,
@NonNull NotificationChannel channel) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
service.updateNotificationChannelForPackage(pkg, uid, channel);
} catch (RemoteException e) {
@@ -1216,7 +1275,7 @@ public class NotificationManager {
*/
@TestApi
public ComponentName getEffectsSuppressor() {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.getEffectsSuppressor();
} catch (RemoteException e) {
@@ -1228,7 +1287,7 @@ public class NotificationManager {
* @hide
*/
public boolean matchesCallFilter(Bundle extras) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.matchesCallFilter(extras);
} catch (RemoteException e) {
@@ -1241,7 +1300,7 @@ public class NotificationManager {
*/
@TestApi
public void cleanUpCallersAfter(long timeThreshold) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
service.cleanUpCallersAfter(timeThreshold);
} catch (RemoteException e) {
@@ -1253,7 +1312,7 @@ public class NotificationManager {
* @hide
*/
public boolean isSystemConditionProviderEnabled(String path) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.isSystemConditionProviderEnabled(path);
} catch (RemoteException e) {
@@ -1271,7 +1330,7 @@ public class NotificationManager {
/** @hide */
public void setZenMode(int mode, Uri conditionId, String reason, boolean fromUser) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
service.setZenMode(mode, conditionId, reason, fromUser);
} catch (RemoteException e) {
@@ -1284,7 +1343,7 @@ public class NotificationManager {
* @hide
*/
public int getZenMode() {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.getZenMode();
} catch (RemoteException e) {
@@ -1297,7 +1356,7 @@ public class NotificationManager {
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public ZenModeConfig getZenModeConfig() {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.getZenModeConfig();
} catch (RemoteException e) {
@@ -1315,7 +1374,7 @@ public class NotificationManager {
*
*/
public @NonNull NotificationManager.Policy getConsolidatedNotificationPolicy() {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.getConsolidatedNotificationPolicy();
} catch (RemoteException e) {
@@ -1327,7 +1386,7 @@ public class NotificationManager {
* @hide
*/
public int getRuleInstanceCount(ComponentName owner) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.getRuleInstanceCount(owner);
} catch (RemoteException e) {
@@ -1364,7 +1423,7 @@ public class NotificationManager {
* See {@link #isNotificationPolicyAccessGranted}.
*/
public Map getAutomaticZenRules() {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
if (Flags.modesApi()) {
return service.getAutomaticZenRules();
@@ -1398,7 +1457,7 @@ public class NotificationManager {
* doesn't own the matching rule. See {@link AutomaticZenRule#getOwner}.
*/
public AutomaticZenRule getAutomaticZenRule(String id) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.getAutomaticZenRule(id);
} catch (RemoteException e) {
@@ -1426,7 +1485,7 @@ public class NotificationManager {
@NonNull
public String addAutomaticZenRule(@NonNull AutomaticZenRule automaticZenRule,
boolean fromUser) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.addAutomaticZenRule(automaticZenRule,
mContext.getPackageName(), fromUser);
@@ -1461,7 +1520,7 @@ public class NotificationManager {
@FlaggedApi(Flags.FLAG_MODES_API)
public boolean updateAutomaticZenRule(@NonNull String id,
@NonNull AutomaticZenRule automaticZenRule, boolean fromUser) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.updateAutomaticZenRule(id, automaticZenRule, fromUser);
} catch (RemoteException e) {
@@ -1481,7 +1540,7 @@ public class NotificationManager {
@FlaggedApi(Flags.FLAG_MODES_API)
@Condition.State
public int getAutomaticZenRuleState(@NonNull String id) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.getAutomaticZenRuleState(id);
} catch (RemoteException e) {
@@ -1527,7 +1586,7 @@ public class NotificationManager {
* @param condition The new state of this rule
*/
public void setAutomaticZenRuleState(@NonNull String id, @NonNull Condition condition) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
service.setAutomaticZenRuleState(id, condition);
} catch (RemoteException e) {
@@ -1555,7 +1614,7 @@ public class NotificationManager {
@TestApi
@FlaggedApi(Flags.FLAG_MODES_API)
public boolean removeAutomaticZenRule(@NonNull String id, boolean fromUser) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.removeAutomaticZenRule(id, fromUser);
} catch (RemoteException e) {
@@ -1574,7 +1633,7 @@ public class NotificationManager {
/** @hide */
public boolean removeAutomaticZenRules(String packageName, boolean fromUser) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.removeAutomaticZenRules(packageName, fromUser);
} catch (RemoteException e) {
@@ -1587,7 +1646,7 @@ public class NotificationManager {
* package.
*/
public @Importance int getImportance() {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.getPackageImportance(mContext.getPackageName());
} catch (RemoteException e) {
@@ -1602,7 +1661,7 @@ public class NotificationManager {
if (Flags.nmBinderPerfPermissionCheck()) {
return mContext.checkSelfPermission(POST_NOTIFICATIONS) == PERMISSION_GRANTED;
} else {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.areNotificationsEnabled(mContext.getPackageName());
} catch (RemoteException e) {
@@ -1623,7 +1682,7 @@ public class NotificationManager {
*/
@Deprecated
public boolean areBubblesAllowed() {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.areBubblesAllowed(mContext.getPackageName());
} catch (RemoteException e) {
@@ -1638,7 +1697,7 @@ public class NotificationManager {
* @see Notification.Builder#setBubbleMetadata(Notification.BubbleMetadata)
*/
public boolean areBubblesEnabled() {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.areBubblesEnabled(mContext.getUser());
} catch (RemoteException e) {
@@ -1665,7 +1724,7 @@ public class NotificationManager {
* @return the users' bubble preference for the app.
*/
public @BubblePreference int getBubblePreference() {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.getBubblePreferenceForPackage(mContext.getPackageName(),
Binder.getCallingUid());
@@ -1685,7 +1744,7 @@ public class NotificationManager {
* @hide
*/
public void silenceNotificationSound() {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
service.silenceNotificationSound();
} catch (RemoteException e) {
@@ -1701,7 +1760,7 @@ public class NotificationManager {
* PersistableBundle, SuspendDialogInfo) suspended}.
*/
public boolean areNotificationsPaused() {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.isPackagePaused(mContext.getPackageName());
} catch (RemoteException e) {
@@ -1724,7 +1783,7 @@ public class NotificationManager {
* user grant or denial of this access.
*/
public boolean isNotificationPolicyAccessGranted() {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.isNotificationPolicyAccessGranted(mContext.getOpPackageName());
} catch (RemoteException e) {
@@ -1745,7 +1804,7 @@ public class NotificationManager {
* {@link android.provider.Settings#ACTION_NOTIFICATION_LISTENER_SETTINGS}.
*/
public boolean isNotificationListenerAccessGranted(ComponentName listener) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.isNotificationListenerAccessGranted(listener);
} catch (RemoteException e) {
@@ -1769,7 +1828,7 @@ public class NotificationManager {
*/
@SystemApi
public boolean isNotificationAssistantAccessGranted(@NonNull ComponentName assistant) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.isNotificationAssistantAccessGranted(assistant);
} catch (RemoteException e) {
@@ -1785,7 +1844,7 @@ public class NotificationManager {
* listeners}.
*/
public boolean shouldHideSilentStatusBarIcons() {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.shouldHideSilentStatusIcons(mContext.getOpPackageName());
} catch (RemoteException e) {
@@ -1804,7 +1863,7 @@ public class NotificationManager {
*/
@SystemApi
public @NonNull @Adjustment.Keys List getAllowedAssistantAdjustments() {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.getAllowedAssistantAdjustments(mContext.getOpPackageName());
} catch (RemoteException e) {
@@ -1818,7 +1877,7 @@ public class NotificationManager {
@TestApi
@FlaggedApi(android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION)
public void allowAssistantAdjustment(@NonNull String capability) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
service.allowAssistantAdjustment(capability);
} catch (RemoteException e) {
@@ -1832,7 +1891,7 @@ public class NotificationManager {
@TestApi
@FlaggedApi(android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION)
public void disallowAssistantAdjustment(@NonNull String capability) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
service.disallowAssistantAdjustment(capability);
} catch (RemoteException e) {
@@ -1843,7 +1902,7 @@ public class NotificationManager {
/** @hide */
@TestApi
public boolean isNotificationPolicyAccessGrantedForPackage(@NonNull String pkg) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.isNotificationPolicyAccessGrantedForPackage(pkg);
} catch (RemoteException e) {
@@ -1857,7 +1916,7 @@ public class NotificationManager {
@TestApi
@FlaggedApi(android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION)
public void setAssistantAdjustmentKeyTypeState(@Adjustment.Types int type, boolean enabled) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
service.setAssistantAdjustmentKeyTypeState(type, enabled);
} catch (RemoteException e) {
@@ -1870,7 +1929,7 @@ public class NotificationManager {
*/
@FlaggedApi(android.app.Flags.FLAG_NOTIFICATION_CLASSIFICATION_UI)
public void setTypeAdjustmentForPackageState(@NonNull String pkg, boolean enabled) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
service.setTypeAdjustmentForPackageState(pkg, enabled);
} catch (RemoteException e) {
@@ -1882,7 +1941,7 @@ public class NotificationManager {
* @hide
*/
public List getEnabledNotificationListenerPackages() {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.getEnabledNotificationListenerPackages();
} catch (RemoteException e) {
@@ -1899,7 +1958,7 @@ public class NotificationManager {
* {@link #setNotificationPolicy(Policy)}.
*/
public Policy getNotificationPolicy() {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.getNotificationPolicy(mContext.getOpPackageName());
} catch (RemoteException e) {
@@ -1929,7 +1988,7 @@ public class NotificationManager {
/** @hide */
public void setNotificationPolicy(@NonNull Policy policy, boolean fromUser) {
checkRequired("policy", policy);
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
service.setNotificationPolicy(mContext.getOpPackageName(), policy, fromUser);
} catch (RemoteException e) {
@@ -1939,7 +1998,7 @@ public class NotificationManager {
/** @hide */
public void setNotificationPolicyAccessGranted(String pkg, boolean granted) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
service.setNotificationPolicyAccessGranted(pkg, granted);
} catch (RemoteException e) {
@@ -1959,7 +2018,7 @@ public class NotificationManager {
@TestApi
@FlaggedApi(Flags.FLAG_MODES_API)
public @NonNull ZenPolicy getDefaultZenPolicy() {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.getDefaultZenPolicy();
} catch (RemoteException e) {
@@ -1971,7 +2030,7 @@ public class NotificationManager {
*/
@FlaggedApi(Flags.FLAG_MODES_UI)
public void setManualZenRuleDeviceEffects(@NonNull ZenDeviceEffects effects) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
service.setManualZenRuleDeviceEffects(effects);
} catch (RemoteException e) {
@@ -2008,7 +2067,7 @@ public class NotificationManager {
@RequiresPermission(android.Manifest.permission.MANAGE_NOTIFICATION_LISTENERS)
public void setNotificationListenerAccessGranted(
@NonNull ComponentName listener, boolean granted, boolean userSet) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
if (CompatChanges.isChangeEnabled(SET_LISTENER_ACCESS_GRANTED_IS_USER_AWARE)) {
service.setNotificationListenerAccessGrantedForUser(listener, mContext.getUserId(),
@@ -2024,7 +2083,7 @@ public class NotificationManager {
/** @hide */
public void setNotificationListenerAccessGrantedForUser(ComponentName listener, int userId,
boolean granted) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
service.setNotificationListenerAccessGrantedForUser(listener, userId, granted, true);
} catch (RemoteException e) {
@@ -2045,7 +2104,7 @@ public class NotificationManager {
@SystemApi
public void setNotificationAssistantAccessGranted(@Nullable ComponentName assistant,
boolean granted) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
service.setNotificationAssistantAccessGranted(assistant, granted);
} catch (RemoteException e) {
@@ -2069,7 +2128,7 @@ public class NotificationManager {
/** @hide */
public List getEnabledNotificationListeners(int userId) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.getEnabledNotificationListeners(userId);
} catch (RemoteException e) {
@@ -2080,7 +2139,7 @@ public class NotificationManager {
/** @hide */
@SystemApi
public @Nullable ComponentName getAllowedNotificationAssistant() {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.getAllowedNotificationAssistant();
} catch (RemoteException e) {
@@ -2100,16 +2159,13 @@ public class NotificationManager {
@SuppressLint("UserHandle")
public boolean hasEnabledNotificationListener(@NonNull String packageName,
@NonNull UserHandle userHandle) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return service.hasEnabledNotificationListener(packageName, userHandle.getIdentifier());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
-
- private Context mContext;
-
private static void checkRequired(String name, Object value) {
if (value == null) {
throw new IllegalArgumentException(name + " is required");
@@ -2125,7 +2181,7 @@ public class NotificationManager {
@TestApi
@RequiresPermission(android.Manifest.permission.MANAGE_TOAST_RATE_LIMITING)
public void setToastRateLimitingEnabled(boolean enable) {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
service.setToastRateLimitingEnabled(enable);
} catch (RemoteException e) {
@@ -2917,7 +2973,7 @@ public class NotificationManager {
* @return An array of {@link StatusBarNotification}.
*/
public StatusBarNotification[] getActiveNotifications() {
- final INotificationManager service = getService();
+ final INotificationManager service = service();
final String pkg = mContext.getPackageName();
try {
final ParceledListSlice parceledList
@@ -2940,7 +2996,7 @@ public class NotificationManager {
* globally.
*/
public final @InterruptionFilter int getCurrentInterruptionFilter() {
- final INotificationManager service = getService();
+ final INotificationManager service = service();
try {
return zenModeToInterruptionFilter(service.getZenMode());
} catch (RemoteException e) {
@@ -2972,7 +3028,7 @@ public class NotificationManager {
/** @hide */
public final void setInterruptionFilter(@InterruptionFilter int interruptionFilter,
boolean fromUser) {
- final INotificationManager service = getService();
+ final INotificationManager service = service();
try {
service.setInterruptionFilter(mContext.getOpPackageName(), interruptionFilter,
fromUser);
@@ -3130,7 +3186,7 @@ public class NotificationManager {
checkRequired("userHandle", userHandle);
checkRequired("executor", executor);
checkRequired("listener", listener);
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
synchronized (mCallNotificationEventCallbacks) {
CallNotificationEventCallbackStub callbackStub =
@@ -3161,7 +3217,7 @@ public class NotificationManager {
public void unregisterCallNotificationEventListener(
@NonNull CallNotificationEventListener listener) {
checkRequired("listener", listener);
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
synchronized (mCallNotificationEventCallbacks) {
CallNotificationEventCallbackStub callbackStub =
@@ -3184,7 +3240,7 @@ public class NotificationManager {
@TestApi
@FlaggedApi(android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION)
public @NonNull Set getUnsupportedAdjustmentTypes() {
- INotificationManager service = getService();
+ INotificationManager service = service();
try {
return new HashSet<>(service.getUnsupportedAdjustmentTypes());
} catch (RemoteException e) {
diff --git a/core/java/android/app/PropertyInvalidatedCache.java b/core/java/android/app/PropertyInvalidatedCache.java
index 3973c58c070841d1952633606edb29e0551243fb..1e971a5c736a8f2053fd8f4ed122afbfc230889a 100644
--- a/core/java/android/app/PropertyInvalidatedCache.java
+++ b/core/java/android/app/PropertyInvalidatedCache.java
@@ -79,6 +79,17 @@ import java.util.concurrent.atomic.AtomicLong;
@TestApi
@android.ravenwood.annotation.RavenwoodKeepWholeClass
public class PropertyInvalidatedCache {
+ /**
+ * A method to report if the PermissionManager notifications can be separated from cache
+ * invalidation. The feature relies on a series of flags; the dependency is captured in this
+ * method.
+ * @hide
+ */
+ public static boolean separatePermissionNotificationsEnabled() {
+ return isSharedMemoryAvailable()
+ && Flags.picSeparatePermissionNotifications();
+ }
+
/**
* This is a configuration class that customizes a cache instance.
* @hide
@@ -1283,6 +1294,13 @@ public class PropertyInvalidatedCache {
public static record Args(@NonNull String mModule, @Nullable String mApi,
int mMaxEntries, boolean mIsolateUids, boolean mTestMode, boolean mCacheNulls) {
+ /**
+ * Default values for fields.
+ */
+ public static final int DEFAULT_MAX_ENTRIES = 32;
+ public static final boolean DEFAULT_ISOLATE_UIDS = true;
+ public static final boolean DEFAULT_CACHE_NULLS = false;
+
// Validation: the module must be one of the known module strings and the maxEntries must
// be positive.
public Args {
@@ -1297,10 +1315,10 @@ public class PropertyInvalidatedCache {
public Args(@NonNull String module) {
this(module,
null, // api
- 32, // maxEntries
- true, // isolateUids
+ DEFAULT_MAX_ENTRIES,
+ DEFAULT_ISOLATE_UIDS,
false, // testMode
- true // allowNulls
+ DEFAULT_CACHE_NULLS
);
}
@@ -1350,7 +1368,7 @@ public class PropertyInvalidatedCache {
* Burst a property name into module and api. Throw if the key is invalid. This method is
* used in to transition legacy cache constructors to the args constructor.
*/
- private static Args parseProperty(@NonNull String name) {
+ private static Args argsFromProperty(@NonNull String name) {
throwIfInvalidCacheKey(name);
// Strip off the leading well-known prefix.
String base = name.substring(CACHE_KEY_PREFIX.length() + 1);
@@ -1373,8 +1391,9 @@ public class PropertyInvalidatedCache {
*
* @hide
*/
+ @Deprecated
public PropertyInvalidatedCache(int maxEntries, @NonNull String propertyName) {
- this(parseProperty(propertyName).maxEntries(maxEntries), propertyName, null);
+ this(argsFromProperty(propertyName).maxEntries(maxEntries), propertyName, null);
}
/**
@@ -1388,9 +1407,10 @@ public class PropertyInvalidatedCache {
* @param cacheName Name of this cache in debug and dumpsys
* @hide
*/
+ @Deprecated
public PropertyInvalidatedCache(int maxEntries, @NonNull String propertyName,
@NonNull String cacheName) {
- this(parseProperty(propertyName).maxEntries(maxEntries), cacheName, null);
+ this(argsFromProperty(propertyName).maxEntries(maxEntries), cacheName, null);
}
/**
@@ -1845,6 +1865,14 @@ public class PropertyInvalidatedCache {
invalidateCache(createPropertyName(module, api));
}
+ /**
+ * Invalidate caches in all processes that have the module and api specified in the args.
+ * @hide
+ */
+ public static void invalidateCache(@NonNull Args args) {
+ invalidateCache(createPropertyName(args.mModule, args.mApi));
+ }
+
/**
* Invalidate PropertyInvalidatedCache caches in all processes that are keyed on
* {@var name}. This function is synchronous: caches are invalidated upon return.
@@ -1921,6 +1949,10 @@ public class PropertyInvalidatedCache {
}
public AutoCorker(@NonNull String propertyName, int autoCorkDelayMs) {
+ if (separatePermissionNotificationsEnabled()) {
+ throw new IllegalStateException("AutoCorking is unavailable");
+ }
+
mPropertyName = propertyName;
mAutoCorkDelayMs = autoCorkDelayMs;
// We can't initialize mHandler here: when we're created, the main loop might not
diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java
index 3cffca796680f98c418928306e7f62b2d486ecff..51d0b18467f4efb44731522b42c2eb65087fefb8 100644
--- a/core/java/android/app/ResourcesManager.java
+++ b/core/java/android/app/ResourcesManager.java
@@ -1517,10 +1517,8 @@ public class ResourcesManager {
int changes = mResConfiguration.updateFrom(config);
if (compat != null && (mResCompatibilityInfo == null
|| !mResCompatibilityInfo.equals(compat))) {
+ changes |= compat.getCompatibilityChangesForConfig(mResCompatibilityInfo);
mResCompatibilityInfo = compat;
- changes |= ActivityInfo.CONFIG_SCREEN_LAYOUT
- | ActivityInfo.CONFIG_SCREEN_SIZE
- | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE;
}
// If a application info update was scheduled to occur in this process but has not
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 2bd2d34d54a24d923277f6519f9c31c647aefa34..920b19cd8f78ffe51fbadb3d0d22274597da88f3 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -42,8 +42,7 @@ import android.app.contentsuggestions.IContentSuggestionsManager;
import android.app.contextualsearch.ContextualSearchManager;
import android.app.ecm.EnhancedConfirmationFrameworkInitializer;
import android.app.job.JobSchedulerFrameworkInitializer;
-import android.app.ondeviceintelligence.IOnDeviceIntelligenceManager;
-import android.app.ondeviceintelligence.OnDeviceIntelligenceManager;
+import android.app.ondeviceintelligence.OnDeviceIntelligenceFrameworkInitializer;
import android.app.people.PeopleManager;
import android.app.prediction.AppPredictionManager;
import android.app.role.RoleFrameworkInitializer;
@@ -82,8 +81,6 @@ import android.content.ContentCaptureOptions;
import android.content.Context;
import android.content.IRestrictionsManager;
import android.content.RestrictionsManager;
-import android.content.integrity.AppIntegrityManager;
-import android.content.integrity.IAppIntegrityManager;
import android.content.om.IOverlayManager;
import android.content.om.OverlayManager;
import android.content.pm.ApplicationInfo;
@@ -292,6 +289,7 @@ import com.android.internal.os.IDropBoxManagerService;
import com.android.internal.policy.PhoneLayoutInflater;
import com.android.internal.util.Preconditions;
+import java.time.InstantSource;
import java.util.Map;
import java.util.Objects;
@@ -628,7 +626,7 @@ public final class SystemServiceRegistry {
com.android.internal.R.style.Theme_Holo_Dialog,
com.android.internal.R.style.Theme_DeviceDefault_Dialog,
com.android.internal.R.style.Theme_DeviceDefault_Light_Dialog)),
- ctx.mMainThread.getHandler());
+ InstantSource.system());
}});
registerService(Context.PEOPLE_SERVICE, PeopleManager.class,
@@ -1581,16 +1579,6 @@ public final class SystemServiceRegistry {
return new AttestationVerificationManager(ctx.getOuterContext(),
IAttestationVerificationManagerService.Stub.asInterface(b));
}});
-
- //CHECKSTYLE:ON IndentationCheck
- registerService(Context.APP_INTEGRITY_SERVICE, AppIntegrityManager.class,
- new CachedServiceFetcher() {
- @Override
- public AppIntegrityManager createService(ContextImpl ctx)
- throws ServiceNotFoundException {
- IBinder b = ServiceManager.getServiceOrThrow(Context.APP_INTEGRITY_SERVICE);
- return new AppIntegrityManager(IAppIntegrityManager.Stub.asInterface(b));
- }});
registerService(Context.APP_HIBERNATION_SERVICE, AppHibernationManager.class,
new CachedServiceFetcher() {
@Override
@@ -1704,19 +1692,6 @@ public final class SystemServiceRegistry {
throw new ServiceNotFoundException(Context.WEARABLE_SENSING_SERVICE);
}});
- registerService(Context.ON_DEVICE_INTELLIGENCE_SERVICE, OnDeviceIntelligenceManager.class,
- new CachedServiceFetcher() {
- @Override
- public OnDeviceIntelligenceManager createService(ContextImpl ctx)
- throws ServiceNotFoundException {
- IBinder iBinder = ServiceManager.getServiceOrThrow(
- Context.ON_DEVICE_INTELLIGENCE_SERVICE);
- IOnDeviceIntelligenceManager manager =
- IOnDeviceIntelligenceManager.Stub.asInterface(iBinder);
- return new OnDeviceIntelligenceManager(ctx.getOuterContext(), manager);
- }
- });
-
registerService(Context.GRAMMATICAL_INFLECTION_SERVICE, GrammaticalInflectionManager.class,
new CachedServiceFetcher() {
@Override
@@ -1861,6 +1836,7 @@ public final class SystemServiceRegistry {
ConnectivityFrameworkInitializerTiramisu.registerServiceWrappers();
NearbyFrameworkInitializer.registerServiceWrappers();
OnDevicePersonalizationFrameworkInitializer.registerServiceWrappers();
+ OnDeviceIntelligenceFrameworkInitializer.registerServiceWrappers();
DeviceLockFrameworkInitializer.registerServiceWrappers();
VirtualizationFrameworkInitializer.registerServiceWrappers();
ConnectivityFrameworkInitializerBaklava.registerServiceWrappers();
diff --git a/core/java/android/app/TaskInfo.java b/core/java/android/app/TaskInfo.java
index 01cc9d82d56d591be11a141ea6d6d10edda7ba45..76705dcdd3d2a0ebbe8104ba73970b5629068489 100644
--- a/core/java/android/app/TaskInfo.java
+++ b/core/java/android/app/TaskInfo.java
@@ -308,11 +308,17 @@ public class TaskInfo {
public boolean isSleeping;
/**
- * Whether the top activity fillsParent() is false
+ * Whether the top activity fillsParent() is false.
* @hide
*/
public boolean isTopActivityTransparent;
+ /**
+ * Whether fillsParent() is false for every activity in the tasks stack.
+ * @hide
+ */
+ public boolean isActivityStackTransparent;
+
/**
* The last non-fullscreen bounds the task was launched in or resized to.
* @hide
@@ -489,6 +495,7 @@ public class TaskInfo {
&& parentTaskId == that.parentTaskId
&& Objects.equals(topActivity, that.topActivity)
&& isTopActivityTransparent == that.isTopActivityTransparent
+ && isActivityStackTransparent == that.isActivityStackTransparent
&& Objects.equals(lastNonFullscreenBounds, that.lastNonFullscreenBounds)
&& Objects.equals(capturedLink, that.capturedLink)
&& capturedLinkTimestamp == that.capturedLinkTimestamp
@@ -567,6 +574,7 @@ public class TaskInfo {
mTopActivityLocusId = source.readTypedObject(LocusId.CREATOR);
displayAreaFeatureId = source.readInt();
isTopActivityTransparent = source.readBoolean();
+ isActivityStackTransparent = source.readBoolean();
lastNonFullscreenBounds = source.readTypedObject(Rect.CREATOR);
capturedLink = source.readTypedObject(Uri.CREATOR);
capturedLinkTimestamp = source.readLong();
@@ -623,6 +631,7 @@ public class TaskInfo {
dest.writeTypedObject(mTopActivityLocusId, flags);
dest.writeInt(displayAreaFeatureId);
dest.writeBoolean(isTopActivityTransparent);
+ dest.writeBoolean(isActivityStackTransparent);
dest.writeTypedObject(lastNonFullscreenBounds, flags);
dest.writeTypedObject(capturedLink, flags);
dest.writeLong(capturedLinkTimestamp);
@@ -668,6 +677,7 @@ public class TaskInfo {
+ " locusId=" + mTopActivityLocusId
+ " displayAreaFeatureId=" + displayAreaFeatureId
+ " isTopActivityTransparent=" + isTopActivityTransparent
+ + " isActivityStackTransparent=" + isActivityStackTransparent
+ " lastNonFullscreenBounds=" + lastNonFullscreenBounds
+ " capturedLink=" + capturedLink
+ " capturedLinkTimestamp=" + capturedLinkTimestamp
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index a8671cf746193d9bd00848477bfb9b334436e2e9..89e25e7d1b4f37b76edce334fec4165ca1844217 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -2092,7 +2092,7 @@ public class WallpaperManager {
/**
* Returns the description of the designated wallpaper. Returns null if the lock screen
- * wallpaper is requested lock screen wallpaper is not set.
+ * wallpaper is requested and lock screen wallpaper is not set.
* @param which Specifies wallpaper to request (home or lock).
* @throws IllegalArgumentException if {@code which} is not exactly one of
@@ -2733,7 +2733,7 @@ public class WallpaperManager {
* @hide
*/
@FlaggedApi(FLAG_LIVE_WALLPAPER_CONTENT_HANDLING)
- @TestApi
+ @SystemApi
@RequiresPermission(android.Manifest.permission.SET_WALLPAPER)
public int setStreamWithDescription(@NonNull InputStream bitmapData,
@NonNull WallpaperDescription description, boolean allowBackup,
diff --git a/core/java/android/app/activity_manager.aconfig b/core/java/android/app/activity_manager.aconfig
index 44940aee6a49c58b8acb7937d78b986427b43d0b..720e045dc9440c10647d09ad4772de4a3104b0fd 100644
--- a/core/java/android/app/activity_manager.aconfig
+++ b/core/java/android/app/activity_manager.aconfig
@@ -51,16 +51,6 @@ flag {
}
}
-flag {
- namespace: "backstage_power"
- name: "gate_fgs_timeout_anr_behavior"
- description: "Gate the new behavior where an ANR is thrown once an FGS times out."
- bug: "339315145"
- metadata {
- purpose: PURPOSE_BUGFIX
- }
-}
-
flag {
namespace: "backstage_power"
name: "enable_fgs_timeout_crash_behavior"
@@ -166,3 +156,10 @@ flag {
bug: "362537357"
is_exported: true
}
+
+flag {
+ name: "jank_perceptible_narrow"
+ namespace: "system_performance"
+ description: "Narrow the scope of Jank Perceptible"
+ bug: "304837972"
+}
diff --git a/core/java/android/app/admin/DevicePolicyIdentifiers.java b/core/java/android/app/admin/DevicePolicyIdentifiers.java
index 35149b5a31357f9497538dbecdfdac4c72066129..89261a4f85ee4f7d39cd6cc67c093a4f243bf6c9 100644
--- a/core/java/android/app/admin/DevicePolicyIdentifiers.java
+++ b/core/java/android/app/admin/DevicePolicyIdentifiers.java
@@ -20,6 +20,7 @@ import android.annotation.FlaggedApi;
import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.annotation.TestApi;
+import android.app.appfunctions.flags.Flags;
import android.os.UserManager;
import java.util.Objects;
@@ -180,6 +181,12 @@ public final class DevicePolicyIdentifiers {
@FlaggedApi(android.view.contentprotection.flags.Flags.FLAG_MANAGE_DEVICE_POLICY_ENABLED)
public static final String CONTENT_PROTECTION_POLICY = "contentProtection";
+ /**
+ * String identifier for {@link DevicePolicyManager#setAppFunctionsPolicy(int)}.
+ */
+ @FlaggedApi(Flags.FLAG_ENABLE_APP_FUNCTION_MANAGER)
+ public static final String APP_FUNCTIONS_POLICY = "appFunctions";
+
/**
* String identifier for {@link DevicePolicyManager#setUsbDataSignalingEnabled}.
*/
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 8372078b46a59ba6534ca2d299a3cd1fe03d2527..9ddc729850c4cb2d32b18187d41190891465f6d6 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -23,6 +23,7 @@ import static android.Manifest.permission.LOCK_DEVICE;
import static android.Manifest.permission.MANAGE_DEVICE_ADMINS;
import static android.Manifest.permission.MANAGE_DEVICE_POLICY_ACCOUNT_MANAGEMENT;
import static android.Manifest.permission.MANAGE_DEVICE_POLICY_APPS_CONTROL;
+import static android.Manifest.permission.MANAGE_DEVICE_POLICY_APP_FUNCTIONS;
import static android.Manifest.permission.MANAGE_DEVICE_POLICY_CAMERA;
import static android.Manifest.permission.MANAGE_DEVICE_POLICY_CERTIFICATES;
import static android.Manifest.permission.MANAGE_DEVICE_POLICY_COMMON_CRITERIA_MODE;
@@ -3931,6 +3932,11 @@ public class DevicePolicyManager {
@FlaggedApi(android.view.contentprotection.flags.Flags.FLAG_MANAGE_DEVICE_POLICY_ENABLED)
public static final int OPERATION_SET_CONTENT_PROTECTION_POLICY = 41;
+ /** @hide */
+ @TestApi
+ @FlaggedApi(android.app.appfunctions.flags.Flags.FLAG_ENABLE_APP_FUNCTION_MANAGER)
+ public static final int OPERATION_SET_APP_FUNCTIONS_POLICY = 42;
+
private static final String PREFIX_OPERATION = "OPERATION_";
/** @hide */
@@ -3975,7 +3981,8 @@ public class DevicePolicyManager {
OPERATION_SET_PERMISSION_POLICY,
OPERATION_SET_RESTRICTIONS_PROVIDER,
OPERATION_UNINSTALL_CA_CERT,
- OPERATION_SET_CONTENT_PROTECTION_POLICY
+ OPERATION_SET_CONTENT_PROTECTION_POLICY,
+ OPERATION_SET_APP_FUNCTIONS_POLICY
})
@Retention(RetentionPolicy.SOURCE)
public static @interface DevicePolicyOperation {
@@ -4346,6 +4353,90 @@ public class DevicePolicyManager {
return CONTENT_PROTECTION_DISABLED;
}
+ /**
+ * Indicates that app functions are not controlled by policy.
+ *
+ *
If no admin set this policy, it means appfunctions are enabled.
+ */
+ @FlaggedApi(android.app.appfunctions.flags.Flags.FLAG_ENABLE_APP_FUNCTION_MANAGER)
+ public static final int APP_FUNCTIONS_NOT_CONTROLLED_BY_POLICY = 0;
+
+ /** Indicates that app functions are controlled and disabled by a policy. */
+ @FlaggedApi(android.app.appfunctions.flags.Flags.FLAG_ENABLE_APP_FUNCTION_MANAGER)
+ public static final int APP_FUNCTIONS_DISABLED = 1;
+
+ /**
+ * Indicates that app functions are controlled and disabled by a policy for cross profile
+ * interactions only.
+ *
+ *
This is different from {@link #APP_FUNCTIONS_DISABLED} in that it only disables cross
+ * profile interactions (even if the caller has permissions required to interact across users).
+ * appfunctions can still be used within the a user profile boundary.
+ */
+ @FlaggedApi(android.app.appfunctions.flags.Flags.FLAG_ENABLE_APP_FUNCTION_MANAGER)
+ public static final int APP_FUNCTIONS_DISABLED_CROSS_PROFILE = 2;
+
+ /** @hide */
+ @IntDef(
+ prefix = {"APP_FUNCTIONS_"},
+ value = {
+ APP_FUNCTIONS_NOT_CONTROLLED_BY_POLICY,
+ APP_FUNCTIONS_DISABLED,
+ APP_FUNCTIONS_DISABLED_CROSS_PROFILE
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface AppFunctionsPolicy {}
+
+ /**
+ * Sets the app functions policy which controls app functions operations on the device.
+ *
+ *
This function can only be called by a device owner, a profile owner or holders of the
+ * permission {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_APP_FUNCTIONS}.
+ *
+ * @param policy The app functions policy to set. One of {@link
+ * #APP_FUNCTIONS_NOT_CONTROLLED_BY_POLICY},
+ * {@link #APP_FUNCTIONS_DISABLED} or
+ * {@link #APP_FUNCTIONS_DISABLED_CROSS_PROFILE}
+ * @throws SecurityException if caller is not a device owner, a profile owner or a holder
+ * of the permission {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_APP_FUNCTIONS}.
+ */
+ @RequiresPermission(value = MANAGE_DEVICE_POLICY_APP_FUNCTIONS, conditional = true)
+ @FlaggedApi(android.app.appfunctions.flags.Flags.FLAG_ENABLE_APP_FUNCTION_MANAGER)
+ public void setAppFunctionsPolicy(@AppFunctionsPolicy int policy) {
+ throwIfParentInstance("setAppFunctionsPolicy");
+ if (mService != null) {
+ try {
+ mService.setAppFunctionsPolicy(mContext.getPackageName(), policy);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+ }
+
+ /**
+ * Returns the current app functions policy.
+ *
+ *
The returned policy will be the current resolved policy rather than the policy set by the
+ * calling admin.
+ *
+ * @throws SecurityException if caller is not a device owner, a profile owner or a holder
+ * of the permission {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_APP_FUNCTIONS}.
+ */
+ @RequiresPermission(value = MANAGE_DEVICE_POLICY_APP_FUNCTIONS, conditional = true)
+ @FlaggedApi(android.app.appfunctions.flags.Flags.FLAG_ENABLE_APP_FUNCTION_MANAGER)
+ public @AppFunctionsPolicy int getAppFunctionsPolicy() {
+ throwIfParentInstance("getAppFunctionsPolicy");
+ if (mService != null) {
+ try {
+ return mService.getAppFunctionsPolicy(mContext.getPackageName(),
+ myUserId());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+ return APP_FUNCTIONS_NOT_CONTROLLED_BY_POLICY;
+ }
+
/**
* This object is a single place to tack on invalidation and disable calls. All
* binder caches in this class derive from this Config, so all can be invalidated or
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 03a9f99550864e8df1ba335e7565cdcfc77c5694..f304c1bf0a8821cf3ecec98f12f6db89bde67366 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -644,4 +644,7 @@ interface IDevicePolicyManager {
int getPolicySizeForAdmin(String callerPackageName, in EnforcingAdmin admin);
int getHeadlessDeviceOwnerMode(String callerPackageName);
+
+ void setAppFunctionsPolicy(String callerPackageName, int policy);
+ int getAppFunctionsPolicy(String callerPackageName, int userId);
}
diff --git a/core/java/android/app/admin/UnknownAuthority.java b/core/java/android/app/admin/UnknownAuthority.java
index 82dcf7e1a115514a0d63a684c20883ce377ea057..bebffdea5f02abc580560a8c2b52f7539900cc43 100644
--- a/core/java/android/app/admin/UnknownAuthority.java
+++ b/core/java/android/app/admin/UnknownAuthority.java
@@ -74,14 +74,14 @@ public final class UnknownAuthority extends Authority {
@Override
public boolean equals(@Nullable Object o) {
if (this == o) return true;
- if (o != null && getClass() == o.getClass()) return false;
+ if (o == null || getClass() != o.getClass()) return false;
UnknownAuthority other = (UnknownAuthority) o;
return Objects.equals(mName, other.mName);
}
@Override
public int hashCode() {
- return mName.hashCode();
+ return Objects.hashCode(mName);
}
@Override
diff --git a/core/java/android/app/admin/flags/flags.aconfig b/core/java/android/app/admin/flags/flags.aconfig
index 22bc356899f4c262ec201f86d574f002e0d15d49..af035cb630dcf05414374237f17478c5ce8b4053 100644
--- a/core/java/android/app/admin/flags/flags.aconfig
+++ b/core/java/android/app/admin/flags/flags.aconfig
@@ -342,16 +342,6 @@ flag {
}
}
-flag {
- name: "dont_write_policy_definition"
- namespace: "enterprise"
- description: "Don't write redundant policy-definition-entry tags"
- bug: "335663055"
- metadata {
- purpose: PURPOSE_BUGFIX
- }
-}
-
flag {
name: "active_admin_cleanup"
namespace: "enterprise"
@@ -398,6 +388,7 @@ flag {
flag {
name: "split_create_managed_profile_enabled"
+ is_exported: true
namespace: "enterprise"
description: "Split up existing create and provision managed profile API."
bug: "375382324"
diff --git a/core/java/android/app/appfunctions/AppFunctionException.java b/core/java/android/app/appfunctions/AppFunctionException.java
index c8d80d3afe43ad33be727f1780bcdd840a75c8ad..d8179c7540d949e1cdd31d732aa4c1117e842c3d 100644
--- a/core/java/android/app/appfunctions/AppFunctionException.java
+++ b/core/java/android/app/appfunctions/AppFunctionException.java
@@ -32,8 +32,8 @@ import java.util.Objects;
/**
* Represents an app function related error.
*
- *
This exception may include an {@link AppFunctionException#getExtras() Bundle}
- * containing additional error-specific metadata.
+ *
This exception may include an {@link AppFunctionException#getExtras() Bundle} containing
+ * additional error-specific metadata.
*
*
The AppFunction SDK can expose structured APIs by packing and unpacking this Bundle.
*/
@@ -84,6 +84,13 @@ public final class AppFunctionException extends Exception implements Parcelable
*/
public static final int ERROR_CANCELLED = 2001;
+ /**
+ * The operation was disallowed by enterprise policy.
+ *
+ *
This error is in the {@link #ERROR_CATEGORY_SYSTEM} category.
+ */
+ public static final int ERROR_ENTERPRISE_POLICY_DISALLOWED = 2002;
+
/**
* An unknown error occurred while processing the call in the AppFunctionService.
*
@@ -231,7 +238,8 @@ public final class AppFunctionException extends Exception implements Parcelable
ERROR_SYSTEM_ERROR,
ERROR_INVALID_ARGUMENT,
ERROR_DISABLED,
- ERROR_CANCELLED
+ ERROR_CANCELLED,
+ ERROR_ENTERPRISE_POLICY_DISALLOWED
})
@Retention(RetentionPolicy.SOURCE)
public @interface ErrorCode {}
diff --git a/core/java/android/app/appfunctions/AppFunctionManager.java b/core/java/android/app/appfunctions/AppFunctionManager.java
index ed088fed41c292aabb68efac071aca757ae49f80..a731e50854660ba0b25c68b5a2959f9bd6058939 100644
--- a/core/java/android/app/appfunctions/AppFunctionManager.java
+++ b/core/java/android/app/appfunctions/AppFunctionManager.java
@@ -34,6 +34,7 @@ import android.os.ICancellationSignal;
import android.os.OutcomeReceiver;
import android.os.ParcelableException;
import android.os.RemoteException;
+import android.os.SystemClock;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -179,7 +180,8 @@ public final class AppFunctionManager {
ExecuteAppFunctionAidlRequest aidlRequest =
new ExecuteAppFunctionAidlRequest(
- request, mContext.getUser(), mContext.getPackageName());
+ request, mContext.getUser(), mContext.getPackageName(),
+ /* requestTime= */ SystemClock.elapsedRealtime());
try {
ICancellationSignal cancellationTransport =
diff --git a/core/java/android/app/appfunctions/ExecuteAppFunctionAidlRequest.java b/core/java/android/app/appfunctions/ExecuteAppFunctionAidlRequest.java
index e623fa10f4748dc7298b3168d518f4f8d091c296..707d1fc0473edb3aaf1e12cc0fc4817e4638c23f 100644
--- a/core/java/android/app/appfunctions/ExecuteAppFunctionAidlRequest.java
+++ b/core/java/android/app/appfunctions/ExecuteAppFunctionAidlRequest.java
@@ -41,8 +41,9 @@ public final class ExecuteAppFunctionAidlRequest implements Parcelable {
ExecuteAppFunctionRequest.CREATOR.createFromParcel(in);
UserHandle userHandle = UserHandle.CREATOR.createFromParcel(in);
String callingPackage = in.readString8();
+ long requestTime = in.readLong();
return new ExecuteAppFunctionAidlRequest(
- clientRequest, userHandle, callingPackage);
+ clientRequest, userHandle, callingPackage, requestTime);
}
@Override
@@ -60,11 +61,15 @@ public final class ExecuteAppFunctionAidlRequest implements Parcelable {
/** The package name of the app that is requesting to execute the app function. */
private final String mCallingPackage;
- public ExecuteAppFunctionAidlRequest(
- ExecuteAppFunctionRequest clientRequest, UserHandle userHandle, String callingPackage) {
+ /** The time of calling executeAppFunction(). */
+ private final long mRequestTime;
+
+ public ExecuteAppFunctionAidlRequest(ExecuteAppFunctionRequest clientRequest,
+ UserHandle userHandle, String callingPackage, long requestTime) {
this.mClientRequest = Objects.requireNonNull(clientRequest);
this.mUserHandle = Objects.requireNonNull(userHandle);
this.mCallingPackage = Objects.requireNonNull(callingPackage);
+ this.mRequestTime = requestTime;
}
@Override
@@ -77,6 +82,7 @@ public final class ExecuteAppFunctionAidlRequest implements Parcelable {
mClientRequest.writeToParcel(dest, flags);
mUserHandle.writeToParcel(dest, flags);
dest.writeString8(mCallingPackage);
+ dest.writeLong(mRequestTime);
}
/** Returns the client request to execute an app function. */
@@ -96,4 +102,9 @@ public final class ExecuteAppFunctionAidlRequest implements Parcelable {
public String getCallingPackage() {
return mCallingPackage;
}
+
+ /** Returns the time of calling executeAppFunction(). */
+ public long getRequestTime() {
+ return mRequestTime;
+ }
}
diff --git a/core/java/android/app/appfunctions/ExecuteAppFunctionRequest.java b/core/java/android/app/appfunctions/ExecuteAppFunctionRequest.java
index a88198a4ec7cf04a93a8f83cbca2bc854070a546..bdc6ce5c73e81f498a4defe99bb157b302affcf4 100644
--- a/core/java/android/app/appfunctions/ExecuteAppFunctionRequest.java
+++ b/core/java/android/app/appfunctions/ExecuteAppFunctionRequest.java
@@ -136,6 +136,16 @@ public final class ExecuteAppFunctionRequest implements Parcelable {
return mExtras;
}
+ /**
+ * Returns the size of the request in bytes.
+ *
+ * @hide
+ */
+ public int getRequestDataSize() {
+ return mTargetPackageName.getBytes().length + mFunctionIdentifier.getBytes().length
+ + mParameters.getDataSize() + mExtras.getSize();
+ }
+
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeString8(mTargetPackageName);
diff --git a/core/java/android/app/appfunctions/ExecuteAppFunctionResponse.java b/core/java/android/app/appfunctions/ExecuteAppFunctionResponse.java
index a4952f48605934ba163ad9b4df540c1e3f03a969..618cc1ca48f904a687e6948aff6f93858816f97f 100644
--- a/core/java/android/app/appfunctions/ExecuteAppFunctionResponse.java
+++ b/core/java/android/app/appfunctions/ExecuteAppFunctionResponse.java
@@ -135,6 +135,15 @@ public final class ExecuteAppFunctionResponse implements Parcelable {
return mExtras;
}
+ /**
+ * Returns the size of the response in bytes.
+ *
+ * @hide
+ */
+ public int getResponseDataSize() {
+ return mResultDocumentWrapper.getDataSize() + mExtras.getSize();
+ }
+
@Override
public int describeContents() {
return 0;
diff --git a/core/java/android/app/appfunctions/GenericDocumentWrapper.java b/core/java/android/app/appfunctions/GenericDocumentWrapper.java
index 541ca7458efe47bcea4a7d819318ce26717221ae..02133b475ec21c98d42ee1c618bfa17514cc923d 100644
--- a/core/java/android/app/appfunctions/GenericDocumentWrapper.java
+++ b/core/java/android/app/appfunctions/GenericDocumentWrapper.java
@@ -50,6 +50,10 @@ public final class GenericDocumentWrapper implements Parcelable {
@Nullable
private Parcel mParcel;
+ @GuardedBy("mLock")
+ @Nullable
+ private Integer mDataSize;
+
private final Object mLock = new Object();
public static final Creator CREATOR =
@@ -75,11 +79,13 @@ public final class GenericDocumentWrapper implements Parcelable {
public GenericDocumentWrapper(@NonNull GenericDocument genericDocument) {
mGenericDocument = Objects.requireNonNull(genericDocument);
mParcel = null;
+ mDataSize = null;
}
public GenericDocumentWrapper(@NonNull Parcel parcel) {
mGenericDocument = null;
mParcel = Objects.requireNonNull(parcel);
+ mDataSize = mParcel.dataSize();
}
/** Returns the wrapped {@link android.app.appsearch.GenericDocument} */
@@ -109,6 +115,21 @@ public final class GenericDocumentWrapper implements Parcelable {
}
}
+ /** Returns the size of the parcelled document. */
+
+ int getDataSize() {
+ synchronized (mLock) {
+ if (mDataSize != null) {
+ return mDataSize;
+ }
+ Parcel tempParcel = Parcel.obtain();
+ writeToParcel(tempParcel, 0);
+ mDataSize = tempParcel.dataSize();
+ tempParcel.recycle();
+ return mDataSize;
+ }
+ }
+
@Override
public int describeContents() {
return 0;
diff --git a/core/java/android/app/appfunctions/SafeOneTimeExecuteAppFunctionCallback.java b/core/java/android/app/appfunctions/SafeOneTimeExecuteAppFunctionCallback.java
index 2426daf5c9f299df511952b0f436971aa2280c8f..e290169bdea87dceed91901b54b3e215565e2245 100644
--- a/core/java/android/app/appfunctions/SafeOneTimeExecuteAppFunctionCallback.java
+++ b/core/java/android/app/appfunctions/SafeOneTimeExecuteAppFunctionCallback.java
@@ -17,6 +17,7 @@
package android.app.appfunctions;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.os.RemoteException;
import android.util.Log;
@@ -37,8 +38,16 @@ public class SafeOneTimeExecuteAppFunctionCallback {
@NonNull private final IExecuteAppFunctionCallback mCallback;
+ @Nullable CompletionCallback mCompletionCallback;
+
public SafeOneTimeExecuteAppFunctionCallback(@NonNull IExecuteAppFunctionCallback callback) {
+ this(callback, /* completionCallback= */ null);
+ }
+
+ public SafeOneTimeExecuteAppFunctionCallback(@NonNull IExecuteAppFunctionCallback callback,
+ @Nullable CompletionCallback completionCallback) {
mCallback = Objects.requireNonNull(callback);
+ mCompletionCallback = completionCallback;
}
/** Invoke wrapped callback with the result. */
@@ -49,6 +58,9 @@ public class SafeOneTimeExecuteAppFunctionCallback {
}
try {
mCallback.onSuccess(result);
+ if (mCompletionCallback != null) {
+ mCompletionCallback.finalizeOnSuccess(result);
+ }
} catch (RemoteException ex) {
// Failed to notify the other end. Ignore.
Log.w(TAG, "Failed to invoke the callback", ex);
@@ -63,6 +75,9 @@ public class SafeOneTimeExecuteAppFunctionCallback {
}
try {
mCallback.onError(error);
+ if (mCompletionCallback != null) {
+ mCompletionCallback.finalizeOnError(error);
+ }
} catch (RemoteException ex) {
// Failed to notify the other end. Ignore.
Log.w(TAG, "Failed to invoke the callback", ex);
@@ -76,4 +91,16 @@ public class SafeOneTimeExecuteAppFunctionCallback {
public void disable() {
mOnResultCalled.set(true);
}
+
+ /**
+ * Provides a hook to execute additional actions after the {@link IExecuteAppFunctionCallback}
+ * has been invoked.
+ */
+ public interface CompletionCallback {
+ /** Called after {@link IExecuteAppFunctionCallback#onSuccess}. */
+ void finalizeOnSuccess(@NonNull ExecuteAppFunctionResponse result);
+
+ /** Called after {@link IExecuteAppFunctionCallback#onError}. */
+ void finalizeOnError(@NonNull AppFunctionException error);
+ }
}
diff --git a/core/java/android/app/contextualsearch/flags.aconfig b/core/java/android/app/contextualsearch/flags.aconfig
index 529b59ac424dbda645bdfb805db48ffdab7963f6..e8cfd79c9cc798d00fef06bab150b29a2a4deda7 100644
--- a/core/java/android/app/contextualsearch/flags.aconfig
+++ b/core/java/android/app/contextualsearch/flags.aconfig
@@ -17,14 +17,14 @@ flag {
flag {
name: "multi_window_screen_context"
- namespace: "machine_learning"
+ namespace: "sysui_integrations"
description: "Report screen context and positions for all windows."
bug: "371065456"
}
flag {
name: "contextual_search_window_layer"
- namespace: "machine_learning"
+ namespace: "sysui_integrations"
description: "Identify live contextual search UI to exclude from contextual search screenshot."
bug: "372510690"
}
\ No newline at end of file
diff --git a/core/java/android/app/jank/JankDataProcessor.java b/core/java/android/app/jank/JankDataProcessor.java
index 7ceaeb3fb07059ca589b3f23cbd74fcba3d08f41..c9472598b35296b3c95ea854b5b994099acc49dd 100644
--- a/core/java/android/app/jank/JankDataProcessor.java
+++ b/core/java/android/app/jank/JankDataProcessor.java
@@ -215,7 +215,8 @@ public class JankDataProcessor {
try {
mPendingJankStats.values().forEach(stat -> {
- FrameworkStatsLog.write(FrameworkStatsLog.JANK_FRAME_COUNT_BY_WIDGET,
+ FrameworkStatsLog.write(
+ FrameworkStatsLog.JANK_FRAME_COUNT_BY_WIDGET_REPORTED,
/*app uid*/ stat.getUid(),
/*activity name*/ stat.getActivityName(),
/*widget id*/ stat.getWidgetId(),
diff --git a/core/java/android/app/jank/JankTracker.java b/core/java/android/app/jank/JankTracker.java
index 469521668d2546c4d6902322faab0a34bad6c9e4..a04f96a9f6e3563bbbf45b3acd0f7781b8765386 100644
--- a/core/java/android/app/jank/JankTracker.java
+++ b/core/java/android/app/jank/JankTracker.java
@@ -29,6 +29,7 @@ import android.view.ViewTreeObserver;
import com.android.internal.annotations.VisibleForTesting;
import java.util.ArrayList;
+import java.util.HashMap;
/**
* This class is responsible for registering callbacks that will receive JankData batches.
@@ -173,6 +174,15 @@ public class JankTracker {
mStateTracker.retrieveAllStates(stateDataList);
}
+ /**
+ * Retrieve all pending jank stats before they are logged, this is intended for testing
+ * purposes only.
+ */
+ @VisibleForTesting
+ public HashMap getPendingJankStats() {
+ return mJankDataProcessor.getPendingJankStats();
+ }
+
/**
* Only intended to be used by tests, the runnable that registers the listeners may not run
* in time for tests to pass. This forces them to run immediately.
@@ -192,7 +202,11 @@ public class JankTracker {
*/
}
- private boolean shouldTrack() {
+ /**
+ * Returns whether jank tracking is enabled or not.
+ */
+ @VisibleForTesting
+ public boolean shouldTrack() {
return mTrackingEnabled && mListenersRegistered;
}
diff --git a/core/java/android/app/notification.aconfig b/core/java/android/app/notification.aconfig
index 8b6840c1b552b3e2ee8e8d81dfa2ff613cc49ef9..b1db1379e4006d7a496035f926a115a796bc311f 100644
--- a/core/java/android/app/notification.aconfig
+++ b/core/java/android/app/notification.aconfig
@@ -283,6 +283,20 @@ flag {
bug: "362981561"
}
+flag {
+ name: "nm_binder_perf_cache_channels"
+ namespace: "systemui"
+ description: "Use IpcDataCache for notification channel/group lookups"
+ bug: "362981561"
+}
+
+flag {
+ name: "nm_binder_perf_throttle_notify"
+ namespace: "systemui"
+ description: "Rate-limit calls to enqueueNotificationWithTag client-side"
+ bug: "362981561"
+}
+
flag {
name: "no_sbnholder"
namespace: "systemui"
diff --git a/core/java/android/app/ondeviceintelligence/OWNERS b/core/java/android/app/ondeviceintelligence/OWNERS
deleted file mode 100644
index 85e9e653e6fb58470a50f6708343a8eb7412dd64..0000000000000000000000000000000000000000
--- a/core/java/android/app/ondeviceintelligence/OWNERS
+++ /dev/null
@@ -1,6 +0,0 @@
-# Bug component: 1363385
-
-sandeepbandaru@google.com
-shivanker@google.com
-hackz@google.com
-volnov@google.com
diff --git a/core/java/android/app/ondeviceintelligence/flags/ondevice_intelligence.aconfig b/core/java/android/app/ondeviceintelligence/flags/ondevice_intelligence.aconfig
deleted file mode 100644
index 74a96c864167cad125d9feaaec0906fd50a20050..0000000000000000000000000000000000000000
--- a/core/java/android/app/ondeviceintelligence/flags/ondevice_intelligence.aconfig
+++ /dev/null
@@ -1,17 +0,0 @@
-package: "android.app.ondeviceintelligence.flags"
-container: "system"
-
-flag {
- name: "enable_on_device_intelligence"
- is_exported: true
- namespace: "ondeviceintelligence"
- description: "Make methods on OnDeviceIntelligenceManager available for local inference."
- bug: "304755128"
-}
-flag {
- name: "enable_on_device_intelligence_module"
- is_exported: true
- namespace: "ondeviceintelligence"
- description: "Enable migration to mainline module and related changes."
- bug: "376427781"
-}
\ No newline at end of file
diff --git a/core/java/android/app/performance.aconfig b/core/java/android/app/performance.aconfig
index 359c84eeb55923847dfd62bc476d0c5b1b934c0a..238f1cb1220831a1769ac99e7df30c4416d14978 100644
--- a/core/java/android/app/performance.aconfig
+++ b/core/java/android/app/performance.aconfig
@@ -35,6 +35,14 @@ flag {
bug: "373752556"
}
+flag {
+ namespace: "system_performance"
+ name: "pic_separate_permission_notifications"
+ is_fixed_read_only: true
+ description: "Seperate PermissionManager notifications from cache udpates"
+ bug: "379699402"
+}
+
flag {
namespace: "system_performance"
name: "pic_cache_nulls"
diff --git a/core/java/android/app/servertransaction/ActivityConfigurationChangeItem.java b/core/java/android/app/servertransaction/ActivityConfigurationChangeItem.java
index 2b52681d1be81b52d57ce90d7291859b8b657bf8..75ecabd8ddb0b4e08cd95fb88e16d3996bbf1738 100644
--- a/core/java/android/app/servertransaction/ActivityConfigurationChangeItem.java
+++ b/core/java/android/app/servertransaction/ActivityConfigurationChangeItem.java
@@ -56,7 +56,7 @@ public class ActivityConfigurationChangeItem extends ActivityTransactionItem {
@Override
public void preExecute(@NonNull ClientTransactionHandler client) {
- CompatibilityInfo.applyOverrideScaleIfNeeded(mConfiguration);
+ CompatibilityInfo.applyOverrideIfNeeded(mConfiguration);
// Notify the client of an upcoming change in the token configuration. This ensures that
// batches of config change items only process the newest configuration.
client.updatePendingActivityConfiguration(getActivityToken(), mConfiguration);
diff --git a/core/java/android/app/servertransaction/ActivityRelaunchItem.java b/core/java/android/app/servertransaction/ActivityRelaunchItem.java
index cecf7013c79c28550cdc6529011d2698a2150d00..bb881908d10f4fe1355b30e167ca062549b4675a 100644
--- a/core/java/android/app/servertransaction/ActivityRelaunchItem.java
+++ b/core/java/android/app/servertransaction/ActivityRelaunchItem.java
@@ -89,7 +89,7 @@ public class ActivityRelaunchItem extends ActivityTransactionItem {
public void preExecute(@NonNull ClientTransactionHandler client) {
// The local config is already scaled so only apply if this item is from server side.
if (!client.isExecutingLocalTransaction()) {
- CompatibilityInfo.applyOverrideScaleIfNeeded(mConfig);
+ CompatibilityInfo.applyOverrideIfNeeded(mConfig);
}
mActivityClientRecord = client.prepareRelaunchActivity(getActivityToken(), mPendingResults,
mPendingNewIntents, mConfigChanges, mConfig, mPreserveWindow, mActivityWindowInfo);
diff --git a/core/java/android/app/servertransaction/ConfigurationChangeItem.java b/core/java/android/app/servertransaction/ConfigurationChangeItem.java
index 123d7926160ca2ed21d3b749d708daace061183f..e42005bdd595de8e99f2e1720574b66d8ad65a4f 100644
--- a/core/java/android/app/servertransaction/ConfigurationChangeItem.java
+++ b/core/java/android/app/servertransaction/ConfigurationChangeItem.java
@@ -46,7 +46,7 @@ public class ConfigurationChangeItem extends ClientTransactionItem {
@Override
public void preExecute(@NonNull ClientTransactionHandler client) {
- CompatibilityInfo.applyOverrideScaleIfNeeded(mConfiguration);
+ CompatibilityInfo.applyOverrideIfNeeded(mConfiguration);
client.updatePendingConfiguration(mConfiguration);
}
diff --git a/core/java/android/app/servertransaction/LaunchActivityItem.java b/core/java/android/app/servertransaction/LaunchActivityItem.java
index 235a9f7aeb4c9fdb9538dfdcad2ea4e63c867031..f2e7a4fcd50bce468ae6ea46a254bec842926098 100644
--- a/core/java/android/app/servertransaction/LaunchActivityItem.java
+++ b/core/java/android/app/servertransaction/LaunchActivityItem.java
@@ -202,8 +202,8 @@ public class LaunchActivityItem extends ClientTransactionItem {
public void preExecute(@NonNull ClientTransactionHandler client) {
client.countLaunchingActivities(1);
client.updateProcessState(mProcState, false);
- CompatibilityInfo.applyOverrideScaleIfNeeded(mCurConfig);
- CompatibilityInfo.applyOverrideScaleIfNeeded(mOverrideConfig);
+ CompatibilityInfo.applyOverrideIfNeeded(mCurConfig);
+ CompatibilityInfo.applyOverrideIfNeeded(mOverrideConfig);
client.updatePendingConfiguration(mCurConfig);
if (mActivityClientController != null) {
ActivityClient.setActivityClientController(mActivityClientController);
diff --git a/core/java/android/app/servertransaction/MoveToDisplayItem.java b/core/java/android/app/servertransaction/MoveToDisplayItem.java
index 1aa563aa63633a0cb232b84ff5d892393097b601..72d1f491f2c6e4f6e77a833f019b59ba45c65021 100644
--- a/core/java/android/app/servertransaction/MoveToDisplayItem.java
+++ b/core/java/android/app/servertransaction/MoveToDisplayItem.java
@@ -58,7 +58,7 @@ public class MoveToDisplayItem extends ActivityTransactionItem {
@Override
public void preExecute(@NonNull ClientTransactionHandler client) {
- CompatibilityInfo.applyOverrideScaleIfNeeded(mConfiguration);
+ CompatibilityInfo.applyOverrideIfNeeded(mConfiguration);
// Notify the client of an upcoming change in the token configuration. This ensures that
// batches of config change items only process the newest configuration.
client.updatePendingActivityConfiguration(getActivityToken(), mConfiguration);
diff --git a/core/java/android/app/supervision/SupervisionManagerInternal.java b/core/java/android/app/supervision/SupervisionManagerInternal.java
index d571e14ff5faacd7ae49b6f819f24072b514eabf..2cf6ae6f9d01a80230ee234cffb31984c867da64 100644
--- a/core/java/android/app/supervision/SupervisionManagerInternal.java
+++ b/core/java/android/app/supervision/SupervisionManagerInternal.java
@@ -27,32 +27,41 @@ import android.os.PersistableBundle;
*/
public abstract class SupervisionManagerInternal {
/**
- * Returns whether supervision is enabled for the specified user
+ * Returns whether the app with given process uid is the active supervision app.
*
- * @param userId The user to retrieve the supervision state for
- * @return whether the user is supervised
+ *
Supervision app is considered active when supervision is enabled for the user running the
+ * given process uid.
+ *
+ * @param uid App process uid.
+ * @return Whether the app is the active supervision app.
*/
- public abstract boolean isSupervisionEnabledForUser(@UserIdInt int userId);
+ public abstract boolean isActiveSupervisionApp(int uid);
/**
- * Returns whether the supervision lock screen needs to be shown.
+ * Returns whether supervision is enabled for the specified user.
+ *
+ * @param userId The user to retrieve the supervision state for.
+ * @return Whether the user is supervised.
*/
+ public abstract boolean isSupervisionEnabledForUser(@UserIdInt int userId);
+
+ /** Returns whether the supervision lock screen needs to be shown. */
public abstract boolean isSupervisionLockscreenEnabledForUser(@UserIdInt int userId);
/**
* Set whether supervision is enabled for the specified user.
*
- * @param userId The user to set the supervision state for
- * @param enabled Whether or not the user should be supervised
+ * @param userId The user to set the supervision state for.
+ * @param enabled Whether or not the user should be supervised.
*/
public abstract void setSupervisionEnabledForUser(@UserIdInt int userId, boolean enabled);
/**
- * Sets whether the supervision lock screen should be shown for the specified user
+ * Sets whether the supervision lock screen should be shown for the specified user.
*
- * @param userId The user set the superivision state for
- * @param enabled Whether or not the superivision lock screen needs to be shown
- * @param options Optional configuration parameters for the supervision lock screen
+ * @param userId The user set the superivision state for.
+ * @param enabled Whether or not the superivision lock screen needs to be shown.
+ * @param options Optional configuration parameters for the supervision lock screen.
*/
public abstract void setSupervisionLockscreenEnabledForUser(
@UserIdInt int userId, boolean enabled, @Nullable PersistableBundle options);
diff --git a/core/java/android/app/supervision/flags.aconfig b/core/java/android/app/supervision/flags.aconfig
index d4f82f665fd418fa13995451897abfd4f419e549..1b0353274fb9b05fc1cb14997d7a9d227d9f0e7a 100644
--- a/core/java/android/app/supervision/flags.aconfig
+++ b/core/java/android/app/supervision/flags.aconfig
@@ -24,3 +24,11 @@ flag {
description: "Flag that enables supervision when the supervision app is the profile owner"
bug: "377261590"
}
+
+flag {
+ name: "deprecate_dpm_supervision_apis"
+ is_exported: true
+ namespace: "supervision"
+ description: "Flag that deprecates supervision methods in DPM"
+ bug: "382034839"
+}
diff --git a/core/java/android/app/wallpaper/WallpaperDescription.java b/core/java/android/app/wallpaper/WallpaperDescription.java
index 3ee00ca3d9412c389393ad41ac212e6dd32976d1..ca2d9e676a022ef52de685382eab1eacd14eac6f 100644
--- a/core/java/android/app/wallpaper/WallpaperDescription.java
+++ b/core/java/android/app/wallpaper/WallpaperDescription.java
@@ -20,6 +20,7 @@ import static android.app.Flags.FLAG_LIVE_WALLPAPER_CONTENT_HANDLING;
import android.annotation.FlaggedApi;
import android.annotation.SuppressLint;
+import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.app.WallpaperInfo;
import android.app.WallpaperManager;
@@ -153,6 +154,7 @@ public final class WallpaperDescription implements Parcelable {
* {@link Builder#setCropHints(SparseArray)}
* @hide
*/
+ @SystemApi
@NonNull
public SparseArray getCropHints() {
return mCropHints;
diff --git a/core/java/android/appwidget/AppWidgetManager.java b/core/java/android/appwidget/AppWidgetManager.java
index 40de2985f68a133e4c6753969554098a3ac35295..67ad4594599fe59583ac6f1652fb2ab8271456e1 100644
--- a/core/java/android/appwidget/AppWidgetManager.java
+++ b/core/java/android/appwidget/AppWidgetManager.java
@@ -37,36 +37,44 @@ import android.compat.annotation.UnsupportedAppUsage;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.Intent.FilterComparison;
import android.content.IntentSender;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.content.pm.ParceledListSlice;
import android.content.pm.ShortcutInfo;
import android.graphics.Rect;
+import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerExecutor;
import android.os.HandlerThread;
+import android.os.IBinder;
import android.os.Looper;
import android.os.PersistableBundle;
import android.os.Process;
import android.os.RemoteException;
import android.os.UserHandle;
+import android.util.ArrayMap;
import android.util.DisplayMetrics;
import android.util.Log;
+import android.util.Pair;
import android.widget.RemoteViews;
import com.android.internal.appwidget.IAppWidgetService;
import com.android.internal.os.BackgroundThread;
import com.android.internal.util.FunctionalUtils;
+import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.Map;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
+import java.util.function.Consumer;
/**
* Updates AppWidget state; gets information about installed AppWidget providers and other
@@ -592,6 +600,8 @@ public class AppWidgetManager {
private boolean mHasPostedLegacyLists = false;
+ private @NonNull ServiceCollectionCache mServiceCollectionCache;
+
/**
* Get the AppWidgetManager instance to use for the supplied {@link android.content.Context
* Context} object.
@@ -612,6 +622,7 @@ public class AppWidgetManager {
mPackageName = context.getOpPackageName();
mService = service;
mDisplayMetrics = context.getResources().getDisplayMetrics();
+ mServiceCollectionCache = new ServiceCollectionCache(context, /* timeout= */ 5000L);
if (mService == null) {
return;
}
@@ -649,7 +660,7 @@ public class AppWidgetManager {
final RemoteViews viewsCopy = new RemoteViews(original);
Runnable updateWidgetWithTask = () -> {
try {
- viewsCopy.collectAllIntents(mMaxBitmapMemory).get();
+ viewsCopy.collectAllIntents(mMaxBitmapMemory, mServiceCollectionCache).get();
action.acceptOrThrow(viewsCopy);
} catch (Exception e) {
Log.e(TAG, failureMsg, e);
@@ -1629,4 +1640,106 @@ public class AppWidgetManager {
thread.start();
return thread.getThreadHandler();
}
+
+ /**
+ * @hide
+ */
+ public static class ServiceCollectionCache {
+
+ private final Context mContext;
+ private final Handler mHandler;
+ private final long mTimeOut;
+
+ private final Map mActiveConnections =
+ new ArrayMap<>();
+
+ public ServiceCollectionCache(Context context, long timeOut) {
+ mContext = context;
+ mHandler = new Handler(BackgroundThread.getHandler().getLooper());
+ mTimeOut = timeOut;
+ }
+
+ /**
+ * Connect to the service indicated by the {@code Intent}, and consume the binder on the
+ * specified executor
+ */
+ public void connectAndConsume(Intent intent, Consumer task, Executor executor) {
+ mHandler.post(() -> connectAndConsumeInner(intent, task, executor));
+ }
+
+ private void connectAndConsumeInner(Intent intent, Consumer task,
+ Executor executor) {
+ ConnectionTask activeConnection = mActiveConnections.computeIfAbsent(
+ new FilterComparison(intent), ConnectionTask::new);
+ activeConnection.add(task, executor);
+ }
+
+ private class ConnectionTask implements ServiceConnection {
+
+ private final Runnable mDestroyAfterTimeout = this::onDestroyTimeout;
+ private final ArrayDeque, Executor>> mTaskQueue =
+ new ArrayDeque<>();
+
+ private boolean mOnDestroyTimeout = false;
+ private IBinder mIBinder;
+
+ ConnectionTask(@NonNull FilterComparison filter) {
+ mContext.bindService(filter.getIntent(),
+ Context.BindServiceFlags.of(Context.BIND_AUTO_CREATE),
+ mHandler::post,
+ this);
+ }
+
+ @Override
+ public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
+ mIBinder = iBinder;
+ mHandler.post(this::handleNext);
+ }
+
+ @Override
+ public void onNullBinding(ComponentName name) {
+ // Use an empty binder, follow up tasks will handle the failure
+ onServiceConnected(name, new Binder());
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName componentName) { }
+
+ void add(Consumer task, Executor executor) {
+ mTaskQueue.add(Pair.create(task, executor));
+ if (mOnDestroyTimeout) {
+ // If we are waiting for timeout, cancel it and execute the next task
+ handleNext();
+ }
+ }
+
+ private void handleNext() {
+ mHandler.removeCallbacks(mDestroyAfterTimeout);
+ Pair, Executor> next = mTaskQueue.pollFirst();
+ if (next != null) {
+ mOnDestroyTimeout = false;
+ next.second.execute(() -> {
+ next.first.accept(mIBinder);
+ mHandler.post(this::handleNext);
+ });
+ } else {
+ // Finished all tasks, start a timeout to unbind this service
+ mOnDestroyTimeout = true;
+ mHandler.postDelayed(mDestroyAfterTimeout, mTimeOut);
+ }
+ }
+
+ /**
+ * Called after we have waited for {@link #mTimeOut} after the last task is finished
+ */
+ private void onDestroyTimeout() {
+ if (!mTaskQueue.isEmpty()) {
+ handleNext();
+ return;
+ }
+ mContext.unbindService(this);
+ mActiveConnections.values().remove(this);
+ }
+ }
+ }
}
diff --git a/core/java/android/companion/DeviceId.java b/core/java/android/companion/DeviceId.java
index f66a1ae5c1758b68ff9d092a2af6a82c478dfb5c..2f19eb49ad4383fb6cc0f9b6a371b6063452b4fe 100644
--- a/core/java/android/companion/DeviceId.java
+++ b/core/java/android/companion/DeviceId.java
@@ -22,7 +22,6 @@ import android.annotation.Nullable;
import android.net.MacAddress;
import android.os.Parcel;
import android.os.Parcelable;
-import android.provider.OneTimeUseBuilder;
import java.util.Locale;
import java.util.Objects;
@@ -154,8 +153,12 @@ public final class DeviceId implements Parcelable {
/**
* A builder for {@link DeviceId}
+ *
+ *
Calling apps must provide at least one of the following to identify
+ * the device: a custom ID using {@link #setCustomId(String)}, or a MAC address using
+ * {@link #setMacAddress(MacAddress)}.
*/
- public static final class Builder extends OneTimeUseBuilder {
+ public static final class Builder {
private String mCustomId;
private MacAddress mMacAddress;
@@ -171,7 +174,6 @@ public final class DeviceId implements Parcelable {
*/
@NonNull
public Builder setCustomId(@Nullable String customId) {
- checkNotUsed();
if (customId != null
&& customId.length() > CUSTOM_ID_LENGTH_LIMIT) {
throw new IllegalArgumentException("Length of the custom id must be at most "
@@ -191,15 +193,12 @@ public final class DeviceId implements Parcelable {
*/
@NonNull
public Builder setMacAddress(@Nullable MacAddress macAddress) {
- checkNotUsed();
mMacAddress = macAddress;
return this;
}
@NonNull
- @Override
public DeviceId build() {
- markUsed();
if (mCustomId == null && mMacAddress == null) {
throw new IllegalArgumentException("At least one device id property must be"
+ "non-null to build a DeviceId.");
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index d7660172a2f13dbb220b2cb9f5c50129fbfb6765..3d75423edfa904d4377a10e599e6c2f0308eaeec 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -55,6 +55,7 @@ import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Rect;
import android.net.Uri;
+import android.os.BadParcelableException;
import android.os.Build;
import android.os.Bundle;
import android.os.BundleMerger;
@@ -6187,7 +6188,8 @@ public class Intent implements Parcelable, Cloneable {
* {@link #EXTRA_CHOOSER_MODIFY_SHARE_ACTION},
* {@link #EXTRA_METADATA_TEXT},
* {@link #EXTRA_CHOOSER_REFINEMENT_INTENT_SENDER},
- * {@link #EXTRA_CHOOSER_RESULT_INTENT_SENDER}.
+ * {@link #EXTRA_CHOOSER_RESULT_INTENT_SENDER},
+ * {@link #EXTRA_EXCLUDE_COMPONENTS}.
*
*/
public static final String EXTRA_CHOOSER_ADDITIONAL_CONTENT_URI =
@@ -7856,6 +7858,10 @@ public class Intent implements Parcelable, Cloneable {
*/
public static final int URI_ALLOW_UNSAFE = 1<<2;
+ static {
+ Bundle.intentClass = Intent.class;
+ }
+
// ---------------------------------------------------------------------
private String mAction;
@@ -12285,7 +12291,6 @@ public class Intent implements Parcelable, Cloneable {
private IBinder mCreatorToken;
// Stores all extra keys whose values are intents for a top level intent.
private ArraySet mNestedIntentKeys;
-
}
/**
@@ -12347,6 +12352,7 @@ public class Intent implements Parcelable, Cloneable {
public int hashCode() {
return Objects.hash(mType, mKey, mIndex);
}
+
}
private @Nullable CreatorTokenInfo mCreatorTokenInfo;
@@ -12397,9 +12403,20 @@ public class Intent implements Parcelable, Cloneable {
addExtendedFlags(EXTENDED_FLAG_NESTED_INTENT_KEYS_COLLECTED);
if (mExtras != null && !mExtras.isEmpty()) {
for (String key : mExtras.keySet()) {
- Object value = mExtras.get(key);
-
- if (value instanceof Intent intent && !visited.contains(intent)) {
+ Object value;
+ try {
+ value = mExtras.get(key);
+ } catch (BadParcelableException e) {
+ // This could happen when the key points to a LazyValue whose class cannot be
+ // found by the classLoader - A nested object more than 1 level deeper who is
+ // of type of a custom class could trigger this situation. In such case, we
+ // ignore it since it is not an intent. However, it could be a custom type that
+ // extends from Intent. If such an object is retrieved later in another
+ // component, then trying to launch such a custom class object will fail unless
+ // removeLaunchSecurityProtection() is called before it is launched.
+ value = null;
+ }
+ if (value instanceof Intent intent) {
handleNestedIntent(intent, visited, new NestedIntentKey(
NestedIntentKey.NESTED_INTENT_KEY_TYPE_EXTRA_PARCEL, key, 0));
} else if (value instanceof Parcelable[] parcelables) {
@@ -12422,7 +12439,6 @@ public class Intent implements Parcelable, Cloneable {
}
private void handleNestedIntent(Intent intent, Set visited, NestedIntentKey key) {
- visited.add(intent);
if (mCreatorTokenInfo == null) {
mCreatorTokenInfo = new CreatorTokenInfo();
}
@@ -12430,7 +12446,10 @@ public class Intent implements Parcelable, Cloneable {
mCreatorTokenInfo.mNestedIntentKeys = new ArraySet<>();
}
mCreatorTokenInfo.mNestedIntentKeys.add(key);
- intent.collectNestedIntentKeysRecur(visited);
+ if (!visited.contains(intent)) {
+ visited.add(intent);
+ intent.collectNestedIntentKeysRecur(visited);
+ }
}
private void handleParcelableArray(Parcelable[] parcelables, String key, Set visited) {
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index a06eb1c5b4ad83fe14f2fe6ddacd9330badc5357..7e0805137d0b1f8b8c6f67c6edefc705a6beffd0 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -11651,7 +11651,7 @@ public abstract class PackageManager {
private static final PropertyInvalidatedCache
sApplicationInfoCache =
new PropertyInvalidatedCache(
- 2048, PermissionManager.CACHE_KEY_PACKAGE_INFO,
+ 2048, PermissionManager.CACHE_KEY_PACKAGE_INFO_CACHE,
"getApplicationInfo") {
@Override
public ApplicationInfo recompute(ApplicationInfoQuery query) {
@@ -11682,18 +11682,6 @@ public abstract class PackageManager {
sApplicationInfoCache.disableLocal();
}
- private static final PropertyInvalidatedCache.AutoCorker sCacheAutoCorker =
- new PropertyInvalidatedCache.AutoCorker(PermissionManager.CACHE_KEY_PACKAGE_INFO);
-
- /**
- * Invalidate caches of package and permission information system-wide.
- *
- * @hide
- */
- public static void invalidatePackageInfoCache() {
- sCacheAutoCorker.autoCork();
- }
-
// Some of the flags don't affect the query result, but let's be conservative and cache
// each combination of flags separately.
@@ -11752,7 +11740,7 @@ public abstract class PackageManager {
private static final PropertyInvalidatedCache
sPackageInfoCache =
new PropertyInvalidatedCache(
- 2048, PermissionManager.CACHE_KEY_PACKAGE_INFO,
+ 2048, PermissionManager.CACHE_KEY_PACKAGE_INFO_CACHE,
"getPackageInfo") {
@Override
public PackageInfo recompute(PackageInfoQuery query) {
@@ -11784,17 +11772,40 @@ public abstract class PackageManager {
/**
* Inhibit package info cache invalidations when correct.
*
- * @hide */
+ * @hide
+ */
public static void corkPackageInfoCache() {
- PropertyInvalidatedCache.corkInvalidations(PermissionManager.CACHE_KEY_PACKAGE_INFO);
+ sPackageInfoCache.corkInvalidations();
}
/**
* Enable package info cache invalidations.
*
- * @hide */
+ * @hide
+ */
public static void uncorkPackageInfoCache() {
- PropertyInvalidatedCache.uncorkInvalidations(PermissionManager.CACHE_KEY_PACKAGE_INFO);
+ sPackageInfoCache.uncorkInvalidations();
+ }
+
+ // This auto-corker is obsolete once the separate permission notifications feature is
+ // committed.
+ private static final PropertyInvalidatedCache.AutoCorker sCacheAutoCorker =
+ PropertyInvalidatedCache.separatePermissionNotificationsEnabled()
+ ? null
+ : new PropertyInvalidatedCache
+ .AutoCorker(PermissionManager.CACHE_KEY_PACKAGE_INFO_CACHE);
+
+ /**
+ * Invalidate caches of package and permission information system-wide.
+ *
+ * @hide
+ */
+ public static void invalidatePackageInfoCache() {
+ if (PropertyInvalidatedCache.separatePermissionNotificationsEnabled()) {
+ sPackageInfoCache.invalidateCache();
+ } else {
+ sCacheAutoCorker.autoCork();
+ }
}
/**
diff --git a/core/java/android/content/pm/TEST_MAPPING b/core/java/android/content/pm/TEST_MAPPING
index 44f2a4ca38e247c7380a8dcd07af617f7763a0c2..23f1ff8926df31e17d63c7e781fa0e69deb9b532 100644
--- a/core/java/android/content/pm/TEST_MAPPING
+++ b/core/java/android/content/pm/TEST_MAPPING
@@ -157,6 +157,17 @@
}
]
},
+ {
+ "name": "CtsPackageInstallerCUJUpdateOwnerShipTestCases",
+ "options":[
+ {
+ "exclude-annotation":"androidx.test.filters.FlakyTest"
+ },
+ {
+ "exclude-annotation":"org.junit.Ignore"
+ }
+ ]
+ },
{
"name": "CtsPackageInstallerCUJUpdateSelfTestCases",
"options":[
diff --git a/core/java/android/content/pm/flags.aconfig b/core/java/android/content/pm/flags.aconfig
index 8ba2dcc2a7cf41643d13ebdcc70a4fa19c0aacc4..dfeee2a2335f76d3f6080c5b29b9170c25864cc2 100644
--- a/core/java/android/content/pm/flags.aconfig
+++ b/core/java/android/content/pm/flags.aconfig
@@ -353,14 +353,6 @@ flag {
is_fixed_read_only: true
}
-flag {
- name: "support_minor_versions_in_minsdkversion"
- namespace: "package_manager_service"
- description: "Block app installations that specify an incompatible minor SDK version"
- bug: "377302905"
- is_exported: true
-}
-
flag {
name: "app_compat_option_16kb"
is_exported: true
diff --git a/core/java/android/content/pm/parsing/ApkLiteParseUtils.java b/core/java/android/content/pm/parsing/ApkLiteParseUtils.java
index 18a45d8d442e0179dbb737a64bcd885e47b8052c..53813012b4b3c6d8e5910b8a6b7f1127b397300b 100644
--- a/core/java/android/content/pm/parsing/ApkLiteParseUtils.java
+++ b/core/java/android/content/pm/parsing/ApkLiteParseUtils.java
@@ -539,9 +539,6 @@ public class ApkLiteParseUtils {
hasBindDeviceAdminPermission);
break;
case TAG_USES_SDK_LIBRARY:
- if (!android.content.pm.Flags.sdkDependencyInstaller()) {
- break;
- }
String usesSdkLibName = parser.getAttributeValue(
ANDROID_RES_NAMESPACE, "name");
// TODO(b/379219371): Due to a bug in bundletool, some apps can use
diff --git a/core/java/android/content/res/CompatibilityInfo.java b/core/java/android/content/res/CompatibilityInfo.java
index d6620d19ccf0b73e863d34afed60136383829769..afcdcb0fbcad36788758adf57062083a3daae62d 100644
--- a/core/java/android/content/res/CompatibilityInfo.java
+++ b/core/java/android/content/res/CompatibilityInfo.java
@@ -17,7 +17,9 @@
package android.content.res;
import android.annotation.Nullable;
+import android.app.WindowConfiguration;
import android.compat.annotation.UnsupportedAppUsage;
+import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.graphics.Canvas;
import android.graphics.Insets;
@@ -34,14 +36,17 @@ import android.util.MergedConfiguration;
import android.view.InsetsSourceControl;
import android.view.InsetsState;
import android.view.MotionEvent;
+import android.view.Surface;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
+import com.android.aconfig.annotations.VisibleForTesting;
+
/**
* CompatibilityInfo class keeps the information about the screen compatibility mode that the
* application is running under.
- *
- * {@hide}
+ *
+ * {@hide}
*/
@RavenwoodKeepWholeClass
public class CompatibilityInfo implements Parcelable {
@@ -129,12 +134,37 @@ public class CompatibilityInfo implements Parcelable {
*/
public final float applicationDensityInvertedScale;
+ /**
+ * Application's display rotation.
+ *
+ *
This field is used to sandbox fixed-orientation activities on displays or display areas
+ * with ignoreOrientationRequest, where the display orientation is more likely to be different
+ * from the orientation the activity requested (e.g. in desktop windowing, or letterboxed).
+ * Mainly set for activities which use the display rotation to orient their content, for example
+ * camera previews.
+ *
+ *
In the case of camera activities, assuming the wrong posture
+ * can lead to sideways or stretched previews. As part of camera compat treatment for desktop
+ * windowing, the app is sandboxed to believe that the app and the device are in the posture the
+ * app requested. For example for portrait fixed-orientation apps, the app is letterboxed to
+ * portrait, camera feed is cropped to portrait, and the display rotation is changed via this
+ * field, for example to {@link Surface.Rotation#ROTATION_0} on devices with portrait natural
+ * orientation. All of these parameters factor in common calculations for setting up the camera
+ * preview.
+ */
+ @Surface.Rotation
+ public int applicationDisplayRotation = WindowConfiguration.ROTATION_UNDEFINED;
+
/** The process level override inverted scale. See {@link #HAS_OVERRIDE_SCALING}. */
private static float sOverrideInvertedScale = 1f;
/** The process level override inverted density scale. See {@link #HAS_OVERRIDE_SCALING}. */
private static float sOverrideDensityInvertScale = 1f;
+ /** The process level override display rotation. */
+ @Surface.Rotation
+ private static int sOverrideDisplayRotation = WindowConfiguration.ROTATION_UNDEFINED;
+
@UnsupportedAppUsage
@Deprecated
public CompatibilityInfo(ApplicationInfo appInfo, int screenLayout, int sw,
@@ -346,11 +376,16 @@ public class CompatibilityInfo implements Parcelable {
return (mCompatibilityFlags & HAS_OVERRIDE_SCALING) != 0;
}
+ /** Returns {@code true} if {@link #sOverrideDisplayRotation} should be set. */
+ public boolean isOverrideDisplayRotationRequired() {
+ return applicationDisplayRotation != WindowConfiguration.ROTATION_UNDEFINED;
+ }
+
@UnsupportedAppUsage
public boolean supportsScreen() {
return (mCompatibilityFlags&NEEDS_SCREEN_COMPAT) == 0;
}
-
+
public boolean neverSupportsScreen() {
return (mCompatibilityFlags&ALWAYS_NEEDS_COMPAT) != 0;
}
@@ -618,6 +653,9 @@ public class CompatibilityInfo implements Parcelable {
}
public void applyToConfiguration(int displayDensity, Configuration inoutConfig) {
+ if (hasOverrideDisplayRotation()) {
+ applyDisplayRotationConfiguration(sOverrideDisplayRotation, inoutConfig);
+ }
if (hasOverrideScale()) return;
if (!supportsScreen()) {
// This is a larger screen device and the app is not
@@ -650,21 +688,42 @@ public class CompatibilityInfo implements Parcelable {
inoutConfig.windowConfiguration.scale(invertScale);
}
- /** @see #sOverrideInvertedScale */
- public static void applyOverrideScaleIfNeeded(Configuration config) {
- if (!hasOverrideScale()) return;
- scaleConfiguration(sOverrideInvertedScale, sOverrideDensityInvertScale, config);
+ /** Changes the WindowConfiguration display rotation for the given configuration. */
+ public static void applyDisplayRotationConfiguration(@Surface.Rotation int displayRotation,
+ Configuration inoutConfig) {
+ if (displayRotation != WindowConfiguration.ROTATION_UNDEFINED) {
+ inoutConfig.windowConfiguration.setDisplayRotation(displayRotation);
+ }
}
- /** @see #sOverrideInvertedScale */
- public static void applyOverrideScaleIfNeeded(MergedConfiguration mergedConfig) {
- if (!hasOverrideScale()) return;
- scaleConfiguration(sOverrideInvertedScale, sOverrideDensityInvertScale,
- mergedConfig.getGlobalConfiguration());
- scaleConfiguration(sOverrideInvertedScale, sOverrideDensityInvertScale,
- mergedConfig.getOverrideConfiguration());
- scaleConfiguration(sOverrideInvertedScale, sOverrideDensityInvertScale,
- mergedConfig.getMergedConfiguration());
+ /** @see #sOverrideInvertedScale and #sOverrideDisplayRotation. */
+ public static void applyOverrideIfNeeded(Configuration config) {
+ if (hasOverrideDisplayRotation()) {
+ applyDisplayRotationConfiguration(sOverrideDisplayRotation, config);
+ }
+ if (hasOverrideScale()) {
+ scaleConfiguration(sOverrideInvertedScale, sOverrideDensityInvertScale, config);
+ }
+ }
+
+ /** @see #sOverrideInvertedScale and #sOverrideDisplayRotation. */
+ public static void applyOverrideIfNeeded(MergedConfiguration mergedConfig) {
+ if (hasOverrideDisplayRotation()) {
+ applyDisplayRotationConfiguration(sOverrideDisplayRotation,
+ mergedConfig.getGlobalConfiguration());
+ applyDisplayRotationConfiguration(sOverrideDisplayRotation,
+ mergedConfig.getOverrideConfiguration());
+ applyDisplayRotationConfiguration(sOverrideDisplayRotation,
+ mergedConfig.getMergedConfiguration());
+ }
+ if (hasOverrideScale()) {
+ scaleConfiguration(sOverrideInvertedScale, sOverrideDensityInvertScale,
+ mergedConfig.getGlobalConfiguration());
+ scaleConfiguration(sOverrideInvertedScale, sOverrideDensityInvertScale,
+ mergedConfig.getOverrideConfiguration());
+ scaleConfiguration(sOverrideInvertedScale, sOverrideDensityInvertScale,
+ mergedConfig.getMergedConfiguration());
+ }
}
/** Returns {@code true} if this process is in a environment with override scale. */
@@ -693,6 +752,22 @@ public class CompatibilityInfo implements Parcelable {
return sOverrideDensityInvertScale;
}
+ /** Returns {@code true} if this process is in a environment with override display rotation. */
+ private static boolean hasOverrideDisplayRotation() {
+ return sOverrideDisplayRotation != WindowConfiguration.ROTATION_UNDEFINED;
+ }
+
+ /** @see #sOverrideInvertedScale */
+ public static void setOverrideDisplayRotation(@Surface.Rotation int displayRotation) {
+ sOverrideDisplayRotation = displayRotation;
+ }
+
+ /** @see #sOverrideDisplayRotation */
+ @VisibleForTesting
+ public static int getOverrideDisplayRotation() {
+ return sOverrideDisplayRotation;
+ }
+
/**
* Compute the frame Rect for applications runs under compatibility mode.
*
@@ -747,18 +822,50 @@ public class CompatibilityInfo implements Parcelable {
if (this == o) {
return true;
}
- try {
- CompatibilityInfo oc = (CompatibilityInfo)o;
- if (mCompatibilityFlags != oc.mCompatibilityFlags) return false;
- if (applicationDensity != oc.applicationDensity) return false;
- if (applicationScale != oc.applicationScale) return false;
- if (applicationInvertedScale != oc.applicationInvertedScale) return false;
- if (applicationDensityScale != oc.applicationDensityScale) return false;
- if (applicationDensityInvertedScale != oc.applicationDensityInvertedScale) return false;
- return true;
- } catch (ClassCastException e) {
+
+ if (!(o instanceof CompatibilityInfo oc)) {
return false;
}
+
+ if (!isCompatibilityFlagsEqual(oc)) return false;
+ if (!isScaleEqual(oc)) return false;
+ if (!isDisplayRotationEqual(oc)) return false;
+ return true;
+ }
+
+ /**
+ * Checks the difference between this and given {@link CompatibilityInfo} o, and returns the
+ * combination of {@link ActivityInfo}.CONFIG_* changes that this difference should trigger.
+ */
+ public int getCompatibilityChangesForConfig(@Nullable CompatibilityInfo o) {
+ int changes = 0;
+ if (!isDisplayRotationEqual(o)) {
+ changes |= ActivityInfo.CONFIG_WINDOW_CONFIGURATION;
+ }
+ if (!isScaleEqual(o) || !isCompatibilityFlagsEqual(o)) {
+ changes |= ActivityInfo.CONFIG_SCREEN_LAYOUT
+ | ActivityInfo.CONFIG_SCREEN_SIZE
+ | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE;
+ }
+ return changes;
+ }
+
+ private boolean isScaleEqual(@Nullable CompatibilityInfo oc) {
+ if (oc == null) return false;
+ if (applicationDensity != oc.applicationDensity) return false;
+ if (applicationScale != oc.applicationScale) return false;
+ if (applicationInvertedScale != oc.applicationInvertedScale) return false;
+ if (applicationDensityScale != oc.applicationDensityScale) return false;
+ if (applicationDensityInvertedScale != oc.applicationDensityInvertedScale) return false;
+ return true;
+ }
+
+ private boolean isDisplayRotationEqual(@Nullable CompatibilityInfo oc) {
+ return oc != null && oc.applicationDisplayRotation == applicationDisplayRotation;
+ }
+
+ private boolean isCompatibilityFlagsEqual(@Nullable CompatibilityInfo oc) {
+ return oc != null && oc.mCompatibilityFlags == mCompatibilityFlags;
}
@Override
@@ -778,6 +885,10 @@ public class CompatibilityInfo implements Parcelable {
sb.append(" overrideDensityInvScale=");
sb.append(applicationDensityInvertedScale);
}
+ if (isOverrideDisplayRotationRequired()) {
+ sb.append(" overrideDisplayRotation=");
+ sb.append(applicationDisplayRotation);
+ }
if (!supportsScreen()) {
sb.append(" resizing");
}
@@ -800,6 +911,7 @@ public class CompatibilityInfo implements Parcelable {
result = 31 * result + Float.floatToIntBits(applicationInvertedScale);
result = 31 * result + Float.floatToIntBits(applicationDensityScale);
result = 31 * result + Float.floatToIntBits(applicationDensityInvertedScale);
+ result = 31 * result + applicationDisplayRotation;
return result;
}
@@ -816,6 +928,7 @@ public class CompatibilityInfo implements Parcelable {
dest.writeFloat(applicationInvertedScale);
dest.writeFloat(applicationDensityScale);
dest.writeFloat(applicationDensityInvertedScale);
+ dest.writeInt(applicationDisplayRotation);
}
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
@@ -839,6 +952,7 @@ public class CompatibilityInfo implements Parcelable {
applicationInvertedScale = source.readFloat();
applicationDensityScale = source.readFloat();
applicationDensityInvertedScale = source.readFloat();
+ applicationDisplayRotation = source.readInt();
}
/**
diff --git a/core/java/android/credentials/flags.aconfig b/core/java/android/credentials/flags.aconfig
index 6c35d106bfb7e7e5f4e8a158800c8054e19cb2c9..d8d4e161006cbfff4ad6af9ec0cd3afeba9246fb 100644
--- a/core/java/android/credentials/flags.aconfig
+++ b/core/java/android/credentials/flags.aconfig
@@ -85,6 +85,16 @@ flag {
bug: "324291187"
}
+flag {
+ namespace: "credential_manager"
+ name: "framework_session_id_metric_bundle"
+ description: "Enables the session_id to be passed across to the UI logs"
+ bug: "379880133"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
flag {
namespace: "credential_manager"
name: "clear_credentials_fix_enabled"
@@ -104,3 +114,13 @@ flag {
purpose: PURPOSE_BUGFIX
}
}
+
+flag {
+ namespace: "credential_manager"
+ name: "propagate_user_context_for_intent_creation"
+ description: "Propagates the user ID in which to find the right OEM UI component to launch"
+ bug: "373711451"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
diff --git a/core/java/android/database/sqlite/SQLiteRawStatement.java b/core/java/android/database/sqlite/SQLiteRawStatement.java
index c59d3cea04147059a887967383ec773e547cf6b6..3f3e46b4334c22a58f00c8f5afe2727262bf498f 100644
--- a/core/java/android/database/sqlite/SQLiteRawStatement.java
+++ b/core/java/android/database/sqlite/SQLiteRawStatement.java
@@ -554,10 +554,16 @@ public final class SQLiteRawStatement implements Closeable {
*
* @see sqlite3_column_type
*
+ * If the row has no data then a {@link SQLiteMisuseException} is thrown. This condition can
+ * occur the last call to {@link #step()} returned false or if {@link #step()} was not called
+ * before the statement was created or after the last call to {@link #reset()}. Note that
+ * {@link SQLiteMisuseException} may be thrown for other reasons.
+ *
* @param columnIndex The index of a column in the result row. It is zero-based.
* @return The type of the value in the column of the result row.
* @throws IllegalStateException if the statement is closed or this is a foreign thread.
* @throws SQLiteBindOrColumnIndexOutOfRangeException if the column is out of range.
+ * @throws SQLiteMisuseException if the row has no data.
* @throws SQLiteException if a native error occurs.
*/
@SQLiteDataType
@@ -580,6 +586,7 @@ public final class SQLiteRawStatement implements Closeable {
* @return The name of the column in the result row.
* @throws IllegalStateException if the statement is closed or this is a foreign thread.
* @throws SQLiteBindOrColumnIndexOutOfRangeException if the column is out of range.
+ * @throws SQLiteMisuseException if the row has no data. See {@link #getColumnType()}.
* @throws SQLiteOutOfMemoryException if the database cannot allocate memory for the name.
*/
@NonNull
@@ -606,6 +613,7 @@ public final class SQLiteRawStatement implements Closeable {
* @return The length, in bytes, of the value in the column.
* @throws IllegalStateException if the statement is closed or this is a foreign thread.
* @throws SQLiteBindOrColumnIndexOutOfRangeException if the column is out of range.
+ * @throws SQLiteMisuseException if the row has no data. See {@link #getColumnType()}.
* @throws SQLiteException if a native error occurs.
*/
public int getColumnLength(int columnIndex) {
@@ -631,6 +639,7 @@ public final class SQLiteRawStatement implements Closeable {
* @return The value of the column as a blob, or null if the column is NULL.
* @throws IllegalStateException if the statement is closed or this is a foreign thread.
* @throws SQLiteBindOrColumnIndexOutOfRangeException if the column is out of range.
+ * @throws SQLiteMisuseException if the row has no data. See {@link #getColumnType()}.
* @throws SQLiteException if a native error occurs.
*/
@Nullable
@@ -664,6 +673,7 @@ public final class SQLiteRawStatement implements Closeable {
* @throws IllegalStateException if the statement is closed or this is a foreign thread.
* @throws IllegalArgumentException if the buffer is too small for offset+length.
* @throws SQLiteBindOrColumnIndexOutOfRangeException if the column is out of range.
+ * @throws SQLiteMisuseException if the row has no data. See {@link #getColumnType()}.
* @throws SQLiteException if a native error occurs.
*/
public int readColumnBlob(int columnIndex, @NonNull byte[] buffer, int offset,
@@ -691,6 +701,7 @@ public final class SQLiteRawStatement implements Closeable {
* @return The value of a column as a double.
* @throws IllegalStateException if the statement is closed or this is a foreign thread.
* @throws SQLiteBindOrColumnIndexOutOfRangeException if the column is out of range.
+ * @throws SQLiteMisuseException if the row has no data. See {@link #getColumnType()}.
* @throws SQLiteException if a native error occurs.
*/
public double getColumnDouble(int columnIndex) {
@@ -715,6 +726,7 @@ public final class SQLiteRawStatement implements Closeable {
* @return The value of the column as an int.
* @throws IllegalStateException if the statement is closed or this is a foreign thread.
* @throws SQLiteBindOrColumnIndexOutOfRangeException if the column is out of range.
+ * @throws SQLiteMisuseException if the row has no data. See {@link #getColumnType()}.
* @throws SQLiteException if a native error occurs.
*/
public int getColumnInt(int columnIndex) {
@@ -739,6 +751,7 @@ public final class SQLiteRawStatement implements Closeable {
* @return The value of the column as an long.
* @throws IllegalStateException if the statement is closed or this is a foreign thread.
* @throws SQLiteBindOrColumnIndexOutOfRangeException if the column is out of range.
+ * @throws SQLiteMisuseException if the row has no data. See {@link #getColumnType()}.
* @throws SQLiteException if a native error occurs.
*/
public long getColumnLong(int columnIndex) {
@@ -763,6 +776,7 @@ public final class SQLiteRawStatement implements Closeable {
* @return The value of the column as a string.
* @throws IllegalStateException if the statement is closed or this is a foreign thread.
* @throws SQLiteBindOrColumnIndexOutOfRangeException if the column is out of range.
+ * @throws SQLiteMisuseException if the row has no data. See {@link #getColumnType()}.
* @throws SQLiteException if a native error occurs.
*/
@NonNull
diff --git a/core/java/android/hardware/contexthub/HubEndpoint.java b/core/java/android/hardware/contexthub/HubEndpoint.java
index 7efdd6dbdf4196c7f4ddf40929c3fb8563bb4409..1f12bbf4d074f3450e3aeafdd560983bc10791a2 100644
--- a/core/java/android/hardware/contexthub/HubEndpoint.java
+++ b/core/java/android/hardware/contexthub/HubEndpoint.java
@@ -107,7 +107,7 @@ public class HubEndpoint {
public void onSessionOpenRequest(
int sessionId,
HubEndpointInfo initiator,
- @Nullable HubServiceInfo serviceInfo)
+ @Nullable String serviceDescriptor)
throws RemoteException {
HubEndpointSession activeSession;
synchronized (mLock) {
@@ -128,16 +128,16 @@ public class HubEndpoint {
processSessionOpenRequestResult(
sessionId,
initiator,
- serviceInfo,
+ serviceDescriptor,
mLifecycleCallback.onSessionOpenRequest(
- initiator, serviceInfo)));
+ initiator, serviceDescriptor)));
}
}
private void processSessionOpenRequestResult(
int sessionId,
HubEndpointInfo initiator,
- @Nullable HubServiceInfo serviceInfo,
+ @Nullable String serviceDescriptor,
HubEndpointSessionResult result) {
if (result == null) {
throw new IllegalArgumentException(
@@ -145,7 +145,7 @@ public class HubEndpoint {
}
if (result.isAccepted()) {
- acceptSession(sessionId, initiator, serviceInfo);
+ acceptSession(sessionId, initiator, serviceDescriptor);
} else {
Log.i(
TAG,
@@ -162,7 +162,7 @@ public class HubEndpoint {
private void acceptSession(
int sessionId,
HubEndpointInfo initiator,
- @Nullable HubServiceInfo serviceInfo) {
+ @Nullable String serviceDescriptor) {
if (mServiceToken == null || mAssignedHubEndpointInfo == null) {
// No longer registered?
return;
@@ -187,7 +187,7 @@ public class HubEndpoint {
HubEndpoint.this,
mAssignedHubEndpointInfo,
initiator,
- serviceInfo);
+ serviceDescriptor);
try {
// oneway call to notify system service that the request is completed
mServiceToken.openSessionRequestComplete(sessionId);
@@ -334,7 +334,6 @@ public class HubEndpoint {
@Nullable IHubEndpointMessageCallback endpointMessageCallback,
@NonNull Executor messageCallbackExecutor) {
mPendingHubEndpointInfo = pendingEndpointInfo;
-
mLifecycleCallback = endpointLifecycleCallback;
mLifecycleCallbackExecutor = lifecycleCallbackExecutor;
mMessageCallback = endpointMessageCallback;
@@ -387,7 +386,7 @@ public class HubEndpoint {
}
/** @hide */
- public void openSession(HubEndpointInfo destinationInfo, @Nullable HubServiceInfo serviceInfo) {
+ public void openSession(HubEndpointInfo destinationInfo, @Nullable String serviceDescriptor) {
// TODO(b/378974199): Consider refactor these assertions
if (mServiceToken == null || mAssignedHubEndpointInfo == null) {
// No longer registered?
@@ -397,7 +396,7 @@ public class HubEndpoint {
HubEndpointSession newSession;
try {
// Request system service to assign session id.
- int sessionId = mServiceToken.openSession(destinationInfo, serviceInfo);
+ int sessionId = mServiceToken.openSession(destinationInfo, serviceDescriptor);
// Save the newly created session
synchronized (mLock) {
@@ -407,7 +406,7 @@ public class HubEndpoint {
HubEndpoint.this,
destinationInfo,
mAssignedHubEndpointInfo,
- serviceInfo);
+ serviceDescriptor);
mActiveSessions.put(sessionId, newSession);
}
} catch (RemoteException e) {
diff --git a/core/java/android/hardware/contexthub/HubEndpointSession.java b/core/java/android/hardware/contexthub/HubEndpointSession.java
index cf952cbdbfdc54864b9d9c8d18ad9696391ade16..77f937ebeabc2025b5988470549d8ef01f2fd895 100644
--- a/core/java/android/hardware/contexthub/HubEndpointSession.java
+++ b/core/java/android/hardware/contexthub/HubEndpointSession.java
@@ -19,6 +19,7 @@ package android.hardware.contexthub;
import android.annotation.FlaggedApi;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.chre.flags.Flags;
import android.hardware.location.ContextHubTransaction;
@@ -43,7 +44,7 @@ public class HubEndpointSession implements AutoCloseable {
@NonNull private final HubEndpoint mHubEndpoint;
@NonNull private final HubEndpointInfo mInitiator;
@NonNull private final HubEndpointInfo mDestination;
- @Nullable private final HubServiceInfo mServiceInfo;
+ @Nullable private final String mServiceDescriptor;
private final AtomicBoolean mIsClosed = new AtomicBoolean(true);
@@ -53,12 +54,12 @@ public class HubEndpointSession implements AutoCloseable {
@NonNull HubEndpoint hubEndpoint,
@NonNull HubEndpointInfo destination,
@NonNull HubEndpointInfo initiator,
- @Nullable HubServiceInfo serviceInfo) {
+ @Nullable String serviceDescriptor) {
mId = id;
mHubEndpoint = hubEndpoint;
mDestination = destination;
mInitiator = initiator;
- mServiceInfo = serviceInfo;
+ mServiceDescriptor = serviceDescriptor;
}
/**
@@ -68,8 +69,11 @@ public class HubEndpointSession implements AutoCloseable {
* @return For messages that does not require a response, the transaction will immediately
* complete. For messages that requires a response, the transaction will complete after
* receiving the response for the message.
+ * @throws SecurityException if the application doesn't have the right permissions to send this
+ * message.
*/
@NonNull
+ @RequiresPermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
public ContextHubTransaction sendMessage(@NonNull HubMessage message) {
if (mIsClosed.get()) {
throw new IllegalStateException("Session is already closed.");
@@ -120,6 +124,7 @@ public class HubEndpointSession implements AutoCloseable {
*
When this function is invoked, the messaging associated with this session is invalidated.
* All futures messages targeted for this client are dropped.
*/
+ @RequiresPermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
public void close() {
if (!mIsClosed.getAndSet(true)) {
mCloseGuard.close();
@@ -128,8 +133,8 @@ public class HubEndpointSession implements AutoCloseable {
}
/**
- * Get the {@link HubServiceInfo} associated with this session. Null value indicates that there
- * is no service associated to this session.
+ * Get the service descriptor associated with this session. Null value indicates that there is
+ * no service associated to this session.
*
*
For hub initiated sessions, the object was previously used in as an argument for open
* request in {@link IHubEndpointLifecycleCallback#onSessionOpenRequest}.
@@ -138,8 +143,8 @@ public class HubEndpointSession implements AutoCloseable {
* android.hardware.location.ContextHubManager#openSession}
*/
@Nullable
- public HubServiceInfo getServiceInfo() {
- return mServiceInfo;
+ public String getServiceDescriptor() {
+ return mServiceDescriptor;
}
@Override
diff --git a/core/java/android/hardware/contexthub/IContextHubEndpoint.aidl b/core/java/android/hardware/contexthub/IContextHubEndpoint.aidl
index 1c98b4b3f4f569d6e56d25de180d9001a12b5eec..b76b2271fe5762a74742299630306978e78314bb 100644
--- a/core/java/android/hardware/contexthub/IContextHubEndpoint.aidl
+++ b/core/java/android/hardware/contexthub/IContextHubEndpoint.aidl
@@ -34,11 +34,12 @@ interface IContextHubEndpoint {
* Request system service to open a session with a specific destination.
*
* @param destination A valid HubEndpointInfo representing the destination.
+ * @param serviceDescriptor An optional descriptor of the service to scope this session to.
*
* @throws IllegalArgumentException If the HubEndpointInfo is not valid.
* @throws IllegalStateException If there are too many opened sessions.
*/
- int openSession(in HubEndpointInfo destination, in @nullable HubServiceInfo serviceInfo);
+ int openSession(in HubEndpointInfo destination, in @nullable String serviceDescriptor);
/**
* Request system service to close a specific session
diff --git a/core/java/android/hardware/contexthub/IContextHubEndpointCallback.aidl b/core/java/android/hardware/contexthub/IContextHubEndpointCallback.aidl
index 1ae5fb9d28c1a2d989ed1f41a629dff648f67c49..63edda84bde552a78263d9d2a7f9ea416630e2ea 100644
--- a/core/java/android/hardware/contexthub/IContextHubEndpointCallback.aidl
+++ b/core/java/android/hardware/contexthub/IContextHubEndpointCallback.aidl
@@ -29,9 +29,9 @@ oneway interface IContextHubEndpointCallback {
*
* @param sessionId An integer identifying the session, assigned by the initiator
* @param initiator HubEndpointInfo representing the requester
- * @param serviceInfo Nullable HubServiceInfo representing the service associated with this session
+ * @param serviceDescriptor Nullable string representing the service associated with this session
*/
- void onSessionOpenRequest(int sessionId, in HubEndpointInfo initiator, in @nullable HubServiceInfo serviceInfo);
+ void onSessionOpenRequest(int sessionId, in HubEndpointInfo initiator, in @nullable String serviceDescriptor);
/**
* Request from system service to close a specific session
diff --git a/core/java/android/hardware/contexthub/IHubEndpointLifecycleCallback.java b/core/java/android/hardware/contexthub/IHubEndpointLifecycleCallback.java
index fe449bb5ce0e92d13a91b8e774bdd54a54bbc18f..698ed0adfd804c4f447648ad7acf98aa98f44e17 100644
--- a/core/java/android/hardware/contexthub/IHubEndpointLifecycleCallback.java
+++ b/core/java/android/hardware/contexthub/IHubEndpointLifecycleCallback.java
@@ -34,12 +34,12 @@ public interface IHubEndpointLifecycleCallback {
* Called when an endpoint is requesting a session be opened with another endpoint.
*
* @param requester The {@link HubEndpointInfo} object representing the requester
- * @param serviceInfo The {@link HubServiceInfo} object representing the service associated with
- * this session. Null indicates that there is no service associated with this session.
+ * @param serviceDescriptor A string describing the service associated with this session. Null
+ * indicates that there is no service associated with this session.
*/
@NonNull
HubEndpointSessionResult onSessionOpenRequest(
- @NonNull HubEndpointInfo requester, @Nullable HubServiceInfo serviceInfo);
+ @NonNull HubEndpointInfo requester, @Nullable String serviceDescriptor);
/**
* Called when a communication session is opened and ready to be used.
diff --git a/core/java/android/hardware/display/DisplayTopology.java b/core/java/android/hardware/display/DisplayTopology.java
index 54d0dd0eb8f8e1c59bf1bb8064796422b29805d5..211aefffa34c3b05b00e6a45abccbffab8f759c3 100644
--- a/core/java/android/hardware/display/DisplayTopology.java
+++ b/core/java/android/hardware/display/DisplayTopology.java
@@ -91,6 +91,15 @@ public final class DisplayTopology implements Parcelable {
@VisibleForTesting
public DisplayTopology(TreeNode root, int primaryDisplayId) {
mRoot = root;
+ if (mRoot != null) {
+ // Set mRoot's position and offset to predictable values, just so we don't leak state
+ // from some previous arrangement the node was used in, or leak arbitrary values passed
+ // to the TreeNode constructor. The position and offset don't mean anything because
+ // mRoot doesn't have a parent.
+ mRoot.mPosition = POSITION_LEFT;
+ mRoot.mOffset = 0f;
+ }
+
mPrimaryDisplayId = primaryDisplayId;
}
@@ -422,6 +431,14 @@ public final class DisplayTopology implements Parcelable {
}
}
}
+
+ // Sort children lists by display ID.
+ final Comparator idComparator = (d1, d2) -> {
+ return Integer.compare(d1.mDisplayId, d2.mDisplayId);
+ };
+ for (TreeNode display : displays) {
+ display.mChildren.sort(idComparator);
+ }
}
/**
@@ -582,6 +599,15 @@ public final class DisplayTopology implements Parcelable {
}
}
+ /** Returns the graph representation of the topology */
+ public DisplayTopologyGraph getGraph() {
+ // TODO(b/364907904): implement
+ return new DisplayTopologyGraph(mPrimaryDisplayId,
+ new DisplayTopologyGraph.DisplayNode[] { new DisplayTopologyGraph.DisplayNode(
+ mRoot == null ? Display.DEFAULT_DISPLAY : mRoot.mDisplayId,
+ new DisplayTopologyGraph.AdjacentDisplay[0])});
+ }
+
/**
* Tests whether two brightness float values are within a small enough tolerance
* of each other.
diff --git a/core/java/android/hardware/display/DisplayTopologyGraph.java b/core/java/android/hardware/display/DisplayTopologyGraph.java
new file mode 100644
index 0000000000000000000000000000000000000000..938e6d108f5dca2b2ffb34a50bec6b7ce1e9a300
--- /dev/null
+++ b/core/java/android/hardware/display/DisplayTopologyGraph.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.display;
+
+/**
+ * Graph of the displays in {@link android.hardware.display.DisplayTopology} tree.
+ *
+ * @hide
+ */
+public record DisplayTopologyGraph(int primaryDisplayId, DisplayNode[] displayNodes) {
+ /**
+ * Display in the topology
+ */
+ public record DisplayNode(
+ int displayId,
+ AdjacentDisplay[] adjacentDisplays) {}
+
+ /**
+ * Edge to adjacent display
+ */
+ public record AdjacentDisplay(
+ // The logical Id of this adjacent display
+ int displayId,
+ // Side of the other display which touches this adjacent display.
+ @DisplayTopology.TreeNode.Position
+ int position,
+ // How many px this display is shifted along the touchingSide, can be negative.
+ float offsetPx) {}
+}
diff --git a/core/java/android/hardware/display/VirtualDisplayConfig.java b/core/java/android/hardware/display/VirtualDisplayConfig.java
index eceaa8ff4c952268ee7bbf01baba9fe87f04ec9e..72570553f78a25732e09ccfa71fc2dfa9362b31f 100644
--- a/core/java/android/hardware/display/VirtualDisplayConfig.java
+++ b/core/java/android/hardware/display/VirtualDisplayConfig.java
@@ -66,6 +66,7 @@ public final class VirtualDisplayConfig implements Parcelable {
private final DisplayCutout mDisplayCutout;
private final boolean mIgnoreActivitySizeRestrictions;
private final float mDefaultBrightness;
+ private final float mDimBrightness;
private final IBrightnessListener mBrightnessListener;
private VirtualDisplayConfig(
@@ -84,6 +85,7 @@ public final class VirtualDisplayConfig implements Parcelable {
@Nullable DisplayCutout displayCutout,
boolean ignoreActivitySizeRestrictions,
@FloatRange(from = 0.0f, to = 1.0f) float defaultBrightness,
+ @FloatRange(from = 0.0f, to = 1.0f) float dimBrightness,
IBrightnessListener brightnessListener) {
mName = name;
mWidth = width;
@@ -100,6 +102,7 @@ public final class VirtualDisplayConfig implements Parcelable {
mDisplayCutout = displayCutout;
mIgnoreActivitySizeRestrictions = ignoreActivitySizeRestrictions;
mDefaultBrightness = defaultBrightness;
+ mDimBrightness = dimBrightness;
mBrightnessListener = brightnessListener;
}
@@ -179,6 +182,19 @@ public final class VirtualDisplayConfig implements Parcelable {
return mDefaultBrightness;
}
+ /**
+ * Returns the dim brightness of the display.
+ *
+ *
Value of {@code 0.0} indicates the minimum supported brightness and value of {@code 1.0}
+ * indicates the maximum supported brightness.
+ *
+ * @see Builder#setDimBrightness(float)
+ */
+ @FlaggedApi(android.companion.virtualdevice.flags.Flags.FLAG_DEVICE_AWARE_DISPLAY_POWER)
+ public @FloatRange(from = 0.0f, to = 1.0f) float getDimBrightness() {
+ return mDimBrightness;
+ }
+
/**
* Returns the listener to get notified about changes in the display brightness.
* @hide
@@ -278,6 +294,7 @@ public final class VirtualDisplayConfig implements Parcelable {
DisplayCutout.ParcelableWrapper.writeCutoutToParcel(mDisplayCutout, dest, flags);
dest.writeBoolean(mIgnoreActivitySizeRestrictions);
dest.writeFloat(mDefaultBrightness);
+ dest.writeFloat(mDimBrightness);
dest.writeStrongBinder(mBrightnessListener != null ? mBrightnessListener.asBinder() : null);
}
@@ -308,8 +325,8 @@ public final class VirtualDisplayConfig implements Parcelable {
&& mIgnoreActivitySizeRestrictions == that.mIgnoreActivitySizeRestrictions
&& Objects.equals(mDisplayCutout, that.mDisplayCutout)
&& mDefaultBrightness == that.mDefaultBrightness
+ && mDimBrightness == that.mDimBrightness
&& Objects.equals(mBrightnessListener, that.mBrightnessListener);
-
}
@Override
@@ -318,7 +335,8 @@ public final class VirtualDisplayConfig implements Parcelable {
mName, mWidth, mHeight, mDensityDpi, mFlags, mSurface, mUniqueId,
mDisplayIdToMirror, mWindowManagerMirroringEnabled, mDisplayCategories,
mRequestedRefreshRate, mIsHomeSupported, mDisplayCutout,
- mIgnoreActivitySizeRestrictions, mDefaultBrightness, mBrightnessListener);
+ mIgnoreActivitySizeRestrictions, mDefaultBrightness, mDimBrightness,
+ mBrightnessListener);
return hashCode;
}
@@ -341,6 +359,7 @@ public final class VirtualDisplayConfig implements Parcelable {
+ " mDisplayCutout=" + mDisplayCutout
+ " mIgnoreActivitySizeRestrictions=" + mIgnoreActivitySizeRestrictions
+ " mDefaultBrightness=" + mDefaultBrightness
+ + " mDimBrightness=" + mDimBrightness
+ ")";
}
@@ -360,8 +379,8 @@ public final class VirtualDisplayConfig implements Parcelable {
mDisplayCutout = DisplayCutout.ParcelableWrapper.readCutoutFromParcel(in);
mIgnoreActivitySizeRestrictions = in.readBoolean();
mDefaultBrightness = in.readFloat();
+ mDimBrightness = in.readFloat();
mBrightnessListener = IBrightnessListener.Stub.asInterface(in.readStrongBinder());
-
}
/**
@@ -432,6 +451,7 @@ public final class VirtualDisplayConfig implements Parcelable {
private DisplayCutout mDisplayCutout = null;
private boolean mIgnoreActivitySizeRestrictions = false;
private float mDefaultBrightness = 0.0f;
+ private float mDimBrightness = PowerManager.BRIGHTNESS_INVALID;
private IBrightnessListener mBrightnessListener = null;
/**
@@ -635,14 +655,14 @@ public final class VirtualDisplayConfig implements Parcelable {
*
*
If unset, defaults to {@code 0.0}
*
+ * @throws IllegalArgumentException if the brightness is outside the valid range [0.0, 1.0]
* @see android.view.View#setKeepScreenOn(boolean)
* @see #setBrightnessListener(Executor, BrightnessListener)
*/
@FlaggedApi(android.companion.virtualdevice.flags.Flags.FLAG_DEVICE_AWARE_DISPLAY_POWER)
@NonNull
public Builder setDefaultBrightness(@FloatRange(from = 0.0f, to = 1.0f) float brightness) {
- if (brightness < PowerManager.BRIGHTNESS_MIN
- || brightness > PowerManager.BRIGHTNESS_MAX) {
+ if (!isValidBrightness(brightness)) {
throw new IllegalArgumentException(
"Virtual display default brightness must be in range [0.0, 1.0]");
}
@@ -650,6 +670,33 @@ public final class VirtualDisplayConfig implements Parcelable {
return this;
}
+ /**
+ * Sets the dim brightness of the display.
+ *
+ *
The system will use this brightness value whenever the display should be dim, i.e.
+ * it is powered on and dimmed due to user activity or app activity.
+ *
+ *
Value of {@code 0.0} indicates the minimum supported brightness and value of
+ * {@code 1.0} indicates the maximum supported brightness.
+ *
+ *
If set, the default brightness must also be set to a value greater or equal to the
+ * dim brightness. If unset, defaults to the system default.
+ *
+ * @throws IllegalArgumentException if the brightness is outside the valid range [0.0, 1.0]
+ * @see Builder#setDefaultBrightness(float)
+ * @see #setBrightnessListener(Executor, BrightnessListener)
+ */
+ @FlaggedApi(android.companion.virtualdevice.flags.Flags.FLAG_DEVICE_AWARE_DISPLAY_POWER)
+ @NonNull
+ public Builder setDimBrightness(@FloatRange(from = 0.0f, to = 1.0f) float brightness) {
+ if (!isValidBrightness(brightness)) {
+ throw new IllegalArgumentException(
+ "Virtual display dim brightness must be in range [0.0, 1.0]");
+ }
+ mDimBrightness = brightness;
+ return this;
+ }
+
/**
* Sets the listener to get notified about changes in the display brightness.
*
@@ -666,11 +713,23 @@ public final class VirtualDisplayConfig implements Parcelable {
return this;
}
+ private boolean isValidBrightness(float brightness) {
+ return !Float.isNaN(brightness) && PowerManager.BRIGHTNESS_MIN <= brightness
+ && brightness <= PowerManager.BRIGHTNESS_MAX;
+ }
+
/**
* Builds the {@link VirtualDisplayConfig} instance.
+ *
+ * @throws IllegalArgumentException if the dim brightness is set to a value greater than
+ * the default brightness.
*/
@NonNull
public VirtualDisplayConfig build() {
+ if (isValidBrightness(mDimBrightness) && mDimBrightness > mDefaultBrightness) {
+ throw new IllegalArgumentException(
+ "The dim brightness must not be greater than the default brightness");
+ }
return new VirtualDisplayConfig(
mName,
mWidth,
@@ -687,6 +746,7 @@ public final class VirtualDisplayConfig implements Parcelable {
mDisplayCutout,
mIgnoreActivitySizeRestrictions,
mDefaultBrightness,
+ mDimBrightness,
mBrightnessListener);
}
}
diff --git a/core/java/android/hardware/input/InputSettings.java b/core/java/android/hardware/input/InputSettings.java
index 3f9317aa24f124e7a64a062efb7d36067d952118..f8f7f5e0586e2453305d46d446ba9e39d2d5b5b8 100644
--- a/core/java/android/hardware/input/InputSettings.java
+++ b/core/java/android/hardware/input/InputSettings.java
@@ -28,7 +28,6 @@ import static com.android.hardware.input.Flags.keyboardA11yStickyKeysFlag;
import static com.android.hardware.input.Flags.mouseReverseVerticalScrolling;
import static com.android.hardware.input.Flags.mouseSwapPrimaryButton;
import static com.android.hardware.input.Flags.touchpadSystemGestureDisable;
-import static com.android.hardware.input.Flags.touchpadTapDragging;
import static com.android.hardware.input.Flags.touchpadThreeFingerTapShortcut;
import static com.android.hardware.input.Flags.touchpadVisualizer;
import static com.android.hardware.input.Flags.useKeyGestureEventHandler;
@@ -365,15 +364,6 @@ public class InputSettings {
UserHandle.USER_CURRENT);
}
- /**
- * Returns true if the feature flag for touchpad tap dragging is enabled.
- *
- * @hide
- */
- public static boolean isTouchpadTapDraggingFeatureFlagEnabled() {
- return touchpadTapDragging();
- }
-
/**
* Returns true if the feature flag for disabling system gestures on touchpads is enabled.
*
@@ -461,9 +451,6 @@ public class InputSettings {
* @hide
*/
public static boolean useTouchpadTapDragging(@NonNull Context context) {
- if (!isTouchpadTapDraggingFeatureFlagEnabled()) {
- return false;
- }
return Settings.System.getIntForUser(context.getContentResolver(),
Settings.System.TOUCHPAD_TAP_DRAGGING, 0, UserHandle.USER_CURRENT) == 1;
}
@@ -480,9 +467,6 @@ public class InputSettings {
*/
@RequiresPermission(Manifest.permission.WRITE_SETTINGS)
public static void setTouchpadTapDragging(@NonNull Context context, boolean enabled) {
- if (!isTouchpadTapDraggingFeatureFlagEnabled()) {
- return;
- }
Settings.System.putIntForUser(context.getContentResolver(),
Settings.System.TOUCHPAD_TAP_DRAGGING, enabled ? 1 : 0,
UserHandle.USER_CURRENT);
diff --git a/core/java/android/hardware/input/KeyGestureEvent.java b/core/java/android/hardware/input/KeyGestureEvent.java
index 711dc3a2cf7c49ce86c0b96b9cbcf1900d249c1c..af756b9217d39121e4bd48661cf2d159749731c6 100644
--- a/core/java/android/hardware/input/KeyGestureEvent.java
+++ b/core/java/android/hardware/input/KeyGestureEvent.java
@@ -43,6 +43,8 @@ public final class KeyGestureEvent {
private static final int LOG_EVENT_UNSPECIFIED =
FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__UNSPECIFIED;
+ // These values should not change and values should not be re-used as this data is persisted to
+ // long term storage and must be kept backwards compatible.
public static final int KEY_GESTURE_TYPE_UNSPECIFIED = 0;
public static final int KEY_GESTURE_TYPE_HOME = 1;
public static final int KEY_GESTURE_TYPE_RECENT_APPS = 2;
diff --git a/core/java/android/hardware/input/input_framework.aconfig b/core/java/android/hardware/input/input_framework.aconfig
index ebb617249993e54f61706ee08fbbe89e0a6b54bd..aaa78aa0916a3a6730e2e81c66871149110d8912 100644
--- a/core/java/android/hardware/input/input_framework.aconfig
+++ b/core/java/android/hardware/input/input_framework.aconfig
@@ -35,13 +35,6 @@ flag {
bug: "294546335"
}
-flag {
- namespace: "input_native"
- name: "touchpad_tap_dragging"
- description: "Offers a setting to enable touchpad tap dragging"
- bug: "321978150"
-}
-
flag {
namespace: "input_native"
name: "keyboard_glyph_map"
@@ -196,4 +189,11 @@ flag {
namespace: "wallet_integration"
description: "Adds new API in WindowManager class to check if the window can override the power key double tap behavior."
bug: "378736024"
- }
\ No newline at end of file
+ }
+
+flag {
+ name: "pointer_acceleration"
+ namespace: "input"
+ description: "Allows the user to disable pointer acceleration for mouse and touchpads."
+ bug: "349006858"
+}
\ No newline at end of file
diff --git a/core/java/android/hardware/location/ContextHubManager.java b/core/java/android/hardware/location/ContextHubManager.java
index 3a74130d5e831c78ebe4300147d9b1bc9e3eb999..d9888ad6cd8d736b4e92e840076383b2053f49f1 100644
--- a/core/java/android/hardware/location/ContextHubManager.java
+++ b/core/java/android/hardware/location/ContextHubManager.java
@@ -841,6 +841,7 @@ public final class ContextHubManager {
* @param endpointId The identifier of the hub endpoint.
* @param callback The callback to be invoked.
* @param executor The executor to invoke the callback on.
+ * @throws UnsupportedOperationException If the operation is not supported.
*/
@RequiresPermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
@FlaggedApi(Flags.FLAG_OFFLOAD_API)
@@ -881,6 +882,7 @@ public final class ContextHubManager {
* @param callback The callback to be invoked.
* @param executor The executor to invoke the callback on.
* @throws IllegalArgumentException if the serviceDescriptor is empty.
+ * @throws UnsupportedOperationException If the operation is not supported.
*/
@RequiresPermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
@FlaggedApi(Flags.FLAG_OFFLOAD_API)
@@ -911,6 +913,7 @@ public final class ContextHubManager {
*
* @param callback The callback previously registered.
* @throws IllegalArgumentException If the callback was not previously registered.
+ * @throws UnsupportedOperationException If the operation is not supported.
*/
@RequiresPermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
@FlaggedApi(Flags.FLAG_OFFLOAD_API)
@@ -1309,16 +1312,18 @@ public final class ContextHubManager {
* ContextHubManager#registerEndpoint(HubEndpoint)}.
* @param destination {@link HubEndpointInfo} object that represents an endpoint from previous
* endpoint discovery results (e.g. from {@link ContextHubManager#findEndpoints(long)}).
- * @param serviceInfo {@link HubServiceInfo} object that describes the service associated with
- * this session. The information will be sent to the destination as part of open request.
+ * @param serviceDescriptor A string that describes the service associated with this session.
+ * The information will be sent to the destination as part of open request.
+ * @throws IllegalStateException if hubEndpoint was not successfully registered, or if there is
+ * insufficient capacity for creating a session.
*/
@RequiresPermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
@FlaggedApi(Flags.FLAG_OFFLOAD_API)
public void openSession(
@NonNull HubEndpoint hubEndpoint,
@NonNull HubEndpointInfo destination,
- @NonNull HubServiceInfo serviceInfo) {
- hubEndpoint.openSession(destination, serviceInfo);
+ @NonNull String serviceDescriptor) {
+ hubEndpoint.openSession(destination, serviceDescriptor);
}
/**
diff --git a/core/java/android/hardware/radio/ProgramSelector.java b/core/java/android/hardware/radio/ProgramSelector.java
index 42028f67f4005e0fb6bdf8ab2a1597ed7df1fb8a..e5717ac87d88d0faf11441b2faacc5ff33616e02 100644
--- a/core/java/android/hardware/radio/ProgramSelector.java
+++ b/core/java/android/hardware/radio/ProgramSelector.java
@@ -43,22 +43,20 @@ import java.util.stream.Stream;
*
DAB channel info
*
*
- *
The primary ID uniquely identifies a station and can be used for equality
- * check. The secondary IDs are supplementary and can speed up tuning process,
- * but the primary ID is sufficient (ie. after a full band scan).
- *
- *
Two selectors with different secondary IDs, but the same primary ID are
- * considered equal. In particular, secondary IDs vector may get updated for
+ *
Except for DAB radio, two selectors with different secondary IDs, but the same primary
+ * ID are considered equal. In particular, secondary IDs vector may get updated for
* an entry on the program list (ie. when a better frequency for a given
- * station is found).
+ * station is found). For DAB radio, two selectors with the same primary ID and the same
+ * DAB frequency and DAB ensemble secondary IDs (if exist) are considered equal.
*
*
The primaryId of a given programType MUST be of a specific type:
*
- *
AM, FM: RDS_PI if the station broadcasts RDS, AMFM_FREQUENCY otherwise;
- *
AM_HD, FM_HD: HD_STATION_ID_EXT;
- *
DAB: DAB_SIDECC;
- *
DRMO: DRMO_SERVICE_ID;
- *
SXM: SXM_SERVICE_ID;
+ *
AM, FM: {@link #IDENTIFIER_TYPE_RDS_PI} if the station broadcasts RDS,
+ * {@link #IDENTIFIER_TYPE_AMFM_FREQUENCY} otherwise;
DAB: {@link #IDENTIFIER_TYPE_DAB_SID_EXT} or
+ * {@link #IDENTIFIER_TYPE_DAB_DMB_SID_EXT};
+ *
DRMO: {@link #IDENTIFIER_TYPE_DRMO_SERVICE_ID};
*
VENDOR: VENDOR_PRIMARY.
*
* @hide
@@ -597,9 +595,9 @@ public final class ProgramSelector implements Parcelable {
* negatives. In particular, it may be way off for certain regions.
* The main purpose is to avoid passing improper units, ie. MHz instead of kHz.
*
- * @param isAm true, if AM, false if FM.
+ * @param isAm {@code true}, if AM, {@code false} if FM.
* @param frequencyKhz the frequency in kHz.
- * @return true, if the frequency is roughly valid.
+ * @return {@code true}, if the frequency is roughly valid.
*/
private static boolean isValidAmFmFrequency(boolean isAm, int frequencyKhz) {
if (isAm) {
@@ -785,8 +783,8 @@ public final class ProgramSelector implements Parcelable {
* ProgramLists for category entries.
*
* @see ProgramList.Filter#areCategoriesIncluded
- * @return False if this identifier's type is not tunable (e.g. DAB ensemble or
- * vendor-specified type). True otherwise.
+ * @return {@link false} if this identifier's type is not tunable (e.g. DAB ensemble or
+ * vendor-specified type). {@link true} otherwise.
*/
public boolean isCategoryType() {
return (mType >= IDENTIFIER_TYPE_VENDOR_START && mType <= IDENTIFIER_TYPE_VENDOR_END)
diff --git a/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java b/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java
index 9b37533f5b02dcf5899e9a46fd3b6a52760e29c8..9badbf8e2a1b7d3dcee4d6f8862ce0f39e450d40 100644
--- a/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java
+++ b/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java
@@ -299,9 +299,10 @@ class IInputMethodSessionWrapper extends IInputMethodSession.Stub
if (event.hasNoModifiers()) {
return false;
}
- return event.hasModifiers(KeyEvent.META_CTRL_ON)
- || event.hasModifiers(KeyEvent.META_ALT_ON)
- || event.hasModifiers(KeyEvent.KEYCODE_FUNCTION);
+ return event.isCtrlPressed()
+ || event.isAltPressed()
+ || event.isFunctionPressed()
+ || event.isMetaPressed();
}
private boolean needsVerification(KeyEvent event) {
diff --git a/core/java/android/net/EventLogTags.logtags b/core/java/android/net/EventLogTags.logtags
index d5ed01496eba669df1a3a0d10bab218aa6c6e013..32953c92d1203c39a36e4fa070e630451510a25c 100644
--- a/core/java/android/net/EventLogTags.logtags
+++ b/core/java/android/net/EventLogTags.logtags
@@ -1,4 +1,4 @@
-# See system/core/logcat/event.logtags for a description of the format of this file.
+# See system/logging/logcat/event.logtags for a description of the format of this file.
option java_package android.net
diff --git a/core/java/android/net/metrics/DnsEvent.java b/core/java/android/net/metrics/DnsEvent.java
index bf351ce07fe8109970a8350c2e88e3c8c9e5dee8..f53d1c4d191dcc36d031cfcaa3acecd5222f9b51 100644
--- a/core/java/android/net/metrics/DnsEvent.java
+++ b/core/java/android/net/metrics/DnsEvent.java
@@ -62,7 +62,11 @@ final public class DnsEvent {
return isSuccess;
}
if (eventCount == eventTypes.length) {
- resize((int) (1.4 * eventCount));
+ int resizeLength = (int) (1.4 * eventCount);
+ if (eventCount == resizeLength) {
+ resizeLength++;
+ }
+ resize(resizeLength);
}
eventTypes[eventCount] = eventType;
returnCodes[eventCount] = returnCode;
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 8b6da7e0ae58f5a0bc6e8dc52e1b7caa100d34aa..84ca5ed4ab1024fbbc53ab3b4a23b4d1661dcae0 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -403,7 +403,7 @@ public class Build {
* increase when the hardware manufacturer provides an OTA update.
*
* This constant records the major version of Android. Use {@link
- * SDK_INT_FULL} if you need to consider the minor version of Android
+ * #SDK_INT_FULL} if you need to consider the minor version of Android
* as well.
*
* Possible values are defined in {@link Build.VERSION_CODES}.
diff --git a/core/java/android/os/Bundle.java b/core/java/android/os/Bundle.java
index 05bd10b053fe92096c1760a61eca1e5676b5e6a2..819d58d9f0598294b755e62e47ff4108aa8a6367 100644
--- a/core/java/android/os/Bundle.java
+++ b/core/java/android/os/Bundle.java
@@ -70,6 +70,11 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable {
*/
static final int FLAG_VERIFY_TOKENS_PRESENT = 1 << 13;
+ /**
+ * Indicates the bundle definitely contains an Intent.
+ */
+ static final int FLAG_HAS_INTENT = 1 << 14;
+
/**
* Status when the Bundle can assert that the underlying Parcel DOES NOT contain
@@ -117,6 +122,11 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable {
/** An unmodifiable {@code Bundle} that is always {@link #isEmpty() empty}. */
public static final Bundle EMPTY;
+ /**
+ * @hide
+ */
+ public static Class> intentClass;
+
/**
* Special extras used to denote extras have been stripped off.
* @hide
@@ -388,6 +398,7 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable {
if ((bundle.mFlags & FLAG_HAS_BINDERS_KNOWN) == 0) {
mFlags &= ~FLAG_HAS_BINDERS_KNOWN;
}
+ mFlags |= bundle.mFlags & FLAG_HAS_INTENT;
}
/**
@@ -447,6 +458,16 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable {
}
}
+ /**
+ * Returns if the bundle definitely contains at least an intent. This method returns false does
+ * not guarantee the bundle does not contain a nested intent. An intent could still exist in a
+ * ParcelableArrayList, ParcelableArray, ParcelableList, a bundle in this bundle, etc.
+ * @hide
+ */
+ public boolean hasIntent() {
+ return (mFlags & FLAG_HAS_INTENT) != 0;
+ }
+
/** {@hide} */
@Override
public void putObject(@Nullable String key, @Nullable Object value) {
@@ -569,6 +590,9 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable {
mMap.put(key, value);
mFlags &= ~FLAG_HAS_FDS_KNOWN;
mFlags &= ~FLAG_HAS_BINDERS_KNOWN;
+ if (intentClass != null && intentClass.isInstance(value)) {
+ mFlags |= FLAG_HAS_INTENT;
+ }
}
/**
diff --git a/core/java/android/os/CombinedMessageQueue/MessageQueue.java b/core/java/android/os/CombinedMessageQueue/MessageQueue.java
index 23114c4318c72bc7c6197846c59e5a978ca8e98c..b509c7a441d338eae4a0aadc99abb9d8c4be9135 100644
--- a/core/java/android/os/CombinedMessageQueue/MessageQueue.java
+++ b/core/java/android/os/CombinedMessageQueue/MessageQueue.java
@@ -18,18 +18,25 @@ package android.os;
import android.annotation.IntDef;
import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SuppressLint;
import android.annotation.TestApi;
+import android.app.ActivityThread;
+import android.app.Instrumentation;
import android.compat.annotation.UnsupportedAppUsage;
import android.os.Process;
import android.os.UserHandle;
import android.ravenwood.annotation.RavenwoodKeepWholeClass;
import android.ravenwood.annotation.RavenwoodRedirect;
import android.ravenwood.annotation.RavenwoodRedirectionClass;
+import android.ravenwood.annotation.RavenwoodReplace;
+import android.ravenwood.annotation.RavenwoodThrow;
import android.util.Log;
import android.util.Printer;
import android.util.SparseArray;
import android.util.proto.ProtoOutputStream;
+import com.android.internal.annotations.GuardedBy;
import com.android.internal.ravenwood.RavenwoodEnvironment;
import dalvik.annotation.optimization.NeverCompile;
@@ -119,7 +126,7 @@ public final class MessageQueue {
MessageQueue(boolean quitAllowed) {
initIsProcessAllowedToUseConcurrent();
- mUseConcurrent = sIsProcessAllowedToUseConcurrent;
+ mUseConcurrent = sIsProcessAllowedToUseConcurrent && !isInstrumenting();
mQuitAllowed = quitAllowed;
mPtr = nativeInit();
}
@@ -172,6 +179,37 @@ public final class MessageQueue {
}
}
+ @RavenwoodReplace
+ private static void throwIfNotTest() {
+ final ActivityThread activityThread = ActivityThread.currentActivityThread();
+ if (activityThread == null) {
+ // Only tests can reach here.
+ return;
+ }
+ final Instrumentation instrumentation = activityThread.getInstrumentation();
+ if (instrumentation == null) {
+ // Only tests can reach here.
+ return;
+ }
+ if (instrumentation.isInstrumenting()) {
+ return;
+ }
+ throw new IllegalStateException("Test-only API called not from a test!");
+ }
+
+ private static void throwIfNotTest$ravenwood() {
+ return;
+ }
+
+ private static boolean isInstrumenting() {
+ final ActivityThread activityThread = ActivityThread.currentActivityThread();
+ if (activityThread == null) {
+ return false;
+ }
+ final Instrumentation instrumentation = activityThread.getInstrumentation();
+ return instrumentation != null && instrumentation.isInstrumenting();
+ }
+
@Override
protected void finalize() throws Throwable {
try {
@@ -192,12 +230,9 @@ public final class MessageQueue {
private static final class MatchDeliverableMessages extends MessageCompare {
@Override
- public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
+ public boolean compareMessage(MessageNode n, Handler h, int what, Object object, Runnable r,
long when) {
- if (m.when <= when) {
- return true;
- }
- return false;
+ return n.mMessage.when <= when;
}
}
private final MatchDeliverableMessages mMatchDeliverableMessages =
@@ -344,7 +379,7 @@ public final class MessageQueue {
* @see OnFileDescriptorEventListener
* @see #removeOnFileDescriptorEventListener
*/
- @android.ravenwood.annotation.RavenwoodThrow(blockedBy = android.os.ParcelFileDescriptor.class)
+ @RavenwoodThrow(blockedBy = android.os.ParcelFileDescriptor.class)
public void addOnFileDescriptorEventListener(@NonNull FileDescriptor fd,
@OnFileDescriptorEventListener.Events int events,
@NonNull OnFileDescriptorEventListener listener) {
@@ -378,7 +413,7 @@ public final class MessageQueue {
* @see OnFileDescriptorEventListener
* @see #addOnFileDescriptorEventListener
*/
- @android.ravenwood.annotation.RavenwoodThrow(blockedBy = android.os.ParcelFileDescriptor.class)
+ @RavenwoodThrow(blockedBy = android.os.ParcelFileDescriptor.class)
public void removeOnFileDescriptorEventListener(@NonNull FileDescriptor fd) {
if (fd == null) {
throw new IllegalArgumentException("fd must not be null");
@@ -394,7 +429,7 @@ public final class MessageQueue {
}
}
- @android.ravenwood.annotation.RavenwoodThrow(blockedBy = android.os.ParcelFileDescriptor.class)
+ @RavenwoodThrow(blockedBy = android.os.ParcelFileDescriptor.class)
private void updateOnFileDescriptorEventListenerLocked(FileDescriptor fd, int events,
OnFileDescriptorEventListener listener) {
final int fdNum = fd.getInt$();
@@ -517,7 +552,7 @@ public final class MessageQueue {
/* This is only read/written from the Looper thread. For use with Concurrent MQ */
private int mNextPollTimeoutMillis;
private boolean mMessageDirectlyQueued;
- private Message nextMessage() {
+ private Message nextMessage(boolean peek) {
int i = 0;
while (true) {
@@ -679,7 +714,7 @@ public final class MessageQueue {
if (sState.compareAndSet(this, sStackStateActive, nextOp)) {
mMessageCounts.clearCounts();
if (found != null) {
- if (!removeFromPriorityQueue(found)) {
+ if (!peek && !removeFromPriorityQueue(found)) {
/*
* RemoveMessages() might be able to pull messages out from under us
* However we can detect that here and just loop around if it happens.
@@ -713,7 +748,7 @@ public final class MessageQueue {
mMessageDirectlyQueued = false;
nativePollOnce(ptr, mNextPollTimeoutMillis);
- Message msg = nextMessage();
+ Message msg = nextMessage(false);
if (msg != null) {
msg.markInUse();
return msg;
@@ -1032,8 +1067,9 @@ public final class MessageQueue {
}
@Override
- public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
+ public boolean compareMessage(MessageNode n, Handler h, int what, Object object, Runnable r,
long when) {
+ final Message m = n.mMessage;
if (m.target == null && m.arg1 == mBarrierToken) {
return true;
}
@@ -1236,10 +1272,155 @@ public final class MessageQueue {
return true;
}
+ private Message legacyPeekOrPoll(boolean peek) {
+ synchronized (this) {
+ // Try to retrieve the next message. Return if found.
+ final long now = SystemClock.uptimeMillis();
+ Message prevMsg = null;
+ Message msg = mMessages;
+ if (msg != null && msg.target == null) {
+ // Stalled by a barrier. Find the next asynchronous message in the queue.
+ do {
+ prevMsg = msg;
+ msg = msg.next;
+ } while (msg != null && !msg.isAsynchronous());
+ }
+ if (msg != null) {
+ if (now >= msg.when) {
+ // Got a message.
+ mBlocked = false;
+ if (peek) {
+ return msg;
+ }
+ if (prevMsg != null) {
+ prevMsg.next = msg.next;
+ if (prevMsg.next == null) {
+ mLast = prevMsg;
+ }
+ } else {
+ mMessages = msg.next;
+ if (msg.next == null) {
+ mLast = null;
+ }
+ }
+ msg.next = null;
+ msg.markInUse();
+ if (msg.isAsynchronous()) {
+ mAsyncMessageCount--;
+ }
+ if (TRACE) {
+ Trace.setCounter("MQ.Delivered", mMessagesDelivered.incrementAndGet());
+ }
+ return msg;
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Get the timestamp of the next executable message in our priority queue.
+ * Returns null if there are no messages ready for delivery.
+ *
+ * Caller must ensure that this doesn't race 'next' from the Looper thread.
+ */
+ @SuppressLint("VisiblySynchronized") // Legacy MessageQueue synchronizes on this
+ Long peekWhenForTest() {
+ throwIfNotTest();
+ Message ret;
+ if (mUseConcurrent) {
+ ret = nextMessage(true);
+ } else {
+ ret = legacyPeekOrPoll(true);
+ }
+ return ret != null ? ret.when : null;
+ }
+
+ /**
+ * Return the next executable message in our priority queue.
+ * Returns null if there are no messages ready for delivery
+ *
+ * Caller must ensure that this doesn't race 'next' from the Looper thread.
+ */
+ @SuppressLint("VisiblySynchronized") // Legacy MessageQueue synchronizes on this
+ @Nullable
+ Message pollForTest() {
+ throwIfNotTest();
+ if (mUseConcurrent) {
+ return nextMessage(false);
+ } else {
+ return legacyPeekOrPoll(false);
+ }
+ }
+
+ /**
+ * @return true if we are blocked on a sync barrier
+ */
+ boolean isBlockedOnSyncBarrier() {
+ throwIfNotTest();
+ if (mUseConcurrent) {
+ Iterator queueIter = mPriorityQueue.iterator();
+ MessageNode queueNode = iterateNext(queueIter);
+
+ if (queueNode.isBarrier()) {
+ long now = SystemClock.uptimeMillis();
+
+ /* Look for a deliverable async node. If one exists we are not blocked. */
+ Iterator asyncQueueIter = mAsyncPriorityQueue.iterator();
+ MessageNode asyncNode = iterateNext(asyncQueueIter);
+ if (asyncNode != null && now >= asyncNode.getWhen()) {
+ return false;
+ }
+ /*
+ * Look for a deliverable sync node. In this case, if one exists we are blocked
+ * since the barrier prevents delivery of the Message.
+ */
+ while (queueNode.isBarrier()) {
+ queueNode = iterateNext(queueIter);
+ }
+ if (queueNode != null && now >= queueNode.getWhen()) {
+ return true;
+ }
+
+ return false;
+ }
+ } else {
+ Message msg = mMessages;
+ if (msg != null && msg.target == null) {
+ Message iter = msg;
+ /* Look for a deliverable async node */
+ do {
+ iter = iter.next;
+ } while (iter != null && !iter.isAsynchronous());
+
+ long now = SystemClock.uptimeMillis();
+ if (iter != null && now >= iter.when) {
+ return false;
+ }
+ /*
+ * Look for a deliverable sync node. In this case, if one exists we are blocked
+ * since the barrier prevents delivery of the Message.
+ */
+ iter = msg;
+ do {
+ iter = iter.next;
+ } while (iter != null && (iter.target == null || iter.isAsynchronous()));
+
+ if (iter != null && now >= iter.when) {
+ return true;
+ }
+ return false;
+ }
+ }
+ /* No barrier was found. */
+ return false;
+ }
+
private static final class MatchHandlerWhatAndObject extends MessageCompare {
@Override
- public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
+ public boolean compareMessage(MessageNode n, Handler h, int what, Object object, Runnable r,
long when) {
+ final Message m = n.mMessage;
if (m.target == h && m.what == what && (object == null || m.obj == object)) {
return true;
}
@@ -1270,8 +1451,9 @@ public final class MessageQueue {
private static final class MatchHandlerWhatAndObjectEquals extends MessageCompare {
@Override
- public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
+ public boolean compareMessage(MessageNode n, Handler h, int what, Object object, Runnable r,
long when) {
+ final Message m = n.mMessage;
if (m.target == h && m.what == what && (object == null || object.equals(m.obj))) {
return true;
}
@@ -1303,8 +1485,9 @@ public final class MessageQueue {
private static final class MatchHandlerRunnableAndObject extends MessageCompare {
@Override
- public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
+ public boolean compareMessage(MessageNode n, Handler h, int what, Object object, Runnable r,
long when) {
+ final Message m = n.mMessage;
if (m.target == h && m.callback == r && (object == null || m.obj == object)) {
return true;
}
@@ -1337,12 +1520,9 @@ public final class MessageQueue {
private static final class MatchHandler extends MessageCompare {
@Override
- public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
+ public boolean compareMessage(MessageNode n, Handler h, int what, Object object, Runnable r,
long when) {
- if (m.target == h) {
- return true;
- }
- return false;
+ return n.mMessage.target == h;
}
}
private final MatchHandler mMatchHandler = new MatchHandler();
@@ -1520,8 +1700,9 @@ public final class MessageQueue {
private static final class MatchHandlerRunnableAndObjectEquals extends MessageCompare {
@Override
- public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
+ public boolean compareMessage(MessageNode n, Handler h, int what, Object object, Runnable r,
long when) {
+ final Message m = n.mMessage;
if (m.target == h && m.callback == r && (object == null || object.equals(m.obj))) {
return true;
}
@@ -1583,8 +1764,9 @@ public final class MessageQueue {
private static final class MatchHandlerAndObject extends MessageCompare {
@Override
- public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
+ public boolean compareMessage(MessageNode n, Handler h, int what, Object object, Runnable r,
long when) {
+ final Message m = n.mMessage;
if (m.target == h && (object == null || m.obj == object)) {
return true;
}
@@ -1644,8 +1826,9 @@ public final class MessageQueue {
private static final class MatchHandlerAndObjectEquals extends MessageCompare {
@Override
- public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
+ public boolean compareMessage(MessageNode n, Handler h, int what, Object object, Runnable r,
long when) {
+ final Message m = n.mMessage;
if (m.target == h && (object == null || object.equals(m.obj))) {
return true;
}
@@ -1751,7 +1934,7 @@ public final class MessageQueue {
private static final class MatchAllMessages extends MessageCompare {
@Override
- public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
+ public boolean compareMessage(MessageNode n, Handler h, int what, Object object, Runnable r,
long when) {
return true;
}
@@ -1763,9 +1946,10 @@ public final class MessageQueue {
private static final class MatchAllFutureMessages extends MessageCompare {
@Override
- public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
+ public boolean compareMessage(MessageNode n, Handler h, int what, Object object, Runnable r,
long when) {
- if (m.when > when) {
+ final Message m = n.mMessage;
+ if (m.when > when) {
return true;
}
return false;
@@ -2471,7 +2655,7 @@ public final class MessageQueue {
* This class is used to find matches for hasMessages() and removeMessages()
*/
private abstract static class MessageCompare {
- public abstract boolean compareMessage(Message m, Handler h, int what, Object object,
+ public abstract boolean compareMessage(MessageNode n, Handler h, int what, Object object,
Runnable r, long when);
}
@@ -2506,7 +2690,7 @@ public final class MessageQueue {
MessageNode p = (MessageNode) top;
while (true) {
- if (compare.compareMessage(p.mMessage, h, what, object, r, when)) {
+ if (compare.compareMessage(p, h, what, object, r, when)) {
found = true;
if (DEBUG) {
Log.d(TAG_C, "stackHasMessages node matches");
@@ -2551,7 +2735,7 @@ public final class MessageQueue {
while (iterator.hasNext()) {
MessageNode msg = iterator.next();
- if (compare.compareMessage(msg.mMessage, h, what, object, r, when)) {
+ if (compare.compareMessage(msg, h, what, object, r, when)) {
if (removeMatches) {
found = true;
if (queue.remove(msg)) {
diff --git a/core/java/android/os/ConcurrentMessageQueue/MessageQueue.java b/core/java/android/os/ConcurrentMessageQueue/MessageQueue.java
index c2a47d7678014c4246cec15409f08d6a04a51f17..de0259eb1e36c946bf1cdccd343c3802819c6f8b 100644
--- a/core/java/android/os/ConcurrentMessageQueue/MessageQueue.java
+++ b/core/java/android/os/ConcurrentMessageQueue/MessageQueue.java
@@ -16,9 +16,12 @@
package android.os;
+import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.TestApi;
+import android.app.ActivityThread;
+import android.app.Instrumentation;
import android.ravenwood.annotation.RavenwoodKeepWholeClass;
import android.ravenwood.annotation.RavenwoodRedirect;
import android.ravenwood.annotation.RavenwoodRedirectionClass;
@@ -364,6 +367,28 @@ public final class MessageQueue {
mPtr = nativeInit();
}
+ @android.ravenwood.annotation.RavenwoodReplace
+ private static void throwIfNotTest() {
+ final ActivityThread activityThread = ActivityThread.currentActivityThread();
+ if (activityThread == null) {
+ // Only tests can reach here.
+ return;
+ }
+ final Instrumentation instrumentation = activityThread.getInstrumentation();
+ if (instrumentation == null) {
+ // Only tests can reach here.
+ return;
+ }
+ if (instrumentation.isInstrumenting()) {
+ return;
+ }
+ throw new IllegalStateException("Test-only API called not from a test!");
+ }
+
+ private static void throwIfNotTest$ravenwood() {
+ return;
+ }
+
@Override
protected void finalize() throws Throwable {
try {
@@ -384,8 +409,9 @@ public final class MessageQueue {
private static final class MatchDeliverableMessages extends MessageCompare {
@Override
- public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
- long when) {
+ public boolean compareMessage(MessageNode n, Handler h, int what, Object object,
+ Runnable r, long when) {
+ final Message m = n.mMessage;
if (m.when <= when) {
return true;
}
@@ -562,7 +588,7 @@ public final class MessageQueue {
private static final AtomicLong mMessagesDelivered = new AtomicLong();
private boolean mMessageDirectlyQueued;
- private Message nextMessage() {
+ private Message nextMessage(boolean peek) {
int i = 0;
while (true) {
@@ -724,7 +750,7 @@ public final class MessageQueue {
if (sState.compareAndSet(this, sStackStateActive, nextOp)) {
mMessageCounts.clearCounts();
if (found != null) {
- if (!removeFromPriorityQueue(found)) {
+ if (!peek && !removeFromPriorityQueue(found)) {
/*
* RemoveMessages() might be able to pull messages out from under us
* However we can detect that here and just loop around if it happens.
@@ -993,8 +1019,9 @@ public final class MessageQueue {
}
@Override
- public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
- long when) {
+ public boolean compareMessage(MessageNode n, Handler h, int what, Object object,
+ Runnable r, long when) {
+ final Message m = n.mMessage;
if (m.target == null && m.arg1 == mBarrierToken) {
return true;
}
@@ -1039,6 +1066,79 @@ public final class MessageQueue {
}
}
+ private static final class MatchEarliestMessage extends MessageCompare {
+ MessageNode mEarliest = null;
+
+ @Override
+ public boolean compareMessage(MessageNode n, Handler h, int what, Object object,
+ Runnable r, long when) {
+ final Message m = n.mMessage;
+ if (mEarliest == null || mEarliest.mMessage.when > m.when) {
+ mEarliest = n;
+ }
+
+ return false;
+ }
+ }
+
+ /**
+ * Get the timestamp of the next executable message in our priority queue.
+ * Returns null if there are no messages ready for delivery.
+ *
+ * Caller must ensure that this doesn't race 'next' from the Looper thread.
+ */
+ @SuppressLint("VisiblySynchronized") // Legacy MessageQueue synchronizes on this
+ Long peekWhenForTest() {
+ throwIfNotTest();
+ Message ret = nextMessage(true);
+ return ret != null ? ret.when : null;
+ }
+
+ /**
+ * Return the next executable message in our priority queue.
+ * Returns null if there are no messages ready for delivery
+ *
+ * Caller must ensure that this doesn't race 'next' from the Looper thread.
+ */
+ @SuppressLint("VisiblySynchronized") // Legacy MessageQueue synchronizes on this
+ @Nullable
+ Message pollForTest() {
+ throwIfNotTest();
+ return nextMessage(false);
+ }
+
+ /**
+ * @return true if we are blocked on a sync barrier
+ */
+ boolean isBlockedOnSyncBarrier() {
+ throwIfNotTest();
+ Iterator queueIter = mPriorityQueue.iterator();
+ MessageNode queueNode = iterateNext(queueIter);
+
+ if (queueNode.isBarrier()) {
+ long now = SystemClock.uptimeMillis();
+
+ /* Look for a deliverable async node. If one exists we are not blocked. */
+ Iterator asyncQueueIter = mAsyncPriorityQueue.iterator();
+ MessageNode asyncNode = iterateNext(asyncQueueIter);
+ if (asyncNode != null && now >= asyncNode.getWhen()) {
+ return false;
+ }
+ /*
+ * Look for a deliverable sync node. In this case, if one exists we are blocked
+ * since the barrier prevents delivery of the Message.
+ */
+ while (queueNode.isBarrier()) {
+ queueNode = iterateNext(queueIter);
+ }
+ if (queueNode != null && now >= queueNode.getWhen()) {
+ return true;
+ }
+
+ return false;
+ }
+ }
+
private StateNode getStateNode(StackNode node) {
if (node.isMessageNode()) {
return ((MessageNode) node).mBottomOfStack;
@@ -1058,7 +1158,7 @@ public final class MessageQueue {
* This class is used to find matches for hasMessages() and removeMessages()
*/
private abstract static class MessageCompare {
- public abstract boolean compareMessage(Message m, Handler h, int what, Object object,
+ public abstract boolean compareMessage(MessageNode n, Handler h, int what, Object object,
Runnable r, long when);
}
@@ -1167,8 +1267,9 @@ public final class MessageQueue {
private static final class MatchHandlerWhatAndObject extends MessageCompare {
@Override
- public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
- long when) {
+ public boolean compareMessage(MessageNode n, Handler h, int what, Object object,
+ Runnable r, long when) {
+ final Message m = n.mMessage;
if (m.target == h && m.what == what && (object == null || m.obj == object)) {
return true;
}
@@ -1187,8 +1288,9 @@ public final class MessageQueue {
private static final class MatchHandlerWhatAndObjectEquals extends MessageCompare {
@Override
- public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
+ public boolean compareMessage(MessageNode n, Handler h, int what, Object object, Runnable r,
long when) {
+ final Message m = n.mMessage;
if (m.target == h && m.what == what && (object == null || object.equals(m.obj))) {
return true;
}
@@ -1208,8 +1310,9 @@ public final class MessageQueue {
private static final class MatchHandlerRunnableAndObject extends MessageCompare {
@Override
- public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
- long when) {
+ public boolean compareMessage(MessageNode n, Handler h, int what, Object object,
+ Runnable r, long when) {
+ final Message m = n.mMessage;
if (m.target == h && m.callback == r && (object == null || m.obj == object)) {
return true;
}
@@ -1229,8 +1332,9 @@ public final class MessageQueue {
private static final class MatchHandler extends MessageCompare {
@Override
- public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
- long when) {
+ public boolean compareMessage(MessageNode n, Handler h, int what, Object object,
+ Runnable r, long when) {
+ final Message m = n.mMessage;
if (m.target == h) {
return true;
}
@@ -1268,8 +1372,9 @@ public final class MessageQueue {
private static final class MatchHandlerRunnableAndObjectEquals extends MessageCompare {
@Override
- public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
- long when) {
+ public boolean compareMessage(MessageNode n, Handler h, int what, Object object,
+ Runnable r, long when) {
+ final Message m = n.mMessage;
if (m.target == h && m.callback == r && (object == null || object.equals(m.obj))) {
return true;
}
@@ -1287,8 +1392,9 @@ public final class MessageQueue {
private static final class MatchHandlerAndObject extends MessageCompare {
@Override
- public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
- long when) {
+ public boolean compareMessage(MessageNode n, Handler h, int what, Object object,
+ Runnable r, long when) {
+ final Message m = n.mMessage;
if (m.target == h && (object == null || m.obj == object)) {
return true;
}
@@ -1305,8 +1411,9 @@ public final class MessageQueue {
private static final class MatchHandlerAndObjectEquals extends MessageCompare {
@Override
- public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
- long when) {
+ public boolean compareMessage(MessageNode n, Handler h, int what, Object object,
+ Runnable r, long when) {
+ final Message m = n.mMessage;
if (m.target == h && (object == null || object.equals(m.obj))) {
return true;
}
@@ -1324,8 +1431,8 @@ public final class MessageQueue {
private static final class MatchAllMessages extends MessageCompare {
@Override
- public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
- long when) {
+ public boolean compareMessage(MessageNode n, Handler h, int what, Object object,
+ Runnable r, long when) {
return true;
}
}
@@ -1336,8 +1443,9 @@ public final class MessageQueue {
private static final class MatchAllFutureMessages extends MessageCompare {
@Override
- public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
- long when) {
+ public boolean compareMessage(MessageNode n, Handler h, int what, Object object,
+ Runnable r, long when) {
+ final Message m = n.mMessage;
if (m.when > when) {
return true;
}
diff --git a/core/java/android/os/CpuHeadroomParamsInternal.aidl b/core/java/android/os/CpuHeadroomParamsInternal.aidl
index d572f965579b71dcff174a645b48b0797b42623c..12b209357d9cc33666c15cda535062c09349a930 100644
--- a/core/java/android/os/CpuHeadroomParamsInternal.aidl
+++ b/core/java/android/os/CpuHeadroomParamsInternal.aidl
@@ -28,6 +28,5 @@ parcelable CpuHeadroomParamsInternal {
int[] tids;
int calculationWindowMillis = 1000;
CpuHeadroomParams.CalculationType calculationType = CpuHeadroomParams.CalculationType.MIN;
- CpuHeadroomParams.SelectionType selectionType = CpuHeadroomParams.SelectionType.ALL;
}
diff --git a/core/java/android/os/IHintManager.aidl b/core/java/android/os/IHintManager.aidl
index 4a14a8d0faf8b3bb84ca649b2eb47555cfeb924e..56a089aff78a47fb1d2959f4dde296eedb78db5f 100644
--- a/core/java/android/os/IHintManager.aidl
+++ b/core/java/android/os/IHintManager.aidl
@@ -21,11 +21,13 @@ import android.os.CpuHeadroomParamsInternal;
import android.os.GpuHeadroomParamsInternal;
import android.os.IHintSession;
import android.os.SessionCreationConfig;
-import android.hardware.power.CpuHeadroomResult;
+
import android.hardware.power.ChannelConfig;
+import android.hardware.power.CpuHeadroomResult;
import android.hardware.power.GpuHeadroomResult;
import android.hardware.power.SessionConfig;
import android.hardware.power.SessionTag;
+import android.hardware.power.SupportInfo;
/** {@hide} */
interface IHintManager {
@@ -40,11 +42,6 @@ interface IHintManager {
IHintSession createHintSessionWithConfig(in IBinder token, in SessionTag tag,
in SessionCreationConfig creationConfig, out SessionConfig config);
- /**
- * Get preferred rate limit in nanoseconds.
- */
- long getHintSessionPreferredRate();
-
void setHintSessionThreads(in IHintSession hintSession, in int[] tids);
int[] getHintSessionThreadIds(in IHintSession hintSession);
@@ -60,14 +57,29 @@ interface IHintManager {
@nullable GpuHeadroomResult getGpuHeadroom(in GpuHeadroomParamsInternal params);
long getGpuHeadroomMinIntervalMillis();
- /**
- * Get Maximum number of graphics pipeline threads allowed per-app.
- */
- int getMaxGraphicsPipelineThreadsCount();
-
/**
* Used by the JNI to pass an interface to the SessionManager;
* for internal use only.
*/
oneway void passSessionManagerBinder(in IBinder sessionManager);
+
+ parcelable HintManagerClientData {
+ int powerHalVersion;
+ int maxGraphicsPipelineThreads;
+ long preferredRateNanos;
+ SupportInfo supportInfo;
+ }
+
+ interface IHintManagerClient {
+ /**
+ * Returns FMQ channel information for the caller, which it associates to the callback binder lifespan.
+ */
+ oneway void receiveChannelConfig(in ChannelConfig config);
+ }
+
+ /**
+ * Set up an ADPF client, receiving a remote client binder interface and
+ * passing back a bundle of support and configuration information.
+ */
+ HintManagerClientData registerClient(in IHintManagerClient client);
}
diff --git a/core/java/android/os/IPowerManager.aidl b/core/java/android/os/IPowerManager.aidl
index e85e58039828fd2d10d8fc15ca9392680c492a22..4cac4dee0bea8745a8efff62e7592695ff2ef3d8 100644
--- a/core/java/android/os/IPowerManager.aidl
+++ b/core/java/android/os/IPowerManager.aidl
@@ -55,7 +55,7 @@ interface IPowerManager
void goToSleepWithDisplayId(int displayId, long time, int reason, int flags);
@UnsupportedAppUsage(maxTargetSdk = 28)
void nap(long time);
- float getBrightnessConstraint(int constraint);
+ float getBrightnessConstraint(int displayId, int constraint);
@UnsupportedAppUsage
boolean isInteractive();
boolean isDisplayInteractive(int displayId);
diff --git a/core/java/android/os/IpcDataCache.java b/core/java/android/os/IpcDataCache.java
index 8db1567336d3ddb9f4154a92b0499fb16cb5b384..a2e9314f6436f9c39ef94d831688f53681297b60 100644
--- a/core/java/android/os/IpcDataCache.java
+++ b/core/java/android/os/IpcDataCache.java
@@ -400,10 +400,11 @@ public class IpcDataCache extends PropertyInvalidatedCache extends PropertyInvalidatedCache extends PropertyInvalidatedCache extends PropertyInvalidatedCache extends PropertyInvalidatedCache extends PropertyInvalidatedCache extends PropertyInvalidatedCache extends PropertyInvalidatedCache computer) {
- super(new Args(config.module()).maxEntries(config.maxEntries()).api(config.api()),
- config.name(), computer);
+ super(config.mArgs, config.mName, computer);
}
/**
diff --git a/core/java/android/os/LegacyMessageQueue/MessageQueue.java b/core/java/android/os/LegacyMessageQueue/MessageQueue.java
index cae82d010132f646e999256edc5c28ecb39fbddb..5e1e1fdca5c86b21cf99844ed399c46c2b190f84 100644
--- a/core/java/android/os/LegacyMessageQueue/MessageQueue.java
+++ b/core/java/android/os/LegacyMessageQueue/MessageQueue.java
@@ -16,9 +16,14 @@
package android.os;
+import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SuppressLint;
import android.annotation.TestApi;
+import android.app.ActivityThread;
+import android.app.Instrumentation;
import android.compat.annotation.UnsupportedAppUsage;
import android.ravenwood.annotation.RavenwoodKeepWholeClass;
import android.ravenwood.annotation.RavenwoodRedirect;
@@ -99,6 +104,28 @@ public final class MessageQueue {
mPtr = nativeInit();
}
+ @android.ravenwood.annotation.RavenwoodReplace
+ private static void throwIfNotTest() {
+ final ActivityThread activityThread = ActivityThread.currentActivityThread();
+ if (activityThread == null) {
+ // Only tests can reach here.
+ return;
+ }
+ final Instrumentation instrumentation = activityThread.getInstrumentation();
+ if (instrumentation == null) {
+ // Only tests can reach here.
+ return;
+ }
+ if (instrumentation.isInstrumenting()) {
+ return;
+ }
+ throw new IllegalStateException("Test-only API called not from a test!");
+ }
+
+ private static void throwIfNotTest$ravenwood() {
+ return;
+ }
+
@Override
protected void finalize() throws Throwable {
try {
@@ -713,6 +740,112 @@ public final class MessageQueue {
return true;
}
+ private Message legacyPeekOrPoll(boolean peek) {
+ synchronized (this) {
+ // Try to retrieve the next message. Return if found.
+ final long now = SystemClock.uptimeMillis();
+ Message prevMsg = null;
+ Message msg = mMessages;
+ if (msg != null && msg.target == null) {
+ // Stalled by a barrier. Find the next asynchronous message in the queue.
+ do {
+ prevMsg = msg;
+ msg = msg.next;
+ } while (msg != null && !msg.isAsynchronous());
+ }
+ if (msg != null) {
+ if (now >= msg.when) {
+ // Got a message.
+ mBlocked = false;
+ if (peek) {
+ return msg;
+ }
+ if (prevMsg != null) {
+ prevMsg.next = msg.next;
+ if (prevMsg.next == null) {
+ mLast = prevMsg;
+ }
+ } else {
+ mMessages = msg.next;
+ if (msg.next == null) {
+ mLast = null;
+ }
+ }
+ msg.next = null;
+ msg.markInUse();
+ if (msg.isAsynchronous()) {
+ mAsyncMessageCount--;
+ }
+ if (TRACE) {
+ Trace.setCounter("MQ.Delivered", mMessagesDelivered.incrementAndGet());
+ }
+ return msg;
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Get the timestamp of the next executable message in our priority queue.
+ * Returns null if there are no messages ready for delivery.
+ *
+ * Caller must ensure that this doesn't race 'next' from the Looper thread.
+ */
+ @SuppressLint("VisiblySynchronized") // Legacy MessageQueue synchronizes on this
+ Long peekWhenForTest() {
+ throwIfNotTest();
+ Message ret = legacyPeekOrPoll(true);
+ return ret != null ? ret.when : null;
+ }
+
+ /**
+ * Return the next executable message in our priority queue.
+ * Returns null if there are no messages ready for delivery
+ *
+ * Caller must ensure that this doesn't race 'next' from the Looper thread.
+ */
+ @SuppressLint("VisiblySynchronized") // Legacy MessageQueue synchronizes on this
+ @Nullable
+ Message pollForTest() {
+ throwIfNotTest();
+ return legacyPeekOrPoll(false);
+ }
+
+ /**
+ * @return true if we are blocked on a sync barrier
+ */
+ boolean isBlockedOnSyncBarrier() {
+ throwIfNotTest();
+ Message msg = mMessages;
+ if (msg != null && msg.target == null) {
+ Message iter = msg;
+ /* Look for a deliverable async node */
+ do {
+ iter = iter.next;
+ } while (iter != null && !iter.isAsynchronous());
+
+ long now = SystemClock.uptimeMillis();
+ if (iter != null && now >= iter.when) {
+ return false;
+ }
+ /*
+ * Look for a deliverable sync node. In this case, if one exists we are blocked
+ * since the barrier prevents delivery of the Message.
+ */
+ iter = msg;
+ do {
+ iter = iter.next;
+ } while (iter != null && (iter.target == null || iter.isAsynchronous()));
+
+ if (iter != null && now >= iter.when) {
+ return true;
+ }
+ return false;
+ }
+ return false;
+ }
+
boolean hasMessages(Handler h, int what, Object object) {
if (h == null) {
return false;
diff --git a/core/java/android/os/OWNERS b/core/java/android/os/OWNERS
index bfcc5cc6f18eae3b1839f7be5d591141b50875fa..8d353384f1e2f0ae04c575f1c37d8ec7b990e9da 100644
--- a/core/java/android/os/OWNERS
+++ b/core/java/android/os/OWNERS
@@ -118,9 +118,10 @@ per-file IpcDataCache.java = file:/PERFORMANCE_OWNERS
# Memory
per-file OomKillRecord.java = file:/MEMORY_OWNERS
-# MessageQueue
+# MessageQueue and related classes
per-file MessageQueue.java = mfasheh@google.com, shayba@google.com
per-file Message.java = mfasheh@google.com, shayba@google.com
+per-file TestLooperManager.java = mfasheh@google.com, shayba@google.com
# Stats
per-file IStatsBootstrapAtomService.aidl = file:/services/core/java/com/android/server/stats/OWNERS
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index bf7116d6a05bc8564e7c15238e169f8599059545..cf473ec9c3eac392ab9f11741d154651cd9be3c1 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -892,6 +892,12 @@ public final class Parcel {
/**
* Report whether the parcel contains any marshalled file descriptors.
+ *
+ * WARNING: Parcelable definitions change over time. Unless you define
+ * a Parcelable yourself OR the Parcelable explicitly guarantees that
+ * it would never include such objects, you should not expect the return
+ * value to stay the same, and your code should continue to work even
+ * if the return value changes.
*/
public boolean hasFileDescriptors() {
return nativeHasFileDescriptors(mNativePtr);
@@ -901,6 +907,12 @@ public final class Parcel {
* Report whether the parcel contains any marshalled file descriptors in the range defined by
* {@code offset} and {@code length}.
*
+ * WARNING: Parcelable definitions change over time. Unless you define
+ * a Parcelable yourself OR the Parcelable explicitly guarantees that
+ * it would never include such objects, you should not expect the return
+ * value to stay the same, and your code should continue to work even
+ * if the return value changes.
+ *
* @param offset The offset from which the range starts. Should be between 0 and
* {@link #dataSize()}.
* @param length The length of the range. Should be between 0 and {@link #dataSize()} - {@code
@@ -921,6 +933,12 @@ public final class Parcel {
*
For most cases, it will use the self-reported {@link Parcelable#describeContents()} method
* for that.
*
+ * WARNING: Parcelable definitions change over time. Unless you define
+ * a Parcelable yourself OR the Parcelable explicitly guarantees that
+ * it would never include such objects, you should not expect the return
+ * value to stay the same, and your code should continue to work even
+ * if the return value changes.
+ *
* @throws IllegalArgumentException if you provide any object not supported by above methods
* (including if the unsupported object is inside a nested container).
*
@@ -990,6 +1008,13 @@ public final class Parcel {
*
* @throws UnsupportedOperationException if binder kernel driver was disabled or if method was
* invoked in case of Binder RPC protocol.
+ *
+ * WARNING: Parcelable definitions change over time. Unless you define
+ * a Parcelable yourself OR the Parcelable explicitly guarantees that
+ * it would never include such objects, you should not expect the return
+ * value to stay the same, and your code should continue to work even
+ * if the return value changes.
+ *
* @hide
*/
public boolean hasBinders() {
@@ -1000,6 +1025,12 @@ public final class Parcel {
* Report whether the parcel contains any marshalled {@link IBinder} objects in the range
* defined by {@code offset} and {@code length}.
*
+ * WARNING: Parcelable definitions change over time. Unless you define
+ * a Parcelable yourself OR the Parcelable explicitly guarantees that
+ * it would never include such objects, you should not expect the return
+ * value to stay the same, and your code should continue to work even
+ * if the return value changes.
+ *
* @param offset The offset from which the range starts. Should be between 0 and
* {@link #dataSize()}.
* @param length The length of the range. Should be between 0 and {@link #dataSize()} - {@code
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index 9e7bf47ae83f1ab307a03568cfe0d031541a2b7b..cd48f0847f8d81099b3037e6b7d116b07db3aefb 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -1266,9 +1266,17 @@ public final class PowerManager {
* @hide
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public float getBrightnessConstraint(int constraint) {
+ public float getBrightnessConstraint(@BrightnessConstraint int constraint) {
+ return getBrightnessConstraint(Display.DEFAULT_DISPLAY, constraint);
+ }
+
+ /**
+ * Gets a float screen brightness setting for a specific display.
+ * @hide
+ */
+ public float getBrightnessConstraint(int displayId, @BrightnessConstraint int constraint) {
try {
- return mService.getBrightnessConstraint(constraint);
+ return mService.getBrightnessConstraint(displayId, constraint);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/core/java/android/os/SELinux.java b/core/java/android/os/SELinux.java
index f64a81177ce2b44b9a0ba24fbb7c58b05c197344..11c54ef802fec4595fd449e401b1fe4b4c19dac6 100644
--- a/core/java/android/os/SELinux.java
+++ b/core/java/android/os/SELinux.java
@@ -193,4 +193,31 @@ public class SELinux {
return false;
}
}
+
+ /**
+ * Gets the genfs labels version of the vendor. The genfs labels version is
+ * specified in {@code /vendor/etc/selinux/genfs_labels_version.txt}. The
+ * version follows the VINTF version format "YYYYMM" and affects how {@code
+ * genfs_contexts} entries are applied.
+ *
+ *
The genfs labels version indicates changes in the SELinux labeling
+ * scheme over time. For example:
+ *
+ *
For version 202504 and later, {@code /sys/class/udc} is labeled as
+ * {@code sysfs_udc}.
+ *
For version 202404 and earlier, {@code /sys/class/udc} is labeled
+ * as {@code sysfs}.
+ *
+ * Check {@code /system/etc/selinux/plat_sepolicy_genfs_{version}.cil} to
+ * see which labels are new in {version}.
+ *
+ *
Older vendors may override {@code genfs_contexts} with vendor-specific
+ * extensions. The framework must not break such labellings to maintain
+ * compatibility with such vendors, by checking the genfs labels version and
+ * implementing a fallback mechanism.
+ *
+ * @return an integer representing the genfs labels version of /vendor, in
+ * the format YYYYMM.
+ */
+ public static final native int getGenfsLabelsVersion();
}
diff --git a/core/java/android/os/ServiceManager.java b/core/java/android/os/ServiceManager.java
index 8aec7eb59e9151c0ae42b20b034c9a58012661e8..9085fe09bdaa5c1a29c81f7482a70a3a633922a5 100644
--- a/core/java/android/os/ServiceManager.java
+++ b/core/java/android/os/ServiceManager.java
@@ -277,7 +277,8 @@ public final class ServiceManager {
if (service != null) {
return service;
} else {
- return Binder.allowBlocking(getIServiceManager().checkService(name).getBinder());
+ return Binder.allowBlocking(
+ getIServiceManager().checkService(name).getServiceWithMetadata().service);
}
} catch (RemoteException e) {
Log.e(TAG, "error in checkService", e);
@@ -425,7 +426,8 @@ public final class ServiceManager {
private static IBinder rawGetService(String name) throws RemoteException {
final long start = sStatLogger.getTime();
- final IBinder binder = getIServiceManager().getService2(name).getBinder();
+ final IBinder binder =
+ getIServiceManager().getService2(name).getServiceWithMetadata().service;
final int time = (int) sStatLogger.logDurationStat(Stats.GET_SERVICE, start);
diff --git a/core/java/android/os/ServiceManagerNative.java b/core/java/android/os/ServiceManagerNative.java
index 5a9c8787ee3be30632c53e0b862e31aa0c89c5a8..49b696d95723f3decabc7cd833d3a08c51afaa66 100644
--- a/core/java/android/os/ServiceManagerNative.java
+++ b/core/java/android/os/ServiceManagerNative.java
@@ -61,7 +61,7 @@ class ServiceManagerProxy implements IServiceManager {
@UnsupportedAppUsage
public IBinder getService(String name) throws RemoteException {
// Same as checkService (old versions of servicemanager had both methods).
- return checkService(name).getBinder();
+ return checkService(name).getServiceWithMetadata().service;
}
public Service getService2(String name) throws RemoteException {
diff --git a/core/java/android/os/TestLooperManager.java b/core/java/android/os/TestLooperManager.java
index 4b16c1dce463bce369790783063548e6093e4864..e2169925fdd35ce3042b6856f9f0838378b8b649 100644
--- a/core/java/android/os/TestLooperManager.java
+++ b/core/java/android/os/TestLooperManager.java
@@ -14,6 +14,8 @@
package android.os;
+import android.annotation.FlaggedApi;
+import android.annotation.Nullable;
import android.util.ArraySet;
import java.util.concurrent.LinkedBlockingQueue;
@@ -93,9 +95,52 @@ public class TestLooperManager {
}
/**
- * Releases the looper to continue standard looping and processing of messages,
- * no further interactions with TestLooperManager will be allowed after
- * release() has been called.
+ * Retrieves and removes the next message that should be executed by this queue.
+ * If the queue is empty or no messages are deliverable, returns null.
+ * This method never blocks.
+ *
+ *
Callers should always call {@link #recycle(Message)} on the message when all interactions
+ * with it have completed.
+ */
+ @FlaggedApi(Flags.FLAG_MESSAGE_QUEUE_TESTABILITY)
+ @Nullable
+ public Message poll() {
+ checkReleased();
+ return mQueue.pollForTest();
+ }
+
+ /**
+ * Retrieves, but does not remove, the values of {@link Message#when} of next message that
+ * should be executed by this queue.
+ * If the queue is empty or no messages are deliverable, returns null.
+ * This method never blocks.
+ *
+ *
Callers should always call {@link #recycle(Message)} on the message when all interactions
+ * with it have completed.
+ */
+ @FlaggedApi(Flags.FLAG_MESSAGE_QUEUE_TESTABILITY)
+ @SuppressWarnings("AutoBoxing") // box the primitive long, or return null to indicate no value
+ @Nullable
+ public Long peekWhen() {
+ checkReleased();
+ return mQueue.peekWhenForTest();
+ }
+
+ /**
+ * Checks whether the Looper is currently blocked on a sync barrier.
+ *
+ * A Looper is blocked on a sync barrier if there is a Message in the Looper's
+ * queue that is ready for execution but is behind a sync barrier
+ */
+ @FlaggedApi(Flags.FLAG_MESSAGE_QUEUE_TESTABILITY)
+ public boolean isBlockedOnSyncBarrier() {
+ checkReleased();
+ return mQueue.isBlockedOnSyncBarrier();
+ }
+
+ /**
+ * Releases the looper to continue standard looping and processing of messages, no further
+ * interactions with TestLooperManager will be allowed after release() has been called.
*/
public void release() {
synchronized (sHeldLoopers) {
diff --git a/core/java/android/os/UpdateEngine.java b/core/java/android/os/UpdateEngine.java
index 0a8f62fd56d849a47982ad4051d59287f2a1f6dd..81e4549c78d1eca57061cb503bd530e72c7c64f1 100644
--- a/core/java/android/os/UpdateEngine.java
+++ b/core/java/android/os/UpdateEngine.java
@@ -16,6 +16,7 @@
package android.os;
+import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.SystemApi;
@@ -667,4 +668,23 @@ public class UpdateEngine {
throw e.rethrowFromSystemServer();
}
}
+
+ /**
+ * Run postinstall script for specified partition |partition|
+ *
+ * @param partition The partition to trigger postinstall runs
+ *
+ * @throws ServiceSpecificException error code of this exception would be one of
+ * https://cs.android.com/android/platform/superproject/main/+/main:system/update_engine/common/error_code.h
+ * @hide
+ */
+ @FlaggedApi(Flags.FLAG_UPDATE_ENGINE_API)
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+ public void triggerPostinstall(@NonNull String partition) {
+ try {
+ mUpdateEngine.triggerPostinstall(partition);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
}
diff --git a/core/java/android/os/flags.aconfig b/core/java/android/os/flags.aconfig
index 6357baa1922699c0f6ac06726d7020fc09b10a78..2a467386569df51d8998980702a10bdc285f63fe 100644
--- a/core/java/android/os/flags.aconfig
+++ b/core/java/android/os/flags.aconfig
@@ -232,6 +232,14 @@ flag {
is_exported: true
}
+flag {
+ name: "material_shape_tokens"
+ namespace: "systemui"
+ description: "Adding new Material Tokens for M3 Shape (corner radius) Spec"
+ bug: "324928718"
+ is_exported: true
+}
+
flag {
name: "message_queue_tail_tracking"
namespace: "system_performance"
diff --git a/core/java/android/os/instrumentation/IDynamicInstrumentationManager.aidl b/core/java/android/os/instrumentation/IDynamicInstrumentationManager.aidl
index c45c51d15cc96a61483c5e68ebbc73d12a166809..af56bfe5038197ce95a81e6a842c109bb823f1f4 100644
--- a/core/java/android/os/instrumentation/IDynamicInstrumentationManager.aidl
+++ b/core/java/android/os/instrumentation/IDynamicInstrumentationManager.aidl
@@ -16,7 +16,7 @@
package android.os.instrumentation;
-import android.os.instrumentation.ExecutableMethodFileOffsets;
+import android.os.instrumentation.IOffsetCallback;
import android.os.instrumentation.MethodDescriptor;
import android.os.instrumentation.TargetProcess;
@@ -28,6 +28,7 @@ import android.os.instrumentation.TargetProcess;
interface IDynamicInstrumentationManager {
/** Provides ART metadata about the described compiled method within the target process */
@PermissionManuallyEnforced
- @nullable ExecutableMethodFileOffsets getExecutableMethodFileOffsets(
- in TargetProcess targetProcess, in MethodDescriptor methodDescriptor);
+ void getExecutableMethodFileOffsets(
+ in TargetProcess targetProcess, in MethodDescriptor methodDescriptor,
+ in IOffsetCallback callback);
}
diff --git a/core/java/android/os/instrumentation/IOffsetCallback.aidl b/core/java/android/os/instrumentation/IOffsetCallback.aidl
new file mode 100644
index 0000000000000000000000000000000000000000..a28c93f5353a905667324ddfadb694bf47ca6dab
--- /dev/null
+++ b/core/java/android/os/instrumentation/IOffsetCallback.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os.instrumentation;
+
+import android.os.instrumentation.ExecutableMethodFileOffsets;
+
+/**
+ * System private API for providing dynamic instrumentation offset results.
+ *
+ * {@hide}
+ */
+oneway interface IOffsetCallback {
+ void onResult(in @nullable ExecutableMethodFileOffsets offsets);
+}
diff --git a/core/java/android/os/instrumentation/MethodDescriptorParser.java b/core/java/android/os/instrumentation/MethodDescriptorParser.java
new file mode 100644
index 0000000000000000000000000000000000000000..57fc44ff623ecdd6c8570fe0a6fa0a18001fd420
--- /dev/null
+++ b/core/java/android/os/instrumentation/MethodDescriptorParser.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os.instrumentation;
+
+import android.annotation.NonNull;
+
+import java.lang.reflect.Method;
+
+/**
+ * A utility class for dynamic instrumentation / uprobestats.
+ *
+ * @hide
+ */
+public final class MethodDescriptorParser {
+
+ /**
+ * Parses a {@link MethodDescriptor} (in string representation) into a {@link Method}.
+ */
+ public static Method parseMethodDescriptor(ClassLoader classLoader,
+ @NonNull MethodDescriptor descriptor) {
+ try {
+ Class> javaClass = classLoader.loadClass(descriptor.fullyQualifiedClassName);
+ Class>[] parameters = new Class[descriptor.fullyQualifiedParameters.length];
+ for (int i = 0; i < descriptor.fullyQualifiedParameters.length; i++) {
+ String typeName = descriptor.fullyQualifiedParameters[i];
+ boolean isArrayType = typeName.endsWith("[]");
+ if (isArrayType) {
+ typeName = typeName.substring(0, typeName.length() - 2);
+ }
+ switch (typeName) {
+ case "boolean":
+ parameters[i] = isArrayType ? boolean.class.arrayType() : boolean.class;
+ break;
+ case "byte":
+ parameters[i] = isArrayType ? byte.class.arrayType() : byte.class;
+ break;
+ case "char":
+ parameters[i] = isArrayType ? char.class.arrayType() : char.class;
+ break;
+ case "short":
+ parameters[i] = isArrayType ? short.class.arrayType() : short.class;
+ break;
+ case "int":
+ parameters[i] = isArrayType ? int.class.arrayType() : int.class;
+ break;
+ case "long":
+ parameters[i] = isArrayType ? long.class.arrayType() : long.class;
+ break;
+ case "float":
+ parameters[i] = isArrayType ? float.class.arrayType() : float.class;
+ break;
+ case "double":
+ parameters[i] = isArrayType ? double.class.arrayType() : double.class;
+ break;
+ default:
+ parameters[i] = isArrayType ? classLoader.loadClass(typeName).arrayType()
+ : classLoader.loadClass(typeName);
+ }
+ }
+
+ return javaClass.getDeclaredMethod(descriptor.methodName, parameters);
+ } catch (ClassNotFoundException | NoSuchMethodException e) {
+ throw new IllegalArgumentException(
+ "The specified method cannot be found. Is this descriptor valid? "
+ + descriptor, e);
+ }
+ }
+}
diff --git a/core/java/android/permission/PermissionManager.java b/core/java/android/permission/PermissionManager.java
index e98397d104d6ac816e1699cc5869c6635bcddbab..2473de4ff6d710e7f1bf9a8f6d863317fb3f5983 100644
--- a/core/java/android/permission/PermissionManager.java
+++ b/core/java/android/permission/PermissionManager.java
@@ -1795,14 +1795,45 @@ public final class PermissionManager {
}
}
- /** @hide */
- public static final String CACHE_KEY_PACKAGE_INFO =
+ // The legacy system property "package_info" had two purposes: to invalidate PIC caches and to
+ // signal that package information, and therefore permissions, might have changed.
+ // AudioSystem is the only client of the signaling behavior. The "separate permissions
+ // notification" feature splits the two behaviors into two system property names.
+ //
+ // If the feature is disabled (legacy behavior) then the two system property names have the
+ // same value. This means there is only one system property in use.
+ //
+ // If the feature is enabled, then the two system property names have different values, which
+ // means there is a system property used by PIC and a system property used for signaling. The
+ // legacy value is hard-coded in native code that relies on the signaling behavior, so the
+ // system property name for signaling is the legacy property name, and the system property
+ // name for PIC is new.
+ private static String getPackageInfoCacheKey() {
+ if (PropertyInvalidatedCache.separatePermissionNotificationsEnabled()) {
+ return PropertyInvalidatedCache.createSystemCacheKey("package_info_cache");
+ } else {
+ return CACHE_KEY_PACKAGE_INFO_NOTIFY;
+ }
+ }
+
+ /**
+ * The system property that is used to notify clients that package information, and therefore
+ * permissions, may have changed.
+ * @hide
+ */
+ public static final String CACHE_KEY_PACKAGE_INFO_NOTIFY =
PropertyInvalidatedCache.createSystemCacheKey("package_info");
+ /**
+ * The system property that is used to invalidate PIC caches.
+ * @hide
+ */
+ public static final String CACHE_KEY_PACKAGE_INFO_CACHE = getPackageInfoCacheKey();
+
/** @hide */
private static final PropertyInvalidatedCache sPermissionCache =
new PropertyInvalidatedCache(
- 2048, CACHE_KEY_PACKAGE_INFO, "checkPermission") {
+ 2048, CACHE_KEY_PACKAGE_INFO_CACHE, "checkPermission") {
@Override
public Integer recompute(PermissionQuery query) {
return checkPermissionUncached(query.permission, query.pid, query.uid,
@@ -1920,7 +1951,7 @@ public final class PermissionManager {
private static PropertyInvalidatedCache
sPackageNamePermissionCache =
new PropertyInvalidatedCache(
- 16, CACHE_KEY_PACKAGE_INFO, "checkPackageNamePermission") {
+ 16, CACHE_KEY_PACKAGE_INFO_CACHE, "checkPackageNamePermission") {
@Override
public Integer recompute(PackageNamePermissionQuery query) {
return checkPackageNamePermissionUncached(
diff --git a/core/java/android/permission/flags.aconfig b/core/java/android/permission/flags.aconfig
index c2b8157de416f6013ce3134b9ef0e2d859589645..aacc6e2a31562f84c56411099bfdf04ac4265c65 100644
--- a/core/java/android/permission/flags.aconfig
+++ b/core/java/android/permission/flags.aconfig
@@ -474,3 +474,31 @@ flag {
description: "Enable cross-user roles platform API"
bug: "367732307"
}
+
+flag {
+ name: "rate_limit_batched_note_op_async_callbacks_enabled"
+ is_fixed_read_only: true
+ is_exported: true
+ namespace: "permissions"
+ description: "Rate limit async noteOp callbacks for batched noteOperation binder call"
+ bug: "366013082"
+}
+
+flag {
+ name: "system_vendor_intelligence_role_enabled"
+ is_exported: true
+ is_fixed_read_only: true
+ namespace: "permissions"
+ description: "This flag is used to enable the role system_vendor_intelligence"
+ bug: "377553620"
+}
+
+flag {
+ name: "fine_power_monitor_permission"
+ is_fixed_read_only: true
+ is_exported: true
+ namespace: "permissions"
+ description: "Add support for fine-grained PowerMonitor readings"
+ bug: "341941666"
+}
+
diff --git a/core/java/android/preference/PreferenceActivity.java b/core/java/android/preference/PreferenceActivity.java
index e4a3c9fa7741627bc3f0ca42e0d8f1bb94619308..25e8a4ddffcd5842eb7be29a96de7c63e585ed40 100644
--- a/core/java/android/preference/PreferenceActivity.java
+++ b/core/java/android/preference/PreferenceActivity.java
@@ -213,7 +213,10 @@ public abstract class PreferenceActivity extends ListActivity implements
private int mPreferenceHeaderItemResId = 0;
private boolean mPreferenceHeaderRemoveEmptyIcon = false;
+ private boolean mIsBackCallbackRegistered = false;
private final OnBackInvokedCallback mOnBackInvokedCallback = this::onBackInvoked;
+ private final FragmentManager.OnBackStackChangedListener mOnBackStackChangedListener =
+ this::updateBackCallbackRegistrationState;
/**
* The starting request code given out to preference framework.
@@ -706,6 +709,7 @@ public abstract class PreferenceActivity extends ListActivity implements
}
}
updateBackCallbackRegistrationState();
+ getFragmentManager().addOnBackStackChangedListener(mOnBackStackChangedListener);
}
@Override
@@ -715,17 +719,25 @@ public abstract class PreferenceActivity extends ListActivity implements
private void updateBackCallbackRegistrationState() {
if (!WindowOnBackInvokedDispatcher.isOnBackInvokedCallbackEnabled(this)) return;
- if (mCurHeader != null && mSinglePane && getFragmentManager().getBackStackEntryCount() == 0
- && getIntent().getStringExtra(EXTRA_SHOW_FRAGMENT) == null) {
- getOnBackInvokedDispatcher()
- .registerOnBackInvokedCallback(PRIORITY_DEFAULT, mOnBackInvokedCallback);
- } else {
+ if ((mCurHeader != null && getIntent().getStringExtra(EXTRA_SHOW_FRAGMENT) == null
+ && mSinglePane) || getFragmentManager().getBackStackEntryCount() != 0) {
+ if (!mIsBackCallbackRegistered) {
+ getOnBackInvokedDispatcher()
+ .registerOnBackInvokedCallback(PRIORITY_DEFAULT, mOnBackInvokedCallback);
+ mIsBackCallbackRegistered = true;
+ }
+ } else if (mIsBackCallbackRegistered) {
getOnBackInvokedDispatcher().unregisterOnBackInvokedCallback(mOnBackInvokedCallback);
+ mIsBackCallbackRegistered = false;
}
}
private void onBackInvoked() {
- if (mCurHeader != null && mSinglePane && getFragmentManager().getBackStackEntryCount() == 0
+ if (WindowOnBackInvokedDispatcher.isOnBackInvokedCallbackEnabled(this)
+ && getFragmentManager().getBackStackEntryCount() != 0) {
+ getFragmentManager().popBackStackImmediate();
+ } else if (mCurHeader != null && mSinglePane
+ && getFragmentManager().getBackStackEntryCount() == 0
&& getIntent().getStringExtra(EXTRA_SHOW_FRAGMENT) == null) {
mCurHeader = null;
@@ -1012,6 +1024,7 @@ public abstract class PreferenceActivity extends ListActivity implements
@Override
protected void onDestroy() {
+ getFragmentManager().removeOnBackStackChangedListener(mOnBackStackChangedListener);
mHandler.removeMessages(MSG_BIND_PREFERENCES);
mHandler.removeMessages(MSG_BUILD_HEADERS);
super.onDestroy();
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 0ae9ffa655cd6b00988207eb596bcaae4ac45e57..4acb6312f90dc29cabe7941c543af0267467fa64 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -2468,6 +2468,25 @@ public final class Settings {
public static final String ACTION_APP_NOTIFICATION_BUBBLE_SETTINGS
= "android.settings.APP_NOTIFICATION_BUBBLE_SETTINGS";
+ /**
+ * Activity Action: Show the settings for users to select their preferred SIM subscription
+ * when a new SIM subscription has become available.
+ *
+ * This Activity will only launch successfully if the newly active subscription ID is set as the
+ * value of {@link EXTRA_SUB_ID} and the value corresponds with an active SIM subscription.
+ *
+ * Input: {@link #EXTRA_SUB_ID}: the subscription ID of the newly active SIM subscription.
+ *
+ * Output: Nothing.
+ *
+ * @hide
+ */
+ @FlaggedApi(com.android.internal.telephony.flags.Flags.FLAG_ACTION_SIM_PREFERENCE_SETTINGS)
+ @SystemApi
+ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+ public static final String ACTION_SIM_PREFERENCE_SETTINGS =
+ "android.settings.SIM_PREFERENCE_SETTINGS";
+
/**
* Intent Extra: The value of {@link android.app.settings.SettingsEnums#EntryPointType} for
* settings metrics that logs the entry point about physical keyboard settings.
@@ -10022,6 +10041,12 @@ public final class Settings {
public static final String MINIMAL_POST_PROCESSING_ALLOWED =
"minimal_post_processing_allowed";
+ /**
+ * Whether to mirror the built-in display on all connected displays.
+ * @hide
+ */
+ public static final String MIRROR_BUILT_IN_DISPLAY = "mirror_built_in_display";
+
/**
* No mode switching will happen.
*
diff --git a/core/java/android/security/authenticationpolicy/DisableSecureLockDeviceParams.java b/core/java/android/security/authenticationpolicy/DisableSecureLockDeviceParams.java
index 64a3f0f60f961c0e732b4907608c75232854c7ee..568a6d7cb923203d8cfbe21c5d8b4b7a89f6e714 100644
--- a/core/java/android/security/authenticationpolicy/DisableSecureLockDeviceParams.java
+++ b/core/java/android/security/authenticationpolicy/DisableSecureLockDeviceParams.java
@@ -38,23 +38,30 @@ public final class DisableSecureLockDeviceParams implements Parcelable {
/**
* Client message associated with the request to disable secure lock on the device. This message
* will be shown on the device when secure lock mode is disabled.
+ *
+ * Since this text is shown in a restricted lockscreen state, typeface properties such as color,
+ * font weight, or other formatting may not be honored.
*/
- private final @NonNull String mMessage;
+ private final @NonNull CharSequence mMessage;
/**
* Creates DisableSecureLockDeviceParams with the given params.
*
* @param message Allows clients to pass in a message with information about the request to
* disable secure lock on the device. This message will be shown to the user when
- * secure lock mode is disabled. If an empty string is provided, it will default
- * to a system-defined string (e.g. "Secure lock mode has been disabled.")
+ * secure lock mode is disabled. If an empty CharSequence is provided, it will
+ * default to a system-defined CharSequence (e.g. "Secure lock mode has been
+ * disabled.")
+ *
+ * Since this text is shown in a restricted lockscreen state, typeface properties
+ * such as color, font weight, or other formatting may not be honored.
*/
- public DisableSecureLockDeviceParams(@NonNull String message) {
+ public DisableSecureLockDeviceParams(@NonNull CharSequence message) {
mMessage = message;
}
private DisableSecureLockDeviceParams(@NonNull Parcel in) {
- mMessage = Objects.requireNonNull(in.readString8());
+ mMessage = Objects.requireNonNull(in.readCharSequence());
}
public static final @NonNull Creator CREATOR =
@@ -77,6 +84,6 @@ public final class DisableSecureLockDeviceParams implements Parcelable {
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
- dest.writeString8(mMessage);
+ dest.writeCharSequence(mMessage);
}
}
diff --git a/core/java/android/security/authenticationpolicy/EnableSecureLockDeviceParams.java b/core/java/android/security/authenticationpolicy/EnableSecureLockDeviceParams.java
index 1d727727ce37dce3a15b4f223d08fc0550feaf11..dfa391fcc85d0b5fe242c9519df692a4035aa7b8 100644
--- a/core/java/android/security/authenticationpolicy/EnableSecureLockDeviceParams.java
+++ b/core/java/android/security/authenticationpolicy/EnableSecureLockDeviceParams.java
@@ -38,23 +38,30 @@ public final class EnableSecureLockDeviceParams implements Parcelable {
/**
* Client message associated with the request to enable secure lock on the device. This message
* will be shown on the device when secure lock mode is enabled.
+ *
+ * Since this text is shown in a restricted lockscreen state, typeface properties such as color,
+ * font weight, or other formatting may not be honored.
*/
- private final @NonNull String mMessage;
+ private final @NonNull CharSequence mMessage;
/**
* Creates EnableSecureLockDeviceParams with the given params.
*
* @param message Allows clients to pass in a message with information about the request to
* enable secure lock on the device. This message will be shown to the user when
- * secure lock mode is enabled. If an empty string is provided, it will default
- * to a system-defined string (e.g. "Device is securely locked remotely.")
+ * secure lock mode is enabled. If an empty CharSequence is provided, it will
+ * default to a system-defined CharSequence (e.g. "Device is securely locked
+ * remotely.")
+ *
+ * Since this text is shown in a restricted lockscreen state, typeface properties
+ * such as color, font weight, or other formatting may not be honored.
*/
- public EnableSecureLockDeviceParams(@NonNull String message) {
+ public EnableSecureLockDeviceParams(@NonNull CharSequence message) {
mMessage = message;
}
private EnableSecureLockDeviceParams(@NonNull Parcel in) {
- mMessage = Objects.requireNonNull(in.readString8());
+ mMessage = Objects.requireNonNull(in.readCharSequence());
}
public static final @NonNull Creator CREATOR =
@@ -77,6 +84,6 @@ public final class EnableSecureLockDeviceParams implements Parcelable {
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
- dest.writeString8(mMessage);
+ dest.writeCharSequence(mMessage);
}
}
diff --git a/core/java/android/security/net/config/CertificatesEntryRef.java b/core/java/android/security/net/config/CertificatesEntryRef.java
index 45cd0f0112995dad338067b5ebf5e08d551c2cb1..a46049fb2f6dfeae04a26b381bca09e14473bfd5 100644
--- a/core/java/android/security/net/config/CertificatesEntryRef.java
+++ b/core/java/android/security/net/config/CertificatesEntryRef.java
@@ -17,6 +17,7 @@
package android.security.net.config;
import android.util.ArraySet;
+
import java.security.cert.X509Certificate;
import java.util.Set;
@@ -24,16 +25,23 @@ import java.util.Set;
public final class CertificatesEntryRef {
private final CertificateSource mSource;
private final boolean mOverridesPins;
+ private final boolean mDisableCT;
- public CertificatesEntryRef(CertificateSource source, boolean overridesPins) {
+ public CertificatesEntryRef(CertificateSource source, boolean overridesPins,
+ boolean disableCT) {
mSource = source;
mOverridesPins = overridesPins;
+ mDisableCT = disableCT;
}
boolean overridesPins() {
return mOverridesPins;
}
+ boolean disableCT() {
+ return mDisableCT;
+ }
+
public Set getTrustAnchors() {
// TODO: cache this [but handle mutable sources]
Set anchors = new ArraySet();
diff --git a/core/java/android/security/net/config/KeyStoreConfigSource.java b/core/java/android/security/net/config/KeyStoreConfigSource.java
index 8d4f098bcb37a2a97d38a0529e21e969d5814b08..a54d8d0499cbfb4922b739376d2711b99916c86a 100644
--- a/core/java/android/security/net/config/KeyStoreConfigSource.java
+++ b/core/java/android/security/net/config/KeyStoreConfigSource.java
@@ -17,8 +17,8 @@
package android.security.net.config;
import android.util.Pair;
+
import java.security.KeyStore;
-import java.security.KeyStoreException;
import java.util.Set;
/**
@@ -32,7 +32,7 @@ class KeyStoreConfigSource implements ConfigSource {
mConfig = new NetworkSecurityConfig.Builder()
.addCertificatesEntryRef(
// Use the KeyStore and do not override pins (of which there are none).
- new CertificatesEntryRef(new KeyStoreCertificateSource(ks), false))
+ new CertificatesEntryRef(new KeyStoreCertificateSource(ks), false, false))
.build();
}
diff --git a/core/java/android/security/net/config/NetworkSecurityConfig.java b/core/java/android/security/net/config/NetworkSecurityConfig.java
index 129ae63ec9c003594deaccf7c274c2bf8183aaa6..410c68b8d04d8328701c52f1846c9ccdbd6794eb 100644
--- a/core/java/android/security/net/config/NetworkSecurityConfig.java
+++ b/core/java/android/security/net/config/NetworkSecurityConfig.java
@@ -112,7 +112,6 @@ public final class NetworkSecurityConfig {
return mHstsEnforced;
}
- // TODO(b/28746284): add exceptions for user-added certificates and enterprise overrides.
public boolean isCertificateTransparencyVerificationRequired() {
return mCertificateTransparencyVerificationRequired;
}
@@ -192,20 +191,21 @@ public final class NetworkSecurityConfig {
* @hide
*/
public static Builder getDefaultBuilder(ApplicationInfo info) {
+ // System certificate store, does not bypass static pins, does not disable CT.
+ CertificatesEntryRef systemRef = new CertificatesEntryRef(
+ SystemCertificateSource.getInstance(), false, false);
Builder builder = new Builder()
.setHstsEnforced(DEFAULT_HSTS_ENFORCED)
- // System certificate store, does not bypass static pins.
- .addCertificatesEntryRef(
- new CertificatesEntryRef(SystemCertificateSource.getInstance(), false));
+ .addCertificatesEntryRef(systemRef);
final boolean cleartextTrafficPermitted = info.targetSdkVersion < Build.VERSION_CODES.P
&& !info.isInstantApp();
builder.setCleartextTrafficPermitted(cleartextTrafficPermitted);
// Applications targeting N and above must opt in into trusting the user added certificate
// store.
if (info.targetSdkVersion <= Build.VERSION_CODES.M && !info.isPrivilegedApp()) {
- // User certificate store, does not bypass static pins.
+ // User certificate store, does not bypass static pins. CT is disabled.
builder.addCertificatesEntryRef(
- new CertificatesEntryRef(UserCertificateSource.getInstance(), false));
+ new CertificatesEntryRef(UserCertificateSource.getInstance(), false, true));
}
return builder;
}
@@ -339,6 +339,16 @@ public final class NetworkSecurityConfig {
if (mCertificateTransparencyVerificationRequiredSet) {
return mCertificateTransparencyVerificationRequired;
}
+ // CT verification has not been set explicitly. Before deferring to
+ // the parent, check if any of the CertificatesEntryRef requires it
+ // to be disabled (i.e., user store or inline certificate).
+ if (hasCertificatesEntryRefs()) {
+ for (CertificatesEntryRef ref : getCertificatesEntryRefs()) {
+ if (ref.disableCT()) {
+ return false;
+ }
+ }
+ }
if (mParentBuilder != null) {
return mParentBuilder.getCertificateTransparencyVerificationRequired();
}
diff --git a/core/java/android/security/net/config/XmlConfigSource.java b/core/java/android/security/net/config/XmlConfigSource.java
index b1c14793bbbd359bcb9f52dd7417a228b273435d..95e579fc538b889e7a8bdc4510b6788c2ddf2200 100644
--- a/core/java/android/security/net/config/XmlConfigSource.java
+++ b/core/java/android/security/net/config/XmlConfigSource.java
@@ -182,6 +182,7 @@ public class XmlConfigSource implements ConfigSource {
boolean overridePins =
parser.getAttributeBooleanValue(null, "overridePins", defaultOverridePins);
int sourceId = parser.getAttributeResourceValue(null, "src", -1);
+ boolean disableCT = false;
String sourceString = parser.getAttributeValue(null, "src");
CertificateSource source = null;
if (sourceString == null) {
@@ -190,10 +191,12 @@ public class XmlConfigSource implements ConfigSource {
if (sourceId != -1) {
// TODO: Cache ResourceCertificateSources by sourceId
source = new ResourceCertificateSource(sourceId, mContext);
+ disableCT = true;
} else if ("system".equals(sourceString)) {
source = SystemCertificateSource.getInstance();
} else if ("user".equals(sourceString)) {
source = UserCertificateSource.getInstance();
+ disableCT = true;
} else if ("wfa".equals(sourceString)) {
source = WfaCertificateSource.getInstance();
} else {
@@ -201,7 +204,7 @@ public class XmlConfigSource implements ConfigSource {
+ "Should be one of system|user|@resourceVal");
}
XmlUtils.skipCurrentTag(parser);
- return new CertificatesEntryRef(source, overridePins);
+ return new CertificatesEntryRef(source, overridePins, disableCT);
}
private Collection parseTrustAnchors(XmlResourceParser parser,
diff --git a/core/java/android/security/responsible_apis_flags.aconfig b/core/java/android/security/responsible_apis_flags.aconfig
index 42dbd37860017ef08cb135b61d07e2876eb72ee1..8add9f7c63cc26bd221c3971d6f7831f26c05334 100644
--- a/core/java/android/security/responsible_apis_flags.aconfig
+++ b/core/java/android/security/responsible_apis_flags.aconfig
@@ -96,14 +96,6 @@ flag {
is_fixed_read_only: true
}
-flag {
- name: "prevent_intent_redirect_show_toast_if_nested_keys_not_collected"
- namespace: "responsible_apis"
- description: "Prevent intent redirect attacks by showing a toast if not yet collected"
- bug: "361143368"
- is_fixed_read_only: true
-}
-
flag {
name: "prevent_intent_redirect_show_toast_if_nested_keys_not_collected_r_w"
namespace: "responsible_apis"
diff --git a/core/java/android/service/autofill/AutofillService.java b/core/java/android/service/autofill/AutofillService.java
index 269839b61befe278a05d11d4a2da33e65eb1bcf4..2d922b4c09ee94b5ebf54de84c85cbf4cc11035c 100644
--- a/core/java/android/service/autofill/AutofillService.java
+++ b/core/java/android/service/autofill/AutofillService.java
@@ -15,9 +15,12 @@
*/
package android.service.autofill;
+import static android.service.autofill.Flags.FLAG_AUTOFILL_SESSION_DESTROYED;
+
import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
import android.annotation.CallSuper;
+import android.annotation.FlaggedApi;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SdkConstant;
@@ -669,6 +672,14 @@ public abstract class AutofillService extends Service {
AutofillService.this,
new SavedDatasetsInfoCallbackImpl(receiver, SavedDatasetsInfo.TYPE_PASSWORDS)));
}
+
+ @Override
+ public void onSessionDestroyed(@Nullable FillEventHistory history) {
+ mHandler.sendMessage(obtainMessage(
+ AutofillService::onSessionDestroyed,
+ AutofillService.this,
+ history));
+ }
};
private Handler mHandler;
@@ -783,26 +794,42 @@ public abstract class AutofillService extends Service {
}
/**
- * Gets the events that happened after the last
- * {@link AutofillService#onFillRequest(FillRequest, android.os.CancellationSignal, FillCallback)}
+ * Called when an Autofill context has ended and the Autofill session is finished. This will be
+ * called as the last step of the Autofill lifecycle described in {@link AutofillManager}.
+ *
+ *
This will also contain the finished Session's FillEventHistory, so providers do not need
+ * to explicitly call {@link #getFillEventHistory()}
+ *
+ *
This will usually happens whenever {@link AutofillManager#commit()} or {@link
+ * AutofillManager#cancel()} is called.
+ */
+ @FlaggedApi(FLAG_AUTOFILL_SESSION_DESTROYED)
+ public void onSessionDestroyed(@Nullable FillEventHistory history) {}
+
+ /**
+ * Gets the events that happened after the last {@link
+ * AutofillService#onFillRequest(FillRequest, android.os.CancellationSignal, FillCallback)}
* call.
*
*
This method is typically used to keep track of previous user actions to optimize further
* requests. For example, the service might return email addresses in alphabetical order by
* default, but change that order based on the address the user picked on previous requests.
*
- *
The history is not persisted over reboots, and it's cleared every time the service
- * replies to a {@link #onFillRequest(FillRequest, CancellationSignal, FillCallback)} by calling
- * {@link FillCallback#onSuccess(FillResponse)} or {@link FillCallback#onFailure(CharSequence)}
- * (if the service doesn't call any of these methods, the history will clear out after some
- * pre-defined time). Hence, the service should call {@link #getFillEventHistory()} before
- * finishing the {@link FillCallback}.
+ *
The history is not persisted over reboots, and it's cleared every time the service replies
+ * to a {@link #onFillRequest(FillRequest, CancellationSignal, FillCallback)} by calling {@link
+ * FillCallback#onSuccess(FillResponse)} or {@link FillCallback#onFailure(CharSequence)} (if the
+ * service doesn't call any of these methods, the history will clear out after some pre-defined
+ * time). Hence, the service should call {@link #getFillEventHistory()} before finishing the
+ * {@link FillCallback}.
*
* @return The history or {@code null} if there are no events.
- *
* @throws RuntimeException if the event history could not be retrieved.
+ * @deprecated Use {@link #onSessionDestroyed(FillEventHistory) instead}
*/
- @Nullable public final FillEventHistory getFillEventHistory() {
+ @FlaggedApi(FLAG_AUTOFILL_SESSION_DESTROYED)
+ @Deprecated
+ @Nullable
+ public final FillEventHistory getFillEventHistory() {
final AutofillManager afm = getSystemService(AutofillManager.class);
if (afm == null) {
diff --git a/core/java/android/service/autofill/FillEventHistory.java b/core/java/android/service/autofill/FillEventHistory.java
index fba8e42cc673ecbf4827e27191b5e67796e41dcb..6d62a2c7db2eb920d70d6937588bf2cbdae06663 100644
--- a/core/java/android/service/autofill/FillEventHistory.java
+++ b/core/java/android/service/autofill/FillEventHistory.java
@@ -341,7 +341,7 @@ public final class FillEventHistory implements Parcelable {
/** Credential Manager suggestions are shown instead of Autofill suggestion */
@FlaggedApi(FLAG_AUTOFILL_W_METRICS)
- public static final int UI_TYPE_CREDMAN = 4;
+ public static final int UI_TYPE_CREDENTIAL_MANAGER = 4;
/** @hide */
@IntDef(prefix = { "UI_TYPE_" }, value = {
diff --git a/core/java/android/service/autofill/IAutoFillService.aidl b/core/java/android/service/autofill/IAutoFillService.aidl
index 3b64b8a0ec5e47854737e704e8a5b80fed2ac17a..71b75e7789c241f9d0ae93d56d5be2e09257fb90 100644
--- a/core/java/android/service/autofill/IAutoFillService.aidl
+++ b/core/java/android/service/autofill/IAutoFillService.aidl
@@ -25,6 +25,8 @@ import android.service.autofill.ISaveCallback;
import android.service.autofill.SaveRequest;
import com.android.internal.os.IResultReceiver;
+parcelable FillEventHistory;
+
/**
* Interface from the system to an auto fill service.
*
@@ -38,4 +40,5 @@ oneway interface IAutoFillService {
void onSaveRequest(in SaveRequest request, in ISaveCallback callback);
void onSavedPasswordCountRequest(in IResultReceiver receiver);
void onConvertCredentialRequest(in ConvertCredentialRequest convertCredentialRequest, in IConvertCredentialCallback convertCredentialCallback);
+ void onSessionDestroyed(in FillEventHistory history);
}
diff --git a/services/core/java/com/android/server/notification/RateEstimator.java b/core/java/android/service/notification/RateEstimator.java
similarity index 92%
rename from services/core/java/com/android/server/notification/RateEstimator.java
rename to core/java/android/service/notification/RateEstimator.java
index eda96ac84b1657112c0e163cf6f35c76d51f15fa..04789c18ffe4cc3c9ac293a8181de79e91062bba 100644
--- a/services/core/java/com/android/server/notification/RateEstimator.java
+++ b/core/java/android/service/notification/RateEstimator.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2016 The Android Open Source Project
+ * Copyright (C) 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -11,10 +11,10 @@
* 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
+ * limitations under the License.
*/
-package com.android.server.notification;
+package android.service.notification;
/**
@@ -22,7 +22,7 @@ package com.android.server.notification;
*
* {@hide}
*/
-class RateEstimator {
+public class RateEstimator {
private static final double RATE_ALPHA = 0.7;
private static final double MINIMUM_DT = 0.0005;
diff --git a/core/java/android/service/ondeviceintelligence/OWNERS b/core/java/android/service/ondeviceintelligence/OWNERS
deleted file mode 100644
index 09774f78d71273cf3ae9de7ef4efc4a2de979e7e..0000000000000000000000000000000000000000
--- a/core/java/android/service/ondeviceintelligence/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-file:/core/java/android/app/ondeviceintelligence/OWNERS
diff --git a/core/java/android/service/settings/preferences/SettingsPreferenceMetadata.java b/core/java/android/service/settings/preferences/SettingsPreferenceMetadata.java
index 1acb7b8460cf1992d129f2bc67ca34d5cf65ed6a..ea7d4a675713655eca8143df344175073df35381 100644
--- a/core/java/android/service/settings/preferences/SettingsPreferenceMetadata.java
+++ b/core/java/android/service/settings/preferences/SettingsPreferenceMetadata.java
@@ -187,27 +187,39 @@ public final class SettingsPreferenceMetadata implements Parcelable {
/** @hide */
@IntDef(value = {
- NOT_SENSITIVE,
- SENSITIVE,
- INTENT_ONLY
+ NO_SENSITIVITY,
+ EXPECT_POST_CONFIRMATION,
+ EXPECT_PRE_CONFIRMATION,
+ NO_DIRECT_ACCESS,
})
@Retention(RetentionPolicy.SOURCE)
public @interface WriteSensitivity {}
/**
- * Preference is not sensitive, thus its value is writable without explicit consent, assuming
- * all necessary permissions are granted.
+ * Indicates preference is not sensitive.
+ *
Its value is writable without explicit consent, assuming all necessary permissions are
+ * granted.
*/
- public static final int NOT_SENSITIVE = 0;
+ public static final int NO_SENSITIVITY = 0;
/**
- * Preference is sensitive, meaning that in addition to necessary permissions, writing its value
- * will also request explicit user consent.
+ * Indicates preference is mildly sensitive.
+ *
In addition to necessary permissions, after writing its value the user should be
+ * given the option to revert back.
*/
- public static final int SENSITIVE = 1;
+ public static final int EXPECT_POST_CONFIRMATION = 1;
/**
- * Preference is not permitted for write-access via API and must be changed via Settings page.
+ * Indicates preference is sensitive.
+ *
In addition to necessary permissions, the user should be prompted for confirmation prior
+ * to making a change. Otherwise it is suggested to provide a deeplink to the Preference's page
+ * instead, accessible via {@link #getLaunchIntent}.
*/
- public static final int INTENT_ONLY = 2;
+ public static final int EXPECT_PRE_CONFIRMATION = 2;
+ /**
+ * Indicates preference is highly sensitivity and carries significant user-risk.
+ *
This Preference cannot be changed through this API and no direct deeplink is available.
+ * Other Metadata is still available.
+ */
+ public static final int NO_DIRECT_ACCESS = 3;
private SettingsPreferenceMetadata(@NonNull Builder builder) {
mKey = builder.mKey;
@@ -303,7 +315,7 @@ public final class SettingsPreferenceMetadata implements Parcelable {
private boolean mAvailable = false;
private boolean mWritable = false;
private boolean mRestricted = false;
- @WriteSensitivity private int mSensitivity = INTENT_ONLY;
+ @WriteSensitivity private int mSensitivity = NO_DIRECT_ACCESS;
private Intent mLaunchIntent;
private Bundle mExtras;
@@ -436,6 +448,9 @@ public final class SettingsPreferenceMetadata implements Parcelable {
*/
@NonNull
public SettingsPreferenceMetadata build() {
+ if (mSensitivity == NO_DIRECT_ACCESS) {
+ mLaunchIntent = null;
+ }
return new SettingsPreferenceMetadata(this);
}
}
diff --git a/core/java/android/speech/tts/EventLogTags.logtags b/core/java/android/speech/tts/EventLogTags.logtags
index e209a286966aa8aad8597c83e2f1c5d12df0b89f..5ba2baec6fcfee1ed6737676c833b56dac00f960 100644
--- a/core/java/android/speech/tts/EventLogTags.logtags
+++ b/core/java/android/speech/tts/EventLogTags.logtags
@@ -1,4 +1,4 @@
-# See system/core/logcat/event.logtags for a description of the format of this file.
+# See system/logging/logcat/event.logtags for a description of the format of this file.
option java_package android.speech.tts;
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index c9d560c3424bc63d890dba0cf5dedb2df841363a..802bddd76e30de63ea7c2fb4b84f31c762b38a4d 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -1301,17 +1301,23 @@ public final class Display {
}
/**
- * Represents the {@link FrameRateCategory} for the Normal frame rate
+ * Normal category determines the framework's recommended normal frame rate.
+ * Opt for this normal rate unless a higher frame rate significantly enhances
+ * the user experience.
*
- * @see FrameRateCategory
+ * @see #getSuggestedFrameRate(int)
+ * @see #FRAME_RATE_CATEGORY_HIGH
*/
@FlaggedApi(FLAG_ENABLE_GET_SUGGESTED_FRAME_RATE)
public static final int FRAME_RATE_CATEGORY_NORMAL = 0;
/**
- * Represents the {@link FrameRateCategory} for the High frame rate
+ * High category determines the framework's recommended high frame rate.
+ * Opt for this high rate when a higher frame rate significantly enhances
+ * the user experience.
*
- * @see FrameRateCategory
+ * @see #getSuggestedFrameRate(int)
+ * @see #FRAME_RATE_CATEGORY_NORMAL
*/
@FlaggedApi(FLAG_ENABLE_GET_SUGGESTED_FRAME_RATE)
public static final int FRAME_RATE_CATEGORY_HIGH = 1;
@@ -1332,22 +1338,17 @@ public final class Display {
*
*
For example, an animation that does not require fast render rates can use
* the {@link #FRAME_RATE_CATEGORY_NORMAL} to get the suggested frame rate.
- * The suggested frame rate then can be used in the
- * {@link Surface.FrameRateParams.Builder#setDesiredRateRange} for desiredMinRate.
*
*
*
* @param category either {@link #FRAME_RATE_CATEGORY_NORMAL}
* or {@link #FRAME_RATE_CATEGORY_HIGH}
*
- * @see Surface#setFrameRate(Surface.FrameRateParams)
- * @see SurfaceControl.Transaction#setFrameRate(SurfaceControl, Surface.FrameRateParams)
+ * @see Surface#setFrameRate(float, int)
* @throws IllegalArgumentException when category is not {@link #FRAME_RATE_CATEGORY_NORMAL}
* or {@link #FRAME_RATE_CATEGORY_HIGH}
*/
diff --git a/core/java/android/view/DisplayEventReceiver.java b/core/java/android/view/DisplayEventReceiver.java
index bb233d2711de05ab0f41a53e27c36a1ff9f1be81..3ff5f95cd71f5791c00c71379a69f683e5435fed 100644
--- a/core/java/android/view/DisplayEventReceiver.java
+++ b/core/java/android/view/DisplayEventReceiver.java
@@ -286,13 +286,22 @@ public abstract class DisplayEventReceiver {
* @param timestampNanos The timestamp of the event, in the {@link System#nanoTime()}
* timebase.
* @param physicalDisplayId Stable display ID that uniquely describes a (display, port) pair.
- * @param modeId The new mode Id
+ * @param modeId The new mode ID
* @param renderPeriod The render frame period, which is a multiple of the mode's vsync period
*/
public void onModeChanged(long timestampNanos, long physicalDisplayId, int modeId,
long renderPeriod) {
}
+ /**
+ * Called when a display mode rejection event is received.
+ *
+ * @param physicalDisplayId Stable display ID that uniquely describes a (display, port) pair.
+ * @param modeId The mode ID of the mode that was rejected
+ */
+ public void onModeRejected(long physicalDisplayId, int modeId) {
+ }
+
/**
* Called when a display hdcp levels change event is received.
*
@@ -384,6 +393,12 @@ public abstract class DisplayEventReceiver {
onModeChanged(timestampNanos, physicalDisplayId, modeId, renderPeriod);
}
+ // Called from native code.
+ @SuppressWarnings("unused")
+ private void dispatchModeRejected(long physicalDisplayId, int modeId) {
+ onModeRejected(physicalDisplayId, modeId);
+ }
+
// Called from native code.
@SuppressWarnings("unused")
private void dispatchFrameRateOverrides(long timestampNanos, long physicalDisplayId,
diff --git a/core/java/android/view/DisplayInfo.java b/core/java/android/view/DisplayInfo.java
index 8b6458a54c43c3ff44ff8d4967500c6b0ebb073a..43078847326cb1e2c074c2d006be20bf7c6fb9a3 100644
--- a/core/java/android/view/DisplayInfo.java
+++ b/core/java/android/view/DisplayInfo.java
@@ -360,6 +360,12 @@ public final class DisplayInfo implements Parcelable {
*/
public float brightnessDefault;
+ /**
+ * The current dim brightness of the display. Value between 0.0 and 1.0,
+ * derived from the configuration of the display device of this logical display.
+ */
+ public float brightnessDim;
+
/**
* The {@link RoundedCorners} if present, otherwise {@code null}.
*/
@@ -479,6 +485,7 @@ public final class DisplayInfo implements Parcelable {
&& brightnessMinimum == other.brightnessMinimum
&& brightnessMaximum == other.brightnessMaximum
&& brightnessDefault == other.brightnessDefault
+ && brightnessDim == other.brightnessDim
&& Objects.equals(roundedCorners, other.roundedCorners)
&& installOrientation == other.installOrientation
&& Objects.equals(displayShape, other.displayShape)
@@ -546,6 +553,7 @@ public final class DisplayInfo implements Parcelable {
brightnessMinimum = other.brightnessMinimum;
brightnessMaximum = other.brightnessMaximum;
brightnessDefault = other.brightnessDefault;
+ brightnessDim = other.brightnessDim;
roundedCorners = other.roundedCorners;
installOrientation = other.installOrientation;
displayShape = other.displayShape;
@@ -620,6 +628,7 @@ public final class DisplayInfo implements Parcelable {
brightnessMinimum = source.readFloat();
brightnessMaximum = source.readFloat();
brightnessDefault = source.readFloat();
+ brightnessDim = source.readFloat();
roundedCorners = source.readTypedObject(RoundedCorners.CREATOR);
int numUserDisabledFormats = source.readInt();
userDisabledHdrTypes = new int[numUserDisabledFormats];
@@ -696,6 +705,7 @@ public final class DisplayInfo implements Parcelable {
dest.writeFloat(brightnessMinimum);
dest.writeFloat(brightnessMaximum);
dest.writeFloat(brightnessDefault);
+ dest.writeFloat(brightnessDim);
dest.writeTypedObject(roundedCorners, flags);
dest.writeInt(userDisabledHdrTypes.length);
for (int i = 0; i < userDisabledHdrTypes.length; i++) {
@@ -994,6 +1004,8 @@ public final class DisplayInfo implements Parcelable {
sb.append(brightnessMaximum);
sb.append(", brightnessDefault ");
sb.append(brightnessDefault);
+ sb.append(", brightnessDim ");
+ sb.append(brightnessDim);
sb.append(", installOrientation ");
sb.append(Surface.rotationToString(installOrientation));
sb.append(", layoutLimitedRefreshRate ");
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 6d85e7589c482992e0682cbfa272fae04a282c68..072a037aa84afbce29386e8b8bb1439e050f9467 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -766,7 +766,7 @@ interface IWindowManager
* container.
*/
@EnforcePermission("MANAGE_APP_TOKENS")
- void updateDisplayWindowRequestedVisibleTypes(int displayId, int requestedVisibleTypes,
+ void updateDisplayWindowRequestedVisibleTypes(int displayId, int visibleTypes, int mask,
in @nullable ImeTracker.Token statsToken);
/**
@@ -932,6 +932,27 @@ interface IWindowManager
*/
void detachWindowContext(IBinder clientToken);
+ /**
+ * Reparents the {@link android.window.WindowContext} to the
+ * {@link com.android.server.wm.DisplayArea} on another display.
+ * This method also reparent the WindowContext associated WindowToken to another display if
+ * necessary.
+ *
+ * {@code type} and {@code options} must be the same as the previous call of
+ * {@link #attachWindowContextToDisplayArea} on the same Context otherwise this will fail
+ * silently.
+ *
+ * @param appThread the process that the window context is on.
+ * @param clientToken the window context's token
+ * @param type The window type of the WindowContext
+ * @param displayId The new display id this context windows should be parented to
+ * @param options Bundle the context was created with
+ *
+ * @return True if the operation was successful, False otherwise.
+ */
+ boolean reparentWindowContextToDisplayArea(in IApplicationThread appThread,
+ IBinder clientToken, int displayId);
+
/**
* Registers a listener, which is to be called whenever cross-window blur is enabled/disabled.
*
diff --git a/core/java/android/view/InsetsSource.java b/core/java/android/view/InsetsSource.java
index b796e0b1c4292a570c28d2b0ed3d762cc0863620..ba208390c8b7db8d4be4431b29e3793fc4df105d 100644
--- a/core/java/android/view/InsetsSource.java
+++ b/core/java/android/view/InsetsSource.java
@@ -357,6 +357,31 @@ public class InsetsSource implements Parcelable {
} else if (mTmpFrame.right == relativeFrame.right) {
return Insets.of(0, 0, mTmpFrame.width(), 0);
}
+ } else {
+ // The source doesn't cover the width or the height of relativeFrame, but just parts of
+ // them. Here uses mSideHint to decide which side should be inset.
+ switch (mSideHint) {
+ case SIDE_LEFT:
+ if (mTmpFrame.left == relativeFrame.left) {
+ return Insets.of(mTmpFrame.width(), 0, 0, 0);
+ }
+ break;
+ case SIDE_TOP:
+ if (mTmpFrame.top == relativeFrame.top) {
+ return Insets.of(0, mTmpFrame.height(), 0, 0);
+ }
+ break;
+ case SIDE_RIGHT:
+ if (mTmpFrame.right == relativeFrame.right) {
+ return Insets.of(0, 0, mTmpFrame.width(), 0);
+ }
+ break;
+ case SIDE_BOTTOM:
+ if (mTmpFrame.bottom == relativeFrame.bottom) {
+ return Insets.of(0, 0, 0, mTmpFrame.height());
+ }
+ break;
+ }
}
return Insets.NONE;
}
diff --git a/core/java/android/view/InsetsState.java b/core/java/android/view/InsetsState.java
index 67050e01b5915a4bdda9fc7698146a2a4f551eb8..213ece09da227b20ba4b91f5194af1f9b81a5fcd 100644
--- a/core/java/android/view/InsetsState.java
+++ b/core/java/android/view/InsetsState.java
@@ -296,8 +296,8 @@ public class InsetsState implements Parcelable {
@SoftInputModeFlags int softInputMode, int windowFlags) {
final int softInputAdjustMode = softInputMode & SOFT_INPUT_MASK_ADJUST;
final int visibleInsetsTypes = softInputAdjustMode != SOFT_INPUT_ADJUST_NOTHING
- ? systemBars() | ime()
- : systemBars();
+ ? systemBars() | displayCutout() | ime()
+ : systemBars() | displayCutout();
@InsetsType int forceConsumingTypes = 0;
Insets insets = Insets.NONE;
for (int i = mSources.size() - 1; i >= 0; i--) {
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java
index 03f9d9814b4317197c614e3e61529cf5b55873b5..6e6e87bb9403f39d9a0d0316df2c062ed489596a 100644
--- a/core/java/android/view/Surface.java
+++ b/core/java/android/view/Surface.java
@@ -205,7 +205,8 @@ public class Surface implements Parcelable {
/** @hide */
@Retention(RetentionPolicy.SOURCE)
@IntDef(prefix = {"FRAME_RATE_COMPATIBILITY_"},
- value = {FRAME_RATE_COMPATIBILITY_DEFAULT, FRAME_RATE_COMPATIBILITY_FIXED_SOURCE})
+ value = {FRAME_RATE_COMPATIBILITY_DEFAULT, FRAME_RATE_COMPATIBILITY_FIXED_SOURCE,
+ FRAME_RATE_COMPATIBILITY_GTE})
public @interface FrameRateCompatibility {}
// From native_window.h. Keep these in sync.
@@ -214,6 +215,11 @@ public class Surface implements Parcelable {
* system selects a frame rate other than what the app requested, the app will be able
* to run at the system frame rate without requiring pull down. This value should be
* used when displaying game content, UIs, and anything that isn't video.
+ *
+ * In Android version {@link Build.VERSION_CODES#BAKLAVA} and above, use
+ * {@link FRAME_RATE_COMPATIBILITY_DEFAULT} for game content.
+ * For other cases, see {@link FRAME_RATE_COMPATIBILITY_FIXED_SOURCE} and
+ * {@link FRAME_RATE_COMPATIBILITY_GTE}.
*/
public static final int FRAME_RATE_COMPATIBILITY_DEFAULT = 0;
@@ -227,6 +233,17 @@ public class Surface implements Parcelable {
*/
public static final int FRAME_RATE_COMPATIBILITY_FIXED_SOURCE = 1;
+ /**
+ * The surface requests a frame rate that is greater than or equal to the specified frame rate.
+ * This value should be used for UIs, animations, scrolling and fling, and anything that is not
+ * a game or video.
+ *
+ * For video, use {@link FRAME_RATE_COMPATIBILITY_FIXED_SOURCE} instead. For game content, use
+ * {@link FRAME_RATE_COMPATIBILITY_DEFAULT}.
+ */
+ @FlaggedApi(com.android.graphics.surfaceflinger.flags.Flags.FLAG_ARR_SETFRAMERATE_GTE_ENUM)
+ public static final int FRAME_RATE_COMPATIBILITY_GTE = 2;
+
/**
* This surface belongs to an app on the High Refresh Rate Deny list, and needs the display
* to operate at the exact frame rate.
@@ -250,13 +267,6 @@ public class Surface implements Parcelable {
*/
public static final int FRAME_RATE_COMPATIBILITY_MIN = 102;
- // From window.h. Keep these in sync.
- /**
- * The surface requests a frame rate that is greater than or equal to {@code frameRate}.
- * @hide
- */
- public static final int FRAME_RATE_COMPATIBILITY_GTE = 103;
-
/** @hide */
@Retention(RetentionPolicy.SOURCE)
@IntDef(prefix = {"CHANGE_FRAME_RATE_"},
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 02c79015fab237adc74bdc30a943aa9816219adc..d13f0e21bf8059779c9330a5993907ec88c8e781 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -17184,7 +17184,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
final WindowManager windowManager = mContext.getSystemService(WindowManager.class);
final WindowMetrics metrics = windowManager.getMaximumWindowMetrics();
final Insets insets = metrics.getWindowInsets().getInsets(
- WindowInsets.Type.navigationBars() | WindowInsets.Type.displayCutout());
+ WindowInsets.Type.systemBars() | WindowInsets.Type.displayCutout());
outRect.set(metrics.getBounds());
outRect.inset(insets);
outRect.offsetTo(0, 0);
@@ -28277,7 +28277,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
mPrivateFlags |= PFLAG_FORCE_LAYOUT;
mPrivateFlags |= PFLAG_INVALIDATED;
- if (mParent != null) {
+ if (mParent != null && !mParent.isLayoutRequested()) {
mParent.requestLayout();
}
if (mAttachInfo != null && mAttachInfo.mViewRequestingLayout == this) {
diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java
index 63bf392b5ef15a9992fdc7e16c9421f17531f2ba..9e97a8eb58aa99eef967f991367655bc2e6b6f2e 100644
--- a/core/java/android/view/ViewConfiguration.java
+++ b/core/java/android/view/ViewConfiguration.java
@@ -591,7 +591,7 @@ public class ViewConfiguration {
res.getBoolean(
com.android.internal.R.bool.config_viewBasedRotaryEncoderHapticsEnabled);
mViewTouchScreenHapticScrollFeedbackEnabled =
- Flags.enableTouchScrollFeedback()
+ Flags.enableScrollFeedbackForTouch()
? res.getBoolean(
com.android.internal.R.bool
.config_viewTouchScreenHapticScrollFeedbackEnabled)
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 31330204e8c60906babc0e1c56bd6df6121f30eb..c1b92ee3f74e905ac9ab934f8ab1eaaca45e40f3 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -17,8 +17,8 @@
package android.view;
import static android.adpf.Flags.adpfViewrootimplActionDownBoost;
-import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
+import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static android.content.pm.ActivityInfo.OVERRIDE_SANDBOX_VIEW_BOUNDS_APIS;
import static android.graphics.HardwareRenderer.SYNC_CONTEXT_IS_STOPPED;
import static android.graphics.HardwareRenderer.SYNC_LOST_SURFACE_REWARD_IF_FOUND;
@@ -2255,7 +2255,7 @@ public final class ViewRootImpl implements ViewParent,
onClientWindowFramesChanged(frames);
- CompatibilityInfo.applyOverrideScaleIfNeeded(mergedConfiguration);
+ CompatibilityInfo.applyOverrideIfNeeded(mergedConfiguration);
final Rect frame = frames.frame;
final Rect displayFrame = frames.displayFrame;
final Rect attachedFrame = frames.attachedFrame;
@@ -2653,8 +2653,7 @@ public final class ViewRootImpl implements ViewParent,
mStopped = stopped;
final ThreadedRenderer renderer = mAttachInfo.mThreadedRenderer;
if (renderer != null) {
- if (DEBUG_DRAW)
- Log.d(mTag, "WindowStopped on " + getTitle() + " set to " + mStopped);
+ if (DEBUG_DRAW) Log.d(mTag, "WindowStopped on " + getTitle() + " set to " + mStopped);
renderer.setStopped(mStopped);
}
if (!mStopped) {
@@ -7980,8 +7979,8 @@ public final class ViewRootImpl implements ViewParent,
private boolean moveFocusToAdjacentWindow(@FocusDirection int direction) {
final int windowingMode = getConfiguration().windowConfiguration.getWindowingMode();
- if (!(windowingMode == WINDOWING_MODE_MULTI_WINDOW
- || windowingMode == WINDOWING_MODE_FREEFORM)) {
+ if (windowingMode != WINDOWING_MODE_MULTI_WINDOW
+ && windowingMode != WINDOWING_MODE_FREEFORM) {
return false;
}
try {
@@ -9461,7 +9460,7 @@ public final class ViewRootImpl implements ViewParent,
mTranslator.translateRectInScreenToAppWindow(mTmpFrames.attachedFrame);
}
mInvCompatScale = 1f / mTmpFrames.compatScale;
- CompatibilityInfo.applyOverrideScaleIfNeeded(mPendingMergedConfiguration);
+ CompatibilityInfo.applyOverrideIfNeeded(mPendingMergedConfiguration);
handleInsetsControlChanged(mTempInsets, mTempControls);
mPendingAlwaysConsumeSystemBars =
diff --git a/core/java/android/view/ViewStructure.java b/core/java/android/view/ViewStructure.java
index 1be7f4849f07a1b7291191643b82219ca5a528fa..43a946a234babe4ed6ab7055a43bc0cdd5e7e275 100644
--- a/core/java/android/view/ViewStructure.java
+++ b/core/java/android/view/ViewStructure.java
@@ -87,8 +87,12 @@ public abstract class ViewStructure {
*
This value is added to mainly help with debugging purpose.
*/
@FlaggedApi(FLAG_AUTOFILL_W_METRICS)
+ @SuppressWarnings(
+ "ActionValue") // Lint expects this as
+ // android.view.contentcapture.extra.VIRTUAL_STRUCTURE_VERSION_NUMBER
+ // but should not have contentcapture
public static final String EXTRA_VIRTUAL_STRUCTURE_TYPE =
- "android.view.ViewStructure.extra.VIRTUAL_STRUCTURE_TYPE";
+ "android.view.extra.VIRTUAL_STRUCTURE_TYPE";
/**
* Key used for specifying the version of the view that generated the virtual structure for
@@ -98,8 +102,12 @@ public abstract class ViewStructure {
* "104.0.5112.69", then the value should be "104.0.5112.69"
*/
@FlaggedApi(FLAG_AUTOFILL_W_METRICS)
+ @SuppressWarnings(
+ "ActionValue") // Lint expects this as
+ // android.view.contentcapture.extra.VIRTUAL_STRUCTURE_TYPE
+ // but should not have contentcapture
public static final String EXTRA_VIRTUAL_STRUCTURE_VERSION_NUMBER =
- "android.view.ViewStructure.extra.VIRTUAL_STRUCTURE_VERSION_NUMBER";
+ "android.view.extra.VIRTUAL_STRUCTURE_VERSION_NUMBER";
/**
* Set the identifier for this view.
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 1e8cad61381c257d87a451fc4670d5c126d6ebb1..101d5c950b71344017d72112c759401185a88b80 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -80,6 +80,9 @@ import static android.view.WindowLayoutParamsProto.WINDOW_ANIMATIONS;
import static android.view.WindowLayoutParamsProto.X;
import static android.view.WindowLayoutParamsProto.Y;
+import static com.android.hardware.input.Flags.FLAG_OVERRIDE_POWER_KEY_BEHAVIOR_IN_FOCUSED_WINDOW;
+import static com.android.hardware.input.Flags.overridePowerKeyBehaviorInFocusedWindow;
+
import android.Manifest.permission;
import android.annotation.CallbackExecutor;
import android.annotation.FlaggedApi;
@@ -4464,6 +4467,29 @@ public interface WindowManager extends ViewManager {
*/
public static final int INPUT_FEATURE_SENSITIVE_FOR_PRIVACY = 1 << 3;
+ /**
+ * Input feature used to indicate that the system should send power key events to this
+ * window when it's in the foreground. The window can override the double press power key
+ * gesture behavior.
+ *
+ * A double press gesture is defined as two
+ * {@link KeyEvent.Callback#onKeyDown(int, KeyEvent)} events within a time span defined by
+ * {@link ViewConfiguration#getMultiPressTimeout()}.
+ *
+ * Note: While the window may receive all power key {@link KeyEvent}s, it can only
+ * override the double press gesture behavior. The system will perform default behavior for
+ * single, long-press and other multi-press gestures, regardless of if the app handles the
+ * key or not.
+ *
+ * To override the default behavior for double press, the app must return true for the
+ * second {@link KeyEvent.Callback#onKeyDown(int, KeyEvent)}. If the app returns false, the
+ * system behavior will be performed for double press.
+ * @hide
+ */
+ @RequiresPermission(permission.OVERRIDE_SYSTEM_KEY_BEHAVIOR_IN_FOCUSED_WINDOW)
+ public static final int
+ INPUT_FEATURE_RECEIVE_POWER_KEY_DOUBLE_PRESS = 1 << 4;
+
/**
* An internal annotation for flags that can be specified to {@link #inputFeatures}.
*
@@ -4477,6 +4503,7 @@ public interface WindowManager extends ViewManager {
INPUT_FEATURE_DISABLE_USER_ACTIVITY,
INPUT_FEATURE_SPY,
INPUT_FEATURE_SENSITIVE_FOR_PRIVACY,
+ INPUT_FEATURE_RECEIVE_POWER_KEY_DOUBLE_PRESS
})
public @interface InputFeatureFlags {
}
@@ -4765,6 +4792,44 @@ public interface WindowManager extends ViewManager {
privateFlags |= PRIVATE_FLAG_FIT_INSETS_CONTROLLED;
}
+ /**
+ * Specifies if the system should send power key events to this window when it's in the
+ * foreground, with only the double tap gesture behavior being overrideable.
+ *
+ * @param enabled if true, the system should send power key events to this window when it's
+ * in the foreground, with only the power key double tap gesture being
+ * overrideable.
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(permission.OVERRIDE_SYSTEM_KEY_BEHAVIOR_IN_FOCUSED_WINDOW)
+ @FlaggedApi(FLAG_OVERRIDE_POWER_KEY_BEHAVIOR_IN_FOCUSED_WINDOW)
+ public void setReceivePowerKeyDoublePressEnabled(boolean enabled) {
+ if (enabled) {
+ inputFeatures
+ |= INPUT_FEATURE_RECEIVE_POWER_KEY_DOUBLE_PRESS;
+ } else {
+ inputFeatures
+ &= ~INPUT_FEATURE_RECEIVE_POWER_KEY_DOUBLE_PRESS;
+ }
+ }
+
+ /**
+ * Returns whether or not the system should send power key events to this window when it's
+ * in the foreground, with only the double tap gesture being overrideable.
+ *
+ * @return if the system should send power key events to this window when it's in the
+ * foreground, with only the double tap gesture being overrideable.
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(permission.OVERRIDE_SYSTEM_KEY_BEHAVIOR_IN_FOCUSED_WINDOW)
+ @FlaggedApi(FLAG_OVERRIDE_POWER_KEY_BEHAVIOR_IN_FOCUSED_WINDOW)
+ public boolean isReceivePowerKeyDoublePressEnabled() {
+ return (inputFeatures
+ & INPUT_FEATURE_RECEIVE_POWER_KEY_DOUBLE_PRESS) != 0;
+ }
+
/**
* Specifies that the window should be considered a trusted system overlay. Trusted system
* overlays are ignored when considering whether windows are obscured during input
@@ -6157,6 +6222,16 @@ public interface WindowManager extends ViewManager {
inputFeatures &= ~INPUT_FEATURE_SPY;
features.add("INPUT_FEATURE_SPY");
}
+ if (overridePowerKeyBehaviorInFocusedWindow()) {
+ if ((inputFeatures
+ & INPUT_FEATURE_RECEIVE_POWER_KEY_DOUBLE_PRESS)
+ != 0) {
+ inputFeatures
+ &=
+ ~INPUT_FEATURE_RECEIVE_POWER_KEY_DOUBLE_PRESS;
+ features.add("INPUT_FEATURE_RECEIVE_POWER_KEY_DOUBLE_PRESS");
+ }
+ }
if (inputFeatures != 0) {
features.add(Integer.toHexString(inputFeatures));
}
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index df0c5a34e9923d60bfd374e8ba7ffab62a63e870..8a10979eb3c9f03d5d87bf09b1476fabe3980b5f 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -6540,6 +6540,15 @@ public class AccessibilityNodeInfo implements Parcelable {
* Class with information if a node is a range.
*/
public static final class RangeInfo {
+ /** @hide */
+ @IntDef(prefix = { "RANGE_TYPE_" }, value = {
+ RANGE_TYPE_INT,
+ RANGE_TYPE_FLOAT,
+ RANGE_TYPE_PERCENT,
+ RANGE_TYPE_INDETERMINATE
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface RangeType {}
/** Range type: integer. */
public static final int RANGE_TYPE_INT = 0;
@@ -6588,7 +6597,7 @@ public class AccessibilityNodeInfo implements Parcelable {
* @param current The current value.
*/
@Deprecated
- public static RangeInfo obtain(int type, float min, float max, float current) {
+ public static RangeInfo obtain(@RangeType int type, float min, float max, float current) {
return new RangeInfo(type, min, max, current);
}
@@ -6602,7 +6611,7 @@ public class AccessibilityNodeInfo implements Parcelable {
* maximum.
* @param current The current value.
*/
- public RangeInfo(int type, float min, float max, float current) {
+ public RangeInfo(@RangeType int type, float min, float max, float current) {
mType = type;
mMin = min;
mMax = max;
@@ -6618,6 +6627,7 @@ public class AccessibilityNodeInfo implements Parcelable {
* @see #RANGE_TYPE_FLOAT
* @see #RANGE_TYPE_PERCENT
*/
+ @RangeType
public int getType() {
return mType;
}
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index 1de0474182dd3a4a9df452a1482070fd953fc3c4..60e528c5fb5875224ca7e3f8298425bcf9419f60 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -26,6 +26,7 @@ import static android.service.autofill.FillRequest.FLAG_SUPPORTS_FILL_DIALOG;
import static android.service.autofill.FillRequest.FLAG_VIEW_NOT_FOCUSED;
import static android.service.autofill.FillRequest.FLAG_VIEW_REQUESTS_CREDMAN_SERVICE;
import static android.service.autofill.Flags.FLAG_FILL_DIALOG_IMPROVEMENTS;
+import static android.service.autofill.Flags.improveFillDialogAconfig;
import static android.service.autofill.Flags.relayoutFix;
import static android.view.ContentInfo.SOURCE_AUTOFILL;
import static android.view.autofill.Helper.sDebug;
@@ -787,6 +788,11 @@ public final class AutofillManager {
private AutofillStateFingerprint mAutofillStateFingerprint;
+ /**
+ * Whether improveFillDialog feature is enabled or not.
+ */
+ private boolean mImproveFillDialogEnabled;
+
/** @hide */
public interface AutofillClient {
/**
@@ -1017,6 +1023,17 @@ public final class AutofillManager {
mRelayoutFix = relayoutFix() && AutofillFeatureFlags.enableRelayoutFixes();
mRelativePositionForRelayout = AutofillFeatureFlags.enableRelativeLocationForRelayout();
mIsCredmanIntegrationEnabled = Flags.autofillCredmanIntegration();
+ mImproveFillDialogEnabled =
+ improveFillDialogAconfig() && AutofillFeatureFlags.isImproveFillDialogEnabled();
+ }
+
+ /**
+ * Whether improvement to fill dialog is enabled.
+ *
+ * @hide
+ */
+ public boolean isImproveFillDialogEnabled() {
+ return mImproveFillDialogEnabled;
}
/**
@@ -1679,6 +1696,11 @@ public final class AutofillManager {
private void notifyViewReadyInner(AutofillId id, @Nullable String[] autofillHints,
boolean isCredmanRequested) {
+ if (isImproveFillDialogEnabled() && !isCredmanRequested) {
+ // We do not want to send pre-trigger request.
+ // TODO(b/377868687): verify if we can remove the flow for isCredmanRequested too.
+ return;
+ }
if (sDebug) {
Log.d(TAG, "notifyViewReadyInner:" + id);
}
@@ -2045,6 +2067,34 @@ public final class AutofillManager {
mEnteredIds.add(id);
}
+ /**
+ * Notify autofill system that IME animation has started
+ * @param startTimeMs start time as measured by SystemClock.elapsedRealtime()
+ */
+ void notifyImeAnimationStart(long startTimeMs) {
+ try {
+ mService.notifyImeAnimationStart(mSessionId, startTimeMs, mContext.getUserId());
+ } catch (RemoteException e) {
+ // The failure could be a consequence of something going wrong on the
+ // server side. Just log the exception and move-on.
+ Log.w(TAG, "notifyImeAnimationStart(): RemoteException caught but ignored " + e);
+ }
+ }
+
+ /**
+ * Notify autofill system that IME animation has ended
+ * @param endTimeMs end time as measured by SystemClock.elapsedRealtime()
+ */
+ void notifyImeAnimationEnd(long endTimeMs) {
+ try {
+ mService.notifyImeAnimationEnd(mSessionId, endTimeMs, mContext.getUserId());
+ } catch (RemoteException e) {
+ // The failure could be a consequence of something going wrong on the
+ // server side. Just log the exception and move-on.
+ Log.w(TAG, "notifyImeAnimationStart(): RemoteException caught but ignored " + e);
+ }
+ }
+
/**
* Called when a virtual view that supports autofill is exited.
*
@@ -4050,6 +4100,10 @@ public final class AutofillManager {
@FlaggedApi(FLAG_FILL_DIALOG_IMPROVEMENTS)
@Deprecated
public boolean showAutofillDialog(@NonNull View view) {
+ if (isImproveFillDialogEnabled()) {
+ Log.i(TAG, "showAutofillDialog() return false due to improve fill dialog");
+ return false;
+ }
Objects.requireNonNull(view);
if (shouldShowAutofillDialog(view, view.getAutofillId())) {
mShowAutofillDialogCalled = true;
@@ -4093,6 +4147,10 @@ public final class AutofillManager {
@FlaggedApi(FLAG_FILL_DIALOG_IMPROVEMENTS)
@Deprecated
public boolean showAutofillDialog(@NonNull View view, int virtualId) {
+ if (isImproveFillDialogEnabled()) {
+ Log.i(TAG, "showAutofillDialog() return false due to improve fill dialog");
+ return false;
+ }
Objects.requireNonNull(view);
if (shouldShowAutofillDialog(view, getAutofillId(view, virtualId))) {
mShowAutofillDialogCalled = true;
@@ -4117,7 +4175,7 @@ public final class AutofillManager {
return false;
}
- if (getImeStateFlag(view) == FLAG_IME_SHOWING) {
+ if (getImeStateFlag(view) == FLAG_IME_SHOWING && !isImproveFillDialogEnabled()) {
// IME is showing
return false;
}
diff --git a/core/java/android/view/autofill/IAutoFillManager.aidl b/core/java/android/view/autofill/IAutoFillManager.aidl
index f67405f7c1e421e137fee7f7ebeb85be9267df5e..28f8577beed79fe5ca435a48b3649e74c7b7bbad 100644
--- a/core/java/android/view/autofill/IAutoFillManager.aidl
+++ b/core/java/android/view/autofill/IAutoFillManager.aidl
@@ -70,4 +70,6 @@ oneway interface IAutoFillManager {
void notifyNotExpiringResponseDuringAuth(int sessionId, int userId);
void notifyViewEnteredIgnoredDuringAuthCount(int sessionId, int userId);
void setAutofillIdsAttemptedForRefill(int sessionId, in List ids, int userId);
+ void notifyImeAnimationStart(int sessionId, long startTimeMs, int userId);
+ void notifyImeAnimationEnd(int sessionId, long endTimeMs, int userId);
}
diff --git a/core/java/android/view/flags/scroll_capture.aconfig b/core/java/android/view/flags/scroll_capture.aconfig
index 9080b1669ed5c487c85b0e0b0218bf962501fea9..6dccbad3b6a98aa29da9a681d1e3a5e5a36f5eb4 100644
--- a/core/java/android/view/flags/scroll_capture.aconfig
+++ b/core/java/android/view/flags/scroll_capture.aconfig
@@ -11,3 +11,12 @@ flag {
}
}
+flag {
+ name: "scroll_capture_relax_scroll_view_criteria"
+ namespace: "systemui"
+ description: "Treat all custom ViewGroups which support scrollTo as ScrollView"
+ bug: "189827634"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
diff --git a/core/java/android/view/flags/scroll_feedback_flags.aconfig b/core/java/android/view/flags/scroll_feedback_flags.aconfig
index ebda4d472b0d91b739c6d199d7aafceaf4cc2fdb..ddf6ff11a83a0ca08f9aaa3710d7db7f66354872 100644
--- a/core/java/android/view/flags/scroll_feedback_flags.aconfig
+++ b/core/java/android/view/flags/scroll_feedback_flags.aconfig
@@ -17,10 +17,10 @@ flag {
}
flag {
- namespace: "toolkit"
- name: "enable_touch_scroll_feedback"
+ namespace: "wear_frameworks"
+ name: "enable_scroll_feedback_for_touch"
description: "Enables touchscreen haptic scroll feedback"
- bug: "331830899"
+ bug: "382135785"
is_fixed_read_only: true
}
diff --git a/core/java/android/view/flags/view_flags.aconfig b/core/java/android/view/flags/view_flags.aconfig
index 641b01054acb28e0aa26a730f63731296222f989..f6fdec94c33252d986be7615baa31e4d8a956e3b 100644
--- a/core/java/android/view/flags/view_flags.aconfig
+++ b/core/java/android/view/flags/view_flags.aconfig
@@ -142,4 +142,12 @@ flag {
description: "Recover from buffer stuffing when SurfaceFlinger misses a frame"
bug: "294922229"
is_fixed_read_only: true
-}
\ No newline at end of file
+}
+
+flag {
+ name: "date_time_view_relative_time_display_configs"
+ namespace: "systemui"
+ description: "Enables DateTimeView to use additional display configurations for relative time"
+ bug: "364653005"
+ is_fixed_read_only: true
+}
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 5dd29b26730de085ed7e1b80d7bad1b2dc1c94fa..6d89f3d89077881247b5e1adfd119b5b5d3e5fba 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -946,11 +946,16 @@ public final class InputMethodManager {
if (state == WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN) {
// when losing focus (e.g., by going to another window), we reset the
// requestedVisibleTypes of WindowInsetsController by hiding the IME
+ final var statsToken = ImeTracker.forLogging().onStart(
+ ImeTracker.TYPE_HIDE, ImeTracker.ORIGIN_CLIENT,
+ SoftInputShowHideReason.REASON_HIDE_WINDOW_LOST_FOCUS,
+ false /* fromUser */);
if (DEBUG) {
Log.d(TAG, "onWindowLostFocus, hiding IME because "
+ "of STATE_ALWAYS_HIDDEN");
}
- mCurRootView.getInsetsController().hide(WindowInsets.Type.ime());
+ mCurRootView.getInsetsController().hide(WindowInsets.Type.ime(),
+ false /* fromIme */, statsToken);
}
}
diff --git a/core/java/android/view/textclassifier/TextClassificationManager.java b/core/java/android/view/textclassifier/TextClassificationManager.java
index b606340b77a748e1eb23f636070031b2c031ee80..b9293242e4ff52c44eedf49b4b6b0d027e9706d2 100644
--- a/core/java/android/view/textclassifier/TextClassificationManager.java
+++ b/core/java/android/view/textclassifier/TextClassificationManager.java
@@ -16,13 +16,20 @@
package android.view.textclassifier;
+import static android.Manifest.permission.ACCESS_TEXT_CLASSIFIER_BY_TYPE;
+
+import android.annotation.FlaggedApi;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
+import android.content.pm.PackageManager;
import android.os.Build;
import android.os.ServiceManager;
+import android.permission.flags.Flags;
import android.view.textclassifier.TextClassifier.TextClassifierType;
import com.android.internal.annotations.GuardedBy;
@@ -115,6 +122,29 @@ public final class TextClassificationManager {
}
}
+ /**
+ * Returns a specific type of text classifier.
+ * If the specified text classifier cannot be found, this returns {@link TextClassifier#NO_OP}.
+ *
+ *
+ * @see TextClassifier#CLASSIFIER_TYPE_SELF_PROVIDED
+ * @see TextClassifier#CLASSIFIER_TYPE_DEVICE_DEFAULT
+ * @see TextClassifier#CLASSIFIER_TYPE_ANDROID_DEFAULT
+ * @hide
+ */
+ @SystemApi
+ @NonNull
+ @FlaggedApi(Flags.FLAG_TEXT_CLASSIFIER_CHOICE_API_ENABLED)
+ @RequiresPermission(ACCESS_TEXT_CLASSIFIER_BY_TYPE)
+ public TextClassifier getClassifier(@TextClassifierType int type) {
+ if (mContext.checkCallingOrSelfPermission(ACCESS_TEXT_CLASSIFIER_BY_TYPE)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException(
+ "Caller does not have permission " + ACCESS_TEXT_CLASSIFIER_BY_TYPE);
+ }
+ return getTextClassifier(type);
+ }
+
private TextClassificationConstants getSettings() {
synchronized (mLock) {
if (mSettings == null) {
diff --git a/core/java/android/view/textclassifier/TextClassifier.java b/core/java/android/view/textclassifier/TextClassifier.java
index ef5004536354044aa60297481671db8b6adc6fa1..59afdac1bfd702763a58354516db347e0f68816a 100644
--- a/core/java/android/view/textclassifier/TextClassifier.java
+++ b/core/java/android/view/textclassifier/TextClassifier.java
@@ -16,16 +16,20 @@
package android.view.textclassifier;
+import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.StringDef;
+import android.annotation.SuppressLint;
+import android.annotation.SystemApi;
import android.annotation.WorkerThread;
import android.os.LocaleList;
import android.os.Looper;
import android.os.Parcel;
import android.os.Parcelable;
+import android.permission.flags.Flags;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.style.URLSpan;
@@ -63,11 +67,6 @@ public interface TextClassifier {
/** @hide */
String LOG_TAG = "androidtc";
-
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(value = {LOCAL, SYSTEM, DEFAULT_SYSTEM})
- @interface TextClassifierType {} // TODO: Expose as system APIs.
/** Specifies a TextClassifier that runs locally in the app's process. @hide */
int LOCAL = 0;
/** Specifies a TextClassifier that runs in the system process and serves all apps. @hide */
@@ -76,8 +75,33 @@ public interface TextClassifier {
int DEFAULT_SYSTEM = 2;
/** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(value = {CLASSIFIER_TYPE_SELF_PROVIDED, CLASSIFIER_TYPE_DEVICE_DEFAULT,
+ CLASSIFIER_TYPE_ANDROID_DEFAULT})
+ @interface TextClassifierType {
+ }
+ /** Specifies a TextClassifier that runs locally in the app's process. @hide */
+ @FlaggedApi(Flags.FLAG_TEXT_CLASSIFIER_CHOICE_API_ENABLED)
+ @SystemApi
+ int CLASSIFIER_TYPE_SELF_PROVIDED = LOCAL;
+ /**
+ * Specifies a TextClassifier that is set as the default on this particular device. This may be
+ * the same as CLASSIFIER_TYPE_DEVICE_DEFAULT, unless set otherwise by the device manufacturer.
+ * @hide
+ */
+ @FlaggedApi(Flags.FLAG_TEXT_CLASSIFIER_CHOICE_API_ENABLED)
+ @SystemApi
+ int CLASSIFIER_TYPE_DEVICE_DEFAULT = SYSTEM;
+ /** Specifies the TextClassifier that is provided by Android. @hide */
+ @FlaggedApi(Flags.FLAG_TEXT_CLASSIFIER_CHOICE_API_ENABLED)
+ @SystemApi
+ int CLASSIFIER_TYPE_ANDROID_DEFAULT = DEFAULT_SYSTEM;
+
+ /** @hide */
+ @SuppressLint("SwitchIntDef")
static String typeToString(@TextClassifierType int type) {
- switch (type) {
+ int unflaggedType = type;
+ switch (unflaggedType) {
case LOCAL:
return "Local";
case SYSTEM:
@@ -108,6 +132,9 @@ public interface TextClassifier {
String TYPE_DATE_TIME = "datetime";
/** Flight number in IATA format. */
String TYPE_FLIGHT_NUMBER = "flight";
+ /** Onetime password. */
+ @FlaggedApi(Flags.FLAG_TEXT_CLASSIFIER_CHOICE_API_ENABLED)
+ String TYPE_OTP = "otp";
/**
* Word that users may be interested to look up for meaning.
* @hide
@@ -126,7 +153,8 @@ public interface TextClassifier {
TYPE_DATE,
TYPE_DATE_TIME,
TYPE_FLIGHT_NUMBER,
- TYPE_DICTIONARY
+ TYPE_DICTIONARY,
+ TYPE_OTP
})
@interface EntityType {}
@@ -197,6 +225,16 @@ public interface TextClassifier {
*/
String EXTRA_FROM_TEXT_CLASSIFIER = "android.view.textclassifier.extra.FROM_TEXT_CLASSIFIER";
+ /**
+ * Extra specifying the package name of the app from which the text to be classified originated.
+ *
+ * For example, a notification assistant might use TextClassifier, but the notification
+ * content could originate from a different app. This key allows you to provide
+ * the package name of that source app.
+ */
+ @FlaggedApi(Flags.FLAG_TEXT_CLASSIFIER_CHOICE_API_ENABLED)
+ String EXTRA_TEXT_ORIGIN_PACKAGE = "android.view.textclassifier.extra.TEXT_ORIGIN_PACKAGE";
+
/**
* Returns suggested text selection start and end indices, recognized entity types, and their
* associated confidence scores. The entity types are ordered from highest to lowest scoring.
diff --git a/core/java/android/webkit/EventLogTags.logtags b/core/java/android/webkit/EventLogTags.logtags
index a90aebd71716202dfe2678c5e26894629eb59fa7..8bbd5a9d0246a1bd95080f070d3705bdb995f889 100644
--- a/core/java/android/webkit/EventLogTags.logtags
+++ b/core/java/android/webkit/EventLogTags.logtags
@@ -1,4 +1,4 @@
-# See system/core/logcat/event.logtags for a description of the format of this file.
+# See system/logging/logcat/event.logtags for a description of the format of this file.
option java_package android.webkit;
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 3c854ea4fad4a089173e0fada4a5a2d24ec805fe..fc3014a0eaec21d2a73712de981d2d8304b92d83 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -16,7 +16,7 @@
package android.widget;
-import static android.view.flags.Flags.enableTouchScrollFeedback;
+import static android.view.flags.Flags.enableScrollFeedbackForTouch;
import static android.view.flags.Flags.scrollFeedbackApi;
import static android.view.flags.Flags.viewVelocityApi;
@@ -3737,7 +3737,7 @@ public abstract class AbsListView extends AdapterView implements Te
atEdge = trackMotionScroll(deltaY, incrementalDeltaY);
// TODO: b/360198915 - Add unit testing for using ScrollFeedbackProvider
- if (enableTouchScrollFeedback()) {
+ if (vtev != null && enableScrollFeedbackForTouch()) {
initHapticScrollFeedbackProviderIfNotExists();
mHapticScrollFeedbackProvider.onScrollProgress(
vtev.getDeviceId(), vtev.getSource(), MotionEvent.AXIS_Y,
@@ -3779,7 +3779,7 @@ public abstract class AbsListView extends AdapterView implements Te
mTouchMode = TOUCH_MODE_OVERSCROLL;
}
- if (enableTouchScrollFeedback()) {
+ if (vtev != null && enableScrollFeedbackForTouch()) {
initHapticScrollFeedbackProviderIfNotExists();
mHapticScrollFeedbackProvider.onScrollLimit(
vtev.getDeviceId(), vtev.getSource(),
diff --git a/core/java/android/widget/DateTimeView.java b/core/java/android/widget/DateTimeView.java
index 41ff69d6fb5f8a1f9d7c24fb9aee9bf6cbb1baf3..143b4b770984e6179750b11b439f056e32e0f8e1 100644
--- a/core/java/android/widget/DateTimeView.java
+++ b/core/java/android/widget/DateTimeView.java
@@ -21,6 +21,7 @@ import static android.text.format.DateUtils.HOUR_IN_MILLIS;
import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
import static android.text.format.DateUtils.YEAR_IN_MILLIS;
+import android.annotation.IntDef;
import android.app.ActivityThread;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.BroadcastReceiver;
@@ -41,6 +42,8 @@ import android.widget.RemoteViews.RemoteView;
import com.android.internal.R;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.text.DateFormat;
import java.time.Instant;
import java.time.LocalDate;
@@ -70,6 +73,23 @@ public class DateTimeView extends TextView {
private static final int SHOW_TIME = 0;
private static final int SHOW_MONTH_DAY_YEAR = 1;
+ /** @hide */
+ @IntDef(value = {UNIT_DISPLAY_LENGTH_SHORTEST, UNIT_DISPLAY_LENGTH_MEDIUM})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface UnitDisplayLength {}
+ public static final int UNIT_DISPLAY_LENGTH_SHORTEST = 0;
+ public static final int UNIT_DISPLAY_LENGTH_MEDIUM = 1;
+
+ /** @hide */
+ @IntDef(flag = true, value = {DISAMBIGUATION_TEXT_PAST, DISAMBIGUATION_TEXT_FUTURE})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface DisambiguationTextMask {}
+ public static final int DISAMBIGUATION_TEXT_PAST = 0x01;
+ public static final int DISAMBIGUATION_TEXT_FUTURE = 0x02;
+
+ private final boolean mCanUseRelativeTimeDisplayConfigs =
+ android.view.flags.Flags.dateTimeViewRelativeTimeDisplayConfigs();
+
private long mTimeMillis;
// The LocalDateTime equivalent of mTimeMillis but truncated to minute, i.e. no seconds / nanos.
private LocalDateTime mLocalTime;
@@ -81,6 +101,8 @@ public class DateTimeView extends TextView {
private static final ThreadLocal sReceiverInfo = new ThreadLocal();
private String mNowText;
private boolean mShowRelativeTime;
+ private int mRelativeTimeDisambiguationTextMask;
+ private int mRelativeTimeUnitDisplayLength = UNIT_DISPLAY_LENGTH_SHORTEST;
public DateTimeView(Context context) {
this(context, null);
@@ -89,20 +111,23 @@ public class DateTimeView extends TextView {
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public DateTimeView(Context context, AttributeSet attrs) {
super(context, attrs);
- final TypedArray a = context.obtainStyledAttributes(attrs,
- com.android.internal.R.styleable.DateTimeView, 0,
- 0);
-
- final int N = a.getIndexCount();
- for (int i = 0; i < N; i++) {
- int attr = a.getIndex(i);
- switch (attr) {
- case R.styleable.DateTimeView_showRelative:
- boolean relative = a.getBoolean(i, false);
- setShowRelativeTime(relative);
- break;
- }
+ final TypedArray a = context.obtainStyledAttributes(
+ attrs, R.styleable.DateTimeView, 0, 0);
+
+ setShowRelativeTime(a.getBoolean(R.styleable.DateTimeView_showRelative, false));
+ if (mCanUseRelativeTimeDisplayConfigs) {
+ setRelativeTimeDisambiguationTextMask(
+ a.getInt(
+ R.styleable.DateTimeView_relativeTimeDisambiguationText,
+ // The original implementation showed disambiguation text for future
+ // times only, so continue with that default.
+ DISAMBIGUATION_TEXT_FUTURE));
+ setRelativeTimeUnitDisplayLength(
+ a.getInt(
+ R.styleable.DateTimeView_relativeTimeUnitDisplayLength,
+ UNIT_DISPLAY_LENGTH_SHORTEST));
}
+
a.recycle();
}
@@ -150,6 +175,29 @@ public class DateTimeView extends TextView {
update();
}
+ /** See {@link R.styleable.DateTimeView_relativeTimeDisambiguationText}. */
+ @android.view.RemotableViewMethod
+ public void setRelativeTimeDisambiguationTextMask(
+ @DisambiguationTextMask int disambiguationTextMask) {
+ if (!mCanUseRelativeTimeDisplayConfigs) {
+ return;
+ }
+ mRelativeTimeDisambiguationTextMask = disambiguationTextMask;
+ updateNowText();
+ update();
+ }
+
+ /** See {@link R.styleable.DateTimeView_relativeTimeUnitDisplayLength}. */
+ @android.view.RemotableViewMethod
+ public void setRelativeTimeUnitDisplayLength(@UnitDisplayLength int unitDisplayLength) {
+ if (!mCanUseRelativeTimeDisplayConfigs) {
+ return;
+ }
+ mRelativeTimeUnitDisplayLength = unitDisplayLength;
+ updateNowText();
+ update();
+ }
+
/**
* Returns whether this view shows relative time
*
@@ -264,17 +312,11 @@ public class DateTimeView extends TextView {
return;
} else if (duration < HOUR_IN_MILLIS) {
count = (int)(duration / MINUTE_IN_MILLIS);
- result = getContext().getResources().getString(past
- ? com.android.internal.R.string.duration_minutes_shortest
- : com.android.internal.R.string.duration_minutes_shortest_future,
- count);
+ result = getContext().getResources().getString(getMinutesStringId(past), count);
millisIncrease = MINUTE_IN_MILLIS;
} else if (duration < DAY_IN_MILLIS) {
count = (int)(duration / HOUR_IN_MILLIS);
- result = getContext().getResources().getString(past
- ? com.android.internal.R.string.duration_hours_shortest
- : com.android.internal.R.string.duration_hours_shortest_future,
- count);
+ result = getContext().getResources().getString(getHoursStringId(past), count);
millisIncrease = HOUR_IN_MILLIS;
} else if (duration < YEAR_IN_MILLIS) {
// In weird cases it can become 0 because of daylight savings
@@ -283,10 +325,7 @@ public class DateTimeView extends TextView {
LocalDateTime localNow = toLocalDateTime(now, zoneId);
count = Math.max(Math.abs(dayDistance(localDateTime, localNow)), 1);
- result = getContext().getResources().getString(past
- ? com.android.internal.R.string.duration_days_shortest
- : com.android.internal.R.string.duration_days_shortest_future,
- count);
+ result = getContext().getResources().getString(getDaysStringId(past), count);
if (past || count != 1) {
mUpdateTimeMillis = computeNextMidnight(localNow, zoneId);
millisIncrease = -1;
@@ -296,10 +335,7 @@ public class DateTimeView extends TextView {
} else {
count = (int)(duration / YEAR_IN_MILLIS);
- result = getContext().getResources().getString(past
- ? com.android.internal.R.string.duration_years_shortest
- : com.android.internal.R.string.duration_years_shortest_future,
- count);
+ result = getContext().getResources().getString(getYearsStringId(past), count);
millisIncrease = YEAR_IN_MILLIS;
}
if (millisIncrease != -1) {
@@ -312,6 +348,139 @@ public class DateTimeView extends TextView {
maybeSetText(result);
}
+ private int getMinutesStringId(boolean past) {
+ if (!mCanUseRelativeTimeDisplayConfigs) {
+ return past
+ ? com.android.internal.R.string.duration_minutes_shortest
+ : com.android.internal.R.string.duration_minutes_shortest_future;
+ }
+
+ if (mRelativeTimeUnitDisplayLength == UNIT_DISPLAY_LENGTH_SHORTEST) {
+ if (past && (mRelativeTimeDisambiguationTextMask & DISAMBIGUATION_TEXT_PAST) != 0) {
+ // "1m ago"
+ return com.android.internal.R.string.duration_minutes_shortest_past;
+ } else if (!past
+ && (mRelativeTimeDisambiguationTextMask & DISAMBIGUATION_TEXT_FUTURE) != 0) {
+ // "in 1m"
+ return com.android.internal.R.string.duration_minutes_shortest_future;
+ } else {
+ // "1m"
+ return com.android.internal.R.string.duration_minutes_shortest;
+ }
+ } else { // UNIT_DISPLAY_LENGTH_MEDIUM
+ if (past && (mRelativeTimeDisambiguationTextMask & DISAMBIGUATION_TEXT_PAST) != 0) {
+ // "1min ago"
+ return com.android.internal.R.string.duration_minutes_medium_past;
+ } else if (!past
+ && (mRelativeTimeDisambiguationTextMask & DISAMBIGUATION_TEXT_FUTURE) != 0) {
+ // "in 1min"
+ return com.android.internal.R.string.duration_minutes_medium_future;
+ } else {
+ // "1min"
+ return com.android.internal.R.string.duration_minutes_medium;
+ }
+ }
+ }
+
+ private int getHoursStringId(boolean past) {
+ if (!mCanUseRelativeTimeDisplayConfigs) {
+ return past
+ ? com.android.internal.R.string.duration_hours_shortest
+ : com.android.internal.R.string.duration_hours_shortest_future;
+ }
+ if (mRelativeTimeUnitDisplayLength == UNIT_DISPLAY_LENGTH_SHORTEST) {
+ if (past && (mRelativeTimeDisambiguationTextMask & DISAMBIGUATION_TEXT_PAST) != 0) {
+ // "1h ago"
+ return com.android.internal.R.string.duration_hours_shortest_past;
+ } else if (!past
+ && (mRelativeTimeDisambiguationTextMask & DISAMBIGUATION_TEXT_FUTURE) != 0) {
+ // "in 1h"
+ return com.android.internal.R.string.duration_hours_shortest_future;
+ } else {
+ // "1h"
+ return com.android.internal.R.string.duration_hours_shortest;
+ }
+ } else { // UNIT_DISPLAY_LENGTH_MEDIUM
+ if (past && (mRelativeTimeDisambiguationTextMask & DISAMBIGUATION_TEXT_PAST) != 0) {
+ // "1hr ago"
+ return com.android.internal.R.string.duration_hours_medium_past;
+ } else if (!past
+ && (mRelativeTimeDisambiguationTextMask & DISAMBIGUATION_TEXT_FUTURE) != 0) {
+ // "in 1hr"
+ return com.android.internal.R.string.duration_hours_medium_future;
+ } else {
+ // "1hr"
+ return com.android.internal.R.string.duration_hours_medium;
+ }
+ }
+ }
+
+ private int getDaysStringId(boolean past) {
+ if (!mCanUseRelativeTimeDisplayConfigs) {
+ return past
+ ? com.android.internal.R.string.duration_days_shortest
+ : com.android.internal.R.string.duration_days_shortest_future;
+ }
+ if (mRelativeTimeUnitDisplayLength == UNIT_DISPLAY_LENGTH_SHORTEST) {
+ if (past && (mRelativeTimeDisambiguationTextMask & DISAMBIGUATION_TEXT_PAST) != 0) {
+ // "1d ago"
+ return com.android.internal.R.string.duration_days_shortest_past;
+ } else if (!past
+ && (mRelativeTimeDisambiguationTextMask & DISAMBIGUATION_TEXT_FUTURE) != 0) {
+ // "in 1d"
+ return com.android.internal.R.string.duration_days_shortest_future;
+ } else {
+ // "1d"
+ return com.android.internal.R.string.duration_days_shortest;
+ }
+ } else { // UNIT_DISPLAY_LENGTH_MEDIUM
+ if (past && (mRelativeTimeDisambiguationTextMask & DISAMBIGUATION_TEXT_PAST) != 0) {
+ // "1d ago"
+ return com.android.internal.R.string.duration_days_medium_past;
+ } else if (!past
+ && (mRelativeTimeDisambiguationTextMask & DISAMBIGUATION_TEXT_FUTURE) != 0) {
+ // "in 1d"
+ return com.android.internal.R.string.duration_days_medium_future;
+ } else {
+ // "1d"
+ return com.android.internal.R.string.duration_days_medium;
+ }
+ }
+ }
+
+ private int getYearsStringId(boolean past) {
+ if (!mCanUseRelativeTimeDisplayConfigs) {
+ return past
+ ? com.android.internal.R.string.duration_years_shortest
+ : com.android.internal.R.string.duration_years_shortest_future;
+ }
+ if (mRelativeTimeUnitDisplayLength == UNIT_DISPLAY_LENGTH_SHORTEST) {
+ if (past && (mRelativeTimeDisambiguationTextMask & DISAMBIGUATION_TEXT_PAST) != 0) {
+ // "1y ago"
+ return com.android.internal.R.string.duration_years_shortest_past;
+ } else if (!past
+ && (mRelativeTimeDisambiguationTextMask & DISAMBIGUATION_TEXT_FUTURE) != 0) {
+ // "in 1y"
+ return com.android.internal.R.string.duration_years_shortest_future;
+ } else {
+ // "1y"
+ return com.android.internal.R.string.duration_years_shortest;
+ }
+ } else { // UNIT_DISPLAY_LENGTH_MEDIUM
+ if (past && (mRelativeTimeDisambiguationTextMask & DISAMBIGUATION_TEXT_PAST) != 0) {
+ // "1y ago"
+ return com.android.internal.R.string.duration_years_medium_past;
+ } else if (!past
+ && (mRelativeTimeDisambiguationTextMask & DISAMBIGUATION_TEXT_FUTURE) != 0) {
+ // "in 1y"
+ return com.android.internal.R.string.duration_years_medium_future;
+ } else {
+ // "1y"
+ return com.android.internal.R.string.duration_years_medium;
+ }
+ }
+ }
+
/**
* Sets text only if the text has actually changed. This prevents needles relayouts of this
* view when set to wrap_content.
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 7e3b904444292ac97eadffa861c77794d9fe94ae..9c2833b91a2b85f01ae4342aed5aeed33e6a0c57 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -47,6 +47,7 @@ import android.app.LoadedApk;
import android.app.PendingIntent;
import android.app.RemoteInput;
import android.appwidget.AppWidgetHostView;
+import android.appwidget.AppWidgetManager.ServiceCollectionCache;
import android.appwidget.flags.Flags;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.ComponentName;
@@ -54,7 +55,6 @@ import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.content.IntentSender;
-import android.content.ServiceConnection;
import android.content.om.FabricatedOverlay;
import android.content.om.OverlayInfo;
import android.content.om.OverlayManager;
@@ -82,7 +82,6 @@ import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
import android.os.CancellationSignal;
-import android.os.IBinder;
import android.os.Parcel;
import android.os.ParcelFileDescriptor;
import android.os.Parcelable;
@@ -127,6 +126,7 @@ import android.widget.CompoundButton.OnCheckedChangeListener;
import com.android.internal.R;
import com.android.internal.util.Preconditions;
import com.android.internal.widget.IRemoteViewsFactory;
+import com.android.internal.widget.remotecompose.core.CoreDocument;
import com.android.internal.widget.remotecompose.core.operations.Theme;
import com.android.internal.widget.remotecompose.player.RemoteComposeDocument;
import com.android.internal.widget.remotecompose.player.RemoteComposePlayer;
@@ -1390,8 +1390,10 @@ public class RemoteViews implements Parcelable, Filter {
/**
* @hide
*/
- public CompletableFuture collectAllIntents(int bitmapSizeLimit) {
- return mCollectionCache.collectAllIntentsNoComplete(this, bitmapSizeLimit);
+ public CompletableFuture collectAllIntents(int bitmapSizeLimit,
+ @NonNull ServiceCollectionCache collectionCache) {
+ return mCollectionCache.collectAllIntentsNoComplete(this, bitmapSizeLimit,
+ collectionCache);
}
private class RemoteCollectionCache {
@@ -1445,7 +1447,8 @@ public class RemoteViews implements Parcelable, Filter {
}
public @NonNull CompletableFuture collectAllIntentsNoComplete(
- @NonNull RemoteViews inViews, int bitmapSizeLimit) {
+ @NonNull RemoteViews inViews, int bitmapSizeLimit,
+ @NonNull ServiceCollectionCache collectionCache) {
SparseArray idToIntentMapping = new SparseArray<>();
// Collect the number of uinque Intent (which is equal to the number of new connections
// to make) for size allocation and exclude certain collections from being written to
@@ -1477,7 +1480,7 @@ public class RemoteViews implements Parcelable, Filter {
/ numOfIntents;
return connectAllUniqueIntents(individualSize, individualBitmapSizeLimit,
- idToIntentMapping);
+ idToIntentMapping, collectionCache);
}
private void collectAllIntentsInternal(@NonNull RemoteViews inViews,
@@ -1543,13 +1546,14 @@ public class RemoteViews implements Parcelable, Filter {
}
private @NonNull CompletableFuture connectAllUniqueIntents(int individualSize,
- int individualBitmapSize, @NonNull SparseArray idToIntentMapping) {
+ int individualBitmapSize, @NonNull SparseArray idToIntentMapping,
+ @NonNull ServiceCollectionCache collectionCache) {
List> intentFutureList = new ArrayList<>();
for (int i = 0; i < idToIntentMapping.size(); i++) {
String currentIntentUri = mIdToUriMapping.get(idToIntentMapping.keyAt(i));
Intent currentIntent = idToIntentMapping.valueAt(i);
intentFutureList.add(getItemsFutureFromIntentWithTimeout(currentIntent,
- individualSize, individualBitmapSize)
+ individualSize, individualBitmapSize, collectionCache)
.thenAccept(items -> {
items.setHierarchyRootData(getHierarchyRootData());
mUriToCollectionMapping.put(currentIntentUri, items);
@@ -1560,7 +1564,8 @@ public class RemoteViews implements Parcelable, Filter {
}
private static CompletableFuture getItemsFutureFromIntentWithTimeout(
- Intent intent, int individualSize, int individualBitmapSize) {
+ Intent intent, int individualSize, int individualBitmapSize,
+ @NonNull ServiceCollectionCache collectionCache) {
if (intent == null) {
Log.e(LOG_TAG, "Null intent received when generating adapter future");
return CompletableFuture.completedFuture(new RemoteCollectionItems
@@ -1580,39 +1585,24 @@ public class RemoteViews implements Parcelable, Filter {
return result;
}
- context.bindService(intent, Context.BindServiceFlags.of(Context.BIND_AUTO_CREATE),
- result.defaultExecutor(), new ServiceConnection() {
- @Override
- public void onServiceConnected(ComponentName componentName,
- IBinder iBinder) {
- RemoteCollectionItems items;
- try {
- items = IRemoteViewsFactory.Stub.asInterface(iBinder)
- .getRemoteCollectionItems(individualSize,
- individualBitmapSize);
- } catch (RemoteException re) {
- items = new RemoteCollectionItems.Builder().build();
- Log.e(LOG_TAG, "Error getting collection items from the"
- + " factory", re);
- } finally {
- context.unbindService(this);
- }
-
- if (items == null) {
- items = new RemoteCollectionItems.Builder().build();
- }
-
- result.complete(items);
- }
+ collectionCache.connectAndConsume(intent, iBinder -> {
+ RemoteCollectionItems items;
+ try {
+ items = IRemoteViewsFactory.Stub.asInterface(iBinder)
+ .getRemoteCollectionItems(individualSize,
+ individualBitmapSize);
+ } catch (RemoteException re) {
+ items = new RemoteCollectionItems.Builder().build();
+ Log.e(LOG_TAG, "Error getting collection items from the"
+ + " factory", re);
+ }
- @Override
- public void onNullBinding(ComponentName name) {
- context.unbindService(this);
- }
+ if (items == null) {
+ items = new RemoteCollectionItems.Builder().build();
+ }
- @Override
- public void onServiceDisconnected(ComponentName componentName) { }
- });
+ result.complete(items);
+ }, result.defaultExecutor());
result.completeOnTimeout(
new RemoteCollectionItems.Builder().build(),
@@ -5825,7 +5815,7 @@ public class RemoteViews implements Parcelable, Filter {
}
try (ByteArrayInputStream is = new ByteArrayInputStream(bytes.get(0))) {
player.setDocument(new RemoteComposeDocument(is));
- player.addClickListener((viewId, metadata) -> {
+ player.addIdActionListener((viewId, metadata) -> {
mActions.forEach(action -> {
if (viewId == action.mViewId
&& action instanceof SetOnClickResponse setOnClickResponse) {
@@ -9829,7 +9819,7 @@ public class RemoteViews implements Parcelable, Filter {
*/
@FlaggedApi(FLAG_DRAW_DATA_PARCEL)
public static long getSupportedVersion() {
- return VERSION;
+ return (long) CoreDocument.getDocumentApiLevel();
}
/**
diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java
index 511c832a4876ff7e71652fe1b85d2a19967315b7..184933fb8288bb081e863a5883702ee49fe7d46c 100644
--- a/core/java/android/widget/ScrollView.java
+++ b/core/java/android/widget/ScrollView.java
@@ -16,7 +16,7 @@
package android.widget;
-import static android.view.flags.Flags.enableTouchScrollFeedback;
+import static android.view.flags.Flags.enableScrollFeedbackForTouch;
import static android.view.flags.Flags.viewVelocityApi;
import android.annotation.ColorInt;
@@ -909,7 +909,7 @@ public class ScrollView extends FrameLayout {
}
// TODO: b/360198915 - Add unit tests.
- if (enableTouchScrollFeedback()) {
+ if (enableScrollFeedbackForTouch()) {
if (hitTopLimit || hitBottomLimit) {
initHapticScrollFeedbackProviderIfNotExists();
mHapticScrollFeedbackProvider.onScrollLimit(vtev.getDeviceId(),
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index d7750bd412a3790dce7a04f3eb9009a1d4518dbe..71a832d84f08a9be1543e166c6a715806eddba75 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -18,6 +18,7 @@ package android.widget;
import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
+import static android.graphics.Paint.NEW_FONT_VARIATION_MANAGEMENT;
import static android.view.ContentInfo.FLAG_CONVERT_TO_PLAIN_TEXT;
import static android.view.ContentInfo.SOURCE_AUTOFILL;
import static android.view.ContentInfo.SOURCE_CLIPBOARD;
@@ -5542,7 +5543,21 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
&& fontVariationSettings.equals(existingSettings))) {
return true;
}
- boolean effective = mTextPaint.setFontVariationSettings(fontVariationSettings);
+
+ final boolean useFontVariationStore = Flags.typefaceRedesignReadonly()
+ && CompatChanges.isChangeEnabled(NEW_FONT_VARIATION_MANAGEMENT);
+ boolean effective;
+ if (useFontVariationStore) {
+ if (mFontWeightAdjustment != 0
+ && mFontWeightAdjustment != Configuration.FONT_WEIGHT_ADJUSTMENT_UNDEFINED) {
+ mTextPaint.setFontVariationSettings(fontVariationSettings, mFontWeightAdjustment);
+ } else {
+ mTextPaint.setFontVariationSettings(fontVariationSettings);
+ }
+ effective = true;
+ } else {
+ effective = mTextPaint.setFontVariationSettings(fontVariationSettings);
+ }
if (effective && mLayout != null) {
nullLayouts();
@@ -10114,6 +10129,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
outAttrs.extras.putBoolean(
STYLUS_HANDWRITING_ENABLED_ANDROIDX_EXTRAS_KEY, handwritingEnabled);
}
+ if (android.view.inputmethod.Flags.writingTools()) {
+ // default to same behavior as isSuggestionsEnabled().
+ outAttrs.setWritingToolsEnabled(isSuggestionsEnabled());
+ }
ArrayList> gestures = new ArrayList<>();
gestures.add(SelectGesture.class);
gestures.add(SelectRangeGesture.class);
diff --git a/core/java/android/window/SystemPerformanceHinter.java b/core/java/android/window/SystemPerformanceHinter.java
index cc2329fc47cb475e907462c1c190c4a43bee6a1c..f8899c5764aa83a0f2eabe990f0da6557db4cba1 100644
--- a/core/java/android/window/SystemPerformanceHinter.java
+++ b/core/java/android/window/SystemPerformanceHinter.java
@@ -163,7 +163,6 @@ public class SystemPerformanceHinter {
// The active sessions
private final ArrayList mActiveSessions = new ArrayList<>();
private final SurfaceControl.Transaction mTransaction;
- private final PerformanceHintManager mPerfHintManager;
private @Nullable PerformanceHintManager.Session mAdpfSession;
private @Nullable DisplayRootProvider mDisplayRootProvider;
@@ -184,7 +183,6 @@ public class SystemPerformanceHinter {
@Nullable DisplayRootProvider displayRootProvider,
@Nullable Supplier transactionSupplier) {
mDisplayRootProvider = displayRootProvider;
- mPerfHintManager = context.getSystemService(PerformanceHintManager.class);
mTransaction = transactionSupplier != null
? transactionSupplier.get()
: new SurfaceControl.Transaction();
@@ -273,7 +271,7 @@ public class SystemPerformanceHinter {
asyncTraceBegin(HINT_SF_EARLY_WAKEUP, Display.INVALID_DISPLAY);
}
}
- if (nowEnabled(oldGlobalFlags, newGlobalFlags, HINT_ADPF)) {
+ if (mAdpfSession != null && nowEnabled(oldGlobalFlags, newGlobalFlags, HINT_ADPF)) {
mAdpfSession.sendHint(PerformanceHintManager.Session.CPU_LOAD_UP);
if (isTraceEnabled) {
asyncTraceBegin(HINT_ADPF, Display.INVALID_DISPLAY);
@@ -323,7 +321,7 @@ public class SystemPerformanceHinter {
asyncTraceEnd(HINT_SF_EARLY_WAKEUP);
}
}
- if (nowDisabled(oldGlobalFlags, newGlobalFlags, HINT_ADPF)) {
+ if (mAdpfSession != null && nowDisabled(oldGlobalFlags, newGlobalFlags, HINT_ADPF)) {
mAdpfSession.sendHint(PerformanceHintManager.Session.CPU_LOAD_RESET);
if (isTraceEnabled) {
asyncTraceEnd(HINT_ADPF);
diff --git a/core/java/android/window/TransitionRequestInfo.java b/core/java/android/window/TransitionRequestInfo.java
index fe936f77de073109322be43c5bcd18be60f8a993..f42c0ec5ee7c0d54e01425bb4c85bfd7239adc6e 100644
--- a/core/java/android/window/TransitionRequestInfo.java
+++ b/core/java/android/window/TransitionRequestInfo.java
@@ -44,10 +44,10 @@ public final class TransitionRequestInfo implements Parcelable {
private @Nullable ActivityManager.RunningTaskInfo mTriggerTask;
/**
- * If non-null, the task containing the pip activity that participates in this
- * transition.
+ * If non-null, this request might lead to a PiP transition; {@code PipChange} caches both
+ * {@code TaskFragment} token and the {@code TaskInfo} of the task with PiP candidate activity.
*/
- private @Nullable ActivityManager.RunningTaskInfo mPipTask;
+ private @Nullable TransitionRequestInfo.PipChange mPipChange;
/** If non-null, a remote-transition associated with the source of this transition. */
private @Nullable RemoteTransition mRemoteTransition;
@@ -70,7 +70,7 @@ public final class TransitionRequestInfo implements Parcelable {
@WindowManager.TransitionType int type,
@Nullable ActivityManager.RunningTaskInfo triggerTask,
@Nullable RemoteTransition remoteTransition) {
- this(type, triggerTask, null /* pipTask */,
+ this(type, triggerTask, null /* pipChange */,
remoteTransition, null /* displayChange */, 0 /* flags */, -1 /* debugId */);
}
@@ -80,7 +80,7 @@ public final class TransitionRequestInfo implements Parcelable {
@Nullable ActivityManager.RunningTaskInfo triggerTask,
@Nullable RemoteTransition remoteTransition,
int flags) {
- this(type, triggerTask, null /* pipTask */,
+ this(type, triggerTask, null /* pipChange */,
remoteTransition, null /* displayChange */, flags, -1 /* debugId */);
}
@@ -91,7 +91,7 @@ public final class TransitionRequestInfo implements Parcelable {
@Nullable RemoteTransition remoteTransition,
@Nullable TransitionRequestInfo.DisplayChange displayChange,
int flags) {
- this(type, triggerTask, null /* pipTask */, remoteTransition, displayChange, flags,
+ this(type, triggerTask, null /* pipChange */, remoteTransition, displayChange, flags,
-1 /* debugId */);
}
@@ -103,7 +103,9 @@ public final class TransitionRequestInfo implements Parcelable {
@Nullable RemoteTransition remoteTransition,
@Nullable TransitionRequestInfo.DisplayChange displayChange,
int flags) {
- this(type, triggerTask, pipTask, remoteTransition, displayChange, flags, -1 /* debugId */);
+ this(type, triggerTask,
+ pipTask != null ? new TransitionRequestInfo.PipChange(pipTask) : null,
+ remoteTransition, displayChange, flags, -1 /* debugId */);
}
/** @hide */
@@ -252,7 +254,7 @@ public final class TransitionRequestInfo implements Parcelable {
/** @hide */
@SuppressWarnings({"unchecked", "RedundantCast"})
@DataClass.Generated.Member
- protected DisplayChange(@android.annotation.NonNull android.os.Parcel in) {
+ /* package-private */ DisplayChange(@android.annotation.NonNull android.os.Parcel in) {
// You can override field unparcelling by defining methods like:
// static FieldType unparcelFieldName(Parcel in) { ... }
@@ -289,7 +291,7 @@ public final class TransitionRequestInfo implements Parcelable {
};
@DataClass.Generated(
- time = 1697564781403L,
+ time = 1733334462577L,
codegenVersion = "1.0.23",
sourceFile = "frameworks/base/core/java/android/window/TransitionRequestInfo.java",
inputSignatures = "private final int mDisplayId\nprivate @android.annotation.Nullable android.graphics.Rect mStartAbsBounds\nprivate @android.annotation.Nullable android.graphics.Rect mEndAbsBounds\nprivate int mStartRotation\nprivate int mEndRotation\nprivate boolean mPhysicalDisplayChanged\nclass DisplayChange extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genToString=true, genSetters=true, genBuilder=false, genConstructor=false)")
@@ -302,6 +304,143 @@ public final class TransitionRequestInfo implements Parcelable {
}
+ @DataClass(genToString = true, genSetters = true, genBuilder = false, genConstructor = false)
+ public static final class PipChange implements Parcelable {
+ // In AE case, we might care about the TF token instead of the task token.
+ @android.annotation.NonNull
+ private WindowContainerToken mTaskFragmentToken;
+
+ @android.annotation.NonNull
+ private ActivityManager.RunningTaskInfo mTaskInfo;
+
+ /** Create empty display-change. */
+ public PipChange(ActivityManager.RunningTaskInfo taskInfo) {
+ mTaskFragmentToken = taskInfo.token;
+ mTaskInfo = taskInfo;
+ }
+
+ /** Create a display-change representing a rotation. */
+ public PipChange(WindowContainerToken taskFragmentToken,
+ ActivityManager.RunningTaskInfo taskInfo) {
+ mTaskFragmentToken = taskFragmentToken;
+ mTaskInfo = taskInfo;
+ }
+
+
+
+ // Code below generated by codegen v1.0.23.
+ //
+ // DO NOT MODIFY!
+ // CHECKSTYLE:OFF Generated code
+ //
+ // To regenerate run:
+ // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/window/TransitionRequestInfo.java
+ //
+ // To exclude the generated code from IntelliJ auto-formatting enable (one-time):
+ // Settings > Editor > Code Style > Formatter Control
+ //@formatter:off
+
+
+ @DataClass.Generated.Member
+ public @android.annotation.NonNull WindowContainerToken getTaskFragmentToken() {
+ return mTaskFragmentToken;
+ }
+
+ @DataClass.Generated.Member
+ public @android.annotation.NonNull ActivityManager.RunningTaskInfo getTaskInfo() {
+ return mTaskInfo;
+ }
+
+ @DataClass.Generated.Member
+ public @android.annotation.NonNull PipChange setTaskFragmentToken(@android.annotation.NonNull WindowContainerToken value) {
+ mTaskFragmentToken = value;
+ com.android.internal.util.AnnotationValidations.validate(
+ android.annotation.NonNull.class, null, mTaskFragmentToken);
+ return this;
+ }
+
+ @DataClass.Generated.Member
+ public @android.annotation.NonNull PipChange setTaskInfo(@android.annotation.NonNull ActivityManager.RunningTaskInfo value) {
+ mTaskInfo = value;
+ com.android.internal.util.AnnotationValidations.validate(
+ android.annotation.NonNull.class, null, mTaskInfo);
+ return this;
+ }
+
+ @Override
+ @DataClass.Generated.Member
+ public String toString() {
+ // You can override field toString logic by defining methods like:
+ // String fieldNameToString() { ... }
+
+ return "PipChange { " +
+ "taskFragmentToken = " + mTaskFragmentToken + ", " +
+ "taskInfo = " + mTaskInfo +
+ " }";
+ }
+
+ @Override
+ @DataClass.Generated.Member
+ public void writeToParcel(@android.annotation.NonNull android.os.Parcel dest, int flags) {
+ // You can override field parcelling by defining methods like:
+ // void parcelFieldName(Parcel dest, int flags) { ... }
+
+ dest.writeTypedObject(mTaskFragmentToken, flags);
+ dest.writeTypedObject(mTaskInfo, flags);
+ }
+
+ @Override
+ @DataClass.Generated.Member
+ public int describeContents() { return 0; }
+
+ /** @hide */
+ @SuppressWarnings({"unchecked", "RedundantCast"})
+ @DataClass.Generated.Member
+ /* package-private */ PipChange(@android.annotation.NonNull android.os.Parcel in) {
+ // You can override field unparcelling by defining methods like:
+ // static FieldType unparcelFieldName(Parcel in) { ... }
+
+ WindowContainerToken taskFragmentToken = (WindowContainerToken) in.readTypedObject(WindowContainerToken.CREATOR);
+ ActivityManager.RunningTaskInfo taskInfo = (ActivityManager.RunningTaskInfo) in.readTypedObject(ActivityManager.RunningTaskInfo.CREATOR);
+
+ this.mTaskFragmentToken = taskFragmentToken;
+ com.android.internal.util.AnnotationValidations.validate(
+ android.annotation.NonNull.class, null, mTaskFragmentToken);
+ this.mTaskInfo = taskInfo;
+ com.android.internal.util.AnnotationValidations.validate(
+ android.annotation.NonNull.class, null, mTaskInfo);
+
+ // onConstructed(); // You can define this method to get a callback
+ }
+
+ @DataClass.Generated.Member
+ public static final @android.annotation.NonNull Parcelable.Creator CREATOR
+ = new Parcelable.Creator() {
+ @Override
+ public PipChange[] newArray(int size) {
+ return new PipChange[size];
+ }
+
+ @Override
+ public PipChange createFromParcel(@android.annotation.NonNull android.os.Parcel in) {
+ return new PipChange(in);
+ }
+ };
+
+ @DataClass.Generated(
+ time = 1733334462588L,
+ codegenVersion = "1.0.23",
+ sourceFile = "frameworks/base/core/java/android/window/TransitionRequestInfo.java",
+ inputSignatures = "private @android.annotation.NonNull android.window.WindowContainerToken mTaskFragmentToken\nprivate @android.annotation.NonNull android.app.ActivityManager.RunningTaskInfo mTaskInfo\nclass PipChange extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genToString=true, genSetters=true, genBuilder=false, genConstructor=false)")
+ @Deprecated
+ private void __metadata() {}
+
+
+ //@formatter:on
+ // End of generated code
+
+ }
+
@@ -326,9 +465,9 @@ public final class TransitionRequestInfo implements Parcelable {
* @param triggerTask
* If non-null, the task containing the activity whose lifecycle change (start or
* finish) has caused this transition to occur.
- * @param pipTask
- * If non-null, the task containing the pip activity that participates in this
- * transition.
+ * @param pipChange
+ * If non-null, this request might lead to a PiP transition; {@code PipChange} caches both
+ * {@code TaskFragment} token and the {@code TaskInfo} of the task with PiP candidate activity.
* @param remoteTransition
* If non-null, a remote-transition associated with the source of this transition.
* @param displayChange
@@ -344,7 +483,7 @@ public final class TransitionRequestInfo implements Parcelable {
public TransitionRequestInfo(
@WindowManager.TransitionType int type,
@Nullable ActivityManager.RunningTaskInfo triggerTask,
- @Nullable ActivityManager.RunningTaskInfo pipTask,
+ @Nullable TransitionRequestInfo.PipChange pipChange,
@Nullable RemoteTransition remoteTransition,
@Nullable TransitionRequestInfo.DisplayChange displayChange,
int flags,
@@ -353,7 +492,7 @@ public final class TransitionRequestInfo implements Parcelable {
com.android.internal.util.AnnotationValidations.validate(
WindowManager.TransitionType.class, null, mType);
this.mTriggerTask = triggerTask;
- this.mPipTask = pipTask;
+ this.mPipChange = pipChange;
this.mRemoteTransition = remoteTransition;
this.mDisplayChange = displayChange;
this.mFlags = flags;
@@ -380,12 +519,12 @@ public final class TransitionRequestInfo implements Parcelable {
}
/**
- * If non-null, the task containing the pip activity that participates in this
- * transition.
+ * If non-null, this request might lead to a PiP transition; {@code PipChange} caches both
+ * {@code TaskFragment} token and the {@code TaskInfo} of the task with PiP candidate activity.
*/
@DataClass.Generated.Member
- public @Nullable ActivityManager.RunningTaskInfo getPipTask() {
- return mPipTask;
+ public @Nullable TransitionRequestInfo.PipChange getPipChange() {
+ return mPipChange;
}
/**
@@ -433,12 +572,12 @@ public final class TransitionRequestInfo implements Parcelable {
}
/**
- * If non-null, the task containing the pip activity that participates in this
- * transition.
+ * If non-null, this request might lead to a PiP transition; {@code PipChange} caches both
+ * {@code TaskFragment} token and the {@code TaskInfo} of the task with PiP candidate activity.
*/
@DataClass.Generated.Member
- public @android.annotation.NonNull TransitionRequestInfo setPipTask(@android.annotation.NonNull ActivityManager.RunningTaskInfo value) {
- mPipTask = value;
+ public @android.annotation.NonNull TransitionRequestInfo setPipChange(@android.annotation.NonNull TransitionRequestInfo.PipChange value) {
+ mPipChange = value;
return this;
}
@@ -471,10 +610,10 @@ public final class TransitionRequestInfo implements Parcelable {
return "TransitionRequestInfo { " +
"type = " + typeToString() + ", " +
"triggerTask = " + mTriggerTask + ", " +
- "pipTask = " + mPipTask + ", " +
+ "pipChange = " + mPipChange + ", " +
"remoteTransition = " + mRemoteTransition + ", " +
"displayChange = " + mDisplayChange + ", " +
- "flags = " + Integer.toHexString(mFlags) + ", " +
+ "flags = " + mFlags + ", " +
"debugId = " + mDebugId +
" }";
}
@@ -487,13 +626,13 @@ public final class TransitionRequestInfo implements Parcelable {
byte flg = 0;
if (mTriggerTask != null) flg |= 0x2;
- if (mPipTask != null) flg |= 0x4;
+ if (mPipChange != null) flg |= 0x4;
if (mRemoteTransition != null) flg |= 0x8;
if (mDisplayChange != null) flg |= 0x10;
dest.writeByte(flg);
dest.writeInt(mType);
if (mTriggerTask != null) dest.writeTypedObject(mTriggerTask, flags);
- if (mPipTask != null) dest.writeTypedObject(mPipTask, flags);
+ if (mPipChange != null) dest.writeTypedObject(mPipChange, flags);
if (mRemoteTransition != null) dest.writeTypedObject(mRemoteTransition, flags);
if (mDisplayChange != null) dest.writeTypedObject(mDisplayChange, flags);
dest.writeInt(mFlags);
@@ -514,7 +653,7 @@ public final class TransitionRequestInfo implements Parcelable {
byte flg = in.readByte();
int type = in.readInt();
ActivityManager.RunningTaskInfo triggerTask = (flg & 0x2) == 0 ? null : (ActivityManager.RunningTaskInfo) in.readTypedObject(ActivityManager.RunningTaskInfo.CREATOR);
- ActivityManager.RunningTaskInfo pipTask = (flg & 0x4) == 0 ? null : (ActivityManager.RunningTaskInfo) in.readTypedObject(ActivityManager.RunningTaskInfo.CREATOR);
+ TransitionRequestInfo.PipChange pipChange = (flg & 0x4) == 0 ? null : (TransitionRequestInfo.PipChange) in.readTypedObject(TransitionRequestInfo.PipChange.CREATOR);
RemoteTransition remoteTransition = (flg & 0x8) == 0 ? null : (RemoteTransition) in.readTypedObject(RemoteTransition.CREATOR);
TransitionRequestInfo.DisplayChange displayChange = (flg & 0x10) == 0 ? null : (TransitionRequestInfo.DisplayChange) in.readTypedObject(TransitionRequestInfo.DisplayChange.CREATOR);
int flags = in.readInt();
@@ -524,7 +663,7 @@ public final class TransitionRequestInfo implements Parcelable {
com.android.internal.util.AnnotationValidations.validate(
WindowManager.TransitionType.class, null, mType);
this.mTriggerTask = triggerTask;
- this.mPipTask = pipTask;
+ this.mPipChange = pipChange;
this.mRemoteTransition = remoteTransition;
this.mDisplayChange = displayChange;
this.mFlags = flags;
@@ -548,10 +687,10 @@ public final class TransitionRequestInfo implements Parcelable {
};
@DataClass.Generated(
- time = 1697564781438L,
+ time = 1733334462604L,
codegenVersion = "1.0.23",
sourceFile = "frameworks/base/core/java/android/window/TransitionRequestInfo.java",
- inputSignatures = "private final @android.view.WindowManager.TransitionType int mType\nprivate @android.annotation.Nullable android.app.ActivityManager.RunningTaskInfo mTriggerTask\nprivate @android.annotation.Nullable android.app.ActivityManager.RunningTaskInfo mPipTask\nprivate @android.annotation.Nullable android.window.RemoteTransition mRemoteTransition\nprivate @android.annotation.Nullable android.window.TransitionRequestInfo.DisplayChange mDisplayChange\nprivate final int mFlags\nprivate final int mDebugId\n java.lang.String typeToString()\nclass TransitionRequestInfo extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genToString=true, genSetters=true, genAidl=true)")
+ inputSignatures = "private final @android.view.WindowManager.TransitionType int mType\nprivate @android.annotation.Nullable android.app.ActivityManager.RunningTaskInfo mTriggerTask\nprivate @android.annotation.Nullable android.window.TransitionRequestInfo.PipChange mPipChange\nprivate @android.annotation.Nullable android.window.RemoteTransition mRemoteTransition\nprivate @android.annotation.Nullable android.window.TransitionRequestInfo.DisplayChange mDisplayChange\nprivate final int mFlags\nprivate final int mDebugId\n java.lang.String typeToString()\nclass TransitionRequestInfo extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genToString=true, genSetters=true, genAidl=true)")
@Deprecated
private void __metadata() {}
diff --git a/core/java/android/window/WindowContext.java b/core/java/android/window/WindowContext.java
index 2b370b9797e572245874f9296d87ee136da44b78..84a8b8f5b5b0173a6675ae4623341559f9f8afc8 100644
--- a/core/java/android/window/WindowContext.java
+++ b/core/java/android/window/WindowContext.java
@@ -32,6 +32,7 @@ import android.view.Display;
import android.view.WindowManager;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.window.flags.Flags;
import java.lang.ref.Reference;
@@ -95,20 +96,20 @@ public class WindowContext extends ContextWrapper implements WindowProvider {
}
/**
- * Updates this context to a new displayId.
+ * Moves this context to another display.
*
- * Note that this doesn't re-parent previously attached windows (they should be removed and
- * re-added manually after this is called). Resources associated with this context will have
- * the correct value and configuration for the new display after this is called.
+ * Note that this re-parents all the previously attached windows. Resources associated with this
+ * context will have the correct value and configuration for the new display after this is
+ * called.
*/
- @Override
- public void updateDisplay(int displayId) {
- if (displayId == getDisplayId()) {
- return;
+ public void reparentToDisplay(int displayId) {
+ if (Flags.reparentWindowTokenApi()) {
+ if (displayId == getDisplayId()) {
+ return;
+ }
+ super.updateDisplay(displayId);
+ mController.reparentToDisplayArea(mType, displayId, mOptions);
}
- super.updateDisplay(displayId);
- mController.detachIfNeeded();
- mController.attachToDisplayArea(mType, displayId, mOptions);
}
@Override
diff --git a/core/java/android/window/WindowContextController.java b/core/java/android/window/WindowContextController.java
index c9ac245bc36f3ca45bf1b09c071b49a504853f45..1e2f454adeefdd3bdd2cd964cd7e3ba219b6f62b 100644
--- a/core/java/android/window/WindowContextController.java
+++ b/core/java/android/window/WindowContextController.java
@@ -158,6 +158,21 @@ public class WindowContextController {
}
}
+ /**
+ * Reparents the window context from the current attached display to another. {@code type} and
+ * {@code options} must be the same as the previous attach call, otherwise this will fail
+ * silently.
+ */
+ public void reparentToDisplayArea(
+ @WindowType int type, int displayId, @Nullable Bundle options) {
+ if (mAttachedToDisplayArea != AttachStatus.STATUS_ATTACHED) {
+ attachToDisplayArea(type, displayId, options);
+ return;
+ }
+ // No need to propagate type and options as this is already attached and they can't change.
+ getWindowTokenClientController().reparentToDisplayArea(mToken, displayId);
+ }
+
/** Gets the {@link WindowTokenClientController}. */
@VisibleForTesting
@NonNull
diff --git a/core/java/android/window/WindowTokenClient.java b/core/java/android/window/WindowTokenClient.java
index 6e76d8d345b2cb6b975f2a70a3cb06f96ccb4550..a551fe701c5b34e62ecaf64bd1ef2c897b4dbfa9 100644
--- a/core/java/android/window/WindowTokenClient.java
+++ b/core/java/android/window/WindowTokenClient.java
@@ -166,7 +166,7 @@ public class WindowTokenClient extends Binder {
@VisibleForTesting
public void onConfigurationChangedInner(@NonNull Context context,
@NonNull Configuration newConfig, int newDisplayId, boolean shouldReportConfigChange) {
- CompatibilityInfo.applyOverrideScaleIfNeeded(newConfig);
+ CompatibilityInfo.applyOverrideIfNeeded(newConfig);
final boolean displayChanged;
final boolean shouldUpdateResources;
final int diff;
diff --git a/core/java/android/window/WindowTokenClientController.java b/core/java/android/window/WindowTokenClientController.java
index fa345956ec4d120c9bd1db299645e8fdca7811bf..1ec05b65861d3235c482a4742ad37b37c900a3a0 100644
--- a/core/java/android/window/WindowTokenClientController.java
+++ b/core/java/android/window/WindowTokenClientController.java
@@ -197,6 +197,21 @@ public class WindowTokenClientController {
}
}
+ /**
+ * Reparents a {@link WindowTokenClient} and its associated WindowContainer if there's one.
+ */
+ public void reparentToDisplayArea(@NonNull WindowTokenClient client, int displayId) {
+ try {
+ if (!getWindowManagerService().reparentWindowContextToDisplayArea(mAppThread, client,
+ displayId)) {
+ Log.e(TAG,
+ "Didn't succeed reparenting of " + client + " to displayId=" + displayId);
+ }
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
private void onWindowContextTokenAttached(@NonNull WindowTokenClient client,
@NonNull WindowContextInfo info, boolean shouldReportConfigChange) {
recordWindowContextToken(client);
diff --git a/core/java/android/window/flags/lse_desktop_experience.aconfig b/core/java/android/window/flags/lse_desktop_experience.aconfig
index 4fb5fa70c0830e6442f60cdd4e0e3ac09916de64..a05d003b2faf5c06b500b004384df1f83580cc95 100644
--- a/core/java/android/window/flags/lse_desktop_experience.aconfig
+++ b/core/java/android/window/flags/lse_desktop_experience.aconfig
@@ -448,6 +448,14 @@ flag {
bug: "350475854"
}
+flag {
+ name: "reparent_window_token_api"
+ namespace: "lse_desktop_experience"
+ description: "Allows to reparent a window token to a different display"
+ is_fixed_read_only: true
+ bug: "381258683"
+}
+
flag {
name: "enable_desktop_windowing_hsum"
namespace: "lse_desktop_experience"
@@ -460,4 +468,36 @@ flag {
namespace: "lse_desktop_experience"
description: "Enable multiple desktop sessions for desktop windowing."
bug: "379158791"
+}
+
+flag {
+ name: "enable_connected_displays_dnd"
+ namespace: "lse_desktop_experience"
+ description: "Enable drag-and-drop between connected displays."
+ bug: "381793841"
+}
+
+flag {
+ name: "enable_connected_displays_window_drag"
+ namespace: "lse_desktop_experience"
+ description: "Enable window drag between connected displays."
+ bug: "381172172"
+}
+
+flag {
+ name: "enable_bug_fixes_for_secondary_display"
+ namespace: "lse_desktop_experience"
+ description: "Bugfixes / papercuts to bring Desktop Windowing to secondary displays."
+ bug: "382023296"
+}
+
+flag {
+ name: "enable_top_visible_root_task_per_user_tracking"
+ namespace: "lse_desktop_experience"
+ description: "Enables tracking the top visible root tasks for a user."
+ bug: "381038076"
+ is_fixed_read_only: true
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
}
\ No newline at end of file
diff --git a/core/java/android/window/flags/windowing_frontend.aconfig b/core/java/android/window/flags/windowing_frontend.aconfig
index 0b034b61c72e9e9f2c03989acfea56614bdbda3e..30f0c7371270fdaecdf6aaaaa50af1ed28db8b2e 100644
--- a/core/java/android/window/flags/windowing_frontend.aconfig
+++ b/core/java/android/window/flags/windowing_frontend.aconfig
@@ -453,3 +453,11 @@ flag {
is_fixed_read_only: true
bug: "376407910"
}
+
+flag {
+ name: "relative_insets"
+ namespace: "windowing_frontend"
+ description: "Support insets definition and calculation relative to task bounds."
+ bug: "277292497"
+ is_fixed_read_only: true
+}
\ No newline at end of file
diff --git a/core/java/android/window/flags/windowing_sdk.aconfig b/core/java/android/window/flags/windowing_sdk.aconfig
index 81734a3e2115c14de52a782bd59d4185db3d98bf..d0d4af6ea598448b3f7d7959008a4398114bb2e5 100644
--- a/core/java/android/window/flags/windowing_sdk.aconfig
+++ b/core/java/android/window/flags/windowing_sdk.aconfig
@@ -116,3 +116,14 @@ flag {
description: "Relax the assumption of non-match parent activity"
bug: "356277166"
}
+
+flag {
+ namespace: "windowing_sdk"
+ name: "allow_multiple_adjacent_task_fragments"
+ description: "Refactor to allow more than 2 adjacent TaskFragments"
+ bug: "373709676"
+ is_fixed_read_only: true
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
diff --git a/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java b/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java
index e2be1f57b1fba2556f5276418a828ce44871cf35..a27eeb8fdd6340d2a387fb1f7464c11b713aa53b 100644
--- a/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java
+++ b/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java
@@ -58,7 +58,6 @@ import android.util.Slog;
import android.view.Window;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityManager;
-import android.view.accessibility.Flags;
import android.widget.Toast;
import com.android.internal.R;
@@ -289,9 +288,7 @@ public class AccessibilityShortcutController {
cr, Settings.Secure.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN, DialogStatus.SHOWN,
userId);
} else {
- if (Flags.restoreA11yShortcutTargetService()) {
- enableDefaultHardwareShortcut(userId);
- }
+ enableDefaultHardwareShortcut(userId);
playNotificationTone();
if (mAlertDialog != null) {
mAlertDialog.dismiss();
diff --git a/core/java/com/android/internal/accessibility/dialog/AccessibilityServiceWarning.java b/core/java/com/android/internal/accessibility/dialog/AccessibilityServiceWarning.java
index 3557633f87c577e55f118a7374094e6c4609099b..2e1a0bff3cd3a4b688e4d41b934e6cb5d020c693 100644
--- a/core/java/com/android/internal/accessibility/dialog/AccessibilityServiceWarning.java
+++ b/core/java/com/android/internal/accessibility/dialog/AccessibilityServiceWarning.java
@@ -29,7 +29,6 @@ import android.view.MotionEvent;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
-import android.view.accessibility.Flags;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
@@ -65,9 +64,6 @@ public class AccessibilityServiceWarning {
Window window = ad.getWindow();
WindowManager.LayoutParams params = window.getAttributes();
params.privateFlags |= SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
- if (!Flags.warningUseDefaultDialogType()) {
- params.type = WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
- }
window.setAttributes(params);
return ad;
}
diff --git a/core/java/com/android/internal/app/AlertController.java b/core/java/com/android/internal/app/AlertController.java
index 92f9e6014107f5c61d461320cadaedd45d2a1708..5d4c40853009807063042b80a8a96c24f5639561 100644
--- a/core/java/com/android/internal/app/AlertController.java
+++ b/core/java/com/android/internal/app/AlertController.java
@@ -267,7 +267,9 @@ public class AlertController {
return Flags.useWearMaterial3Ui()
&& CompatChanges.isChangeEnabled(WEAR_MATERIAL3_ALERTDIALOG)
&& context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH)
- && context.getThemeResId() == com.android.internal.R.style.Theme_DeviceDefault;
+ && (context.getThemeResId() == com.android.internal.R.style.Theme_DeviceDefault
+ || context.getThemeResId()
+ == com.android.internal.R.style.Theme_DeviceDefault_Dialog_Alert);
}
static boolean canTextInput(View v) {
diff --git a/core/java/com/android/internal/app/IntentForwarderActivity.java b/core/java/com/android/internal/app/IntentForwarderActivity.java
index ee5bd65e76ded0af273534a13252ac425ee5d646..644d699199985d909b8c35baa3887e5da9293ed6 100644
--- a/core/java/com/android/internal/app/IntentForwarderActivity.java
+++ b/core/java/com/android/internal/app/IntentForwarderActivity.java
@@ -70,6 +70,7 @@ import android.widget.Toast;
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.app.chooser.TargetInfo;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -352,6 +353,7 @@ public class IntentForwarderActivity extends Activity {
findViewById(R.id.use_same_profile_browser).setOnClickListener(v -> finish());
findViewById(R.id.button_open).setOnClickListener(v -> {
+ TargetInfo.refreshIntentCreatorToken(launchIntent);
startActivityAsCaller(
launchIntent,
ActivityOptions.makeCustomAnimation(
@@ -476,6 +478,7 @@ public class IntentForwarderActivity extends Activity {
private void startActivityAsCaller(Intent newIntent, int userId) {
try {
+ TargetInfo.refreshIntentCreatorToken(newIntent);
startActivityAsCaller(
newIntent,
/* options= */ null,
@@ -502,6 +505,7 @@ public class IntentForwarderActivity extends Activity {
return;
}
sanitizeIntent(innerIntent);
+ TargetInfo.refreshIntentCreatorToken(intentReceived);
startActivityAsCaller(intentReceived, null, false, getUserId());
finish();
}
@@ -525,6 +529,7 @@ public class IntentForwarderActivity extends Activity {
if (singleTabOnly) {
intentReceived.putExtra(EXTRA_RESTRICT_TO_SINGLE_USER, true);
}
+ TargetInfo.refreshIntentCreatorToken(intentReceived);
startActivityAsCaller(intentReceived, null, false, userId);
finish();
}
diff --git a/core/java/com/android/internal/app/chooser/DisplayResolveInfo.java b/core/java/com/android/internal/app/chooser/DisplayResolveInfo.java
index 473134ea46f3f41387a157d5dc2c5f2a7f171ff8..0c650774105ec67d95b9c3b65f4eb80498754bec 100644
--- a/core/java/com/android/internal/app/chooser/DisplayResolveInfo.java
+++ b/core/java/com/android/internal/app/chooser/DisplayResolveInfo.java
@@ -173,6 +173,7 @@ public class DisplayResolveInfo implements TargetInfo, Parcelable {
@Override
public boolean startAsCaller(ResolverActivity activity, Bundle options, int userId) {
TargetInfo.prepareIntentForCrossProfileLaunch(mResolvedIntent, userId);
+ TargetInfo.refreshIntentCreatorToken(mResolvedIntent);
activity.startActivityAsCaller(mResolvedIntent, options, false, userId);
return true;
}
@@ -180,6 +181,7 @@ public class DisplayResolveInfo implements TargetInfo, Parcelable {
@Override
public boolean startAsUser(Activity activity, Bundle options, UserHandle user) {
TargetInfo.prepareIntentForCrossProfileLaunch(mResolvedIntent, user.getIdentifier());
+ TargetInfo.refreshIntentCreatorToken(mResolvedIntent);
activity.startActivityAsUser(mResolvedIntent, options, user);
return false;
}
diff --git a/core/java/com/android/internal/app/chooser/SelectableTargetInfo.java b/core/java/com/android/internal/app/chooser/SelectableTargetInfo.java
index d7f3a76c61e0aabde31ef7033ec13a8de626c74e..0eaa43d2c6e8d6a19e3a152e053dc662c60af7f1 100644
--- a/core/java/com/android/internal/app/chooser/SelectableTargetInfo.java
+++ b/core/java/com/android/internal/app/chooser/SelectableTargetInfo.java
@@ -260,6 +260,7 @@ public final class SelectableTargetInfo implements ChooserTargetInfo {
intent.setComponent(mChooserTarget.getComponentName());
intent.putExtras(mChooserTarget.getIntentExtras());
TargetInfo.prepareIntentForCrossProfileLaunch(intent, userId);
+ TargetInfo.refreshIntentCreatorToken(intent);
// Important: we will ignore the target security checks in ActivityManager
// if and only if the ChooserTarget's target package is the same package
diff --git a/core/java/com/android/internal/app/chooser/TargetInfo.java b/core/java/com/android/internal/app/chooser/TargetInfo.java
index 7bb7ddc65c6dbfababbebc026bd0f54fb88ab6f4..fcf5883cc84b9dafbb3a4901073ded97a032112d 100644
--- a/core/java/com/android/internal/app/chooser/TargetInfo.java
+++ b/core/java/com/android/internal/app/chooser/TargetInfo.java
@@ -17,13 +17,17 @@
package com.android.internal.app.chooser;
+import static android.security.Flags.preventIntentRedirect;
+
import android.app.Activity;
+import android.app.ActivityManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ResolveInfo;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
+import android.os.RemoteException;
import android.os.UserHandle;
import com.android.internal.app.ResolverActivity;
@@ -141,4 +145,20 @@ public interface TargetInfo {
intent.fixUris(currentUserId);
}
}
+
+ /**
+ * refreshes intent's creatorToken with its current intent key fields. This allows
+ * ChooserActivity to still keep original creatorToken's creator uid after making changes to
+ * the intent and still keep it valid.
+ * @param intent the intent's creatorToken needs to up refreshed.
+ */
+ static void refreshIntentCreatorToken(Intent intent) {
+ if (!preventIntentRedirect()) return;
+ try {
+ intent.setCreatorToken(ActivityManager.getService().refreshIntentCreatorToken(
+ intent.cloneForCreatorToken()));
+ } catch (RemoteException e) {
+ throw new RuntimeException("Failure from system", e);
+ }
+ }
}
diff --git a/core/java/com/android/internal/inputmethod/SoftInputShowHideReason.java b/core/java/com/android/internal/inputmethod/SoftInputShowHideReason.java
index 429a6a267bb1abe33cc57a6e27c85a90b3a0eed9..592ea9e5e60083429dcfe0fa24348d0461305edf 100644
--- a/core/java/com/android/internal/inputmethod/SoftInputShowHideReason.java
+++ b/core/java/com/android/internal/inputmethod/SoftInputShowHideReason.java
@@ -91,6 +91,7 @@ import java.lang.annotation.Retention;
SoftInputShowHideReason.CONTROL_WINDOW_INSETS_ANIMATION,
SoftInputShowHideReason.SHOW_INPUT_TARGET_CHANGED,
SoftInputShowHideReason.HIDE_INPUT_TARGET_CHANGED,
+ SoftInputShowHideReason.REASON_HIDE_WINDOW_LOST_FOCUS,
})
public @interface SoftInputShowHideReason {
/** Default, undefined reason. */
@@ -418,4 +419,7 @@ public @interface SoftInputShowHideReason {
* {@link android.view.InsetsController#controlWindowInsetsAnimation}.
*/
int CONTROL_WINDOW_INSETS_ANIMATION = ImeProtoEnums.REASON_CONTROL_WINDOW_INSETS_ANIMATION;
+
+ /** Hide soft input when the window lost focus. */
+ int REASON_HIDE_WINDOW_LOST_FOCUS = ImeProtoEnums.REASON_HIDE_WINDOW_LOST_FOCUS;
}
diff --git a/core/java/com/android/internal/jank/EventLogTags.logtags b/core/java/com/android/internal/jank/EventLogTags.logtags
index 66ee131badacabde48eebbd49dbca21115fc5324..dfec49907c69eb989d154e1398045b5f71ca8940 100644
--- a/core/java/com/android/internal/jank/EventLogTags.logtags
+++ b/core/java/com/android/internal/jank/EventLogTags.logtags
@@ -1,4 +1,4 @@
-# See system/core/logcat/event.logtags for a description of the format of this file.
+# See system/logging/logcat/event.logtags for a description of the format of this file.
option java_package com.android.internal.jank;
diff --git a/core/java/com/android/internal/os/TEST_MAPPING b/core/java/com/android/internal/os/TEST_MAPPING
index 4400ed11772126331531887e509c7a374fd164db..1923c5fb9186f87a9e3ef78e8e451feb9b6698df 100644
--- a/core/java/com/android/internal/os/TEST_MAPPING
+++ b/core/java/com/android/internal/os/TEST_MAPPING
@@ -20,7 +20,7 @@
"file_patterns": [
"BinderDeathDispatcher\\.java"
],
- "name": "FrameworksCoreTests_internal_os_binder"
+ "name": "FrameworksCoreTests_all_binder"
},
{
"file_patterns": [
diff --git a/core/java/com/android/internal/pm/pkg/component/AconfigFlags.java b/core/java/com/android/internal/pm/pkg/component/AconfigFlags.java
index c953d88c94828a690a803de8d9a49884bb26a4d7..445dac7411daa6f150a151447dc60631984adf1f 100644
--- a/core/java/com/android/internal/pm/pkg/component/AconfigFlags.java
+++ b/core/java/com/android/internal/pm/pkg/component/AconfigFlags.java
@@ -25,7 +25,6 @@ import android.aconfig.nano.Aconfig.parsed_flags;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.res.Flags;
-import android.content.res.XmlResourceParser;
import android.os.Environment;
import android.os.Process;
import android.util.ArrayMap;
@@ -247,20 +246,23 @@ public class AconfigFlags {
negated = true;
featureFlag = featureFlag.substring(1).strip();
}
- final Boolean flagValue = getFlagValue(featureFlag);
- boolean shouldSkip = false;
+ Boolean flagValue = getFlagValue(featureFlag);
+ boolean isUndefined = false;
if (flagValue == null) {
- Slog.w(LOG_TAG, "Skipping element " + parser.getName()
- + " due to unknown feature flag " + featureFlag);
- shouldSkip = true;
- } else if (flagValue == negated) {
+ isUndefined = true;
+ flagValue = false;
+ }
+ boolean shouldSkip = false;
+ if (flagValue == negated) {
// Skip if flag==false && attr=="flag" OR flag==true && attr=="!flag" (negated)
- Slog.i(LOG_TAG, "Skipping element " + parser.getName()
- + " behind feature flag " + featureFlag + " = " + flagValue);
shouldSkip = true;
}
if (pkg != null && android.content.pm.Flags.includeFeatureFlagsInPackageCacher()) {
- pkg.addFeatureFlag(featureFlag, flagValue);
+ if (isUndefined) {
+ pkg.addFeatureFlag(featureFlag, null);
+ } else {
+ pkg.addFeatureFlag(featureFlag, flagValue);
+ }
}
return shouldSkip;
}
diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
index ff08dd27225ff52f829fef801cbde5a6d5bcb3fa..3e2f30118b2a2b0d1a50bdbc26539ad09ab0242c 100644
--- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
@@ -67,6 +67,13 @@ interface IStatusBarService
// ---- Methods below are for use by the status bar policy services ----
// You need the STATUS_BAR_SERVICE permission
RegisterStatusBarResult registerStatusBar(IStatusBar callbacks);
+ /**
+ * Registers the status bar for all displays.
+ *
+ * Returns a map of all display IDs (as strings) to their corresponding RegisterStatusBarResult
+ * objects.
+ */
+ Map registerStatusBarForAllDisplays(IStatusBar callbacks);
void onPanelRevealed(boolean clearNotificationEffects, int numItems);
void onPanelHidden();
// Mark current notifications as "seen" and stop ringing, vibrating, blinking.
diff --git a/core/java/com/android/internal/util/ArrayUtils.java b/core/java/com/android/internal/util/ArrayUtils.java
index 1e965c5db7ae0158fc09eb3ef66a571913bc29fa..bda7547087ae536a2f1e04c881c06c4b3977d7f1 100644
--- a/core/java/com/android/internal/util/ArrayUtils.java
+++ b/core/java/com/android/internal/util/ArrayUtils.java
@@ -20,6 +20,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.compat.annotation.UnsupportedAppUsage;
import android.os.Build;
+import android.ravenwood.annotation.RavenwoodReplace;
import android.util.ArraySet;
import android.util.EmptyArray;
@@ -39,6 +40,10 @@ import java.util.function.IntFunction;
/**
* Static utility methods for arrays that aren't already included in {@link java.util.Arrays}.
+ *
+ * Test with:
+ * atest FrameworksUtilTests:com.android.internal.util.ArrayUtilsTest
+ * atest FrameworksUtilTestsRavenwood:com.android.internal.util.ArrayUtilsTest
*/
@android.ravenwood.annotation.RavenwoodKeepWholeClass
public class ArrayUtils {
@@ -84,6 +89,69 @@ public class ArrayUtils {
return (T[])VMRuntime.getRuntime().newUnpaddedArray(clazz, minLen);
}
+ /**
+ * This is like new byte[length], but it allocates the array as non-movable. This
+ * prevents copies of the data from being left on the Java heap as a result of heap compaction.
+ * Use this when the array will contain sensitive data such as a password or cryptographic key
+ * that needs to be wiped from memory when no longer needed. The owner of the array is still
+ * responsible for the zeroization; {@link #zeroize(byte[])} should be used to do so.
+ *
+ * @param length the length of the array to allocate
+ * @return the new array
+ */
+ public static byte[] newNonMovableByteArray(int length) {
+ return (byte[]) VMRuntime.getRuntime().newNonMovableArray(byte.class, length);
+ }
+
+ /**
+ * Like {@link #newNonMovableByteArray(int)}, but allocates a char array.
+ *
+ * @param length the length of the array to allocate
+ * @return the new array
+ */
+ public static char[] newNonMovableCharArray(int length) {
+ return (char[]) VMRuntime.getRuntime().newNonMovableArray(char.class, length);
+ }
+
+ /**
+ * Zeroizes a byte array as securely as possible. Use this when the array contains sensitive
+ * data such as a password or cryptographic key.
+ *
+ * This zeroizes the array in a way that is guaranteed to not be optimized out by the compiler.
+ * If supported by the architecture, it zeroizes the data not just in the L1 data cache but also
+ * in other levels of the memory hierarchy up to and including main memory (but not above that).
+ *
+ * This works on any byte[], but to ensure that copies of the array aren't left on
+ * the Java heap the array should have been allocated with {@link #newNonMovableByteArray(int)}.
+ * Use on other arrays might also introduce performance anomalies.
+ *
+ * @param array the array to zeroize. If null, this method has no effect.
+ */
+ @RavenwoodReplace public static native void zeroize(byte[] array);
+
+ /**
+ * Replacement of the above method for host-side unit testing that doesn't support JNI yet.
+ */
+ public static void zeroize$ravenwood(byte[] array) {
+ if (array != null) {
+ Arrays.fill(array, (byte) 0);
+ }
+ }
+
+ /**
+ * Like {@link #zeroize(byte[])}, but for char arrays.
+ */
+ @RavenwoodReplace public static native void zeroize(char[] array);
+
+ /**
+ * Replacement of the above method for host-side unit testing that doesn't support JNI yet.
+ */
+ public static void zeroize$ravenwood(char[] array) {
+ if (array != null) {
+ Arrays.fill(array, (char) 0);
+ }
+ }
+
/**
* Checks if the beginnings of two byte arrays are equal.
*
diff --git a/core/java/com/android/internal/util/LatencyTracker.java b/core/java/com/android/internal/util/LatencyTracker.java
index 754f77e72f8a38fea58e879d9a64547ef5484ec4..d49afa7356464d6f7af1e7f525adc46ef436e275 100644
--- a/core/java/com/android/internal/util/LatencyTracker.java
+++ b/core/java/com/android/internal/util/LatencyTracker.java
@@ -435,9 +435,11 @@ public class LatencyTracker {
public void startListeningForLatencyTrackerConfigChanges() {
final Context context = ActivityThread.currentApplication();
if (context == null) {
- if (DEBUG) {
- Log.d(TAG, "No application for package: " + ActivityThread.currentPackageName());
- }
+ Log.e(
+ TAG,
+ String.format(
+ "No application for package: %s. Latency Tracker Disabled",
+ ActivityThread.currentPackageName()));
return;
}
if (context.checkCallingOrSelfPermission(READ_DEVICE_CONFIG) != PERMISSION_GRANTED) {
diff --git a/core/java/com/android/internal/vibrator/persistence/SerializedBasicEnvelopeEffect.java b/core/java/com/android/internal/vibrator/persistence/SerializedBasicEnvelopeEffect.java
new file mode 100644
index 0000000000000000000000000000000000000000..a090c7abc2dbbad2614ae227db898a60bccb23cf
--- /dev/null
+++ b/core/java/com/android/internal/vibrator/persistence/SerializedBasicEnvelopeEffect.java
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.vibrator.persistence;
+
+import static com.android.internal.vibrator.persistence.XmlConstants.ATTRIBUTE_DURATION_MS;
+import static com.android.internal.vibrator.persistence.XmlConstants.ATTRIBUTE_INITIAL_SHARPNESS;
+import static com.android.internal.vibrator.persistence.XmlConstants.ATTRIBUTE_INTENSITY;
+import static com.android.internal.vibrator.persistence.XmlConstants.ATTRIBUTE_SHARPNESS;
+import static com.android.internal.vibrator.persistence.XmlConstants.NAMESPACE;
+import static com.android.internal.vibrator.persistence.XmlConstants.TAG_BASIC_ENVELOPE_EFFECT;
+import static com.android.internal.vibrator.persistence.XmlConstants.TAG_CONTROL_POINT;
+
+import android.annotation.NonNull;
+import android.os.VibrationEffect;
+
+import com.android.modules.utils.TypedXmlPullParser;
+import com.android.modules.utils.TypedXmlSerializer;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Locale;
+
+/**
+ * Serialized representation of a basic envelope effect created via
+ * {@link VibrationEffect.BasicEnvelopeBuilder}.
+ *
+ * @hide
+ */
+final class SerializedBasicEnvelopeEffect implements SerializedComposedEffect.SerializedSegment {
+ private final BasicControlPoint[] mControlPoints;
+ private final float mInitialSharpness;
+
+ SerializedBasicEnvelopeEffect(BasicControlPoint[] controlPoints, float initialSharpness) {
+ mControlPoints = controlPoints;
+ mInitialSharpness = initialSharpness;
+ }
+
+ @Override
+ public void write(@NonNull TypedXmlSerializer serializer) throws IOException {
+ serializer.startTag(NAMESPACE, TAG_BASIC_ENVELOPE_EFFECT);
+
+ if (!Float.isNaN(mInitialSharpness)) {
+ serializer.attributeFloat(NAMESPACE, ATTRIBUTE_INITIAL_SHARPNESS, mInitialSharpness);
+ }
+
+ for (BasicControlPoint point : mControlPoints) {
+ serializer.startTag(NAMESPACE, TAG_CONTROL_POINT);
+ serializer.attributeFloat(NAMESPACE, ATTRIBUTE_INTENSITY, point.mIntensity);
+ serializer.attributeFloat(NAMESPACE, ATTRIBUTE_SHARPNESS, point.mSharpness);
+ serializer.attributeLong(NAMESPACE, ATTRIBUTE_DURATION_MS, point.mDurationMs);
+ serializer.endTag(NAMESPACE, TAG_CONTROL_POINT);
+ }
+
+ serializer.endTag(NAMESPACE, TAG_BASIC_ENVELOPE_EFFECT);
+ }
+
+ @Override
+ public void deserializeIntoComposition(@NonNull VibrationEffect.Composition composition) {
+ VibrationEffect.BasicEnvelopeBuilder builder = new VibrationEffect.BasicEnvelopeBuilder();
+
+ if (!Float.isNaN(mInitialSharpness)) {
+ builder.setInitialSharpness(mInitialSharpness);
+ }
+
+ for (BasicControlPoint point : mControlPoints) {
+ builder.addControlPoint(point.mIntensity, point.mSharpness, point.mDurationMs);
+ }
+ composition.addEffect(builder.build());
+ }
+
+ @Override
+ public String toString() {
+ return "SerializedBasicEnvelopeEffect{"
+ + "initialSharpness=" + (Float.isNaN(mInitialSharpness) ? "" : mInitialSharpness)
+ + ", controlPoints=" + Arrays.toString(mControlPoints)
+ + '}';
+ }
+
+ static final class Builder {
+ private final List mControlPoints;
+ private float mInitialSharpness = Float.NaN;
+
+ Builder() {
+ mControlPoints = new ArrayList<>();
+ }
+
+ void setInitialSharpness(float sharpness) {
+ mInitialSharpness = sharpness;
+ }
+
+ void addControlPoint(float intensity, float sharpness, long durationMs) {
+ mControlPoints.add(new BasicControlPoint(intensity, sharpness, durationMs));
+ }
+
+ SerializedBasicEnvelopeEffect build() {
+ return new SerializedBasicEnvelopeEffect(
+ mControlPoints.toArray(new BasicControlPoint[0]), mInitialSharpness);
+ }
+ }
+
+ /** Parser implementation for {@link SerializedBasicEnvelopeEffect}. */
+ static final class Parser {
+
+ @NonNull
+ static SerializedBasicEnvelopeEffect parseNext(@NonNull TypedXmlPullParser parser,
+ @XmlConstants.Flags int flags) throws XmlParserException, IOException {
+ XmlValidator.checkStartTag(parser, TAG_BASIC_ENVELOPE_EFFECT);
+ XmlValidator.checkTagHasNoUnexpectedAttributes(parser, ATTRIBUTE_INITIAL_SHARPNESS);
+
+ Builder builder = new Builder();
+ builder.setInitialSharpness(
+ XmlReader.readAttributeFloatInRange(parser, ATTRIBUTE_INITIAL_SHARPNESS, 0f, 1f,
+ Float.NaN));
+
+ int outerDepth = parser.getDepth();
+
+ // Read all nested tags
+ while (XmlReader.readNextTagWithin(parser, outerDepth)) {
+ parseControlPoint(parser, builder);
+ // Consume tag
+ XmlReader.readEndTag(parser);
+ }
+
+ // Check schema assertions about
+ XmlValidator.checkParserCondition(!builder.mControlPoints.isEmpty(),
+ "Expected tag %s to have at least one control point",
+ TAG_BASIC_ENVELOPE_EFFECT);
+ XmlValidator.checkParserCondition(builder.mControlPoints.getLast().mIntensity == 0,
+ "Basic envelope effects must end at a zero intensity control point");
+
+ return builder.build();
+ }
+
+ private static void parseControlPoint(TypedXmlPullParser parser, Builder builder)
+ throws XmlParserException {
+ XmlValidator.checkStartTag(parser, TAG_CONTROL_POINT);
+ XmlValidator.checkTagHasNoUnexpectedAttributes(
+ parser, ATTRIBUTE_DURATION_MS, ATTRIBUTE_INTENSITY,
+ ATTRIBUTE_SHARPNESS);
+ float intensity = XmlReader.readAttributeFloatInRange(parser, ATTRIBUTE_INTENSITY, 0,
+ 1);
+ float sharpness = XmlReader.readAttributeFloatInRange(parser, ATTRIBUTE_SHARPNESS, 0,
+ 1);
+ long durationMs = XmlReader.readAttributePositiveLong(parser, ATTRIBUTE_DURATION_MS);
+
+ builder.addControlPoint(intensity, sharpness, durationMs);
+ }
+ }
+
+ private static final class BasicControlPoint {
+ private final float mIntensity;
+ private final float mSharpness;
+ private final long mDurationMs;
+
+ BasicControlPoint(float intensity, float sharpness, long durationMs) {
+ mIntensity = intensity;
+ mSharpness = sharpness;
+ mDurationMs = durationMs;
+ }
+
+ @Override
+ public String toString() {
+ return String.format(Locale.ROOT, "(%.2f, %.2f, %dms)", mIntensity, mSharpness,
+ mDurationMs);
+ }
+ }
+}
+
diff --git a/core/java/com/android/internal/vibrator/persistence/SerializedWaveformEnvelopeEffect.java b/core/java/com/android/internal/vibrator/persistence/SerializedWaveformEnvelopeEffect.java
new file mode 100644
index 0000000000000000000000000000000000000000..6a893430d7ad427204ba93df84d7b901d822c2bd
--- /dev/null
+++ b/core/java/com/android/internal/vibrator/persistence/SerializedWaveformEnvelopeEffect.java
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.vibrator.persistence;
+
+import static com.android.internal.vibrator.persistence.XmlConstants.ATTRIBUTE_AMPLITUDE;
+import static com.android.internal.vibrator.persistence.XmlConstants.ATTRIBUTE_DURATION_MS;
+import static com.android.internal.vibrator.persistence.XmlConstants.ATTRIBUTE_FREQUENCY_HZ;
+import static com.android.internal.vibrator.persistence.XmlConstants.ATTRIBUTE_INITIAL_FREQUENCY_HZ;
+import static com.android.internal.vibrator.persistence.XmlConstants.NAMESPACE;
+import static com.android.internal.vibrator.persistence.XmlConstants.TAG_CONTROL_POINT;
+import static com.android.internal.vibrator.persistence.XmlConstants.TAG_WAVEFORM_ENVELOPE_EFFECT;
+
+import android.annotation.NonNull;
+import android.os.VibrationEffect;
+
+import com.android.modules.utils.TypedXmlPullParser;
+import com.android.modules.utils.TypedXmlSerializer;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Locale;
+
+/**
+ * Serialized representation of a waveform envelope effect created via
+ * {@link VibrationEffect.WaveformEnvelopeBuilder}.
+ *
+ * @hide
+ */
+final class SerializedWaveformEnvelopeEffect implements SerializedComposedEffect.SerializedSegment {
+
+ private final WaveformControlPoint[] mControlPoints;
+ private final float mInitialFrequency;
+
+ SerializedWaveformEnvelopeEffect(WaveformControlPoint[] controlPoints, float initialFrequency) {
+ mControlPoints = controlPoints;
+ mInitialFrequency = initialFrequency;
+ }
+
+ @Override
+ public void write(@NonNull TypedXmlSerializer serializer) throws IOException {
+ serializer.startTag(NAMESPACE, TAG_WAVEFORM_ENVELOPE_EFFECT);
+
+ if (!Float.isNaN(mInitialFrequency)) {
+ serializer.attributeFloat(NAMESPACE, ATTRIBUTE_INITIAL_FREQUENCY_HZ, mInitialFrequency);
+ }
+
+ for (WaveformControlPoint point : mControlPoints) {
+ serializer.startTag(NAMESPACE, TAG_CONTROL_POINT);
+ serializer.attributeFloat(NAMESPACE, ATTRIBUTE_AMPLITUDE, point.mAmplitude);
+ serializer.attributeFloat(NAMESPACE, ATTRIBUTE_FREQUENCY_HZ, point.mFrequency);
+ serializer.attributeLong(NAMESPACE, ATTRIBUTE_DURATION_MS, point.mDurationMs);
+ serializer.endTag(NAMESPACE, TAG_CONTROL_POINT);
+ }
+
+ serializer.endTag(NAMESPACE, TAG_WAVEFORM_ENVELOPE_EFFECT);
+ }
+
+ @Override
+ public void deserializeIntoComposition(@NonNull VibrationEffect.Composition composition) {
+ VibrationEffect.WaveformEnvelopeBuilder builder =
+ new VibrationEffect.WaveformEnvelopeBuilder();
+
+ if (!Float.isNaN(mInitialFrequency)) {
+ builder.setInitialFrequencyHz(mInitialFrequency);
+ }
+
+ for (WaveformControlPoint point : mControlPoints) {
+ builder.addControlPoint(point.mAmplitude, point.mFrequency, point.mDurationMs);
+ }
+ composition.addEffect(builder.build());
+ }
+
+ @Override
+ public String toString() {
+ return "SerializedWaveformEnvelopeEffect{"
+ + "InitialFrequency=" + (Float.isNaN(mInitialFrequency) ? "" : mInitialFrequency)
+ + ", controlPoints=" + Arrays.toString(mControlPoints)
+ + '}';
+ }
+
+ static final class Builder {
+ private final List mControlPoints;
+ private float mInitialFrequencyHz = Float.NaN;
+
+ Builder() {
+ mControlPoints = new ArrayList<>();
+ }
+
+ void setInitialFrequencyHz(float frequencyHz) {
+ mInitialFrequencyHz = frequencyHz;
+ }
+
+ void addControlPoint(float amplitude, float frequencyHz, long durationMs) {
+ mControlPoints.add(new WaveformControlPoint(amplitude, frequencyHz, durationMs));
+ }
+
+ SerializedWaveformEnvelopeEffect build() {
+ return new SerializedWaveformEnvelopeEffect(
+ mControlPoints.toArray(new WaveformControlPoint[0]), mInitialFrequencyHz);
+ }
+ }
+
+ /** Parser implementation for {@link SerializedWaveformEnvelopeEffect}. */
+ static final class Parser {
+
+ @NonNull
+ static SerializedWaveformEnvelopeEffect parseNext(@NonNull TypedXmlPullParser parser,
+ @XmlConstants.Flags int flags) throws XmlParserException, IOException {
+ XmlValidator.checkStartTag(parser, TAG_WAVEFORM_ENVELOPE_EFFECT);
+ XmlValidator.checkTagHasNoUnexpectedAttributes(parser, ATTRIBUTE_INITIAL_FREQUENCY_HZ);
+
+ Builder builder = new Builder();
+ builder.setInitialFrequencyHz(
+ XmlReader.readAttributePositiveFloat(parser, ATTRIBUTE_INITIAL_FREQUENCY_HZ,
+ Float.NaN));
+
+ int outerDepth = parser.getDepth();
+
+ while (XmlReader.readNextTagWithin(parser, outerDepth)) {
+ parseControlPoint(parser, builder);
+ // Consume tag
+ XmlReader.readEndTag(parser);
+ }
+
+ // Check schema assertions about
+ XmlValidator.checkParserCondition(!builder.mControlPoints.isEmpty(),
+ "Expected tag %s to have at least one control point",
+ TAG_WAVEFORM_ENVELOPE_EFFECT);
+
+ return builder.build();
+ }
+
+ private static void parseControlPoint(TypedXmlPullParser parser, Builder builder)
+ throws XmlParserException {
+ XmlValidator.checkStartTag(parser, TAG_CONTROL_POINT);
+ XmlValidator.checkTagHasNoUnexpectedAttributes(
+ parser, ATTRIBUTE_DURATION_MS, ATTRIBUTE_AMPLITUDE,
+ ATTRIBUTE_FREQUENCY_HZ);
+ float amplitude = XmlReader.readAttributeFloatInRange(parser, ATTRIBUTE_AMPLITUDE, 0,
+ 1);
+ float frequencyHz = XmlReader.readAttributePositiveFloat(parser,
+ ATTRIBUTE_FREQUENCY_HZ);
+ long durationMs = XmlReader.readAttributePositiveLong(parser, ATTRIBUTE_DURATION_MS);
+
+ builder.addControlPoint(amplitude, frequencyHz, durationMs);
+ }
+ }
+
+ private static final class WaveformControlPoint {
+ private final float mAmplitude;
+ private final float mFrequency;
+ private final long mDurationMs;
+
+ WaveformControlPoint(float amplitude, float frequency, long durationMs) {
+ mAmplitude = amplitude;
+ mFrequency = frequency;
+ mDurationMs = durationMs;
+ }
+
+ @Override
+ public String toString() {
+ return String.format(Locale.ROOT, "(%.2f, %.2f, %dms)", mAmplitude, mFrequency,
+ mDurationMs);
+ }
+ }
+}
diff --git a/core/java/com/android/internal/vibrator/persistence/VibrationEffectXmlParser.java b/core/java/com/android/internal/vibrator/persistence/VibrationEffectXmlParser.java
index a9fbcafa128d38bcd7997763cccbc1f44b99d7c4..314bfe40ee0b5da89f13bbd1e6047436b5d3a4d2 100644
--- a/core/java/com/android/internal/vibrator/persistence/VibrationEffectXmlParser.java
+++ b/core/java/com/android/internal/vibrator/persistence/VibrationEffectXmlParser.java
@@ -16,11 +16,13 @@
package com.android.internal.vibrator.persistence;
+import static com.android.internal.vibrator.persistence.XmlConstants.TAG_BASIC_ENVELOPE_EFFECT;
import static com.android.internal.vibrator.persistence.XmlConstants.TAG_PREDEFINED_EFFECT;
import static com.android.internal.vibrator.persistence.XmlConstants.TAG_PRIMITIVE_EFFECT;
import static com.android.internal.vibrator.persistence.XmlConstants.TAG_VENDOR_EFFECT;
import static com.android.internal.vibrator.persistence.XmlConstants.TAG_VIBRATION_EFFECT;
import static com.android.internal.vibrator.persistence.XmlConstants.TAG_WAVEFORM_EFFECT;
+import static com.android.internal.vibrator.persistence.XmlConstants.TAG_WAVEFORM_ENVELOPE_EFFECT;
import android.annotation.NonNull;
import android.os.VibrationEffect;
@@ -92,6 +94,32 @@ import java.util.List;
* }
*
*
+ * * Waveform Envelope effects
+ *
+ *
+ * {@code
+ *
+ *
+ *
+ *
+ *
+ *
+ * }
+ *
+ *
+ * * Basic Envelope effects
+ *
+ *
+ * {@code
+ *
+ *
+ *
+ *
+ *
+ *
+ * }
+ *
+ *
* @hide
*/
public class VibrationEffectXmlParser {
@@ -151,6 +179,18 @@ public class VibrationEffectXmlParser {
serializedVibration = new SerializedComposedEffect(
SerializedAmplitudeStepWaveform.Parser.parseNext(parser));
break;
+ case TAG_WAVEFORM_ENVELOPE_EFFECT:
+ if (Flags.normalizedPwleEffects()) {
+ serializedVibration = new SerializedComposedEffect(
+ SerializedWaveformEnvelopeEffect.Parser.parseNext(parser, flags));
+ break;
+ } // else fall through
+ case TAG_BASIC_ENVELOPE_EFFECT:
+ if (Flags.normalizedPwleEffects()) {
+ serializedVibration = new SerializedComposedEffect(
+ SerializedBasicEnvelopeEffect.Parser.parseNext(parser, flags));
+ break;
+ } // else fall through
default:
throw new XmlParserException("Unexpected tag " + parser.getName()
+ " in vibration tag " + vibrationTagName);
diff --git a/core/java/com/android/internal/vibrator/persistence/VibrationEffectXmlSerializer.java b/core/java/com/android/internal/vibrator/persistence/VibrationEffectXmlSerializer.java
index cb834a5eac7e816eaaedabcc54e29eb633205116..ebe34344c6f54a8f58b41959c51c654a7afd72d4 100644
--- a/core/java/com/android/internal/vibrator/persistence/VibrationEffectXmlSerializer.java
+++ b/core/java/com/android/internal/vibrator/persistence/VibrationEffectXmlSerializer.java
@@ -19,9 +19,11 @@ package com.android.internal.vibrator.persistence;
import android.annotation.NonNull;
import android.os.PersistableBundle;
import android.os.VibrationEffect;
+import android.os.vibrator.BasicPwleSegment;
import android.os.vibrator.Flags;
import android.os.vibrator.PrebakedSegment;
import android.os.vibrator.PrimitiveSegment;
+import android.os.vibrator.PwleSegment;
import android.os.vibrator.StepSegment;
import android.os.vibrator.VibrationEffectSegment;
@@ -45,6 +47,8 @@ import java.util.List;
*
A composition created exclusively via
* {@link VibrationEffect.Composition#addPrimitive(int, float, int)}
*
{@link VibrationEffect.BasicEnvelopeBuilder}
*
*
* @hide
@@ -77,6 +81,12 @@ public final class VibrationEffectXmlSerializer {
if (firstSegment instanceof PrimitiveSegment) {
return serializePrimitiveEffect(composed);
}
+ if (Flags.normalizedPwleEffects() && firstSegment instanceof PwleSegment) {
+ return serializeWaveformEnvelopeEffect(composed);
+ }
+ if (Flags.normalizedPwleEffects() && firstSegment instanceof BasicPwleSegment) {
+ return serializeBasicEnvelopeEffect(composed);
+ }
return serializeWaveformEffect(composed);
}
@@ -110,6 +120,53 @@ public final class VibrationEffectXmlSerializer {
return new SerializedComposedEffect(primitives);
}
+ private static SerializedComposedEffect serializeWaveformEnvelopeEffect(
+ VibrationEffect.Composed effect) throws XmlSerializerException {
+ SerializedWaveformEnvelopeEffect.Builder builder =
+ new SerializedWaveformEnvelopeEffect.Builder();
+ List segments = effect.getSegments();
+ XmlValidator.checkSerializerCondition(effect.getRepeatIndex() == -1,
+ "Unsupported repeating waveform envelope effect %s", effect);
+ for (int i = 0; i < segments.size(); i++) {
+ XmlValidator.checkSerializerCondition(segments.get(i) instanceof PwleSegment,
+ "Unsupported segment for waveform envelope effect %s", segments.get(i));
+ PwleSegment segment = (PwleSegment) segments.get(i);
+
+ if (i == 0 && segment.getStartFrequencyHz() != segment.getEndFrequencyHz()) {
+ // Initial frequency explicitly defined.
+ builder.setInitialFrequencyHz(segment.getStartFrequencyHz());
+ }
+
+ builder.addControlPoint(segment.getEndAmplitude(), segment.getEndFrequencyHz(),
+ segment.getDuration());
+ }
+
+ return new SerializedComposedEffect(builder.build());
+ }
+
+ private static SerializedComposedEffect serializeBasicEnvelopeEffect(
+ VibrationEffect.Composed effect) throws XmlSerializerException {
+ SerializedBasicEnvelopeEffect.Builder builder = new SerializedBasicEnvelopeEffect.Builder();
+ List segments = effect.getSegments();
+ XmlValidator.checkSerializerCondition(effect.getRepeatIndex() == -1,
+ "Unsupported repeating basic envelope effect %s", effect);
+ for (int i = 0; i < segments.size(); i++) {
+ XmlValidator.checkSerializerCondition(segments.get(i) instanceof BasicPwleSegment,
+ "Unsupported segment for basic envelope effect %s", segments.get(i));
+ BasicPwleSegment segment = (BasicPwleSegment) segments.get(i);
+
+ if (i == 0 && segment.getStartSharpness() != segment.getEndSharpness()) {
+ // Initial sharpness explicitly defined.
+ builder.setInitialSharpness(segment.getStartSharpness());
+ }
+
+ builder.addControlPoint(segment.getEndIntensity(), segment.getEndSharpness(),
+ segment.getDuration());
+ }
+
+ return new SerializedComposedEffect(builder.build());
+ }
+
private static SerializedComposedEffect serializeWaveformEffect(
VibrationEffect.Composed effect) throws XmlSerializerException {
SerializedAmplitudeStepWaveform.Builder serializedWaveformBuilder =
diff --git a/core/java/com/android/internal/vibrator/persistence/XmlConstants.java b/core/java/com/android/internal/vibrator/persistence/XmlConstants.java
index 4122215a2b04a5d197a0d26cb9f0b46cb28dff45..df262cfecd5ac472cbec621601973a62f3915e25 100644
--- a/core/java/com/android/internal/vibrator/persistence/XmlConstants.java
+++ b/core/java/com/android/internal/vibrator/persistence/XmlConstants.java
@@ -42,14 +42,22 @@ public final class XmlConstants {
public static final String TAG_PREDEFINED_EFFECT = "predefined-effect";
public static final String TAG_PRIMITIVE_EFFECT = "primitive-effect";
public static final String TAG_VENDOR_EFFECT = "vendor-effect";
+ public static final String TAG_WAVEFORM_ENVELOPE_EFFECT = "waveform-envelope-effect";
+ public static final String TAG_BASIC_ENVELOPE_EFFECT = "basic-envelope-effect";
public static final String TAG_WAVEFORM_EFFECT = "waveform-effect";
public static final String TAG_WAVEFORM_ENTRY = "waveform-entry";
public static final String TAG_REPEATING = "repeating";
+ public static final String TAG_CONTROL_POINT = "control-point";
public static final String ATTRIBUTE_NAME = "name";
public static final String ATTRIBUTE_FALLBACK = "fallback";
public static final String ATTRIBUTE_DURATION_MS = "durationMs";
public static final String ATTRIBUTE_AMPLITUDE = "amplitude";
+ public static final String ATTRIBUTE_FREQUENCY_HZ = "frequencyHz";
+ public static final String ATTRIBUTE_INITIAL_FREQUENCY_HZ = "initialFrequencyHz";
+ public static final String ATTRIBUTE_INTENSITY = "intensity";
+ public static final String ATTRIBUTE_SHARPNESS = "sharpness";
+ public static final String ATTRIBUTE_INITIAL_SHARPNESS = "initialSharpness";
public static final String ATTRIBUTE_SCALE = "scale";
public static final String ATTRIBUTE_DELAY_MS = "delayMs";
public static final String ATTRIBUTE_DELAY_TYPE = "delayType";
diff --git a/core/java/com/android/internal/vibrator/persistence/XmlReader.java b/core/java/com/android/internal/vibrator/persistence/XmlReader.java
index 0ac6fefc8cb2de37d260e3de9031ce45cd49fa7b..1c4a783f0fe47a8d6a1080d12dc996cb1ba938ef 100644
--- a/core/java/com/android/internal/vibrator/persistence/XmlReader.java
+++ b/core/java/com/android/internal/vibrator/persistence/XmlReader.java
@@ -221,12 +221,63 @@ public final class XmlReader {
if (parser.getAttributeIndex(NAMESPACE, attrName) < 0) {
return defaultValue;
}
+
+ return readAttributeFloatInRange(parser, attrName, lowerInclusive, upperInclusive);
+ }
+
+ /**
+ * Read attribute from current tag as a float within given inclusive range.
+ */
+ public static float readAttributeFloatInRange(
+ TypedXmlPullParser parser, String attrName, float lowerInclusive,
+ float upperInclusive) throws XmlParserException {
String tagName = parser.getName();
float value = readAttributeFloat(parser, attrName);
XmlValidator.checkParserCondition(value >= lowerInclusive && value <= upperInclusive,
- "Unexpected %s = %f in tag %s, expected %s in [%f, %f]",
- attrName, value, tagName, attrName, lowerInclusive, upperInclusive);
+ "Unexpected %s = %f in tag %s, expected %s in [%f, %f]", attrName, value, tagName,
+ attrName, lowerInclusive, upperInclusive);
+ return value;
+ }
+
+ /**
+ * Read attribute from current tag as a positive float, returning default value if attribute
+ * is missing.
+ */
+ public static float readAttributePositiveFloat(TypedXmlPullParser parser, String attrName,
+ float defaultValue) throws XmlParserException {
+ if (parser.getAttributeIndex(NAMESPACE, attrName) < 0) {
+ return defaultValue;
+ }
+
+ return readAttributePositiveFloat(parser, attrName);
+ }
+
+ /**
+ * Read attribute from current tag as a positive float.
+ */
+ public static float readAttributePositiveFloat(TypedXmlPullParser parser, String attrName)
+ throws XmlParserException {
+ String tagName = parser.getName();
+ float value = readAttributeFloat(parser, attrName);
+
+ XmlValidator.checkParserCondition(value > 0,
+ "Unexpected %s = %d in tag %s, expected %s > 0", attrName, value, tagName,
+ attrName);
+ return value;
+ }
+
+ /**
+ * Read attribute from current tag as a positive long.
+ */
+ public static long readAttributePositiveLong(TypedXmlPullParser parser, String attrName)
+ throws XmlParserException {
+ String tagName = parser.getName();
+ long value = readAttributeLong(parser, attrName);
+
+ XmlValidator.checkParserCondition(value > 0,
+ "Unexpected %s = %d in tag %s, expected %s > 0", attrName, value, tagName,
+ attrName);
return value;
}
@@ -251,4 +302,15 @@ public final class XmlReader {
throw XmlParserException.createFromPullParserException(tagName, attrName, rawValue, e);
}
}
+
+ private static long readAttributeLong(TypedXmlPullParser parser, String attrName)
+ throws XmlParserException {
+ String tagName = parser.getName();
+ try {
+ return parser.getAttributeLong(NAMESPACE, attrName);
+ } catch (XmlPullParserException e) {
+ String rawValue = parser.getAttributeValue(NAMESPACE, attrName);
+ throw XmlParserException.createFromPullParserException(tagName, attrName, rawValue, e);
+ }
+ }
}
diff --git a/core/java/com/android/internal/view/ScrollCaptureInternal.java b/core/java/com/android/internal/view/ScrollCaptureInternal.java
index 72b5488f4bac411bb5425dcc792ea256eff5b8d4..0ed0613d02e69f87a56376680e1802fc08907854 100644
--- a/core/java/com/android/internal/view/ScrollCaptureInternal.java
+++ b/core/java/com/android/internal/view/ScrollCaptureInternal.java
@@ -16,6 +16,8 @@
package com.android.internal.view;
+import static android.view.flags.Flags.scrollCaptureRelaxScrollViewCriteria;
+
import android.annotation.Nullable;
import android.content.Context;
import android.content.res.Resources;
@@ -49,7 +51,7 @@ public class ScrollCaptureInternal {
public static final int TYPE_FIXED = 0;
/**
- * Slides a single child view using mScrollX/mScrollY.
+ * Moves the viewport across absolute positioned child views using the scrollY property.
*/
public static final int TYPE_SCROLLING = 1;
@@ -63,7 +65,7 @@ public class ScrollCaptureInternal {
/**
* Unknown scrollable view with no child views (or not a subclass of ViewGroup).
*/
- private static final int TYPE_OPAQUE = 3;
+ public static final int TYPE_OPAQUE = 3;
/**
* Performs tests on the given View and determines:
@@ -73,7 +75,7 @@ public class ScrollCaptureInternal {
* This needs to be fast and not alloc memory. It's called on everything in the tree not marked
* as excluded during scroll capture search.
*/
- private static int detectScrollingType(View view) {
+ public static int detectScrollingType(View view) {
// Confirm that it can scroll.
if (!(view.canScrollVertically(DOWN) || view.canScrollVertically(UP))) {
// Nothing to scroll here, move along.
@@ -95,25 +97,25 @@ public class ScrollCaptureInternal {
if (DEBUG_VERBOSE) {
Log.v(TAG, "hint: is a subclass of ViewGroup");
}
-
- // ScrollViews accept only a single child.
- if (((ViewGroup) view).getChildCount() > 1) {
- if (DEBUG_VERBOSE) {
- Log.v(TAG, "hint: scrollable with multiple children");
+ // Flag: Optionally allow ScrollView-like ViewGroups which have more than one child view.
+ if (!scrollCaptureRelaxScrollViewCriteria()) {
+ // ScrollViews accept only a single child.
+ if (((ViewGroup) view).getChildCount() > 1) {
+ if (DEBUG_VERBOSE) {
+ Log.v(TAG, "hint: scrollable with multiple children");
+ }
+ return TYPE_RECYCLING;
}
- return TYPE_RECYCLING;
}
// At least one child view is required.
- if (((ViewGroup) view).getChildCount() < 1) {
- if (DEBUG_VERBOSE) {
- Log.v(TAG, "scrollable with no children");
- }
+ if (((ViewGroup) view).getChildCount() == 0) {
+ Log.w(TAG, "scrollable but no children!");
return TYPE_OPAQUE;
}
if (DEBUG_VERBOSE) {
Log.v(TAG, "hint: single child view");
}
- //Because recycling containers don't use scrollY, a non-zero value means Scroll view.
+ // Because recycling containers don't use scrollY, a non-zero value means Scroll view.
if (view.getScrollY() != 0) {
if (DEBUG_VERBOSE) {
Log.v(TAG, "hint: scrollY != 0");
@@ -132,7 +134,7 @@ public class ScrollCaptureInternal {
Log.v(TAG, "hint: cannot be scrolled up");
}
- // canScrollVertically(UP) == false, getScrollY() == 0, getChildCount() == 1.
+ // canScrollVertically(UP) == false, getScrollY() == 0, getChildCount() >= 1.
// For Recycling containers, this should be a no-op (RecyclerView logs a warning)
view.scrollTo(view.getScrollX(), 1);
diff --git a/core/java/com/android/internal/widget/CallLayout.java b/core/java/com/android/internal/widget/CallLayout.java
index c85257578492ee10df2489b4b2eb17835f106016..3a7c75afdd14402fe8a6020e442f932e0efa977d 100644
--- a/core/java/com/android/internal/widget/CallLayout.java
+++ b/core/java/com/android/internal/widget/CallLayout.java
@@ -30,7 +30,6 @@ import android.util.AttributeSet;
import android.view.RemotableViewMethod;
import android.widget.FrameLayout;
import android.widget.RemoteViews;
-import android.widget.TextView;
import android.widget.flags.Flags;
import com.android.internal.R;
@@ -59,7 +58,6 @@ public class CallLayout extends FrameLayout {
private CachingIconView mConversationIconView;
private CachingIconView mIcon;
private CachingIconView mConversationIconBadgeBg;
- private TextView mConversationText;
public CallLayout(@NonNull Context context) {
super(context);
@@ -83,7 +81,6 @@ public class CallLayout extends FrameLayout {
protected void onFinishInflate() {
super.onFinishInflate();
mPeopleHelper.init(getContext());
- mConversationText = findViewById(R.id.conversation_text);
mConversationIconView = findViewById(R.id.conversation_icon);
mIcon = findViewById(R.id.icon);
mConversationIconBadgeBg = findViewById(R.id.conversation_icon_badge_bg);
diff --git a/core/java/com/android/internal/widget/ConversationLayout.java b/core/java/com/android/internal/widget/ConversationLayout.java
index 4b90420a75eecdaefccc2e0a98958aaaf69ea3ee..b3ab5d3cd258f4380cd977f7efe8517914447a5e 100644
--- a/core/java/com/android/internal/widget/ConversationLayout.java
+++ b/core/java/com/android/internal/widget/ConversationLayout.java
@@ -777,37 +777,40 @@ public class ConversationLayout extends FrameLayout
}
- int conversationAvatarSize;
- int facepileAvatarSize;
- int facePileBackgroundSize;
- if (mIsCollapsed) {
- conversationAvatarSize = mConversationAvatarSize;
- facepileAvatarSize = mFacePileAvatarSize;
- facePileBackgroundSize = facepileAvatarSize + 2 * mFacePileProtectionWidth;
- } else {
- conversationAvatarSize = mConversationAvatarSizeExpanded;
- facepileAvatarSize = mFacePileAvatarSizeExpandedGroup;
- facePileBackgroundSize = facepileAvatarSize + 2 * mFacePileProtectionWidthExpanded;
- }
- LayoutParams layoutParams = (LayoutParams) mConversationFacePile.getLayoutParams();
- layoutParams.width = conversationAvatarSize;
- layoutParams.height = conversationAvatarSize;
- mConversationFacePile.setLayoutParams(layoutParams);
+ if (!notificationsRedesignTemplates()) {
+ // We no longer need to update the size based on expansion state.
+ int conversationAvatarSize;
+ int facepileAvatarSize;
+ int facePileBackgroundSize;
+ if (mIsCollapsed) {
+ conversationAvatarSize = mConversationAvatarSize;
+ facepileAvatarSize = mFacePileAvatarSize;
+ facePileBackgroundSize = facepileAvatarSize + 2 * mFacePileProtectionWidth;
+ } else {
+ conversationAvatarSize = mConversationAvatarSizeExpanded;
+ facepileAvatarSize = mFacePileAvatarSizeExpandedGroup;
+ facePileBackgroundSize = facepileAvatarSize + 2 * mFacePileProtectionWidthExpanded;
+ }
+ LayoutParams layoutParams = (LayoutParams) mConversationFacePile.getLayoutParams();
+ layoutParams.width = conversationAvatarSize;
+ layoutParams.height = conversationAvatarSize;
+ mConversationFacePile.setLayoutParams(layoutParams);
- layoutParams = (LayoutParams) bottomView.getLayoutParams();
- layoutParams.width = facepileAvatarSize;
- layoutParams.height = facepileAvatarSize;
- bottomView.setLayoutParams(layoutParams);
+ layoutParams = (LayoutParams) bottomView.getLayoutParams();
+ layoutParams.width = facepileAvatarSize;
+ layoutParams.height = facepileAvatarSize;
+ bottomView.setLayoutParams(layoutParams);
- layoutParams = (LayoutParams) topView.getLayoutParams();
- layoutParams.width = facepileAvatarSize;
- layoutParams.height = facepileAvatarSize;
- topView.setLayoutParams(layoutParams);
+ layoutParams = (LayoutParams) topView.getLayoutParams();
+ layoutParams.width = facepileAvatarSize;
+ layoutParams.height = facepileAvatarSize;
+ topView.setLayoutParams(layoutParams);
- layoutParams = (LayoutParams) bottomBackground.getLayoutParams();
- layoutParams.width = facePileBackgroundSize;
- layoutParams.height = facePileBackgroundSize;
- bottomBackground.setLayoutParams(layoutParams);
+ layoutParams = (LayoutParams) bottomBackground.getLayoutParams();
+ layoutParams.width = facePileBackgroundSize;
+ layoutParams.height = facePileBackgroundSize;
+ bottomBackground.setLayoutParams(layoutParams);
+ }
}
/**
@@ -832,6 +835,11 @@ public class ConversationLayout extends FrameLayout
* update the icon position and sizing
*/
private void updateIconPositionAndSize() {
+ if (notificationsRedesignTemplates()) {
+ // Icon size is fixed in the redesign.
+ return;
+ }
+
int badgeProtrusion;
int conversationAvatarSize;
if (mIsOneToOne || mIsCollapsed) {
@@ -864,6 +872,11 @@ public class ConversationLayout extends FrameLayout
}
private void updatePaddingsBasedOnContentAvailability() {
+ if (notificationsRedesignTemplates()) {
+ // group icons have the same size as 1:1 conversations
+ return;
+ }
+
// groups have avatars that need more spacing
mMessagingLinearLayout.setSpacing(
mIsOneToOne ? mMessageSpacingStandard : mMessageSpacingGroup);
diff --git a/core/java/com/android/internal/widget/flags.aconfig b/core/java/com/android/internal/widget/flags.aconfig
new file mode 100644
index 0000000000000000000000000000000000000000..f05aa4f460a52719ada93942c29eb7e79f68c225
--- /dev/null
+++ b/core/java/com/android/internal/widget/flags.aconfig
@@ -0,0 +1,9 @@
+package: "com.android.internal.widget.flags"
+container: "system"
+
+flag {
+ name: "hide_last_char_with_physical_input"
+ namespace: "input"
+ description: "Feature flag for changing the default of hiding the last interacted symbol when a physical input device is present"
+ bug: "339270220"
+}
diff --git a/core/java/com/android/internal/widget/floatingtoolbar/LocalFloatingToolbarPopup.java b/core/java/com/android/internal/widget/floatingtoolbar/LocalFloatingToolbarPopup.java
index 38685b652c5081e5c576a03dfc9c1f2bda723ce7..5177a03600327eeeefef0a9707e0cb65b8ec5f49 100644
--- a/core/java/com/android/internal/widget/floatingtoolbar/LocalFloatingToolbarPopup.java
+++ b/core/java/com/android/internal/widget/floatingtoolbar/LocalFloatingToolbarPopup.java
@@ -435,10 +435,15 @@ public final class LocalFloatingToolbarPopup implements FloatingToolbarPopup {
private void refreshCoordinatesAndOverflowDirection(Rect contentRectOnScreen) {
refreshViewPort();
- // Initialize x ensuring that the toolbar isn't rendered behind the nav bar in
- // landscape.
- final int x = Math.clamp(contentRectOnScreen.centerX() - mPopupWindow.getWidth() / 2,
- mViewPortOnScreen.left, mViewPortOnScreen.right - mPopupWindow.getWidth());
+ final int x;
+ if (mPopupWindow.getWidth() > mViewPortOnScreen.width()) {
+ // Not enough space - prefer to position as far left as possible
+ x = mViewPortOnScreen.left;
+ } else {
+ // Initialize x ensuring that the toolbar isn't rendered behind the system bar insets
+ x = Math.clamp(contentRectOnScreen.centerX() - mPopupWindow.getWidth() / 2,
+ mViewPortOnScreen.left, mViewPortOnScreen.right - mPopupWindow.getWidth());
+ }
final int y;
diff --git a/core/java/com/android/internal/widget/remotecompose/accessibility/AndroidPlatformSemanticNodeApplier.java b/core/java/com/android/internal/widget/remotecompose/accessibility/AndroidPlatformSemanticNodeApplier.java
new file mode 100644
index 0000000000000000000000000000000000000000..1bdbaa48d18ca30debc46b05db23bb51cb3be044
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/accessibility/AndroidPlatformSemanticNodeApplier.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.accessibility;
+
+import android.graphics.Rect;
+import android.view.accessibility.AccessibilityNodeInfo;
+
+public class AndroidPlatformSemanticNodeApplier
+ extends BaseSemanticNodeApplier {
+
+ private static final String ROLE_DESCRIPTION_KEY = "AccessibilityNodeInfo.roleDescription";
+
+ @Override
+ protected void setClickable(AccessibilityNodeInfo nodeInfo, boolean clickable) {
+ nodeInfo.setClickable(clickable);
+ if (clickable) {
+ nodeInfo.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_CLICK);
+ } else {
+ nodeInfo.removeAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_CLICK);
+ }
+ }
+
+ @Override
+ protected void setEnabled(AccessibilityNodeInfo nodeInfo, boolean enabled) {
+ nodeInfo.setEnabled(enabled);
+ }
+
+ @Override
+ protected CharSequence getStateDescription(AccessibilityNodeInfo nodeInfo) {
+ return nodeInfo.getStateDescription();
+ }
+
+ @Override
+ protected void setStateDescription(AccessibilityNodeInfo nodeInfo, CharSequence description) {
+ nodeInfo.setStateDescription(description);
+ }
+
+ @Override
+ protected void setRoleDescription(AccessibilityNodeInfo nodeInfo, String description) {
+ nodeInfo.getExtras().putCharSequence(ROLE_DESCRIPTION_KEY, description);
+ }
+
+ @Override
+ protected CharSequence getText(AccessibilityNodeInfo nodeInfo) {
+ return nodeInfo.getText();
+ }
+
+ @Override
+ protected void setText(AccessibilityNodeInfo nodeInfo, CharSequence text) {
+ nodeInfo.setText(text);
+ }
+
+ @Override
+ protected CharSequence getContentDescription(AccessibilityNodeInfo nodeInfo) {
+ return nodeInfo.getContentDescription();
+ }
+
+ @Override
+ protected void setContentDescription(AccessibilityNodeInfo nodeInfo, CharSequence description) {
+ nodeInfo.setContentDescription(description);
+ }
+
+ @Override
+ protected void setBoundsInScreen(AccessibilityNodeInfo nodeInfo, Rect bounds) {
+ nodeInfo.setBoundsInParent(bounds);
+ nodeInfo.setBoundsInScreen(bounds);
+ }
+
+ @Override
+ protected void setUniqueId(AccessibilityNodeInfo nodeInfo, String id) {
+ nodeInfo.setUniqueId(id);
+ }
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/accessibility/BaseSemanticNodeApplier.java b/core/java/com/android/internal/widget/remotecompose/accessibility/BaseSemanticNodeApplier.java
new file mode 100644
index 0000000000000000000000000000000000000000..228afb88b5de8463920b04205f6b8036d1da4055
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/accessibility/BaseSemanticNodeApplier.java
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.accessibility;
+
+import android.graphics.Rect;
+
+import com.android.internal.widget.remotecompose.core.operations.layout.Component;
+import com.android.internal.widget.remotecompose.core.semantics.AccessibilitySemantics;
+import com.android.internal.widget.remotecompose.core.semantics.AccessibleComponent;
+import com.android.internal.widget.remotecompose.core.semantics.CoreSemantics;
+
+import java.util.List;
+
+/**
+ * Base class for applying semantic information to a node.
+ *
+ *
This class provides common functionality for applying semantic information extracted from
+ * Compose UI components to a node representation used for accessibility purposes. It handles
+ * applying properties like content description, text, role, clickability, and bounds.
+ *
+ *
Subclasses are responsible for implementing methods to actually set these properties on the
+ * specific node type they handle.
+ *
+ * @param The type of node this applier works with.
+ */
+public abstract class BaseSemanticNodeApplier implements SemanticNodeApplier {
+ @Override
+ public void applyComponent(
+ RemoteComposeDocumentAccessibility remoteComposeAccessibility,
+ N nodeInfo,
+ Component component,
+ List semantics) {
+ float[] locationInWindow = new float[2];
+ component.getLocationInWindow(locationInWindow);
+ Rect bounds =
+ new Rect(
+ (int) locationInWindow[0],
+ (int) locationInWindow[1],
+ (int) (locationInWindow[0] + component.getWidth()),
+ (int) (locationInWindow[1] + component.getHeight()));
+ setBoundsInScreen(nodeInfo, bounds);
+
+ setUniqueId(nodeInfo, String.valueOf(component.getComponentId()));
+
+ if (component instanceof AccessibleComponent) {
+ applyContentDescription(
+ ((AccessibleComponent) component).getContentDescriptionId(),
+ nodeInfo,
+ remoteComposeAccessibility);
+
+ applyText(
+ ((AccessibleComponent) component).getTextId(),
+ nodeInfo,
+ remoteComposeAccessibility);
+
+ applyRole(((AccessibleComponent) component).getRole(), nodeInfo);
+ }
+
+ applySemantics(remoteComposeAccessibility, nodeInfo, semantics);
+
+ if (getText(nodeInfo) == null && getContentDescription(nodeInfo) == null) {
+ setContentDescription(nodeInfo, "");
+ }
+ }
+
+ protected void applySemantics(
+ RemoteComposeDocumentAccessibility remoteComposeAccessibility,
+ N nodeInfo,
+ List semantics) {
+ for (AccessibilitySemantics semantic : semantics) {
+ if (semantic.isInterestingForSemantics()) {
+ if (semantic instanceof CoreSemantics) {
+ CoreSemantics coreSemantics = (CoreSemantics) semantic;
+ applyCoreSemantics(remoteComposeAccessibility, nodeInfo, coreSemantics);
+ } else if (semantic instanceof AccessibleComponent) {
+ AccessibleComponent accessibleComponent = (AccessibleComponent) semantic;
+ if (accessibleComponent.isClickable()) {
+ setClickable(nodeInfo, true);
+ }
+
+ if (accessibleComponent.getContentDescriptionId() != null) {
+ applyContentDescription(
+ accessibleComponent.getContentDescriptionId(),
+ nodeInfo,
+ remoteComposeAccessibility);
+ }
+
+ if (accessibleComponent.getTextId() != null) {
+ applyText(
+ accessibleComponent.getTextId(),
+ nodeInfo,
+ remoteComposeAccessibility);
+ }
+
+ applyRole(accessibleComponent.getRole(), nodeInfo);
+ }
+ }
+ }
+ }
+
+ protected void applyCoreSemantics(
+ RemoteComposeDocumentAccessibility remoteComposeAccessibility,
+ N nodeInfo,
+ CoreSemantics coreSemantics) {
+ applyContentDescription(
+ coreSemantics.getContentDescriptionId(), nodeInfo, remoteComposeAccessibility);
+
+ applyRole(coreSemantics.getRole(), nodeInfo);
+
+ applyText(coreSemantics.getTextId(), nodeInfo, remoteComposeAccessibility);
+
+ applyStateDescription(
+ coreSemantics.getStateDescriptionId(), nodeInfo, remoteComposeAccessibility);
+
+ if (!coreSemantics.mEnabled) {
+ setEnabled(nodeInfo, false);
+ }
+ }
+
+ protected void applyStateDescription(
+ Integer stateDescriptionId,
+ N nodeInfo,
+ RemoteComposeDocumentAccessibility remoteComposeAccessibility) {
+ if (stateDescriptionId != null) {
+ setStateDescription(
+ nodeInfo,
+ appendNullable(
+ getStateDescription(nodeInfo),
+ remoteComposeAccessibility.stringValue(stateDescriptionId)));
+ }
+ }
+
+ protected void applyRole(AccessibleComponent.Role role, N nodeInfo) {
+ if (role != null) {
+ setRoleDescription(nodeInfo, role.getDescription());
+ }
+ }
+
+ protected void applyText(
+ Integer textId,
+ N nodeInfo,
+ RemoteComposeDocumentAccessibility remoteComposeAccessibility) {
+ if (textId != null) {
+ setText(
+ nodeInfo,
+ appendNullable(
+ getText(nodeInfo), remoteComposeAccessibility.stringValue(textId)));
+ }
+ }
+
+ protected void applyContentDescription(
+ Integer contentDescriptionId,
+ N nodeInfo,
+ RemoteComposeDocumentAccessibility remoteComposeAccessibility) {
+ if (contentDescriptionId != null) {
+ setContentDescription(
+ nodeInfo,
+ appendNullable(
+ getContentDescription(nodeInfo),
+ remoteComposeAccessibility.stringValue(contentDescriptionId)));
+ }
+ }
+
+ private CharSequence appendNullable(CharSequence contentDescription, String value) {
+ if (contentDescription == null) {
+ return value;
+ } else if (value == null) {
+ return contentDescription;
+ } else {
+ return contentDescription + " " + value;
+ }
+ }
+
+ protected abstract void setClickable(N nodeInfo, boolean b);
+
+ protected abstract void setEnabled(N nodeInfo, boolean b);
+
+ protected abstract CharSequence getStateDescription(N nodeInfo);
+
+ protected abstract void setStateDescription(N nodeInfo, CharSequence charSequence);
+
+ protected abstract void setRoleDescription(N nodeInfo, String description);
+
+ protected abstract CharSequence getText(N nodeInfo);
+
+ protected abstract void setText(N nodeInfo, CharSequence charSequence);
+
+ protected abstract CharSequence getContentDescription(N nodeInfo);
+
+ protected abstract void setContentDescription(N nodeInfo, CharSequence charSequence);
+
+ protected abstract void setBoundsInScreen(N nodeInfo, Rect bounds);
+
+ protected abstract void setUniqueId(N nodeInfo, String s);
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/accessibility/CoreDocumentAccessibility.java b/core/java/com/android/internal/widget/remotecompose/accessibility/CoreDocumentAccessibility.java
new file mode 100644
index 0000000000000000000000000000000000000000..2cd4f0362306c0629f2434c5a5364c6219c76a38
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/accessibility/CoreDocumentAccessibility.java
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.accessibility;
+
+import android.annotation.Nullable;
+import android.graphics.PointF;
+import android.os.Bundle;
+
+import com.android.internal.widget.remotecompose.core.CoreDocument;
+import com.android.internal.widget.remotecompose.core.Operation;
+import com.android.internal.widget.remotecompose.core.operations.layout.ClickModifierOperation;
+import com.android.internal.widget.remotecompose.core.operations.layout.Component;
+import com.android.internal.widget.remotecompose.core.operations.layout.LayoutComponent;
+import com.android.internal.widget.remotecompose.core.operations.layout.RootLayoutComponent;
+import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.ComponentModifiers;
+import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.ModifierOperation;
+import com.android.internal.widget.remotecompose.core.semantics.AccessibilitySemantics;
+import com.android.internal.widget.remotecompose.core.semantics.AccessibleComponent;
+import com.android.internal.widget.remotecompose.core.semantics.CoreSemantics;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/**
+ * Java Player implementation of the {@link RemoteComposeDocumentAccessibility} interface. Each item
+ * in the semantic tree is a {@link Component} from the remote Compose UI. Each Component can have a
+ * list of modifiers that must be tagged with {@link AccessibilitySemantics} either incidentally
+ * (see {@link ClickModifierOperation}) or explicitly (see {@link CoreSemantics}).
+ */
+public class CoreDocumentAccessibility implements RemoteComposeDocumentAccessibility {
+ private final CoreDocument mDocument;
+
+ public CoreDocumentAccessibility(CoreDocument document) {
+ this.mDocument = document;
+ }
+
+ @Nullable
+ @Override
+ public Integer getComponentIdAt(PointF point) {
+ return RootId;
+ }
+
+ @Override
+ public @Nullable Component findComponentById(int virtualViewId) {
+ RootLayoutComponent root = mDocument.getRootLayoutComponent();
+
+ if (root == null || virtualViewId == -1) {
+ return root;
+ }
+
+ return componentStream(root)
+ .filter(op -> op.getComponentId() == virtualViewId)
+ .findFirst()
+ .orElse(null);
+ }
+
+ @Override
+ public CoreSemantics.Mode mergeMode(Component component) {
+ if (!(component instanceof LayoutComponent)) {
+ return CoreSemantics.Mode.SET;
+ }
+
+ CoreSemantics.Mode result = CoreSemantics.Mode.SET;
+
+ for (ModifierOperation modifier :
+ ((LayoutComponent) component).getComponentModifiers().getList()) {
+ if (modifier instanceof AccessibleComponent) {
+ AccessibleComponent semantics = (AccessibleComponent) modifier;
+
+ if (semantics.getMode().ordinal() > result.ordinal()) {
+ result = semantics.getMode();
+ }
+ }
+ }
+
+ return result;
+ }
+
+ @Override
+ public boolean performAction(Component component, int action, Bundle arguments) {
+ if (action == ACTION_CLICK) {
+ mDocument.performClick(component.getComponentId());
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ @Nullable
+ @Override
+ public String stringValue(int id) {
+ Object value = mDocument.getRemoteComposeState().getFromId(id);
+
+ return value != null ? String.valueOf(value) : null;
+ }
+
+ @Override
+ public List semanticModifiersForComponent(Component component) {
+ if (!(component instanceof LayoutComponent)) {
+ return Collections.emptyList();
+ }
+
+ List modifiers =
+ ((LayoutComponent) component).getComponentModifiers().getList();
+
+ return modifiers.stream()
+ .filter(
+ it ->
+ it instanceof AccessibilitySemantics
+ && ((AccessibilitySemantics) it)
+ .isInterestingForSemantics())
+ .map(i -> (AccessibilitySemantics) i)
+ .collect(Collectors.toList());
+ }
+
+ @Override
+ public List semanticallyRelevantChildComponents(
+ Component component, boolean useUnmergedTree) {
+ if (!component.isVisible()) {
+ return Collections.emptyList();
+ }
+
+ CoreSemantics.Mode mergeMode = mergeMode(component);
+ if (mergeMode == CoreSemantics.Mode.CLEAR_AND_SET
+ || (!useUnmergedTree && mergeMode == CoreSemantics.Mode.MERGE)) {
+ return Collections.emptyList();
+ }
+
+ ArrayList result = new ArrayList<>();
+
+ for (Operation child : component.mList) {
+ if (child instanceof Component) {
+ if (isInteresting((Component) child)) {
+ result.add(((Component) child).getComponentId());
+ } else {
+ result.addAll(
+ semanticallyRelevantChildComponents(
+ (Component) child, useUnmergedTree));
+ }
+ }
+ }
+
+ return result;
+ }
+
+ static Stream componentStream(Component root) {
+ return Stream.concat(
+ Stream.of(root),
+ root.mList.stream()
+ .flatMap(
+ op -> {
+ if (op instanceof Component) {
+ return componentStream((Component) op);
+ } else {
+ return Stream.empty();
+ }
+ }));
+ }
+
+ static Stream modifiersStream(Component component) {
+ return component.mList.stream()
+ .filter(it -> it instanceof ComponentModifiers)
+ .flatMap(it -> ((ComponentModifiers) it).getList().stream());
+ }
+
+ static boolean isInteresting(Component component) {
+ if (!component.isVisible()) {
+ return false;
+ }
+
+ return isContainerWithSemantics(component)
+ || modifiersStream(component)
+ .anyMatch(CoreDocumentAccessibility::isModifierWithSemantics);
+ }
+
+ static boolean isModifierWithSemantics(ModifierOperation modifier) {
+ return modifier instanceof AccessibilitySemantics
+ && ((AccessibilitySemantics) modifier).isInterestingForSemantics();
+ }
+
+ static boolean isContainerWithSemantics(Component component) {
+ if (component instanceof AccessibilitySemantics) {
+ return ((AccessibilitySemantics) component).isInterestingForSemantics();
+ }
+
+ if (!(component instanceof LayoutComponent)) {
+ return false;
+ }
+
+ return ((LayoutComponent) component)
+ .getComponentModifiers().getList().stream()
+ .anyMatch(CoreDocumentAccessibility::isModifierWithSemantics);
+ }
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/accessibility/PlatformRemoteComposeAccessibilityRegistrar.java b/core/java/com/android/internal/widget/remotecompose/accessibility/PlatformRemoteComposeAccessibilityRegistrar.java
new file mode 100644
index 0000000000000000000000000000000000000000..010253e9cb95b382e30cecc8c547555f87e9a8be
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/accessibility/PlatformRemoteComposeAccessibilityRegistrar.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.accessibility;
+
+import android.annotation.NonNull;
+import android.view.View;
+
+import com.android.internal.widget.remotecompose.core.CoreDocument;
+
+/**
+ * Trivial wrapper for calling setAccessibilityDelegate on a View. This exists primarily because the
+ * RemoteDocumentPlayer is either running in the platform on a known API version, or outside in
+ * which case it must use the Androidx ViewCompat class.
+ */
+public class PlatformRemoteComposeAccessibilityRegistrar
+ implements RemoteComposeAccessibilityRegistrar {
+ public PlatformRemoteComposeTouchHelper forRemoteComposePlayer(
+ View player, @NonNull CoreDocument coreDocument) {
+ return new PlatformRemoteComposeTouchHelper(
+ player,
+ new CoreDocumentAccessibility(coreDocument),
+ new AndroidPlatformSemanticNodeApplier());
+ }
+
+ public void setAccessibilityDelegate(View remoteComposePlayer, CoreDocument document) {
+ remoteComposePlayer.setAccessibilityDelegate(
+ forRemoteComposePlayer(remoteComposePlayer, document));
+ }
+
+ public void clearAccessibilityDelegate(View remoteComposePlayer) {
+ remoteComposePlayer.setAccessibilityDelegate(null);
+ }
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/accessibility/PlatformRemoteComposeTouchHelper.java b/core/java/com/android/internal/widget/remotecompose/accessibility/PlatformRemoteComposeTouchHelper.java
new file mode 100644
index 0000000000000000000000000000000000000000..39a2ab3010acd9e89536241bf346129f74ef0c37
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/accessibility/PlatformRemoteComposeTouchHelper.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.accessibility;
+
+import static com.android.internal.widget.remotecompose.accessibility.RemoteComposeDocumentAccessibility.RootId;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.graphics.PointF;
+import android.os.Bundle;
+import android.util.IntArray;
+import android.view.View;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityNodeInfo;
+
+import com.android.internal.widget.ExploreByTouchHelper;
+import com.android.internal.widget.remotecompose.core.CoreDocument;
+import com.android.internal.widget.remotecompose.core.operations.layout.Component;
+import com.android.internal.widget.remotecompose.core.semantics.AccessibilitySemantics;
+import com.android.internal.widget.remotecompose.core.semantics.CoreSemantics.Mode;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.Stack;
+
+public class PlatformRemoteComposeTouchHelper extends ExploreByTouchHelper {
+ private final RemoteComposeDocumentAccessibility mRemoteDocA11y;
+
+ private final SemanticNodeApplier mApplier;
+
+ public PlatformRemoteComposeTouchHelper(
+ View host,
+ RemoteComposeDocumentAccessibility remoteDocA11y,
+ SemanticNodeApplier applier) {
+ super(host);
+ this.mRemoteDocA11y = remoteDocA11y;
+ this.mApplier = applier;
+ }
+
+ public static PlatformRemoteComposeTouchHelper forRemoteComposePlayer(
+ View player, @NonNull CoreDocument coreDocument) {
+ return new PlatformRemoteComposeTouchHelper(
+ player,
+ new CoreDocumentAccessibility(coreDocument),
+ new AndroidPlatformSemanticNodeApplier());
+ }
+
+ /**
+ * Gets the virtual view ID at a given location on the screen.
+ *
+ *
This method is called by the Accessibility framework to determine which virtual view, if
+ * any, is located at a specific point on the screen. It uses the {@link
+ * RemoteComposeDocumentAccessibility#getComponentIdAt(PointF)} method to find the ID of the
+ * component at the given coordinates.
+ *
+ * @param x The x-coordinate of the location in pixels.
+ * @param y The y-coordinate of the location in pixels.
+ * @return The ID of the virtual view at the given location, or {@link #INVALID_ID} if no
+ * virtual view is found at that location.
+ */
+ @Override
+ protected int getVirtualViewAt(float x, float y) {
+ Integer root = mRemoteDocA11y.getComponentIdAt(new PointF(x, y));
+
+ if (root == null) {
+ return INVALID_ID;
+ }
+
+ return root;
+ }
+
+ /**
+ * Populates a list with the visible virtual view IDs.
+ *
+ *
This method is called by the accessibility framework to retrieve the IDs of all visible
+ * virtual views in the accessibility hierarchy. It traverses the hierarchy starting from the
+ * root node (RootId) and adds the ID of each visible view to the provided list.
+ *
+ * @param virtualViewIds The list to be populated with the visible virtual view IDs.
+ */
+ @Override
+ protected void getVisibleVirtualViews(IntArray virtualViewIds) {
+ Stack toVisit = new Stack<>();
+ Set visited = new HashSet<>();
+
+ toVisit.push(RootId);
+
+ while (!toVisit.isEmpty()) {
+ Integer componentId = toVisit.remove(0);
+
+ if (visited.add(componentId)) {
+ Component component = mRemoteDocA11y.findComponentById(componentId);
+
+ // Only include the root when it has semantics such as content description
+ if (!RootId.equals(componentId)
+ || !mRemoteDocA11y.semanticModifiersForComponent(component).isEmpty()) {
+ virtualViewIds.add(componentId);
+ }
+
+ if (component != null) {
+ Mode mergeMode = mRemoteDocA11y.mergeMode(component);
+
+ if (mergeMode == Mode.SET) {
+ List childViews =
+ mRemoteDocA11y.semanticallyRelevantChildComponents(
+ component, false);
+
+ toVisit.addAll(childViews);
+ }
+ }
+ }
+ }
+ }
+
+ @Override
+ public void onPopulateNodeForVirtualView(
+ int virtualViewId, @NonNull AccessibilityNodeInfo node) {
+ Component component = mRemoteDocA11y.findComponentById(virtualViewId);
+
+ Mode mergeMode = mRemoteDocA11y.mergeMode(component);
+
+ // default to enabled
+ node.setEnabled(true);
+
+ if (mergeMode == Mode.MERGE) {
+ List childViews =
+ mRemoteDocA11y.semanticallyRelevantChildComponents(component, true);
+
+ for (Integer childView : childViews) {
+ onPopulateNodeForVirtualView(childView, node);
+ }
+ }
+
+ List semantics =
+ mRemoteDocA11y.semanticModifiersForComponent(component);
+ mApplier.applyComponent(mRemoteDocA11y, node, component, semantics);
+ }
+
+ @Override
+ protected void onPopulateEventForVirtualView(int virtualViewId, AccessibilityEvent event) {}
+
+ @Override
+ protected boolean onPerformActionForVirtualView(
+ int virtualViewId, int action, @Nullable Bundle arguments) {
+ Component component = mRemoteDocA11y.findComponentById(virtualViewId);
+
+ if (component != null) {
+ return mRemoteDocA11y.performAction(component, action, arguments);
+ } else {
+ return false;
+ }
+ }
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/accessibility/RemoteComposeAccessibilityRegistrar.java b/core/java/com/android/internal/widget/remotecompose/accessibility/RemoteComposeAccessibilityRegistrar.java
new file mode 100644
index 0000000000000000000000000000000000000000..7e8236b35e9709a3bae1d6c3350787d308fca3ef
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/accessibility/RemoteComposeAccessibilityRegistrar.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.accessibility;
+
+import android.view.View;
+
+import com.android.internal.widget.remotecompose.core.CoreDocument;
+
+/**
+ * Interface for registering and clearing accessibility delegates for remote compose players.
+ *
+ *
This interface is responsible for managing the accessibility delegate associated with a remote
+ * compose player view. It allows for setting and clearing the delegate, which is used to handle
+ * accessibility events and provide accessibility information for the remote compose content.
+ */
+public interface RemoteComposeAccessibilityRegistrar {
+ void setAccessibilityDelegate(View remoteComposePlayer, CoreDocument document);
+
+ void clearAccessibilityDelegate(View remoteComposePlayer);
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/accessibility/RemoteComposeDocumentAccessibility.java b/core/java/com/android/internal/widget/remotecompose/accessibility/RemoteComposeDocumentAccessibility.java
new file mode 100644
index 0000000000000000000000000000000000000000..50f75e4889ddc7e1bb0dff1bfdc851ab2942eb2f
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/accessibility/RemoteComposeDocumentAccessibility.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.accessibility;
+
+import android.annotation.Nullable;
+import android.graphics.PointF;
+import android.os.Bundle;
+import android.view.View;
+
+import com.android.internal.widget.remotecompose.core.operations.layout.Component;
+import com.android.internal.widget.remotecompose.core.semantics.AccessibilitySemantics;
+import com.android.internal.widget.remotecompose.core.semantics.CoreSemantics;
+
+import java.util.List;
+
+/**
+ * Interface for interacting with the accessibility features of a remote Compose UI. This interface
+ * provides methods to perform actions, retrieve state, and query the accessibility tree of the
+ * remote Compose UI.
+ */
+public interface RemoteComposeDocumentAccessibility {
+ // Matches ExploreByTouchHelper.HOST_ID
+ Integer RootId = View.NO_ID;
+
+ // androidx.core.view.accessibility.AccessibilityNodeInfoCompat.ACTION_CLICK
+ int ACTION_CLICK = 0x00000010;
+
+ /**
+ * Performs the specified action on the given component.
+ *
+ * @param component The component on which to perform the action.
+ * @param action The action to perform.
+ * @param arguments Optional arguments for the action.
+ * @return {@code true} if the action was performed successfully, {@code false} otherwise.
+ */
+ boolean performAction(Component component, int action, Bundle arguments);
+
+ /**
+ * Retrieves the string value associated with the given ID.
+ *
+ * @param id The ID to retrieve the string value for.
+ * @return The string value associated with the ID, or {@code null} if no such value exists.
+ */
+ @Nullable
+ String stringValue(int id);
+
+ /**
+ * Retrieves a list of child view IDs semantically contained within the given component/virtual
+ * view. These may later be hidden from accessibility services by properties, but should contain
+ * only possibly semantically relevant virtual views.
+ *
+ * @param component The component to retrieve child view IDs from, or [RootId] for the top
+ * level.
+ * @param useUnmergedTree Whether to include merged children
+ * @return A list of integer IDs representing the child views of the component.
+ */
+ List semanticallyRelevantChildComponents(Component component, boolean useUnmergedTree);
+
+ /**
+ * Retrieves the semantic modifiers associated with a given component.
+ *
+ * @param component The component for which to retrieve semantic modifiers.
+ * @return A list of semantic modifiers applicable to the component.
+ */
+ List semanticModifiersForComponent(Component component);
+
+ /**
+ * Gets all applied merge modes of the given component. A Merge mode is one of Set, Merge or
+ * Clear and describes how to apply and combine hierarchical semantics.
+ *
+ * @param component The component to merge the mode for.
+ * @return The effective merge modes, potentially conflicting but resolved to a single value.
+ */
+ CoreSemantics.Mode mergeMode(Component component);
+
+ /**
+ * Finds a component by its ID.
+ *
+ * @param id the ID of the component to find
+ * @return the component with the given ID, or {@code null} if no such component exists
+ */
+ @Nullable
+ Component findComponentById(int id);
+
+ @Nullable
+ Integer getComponentIdAt(PointF point);
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/accessibility/RemoteComposeTouchHelper.java b/core/java/com/android/internal/widget/remotecompose/accessibility/RemoteComposeTouchHelper.java
new file mode 100644
index 0000000000000000000000000000000000000000..13641025a33b1c37001ddfa48a5f3a20c3f6a879
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/accessibility/RemoteComposeTouchHelper.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.accessibility;
+
+/**
+ * This class is the entry point for finding the AccessibilityDelegate for a RemoteCompose document.
+ */
+public class RemoteComposeTouchHelper {
+ /** Get the platform specific accessibility delegate registrar */
+ public static final RemoteComposeAccessibilityRegistrar REGISTRAR =
+ new PlatformRemoteComposeAccessibilityRegistrar();
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/accessibility/SemanticNodeApplier.java b/core/java/com/android/internal/widget/remotecompose/accessibility/SemanticNodeApplier.java
new file mode 100644
index 0000000000000000000000000000000000000000..832b5426f4767c25545fc327921b7d22ea62cfc1
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/accessibility/SemanticNodeApplier.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.accessibility;
+
+import com.android.internal.widget.remotecompose.core.operations.layout.Component;
+import com.android.internal.widget.remotecompose.core.semantics.AccessibilitySemantics;
+
+import java.util.List;
+
+/**
+ * An interface for applying semantic information to a semantics node.
+ *
+ *
Implementations of this interface are responsible for taking a node represented by [nodeInfo]
+ * and applying a list of [semantics] (representing accessible actions and properties) to it. This
+ * process might involve: - Modifying the node's properties (e.g., content description, clickable
+ * state). - Adding a child node to represent a specific semantic element. - Performing any other
+ * action necessary to make the node semantically meaningful and accessible to assistive
+ * technologies.
+ *
+ * @param The type representing information about the node. This could be an Androidx
+ * `AccessibilityNodeInfoCompat`, or potentially a platform `AccessibilityNodeInfo`.
+ */
+public interface SemanticNodeApplier {
+ void applyComponent(
+ RemoteComposeDocumentAccessibility remoteComposeAccessibility,
+ N nodeInfo,
+ Component component,
+ List semantics);
+
+ String VIRTUAL_VIEW_ID_KEY = "VirtualViewId";
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/CoreDocument.java b/core/java/com/android/internal/widget/remotecompose/core/CoreDocument.java
index 370289a84502f24cdb33d0404046c0af9e9f40c5..33f93fccff5810fa31bf637bfd7c45316389bafc 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/CoreDocument.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/CoreDocument.java
@@ -18,17 +18,19 @@ package com.android.internal.widget.remotecompose.core;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.widget.remotecompose.core.operations.ComponentValue;
import com.android.internal.widget.remotecompose.core.operations.FloatExpression;
import com.android.internal.widget.remotecompose.core.operations.IntegerExpression;
import com.android.internal.widget.remotecompose.core.operations.NamedVariable;
import com.android.internal.widget.remotecompose.core.operations.RootContentBehavior;
+import com.android.internal.widget.remotecompose.core.operations.ShaderData;
+import com.android.internal.widget.remotecompose.core.operations.TextData;
import com.android.internal.widget.remotecompose.core.operations.Theme;
import com.android.internal.widget.remotecompose.core.operations.layout.ClickModifierOperation;
import com.android.internal.widget.remotecompose.core.operations.layout.Component;
import com.android.internal.widget.remotecompose.core.operations.layout.ComponentEnd;
import com.android.internal.widget.remotecompose.core.operations.layout.ComponentStartOperation;
-import com.android.internal.widget.remotecompose.core.operations.layout.LayoutComponent;
import com.android.internal.widget.remotecompose.core.operations.layout.LoopEnd;
import com.android.internal.widget.remotecompose.core.operations.layout.LoopOperation;
import com.android.internal.widget.remotecompose.core.operations.layout.OperationsListEnd;
@@ -38,12 +40,14 @@ import com.android.internal.widget.remotecompose.core.operations.layout.TouchDow
import com.android.internal.widget.remotecompose.core.operations.layout.TouchUpModifierOperation;
import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.ComponentModifiers;
import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.ModifierOperation;
+import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.ScrollModifierOperation;
import com.android.internal.widget.remotecompose.core.operations.utilities.StringSerializer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
+import java.util.Objects;
import java.util.Set;
/**
@@ -53,13 +57,14 @@ import java.util.Set;
public class CoreDocument {
private static final boolean DEBUG = false;
+ private static final int DOCUMENT_API_LEVEL = 2;
@NonNull ArrayList mOperations = new ArrayList<>();
@Nullable RootLayoutComponent mRootLayoutComponent = null;
@NonNull RemoteComposeState mRemoteComposeState = new RemoteComposeState();
- @NonNull TimeVariables mTimeVariables = new TimeVariables();
+ @VisibleForTesting @NonNull public TimeVariables mTimeVariables = new TimeVariables();
// Semantic version of the document
@NonNull Version mVersion = new Version(0, 1, 0);
@@ -86,6 +91,11 @@ public class CoreDocument {
private int mLastId = 1; // last component id when inflating the file
+ /** Returns a version number that is monotonically increasing. */
+ public static int getDocumentApiLevel() {
+ return DOCUMENT_API_LEVEL;
+ }
+
@Nullable
public String getContentDescription() {
return mContentDescription;
@@ -434,11 +444,11 @@ public class CoreDocument {
mActionListeners.clear();
}
- public interface ClickCallbacks {
- void click(int id, @Nullable String metadata);
+ public interface IdActionCallback {
+ void onAction(int id, @Nullable String metadata);
}
- @NonNull HashSet mClickListeners = new HashSet<>();
+ @NonNull HashSet mIdActionListeners = new HashSet<>();
@NonNull HashSet mTouchListeners = new HashSet<>();
@NonNull HashSet mClickAreas = new HashSet<>();
@@ -463,6 +473,21 @@ public class CoreDocument {
float mBottom;
@Nullable final String mMetadata;
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof ClickAreaRepresentation)) return false;
+ ClickAreaRepresentation that = (ClickAreaRepresentation) o;
+ return mId == that.mId
+ && Objects.equals(mContentDescription, that.mContentDescription)
+ && Objects.equals(mMetadata, that.mMetadata);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mId, mContentDescription, mMetadata);
+ }
+
public ClickAreaRepresentation(
int id,
@Nullable String contentDescription,
@@ -565,6 +590,7 @@ public class CoreDocument {
TouchUpModifierOperation currentTouchUpModifier = null;
TouchCancelModifierOperation currentTouchCancelModifier = null;
LoopOperation currentLoop = null;
+ ScrollModifierOperation currentScrollModifier = null;
mLastId = -1;
for (Operation o : operations) {
@@ -579,8 +605,8 @@ public class CoreDocument {
mLastId = component.getComponentId();
}
} else if (o instanceof ComponentEnd) {
- if (currentComponent instanceof LayoutComponent) {
- ((LayoutComponent) currentComponent).inflate();
+ if (currentComponent != null) {
+ currentComponent.inflate();
}
components.remove(components.size() - 1);
if (!components.isEmpty()) {
@@ -602,6 +628,9 @@ public class CoreDocument {
} else if (o instanceof TouchCancelModifierOperation) {
currentTouchCancelModifier = (TouchCancelModifierOperation) o;
ops = currentTouchCancelModifier.getList();
+ } else if (o instanceof ScrollModifierOperation) {
+ currentScrollModifier = (ScrollModifierOperation) o;
+ ops = currentScrollModifier.getList();
} else if (o instanceof OperationsListEnd) {
ops = currentComponent.getList();
if (currentClickModifier != null) {
@@ -616,6 +645,9 @@ public class CoreDocument {
} else if (currentTouchCancelModifier != null) {
ops.add(currentTouchCancelModifier);
currentTouchCancelModifier = null;
+ } else if (currentScrollModifier != null) {
+ ops.add(currentScrollModifier);
+ currentScrollModifier = null;
}
} else if (o instanceof LoopOperation) {
currentLoop = (LoopOperation) o;
@@ -665,7 +697,9 @@ public class CoreDocument {
}
}
}
+ op.markNotDirty();
op.apply(context);
+ context.incrementOpCount();
}
}
@@ -740,9 +774,13 @@ public class CoreDocument {
float right,
float bottom,
@Nullable String metadata) {
- mClickAreas.add(
+
+ ClickAreaRepresentation car =
new ClickAreaRepresentation(
- id, contentDescription, left, top, right, bottom, metadata));
+ id, contentDescription, left, top, right, bottom, metadata);
+
+ boolean old = mClickAreas.remove(car);
+ mClickAreas.add(car);
}
/**
@@ -755,12 +793,12 @@ public class CoreDocument {
}
/**
- * Add a click listener. This will get called when a click is detected on the document
+ * Add an id action listener. This will get called when e.g. a click is detected on the document
*
- * @param callback called when a click area has been hit, passing the click are id and metadata.
+ * @param callback called when an action is executed, passing the id and metadata.
*/
- public void addClickListener(@NonNull ClickCallbacks callback) {
- mClickListeners.add(callback);
+ public void addIdActionListener(@NonNull IdActionCallback callback) {
+ mIdActionListeners.add(callback);
}
/**
@@ -769,8 +807,8 @@ public class CoreDocument {
* @return set of click listeners
*/
@NonNull
- public HashSet getClickListeners() {
- return mClickListeners;
+ public HashSet getIdActionListeners() {
+ return mIdActionListeners;
}
/**
@@ -799,15 +837,15 @@ public class CoreDocument {
warnClickListeners(clickArea);
}
}
- for (ClickCallbacks listener : mClickListeners) {
- listener.click(id, "");
+ for (IdActionCallback listener : mIdActionListeners) {
+ listener.onAction(id, "");
}
}
/** Warn click listeners when a click area is activated */
private void warnClickListeners(@NonNull ClickAreaRepresentation clickArea) {
- for (ClickCallbacks listener : mClickListeners) {
- listener.click(clickArea.mId, clickArea.mMetadata);
+ for (IdActionCallback listener : mIdActionListeners) {
+ listener.onAction(clickArea.mId, clickArea.mMetadata);
}
}
@@ -881,7 +919,7 @@ public class CoreDocument {
}
if (mRootLayoutComponent != null) {
for (Component component : mAppliedTouchOperations) {
- component.onTouchUp(context, this, x, y, true);
+ component.onTouchUp(context, this, x, y, dx, dy, true);
}
mAppliedTouchOperations.clear();
}
@@ -963,6 +1001,16 @@ public class CoreDocument {
private final float[] mScaleOutput = new float[2];
private final float[] mTranslateOutput = new float[2];
private int mRepaintNext = -1; // delay to next repaint -1 = don't 1 = asap
+ private int mLastOpCount;
+
+ /**
+ * This is the number of ops used to calculate the last frame.
+ *
+ * @return number of ops
+ */
+ public int getOpsPerFrame() {
+ return mLastOpCount;
+ }
/**
* Returns > 0 if it needs to repaint
@@ -980,6 +1028,7 @@ public class CoreDocument {
* @param theme the theme we want to use for this document.
*/
public void paint(@NonNull RemoteContext context, int theme) {
+ context.getLastOpCount();
context.getPaintContext().clearNeedsRepaint();
context.loadFloat(RemoteContext.ID_DENSITY, context.getDensity());
context.mMode = RemoteContext.ContextMode.UNSET;
@@ -990,21 +1039,24 @@ public class CoreDocument {
context.mRemoteComposeState = mRemoteComposeState;
context.mRemoteComposeState.setContext(context);
+ // If we have a content sizing set, we are going to take the original document
+ // dimension into account and apply scale+translate according to the RootContentBehavior
+ // rules.
if (mContentSizing == RootContentBehavior.SIZING_SCALE) {
// we need to add canvas transforms ops here
computeScale(context.mWidth, context.mHeight, mScaleOutput);
- computeTranslate(
- context.mWidth,
- context.mHeight,
- mScaleOutput[0],
- mScaleOutput[1],
- mTranslateOutput);
+ float sw = mScaleOutput[0];
+ float sh = mScaleOutput[1];
+ computeTranslate(context.mWidth, context.mHeight, sw, sh, mTranslateOutput);
context.mPaintContext.translate(mTranslateOutput[0], mTranslateOutput[1]);
- context.mPaintContext.scale(mScaleOutput[0], mScaleOutput[1]);
+ context.mPaintContext.scale(sw, sh);
+ } else {
+ // If not, we set the document width and height to be the current context width and
+ // height.
+ setWidth((int) context.mWidth);
+ setHeight((int) context.mHeight);
}
mTimeVariables.updateTime(context);
- context.loadFloat(RemoteContext.ID_WINDOW_WIDTH, context.mWidth);
- context.loadFloat(RemoteContext.ID_WINDOW_HEIGHT, context.mHeight);
mRepaintNext = context.updateOps();
if (mRootLayoutComponent != null) {
if (context.mWidth != mRootLayoutComponent.getWidth()
@@ -1014,11 +1066,11 @@ public class CoreDocument {
if (mRootLayoutComponent.needsMeasure()) {
mRootLayoutComponent.layout(context);
}
- // TODO -- this should be specifically about applying animation, not paint
- mRootLayoutComponent.paint(context.getPaintContext());
- context.mPaintContext.reset();
- // TODO -- should be able to remove this
- mRootLayoutComponent.updateVariables(context);
+ if (mRootLayoutComponent.needsBoundsAnimation()) {
+ mRepaintNext = 1;
+ mRootLayoutComponent.clearNeedsBoundsAnimation();
+ mRootLayoutComponent.animatingBounds(context);
+ }
if (DEBUG) {
String hierarchy = mRootLayoutComponent.displayHierarchy();
System.out.println(hierarchy);
@@ -1039,7 +1091,14 @@ public class CoreDocument {
|| context.getTheme() == Theme.UNSPECIFIED;
}
if (apply) {
- op.apply(context);
+ if (op.isDirty() || op instanceof PaintOperation) {
+ if (op.isDirty() && op instanceof VariableSupport) {
+ op.markNotDirty();
+ ((VariableSupport) op).updateVariables(context);
+ }
+ context.incrementOpCount();
+ op.apply(context);
+ }
}
}
if (context.getPaintContext().doesNeedsRepaint()
@@ -1047,10 +1106,41 @@ public class CoreDocument {
mRepaintNext = 1;
}
context.mMode = RemoteContext.ContextMode.UNSET;
- // System.out.println(">> " + ( System.nanoTime() - time)*1E-6f+" ms");
if (DEBUG && mRootLayoutComponent != null) {
System.out.println(mRootLayoutComponent.displayHierarchy());
}
+ mLastOpCount = context.getLastOpCount();
+ }
+
+ /**
+ * Get an estimated number of operations executed in a paint
+ *
+ * @return number of operations
+ */
+ public int getNumberOfOps() {
+ int count = mOperations.size();
+
+ for (Operation mOperation : mOperations) {
+ if (mOperation instanceof Component) {
+ count += getChildOps((Component) mOperation);
+ }
+ }
+ return count;
+ }
+
+ private int getChildOps(@NonNull Component base) {
+ int count = base.mList.size();
+ for (Operation mOperation : base.mList) {
+
+ if (mOperation instanceof Component) {
+ int mult = 1;
+ if (mOperation instanceof LoopOperation) {
+ mult = ((LoopOperation) mOperation).estimateIterations();
+ }
+ count += mult * getChildOps((Component) mOperation);
+ }
+ }
+ return count;
}
@NonNull
@@ -1074,6 +1164,9 @@ public class CoreDocument {
if (mOperation instanceof Component) {
Component com = (Component) mOperation;
count += addChildren(com, map, buffer);
+ } else if (mOperation instanceof LoopOperation) {
+ LoopOperation com = (LoopOperation) mOperation;
+ count += addChildren(com, map, buffer);
}
}
@@ -1111,6 +1204,35 @@ public class CoreDocument {
if (mOperation instanceof Component) {
count += addChildren((Component) mOperation, map, tmp);
}
+ if (mOperation instanceof LoopOperation) {
+ count += addChildren((LoopOperation) mOperation, map, tmp);
+ }
+ }
+ return count;
+ }
+
+ private int addChildren(
+ @NonNull LoopOperation base,
+ @NonNull HashMap map,
+ @NonNull WireBuffer tmp) {
+ int count = base.mList.size();
+ for (Operation mOperation : base.mList) {
+ Class extends Operation> c = mOperation.getClass();
+ int[] values;
+ if (map.containsKey(c.getSimpleName())) {
+ values = map.get(c.getSimpleName());
+ } else {
+ values = new int[2];
+ map.put(c.getSimpleName(), values);
+ }
+ values[0] += 1;
+ values[1] += sizeOfComponent(mOperation, tmp);
+ if (mOperation instanceof Component) {
+ count += addChildren((Component) mOperation, map, tmp);
+ }
+ if (mOperation instanceof LoopOperation) {
+ count += addChildren((LoopOperation) mOperation, map, tmp);
+ }
}
return count;
}
@@ -1143,4 +1265,29 @@ public class CoreDocument {
public List getOperations() {
return mOperations;
}
+
+ /** defines if a shader can be run */
+ public interface ShaderControl {
+ boolean isShaderValid(String shader);
+ }
+
+ /**
+ * validate the shaders
+ *
+ * @param context the remote context
+ * @param ctl the call back to allow evaluation of shaders
+ */
+ public void checkShaders(RemoteContext context, ShaderControl ctl) {
+ for (Operation op : mOperations) {
+ if (op instanceof TextData) {
+ op.apply(context);
+ }
+ if (op instanceof ShaderData) {
+ ShaderData sd = (ShaderData) op;
+ int id = sd.getShaderTextId();
+ String str = context.getText(id);
+ sd.enable(ctl.isShaderValid(str));
+ }
+ }
+ }
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/Operation.java b/core/java/com/android/internal/widget/remotecompose/core/Operation.java
index 6f6a0a89296455849f86877430976ba1ad573fa3..150ebd0d3dfc08254df33a84acfb8e19e812a5b0 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/Operation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/Operation.java
@@ -20,6 +20,8 @@ import android.annotation.NonNull;
/** Base interface for RemoteCompose operations */
public abstract class Operation {
+ private static final boolean ENABLE_DIRTY_FLAG_OPTIMIZATION = true;
+
/** add the operation to the buffer */
public abstract void write(@NonNull WireBuffer buffer);
@@ -33,4 +35,30 @@ public abstract class Operation {
/** Debug utility to display an operation + indentation */
@NonNull
public abstract String deepToString(@NonNull String indent);
+
+ private boolean mDirty = true;
+
+ /** Mark the operation as "dirty" to indicate it will need to be re-executed. */
+ public void markDirty() {
+ mDirty = true;
+ }
+
+ /** Mark the operation as "not dirty" */
+ public void markNotDirty() {
+ if (ENABLE_DIRTY_FLAG_OPTIMIZATION) {
+ mDirty = false;
+ }
+ }
+
+ /**
+ * Returns true if the operation is marked as "dirty"
+ *
+ * @return true if dirty
+ */
+ public boolean isDirty() {
+ if (ENABLE_DIRTY_FLAG_OPTIMIZATION) {
+ return mDirty;
+ }
+ return true;
+ }
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/OperationInterface.java b/core/java/com/android/internal/widget/remotecompose/core/OperationInterface.java
index 741303a40bc918973cc906b5639025c755bcd58e..06beffcac0dea18ec271a0df81a9bd8e59d54005 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/OperationInterface.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/OperationInterface.java
@@ -33,4 +33,14 @@ public interface OperationInterface {
/** Debug utility to display an operation + indentation */
@NonNull
String deepToString(@NonNull String indent);
+
+ /**
+ * Returns true if the operation is marked as "dirty"
+ *
+ * @return true if dirty
+ */
+ boolean isDirty();
+
+ /** Mark the operation as "dirty" to indicate it will need to be re-executed. */
+ void markNotDirty();
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/Operations.java b/core/java/com/android/internal/widget/remotecompose/core/Operations.java
index 006fe3afb4d81d45feabc1e518bfa186cd8ffa6a..04e490fa5214fd4ac0d7a22c223347338139cc37 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/Operations.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/Operations.java
@@ -98,8 +98,10 @@ import com.android.internal.widget.remotecompose.core.operations.layout.modifier
import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.HeightModifierOperation;
import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.HostActionOperation;
import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.HostNamedActionOperation;
+import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.MarqueeModifierOperation;
import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.OffsetModifierOperation;
import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.PaddingModifierOperation;
+import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.RippleModifierOperation;
import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.RoundedClipRectModifierOperation;
import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.ScrollModifierOperation;
import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.ValueFloatChangeActionOperation;
@@ -110,6 +112,7 @@ import com.android.internal.widget.remotecompose.core.operations.layout.modifier
import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.WidthModifierOperation;
import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.ZIndexModifierOperation;
import com.android.internal.widget.remotecompose.core.operations.utilities.IntMap;
+import com.android.internal.widget.remotecompose.core.semantics.CoreSemantics;
import com.android.internal.widget.remotecompose.core.types.BooleanConstant;
import com.android.internal.widget.remotecompose.core.types.IntegerConstant;
import com.android.internal.widget.remotecompose.core.types.LongConstant;
@@ -126,6 +129,9 @@ public class Operations {
public static final int CLICK_AREA = 64;
public static final int ROOT_CONTENT_BEHAVIOR = 65;
public static final int ROOT_CONTENT_DESCRIPTION = 103;
+ // TODO reorder before submitting
+ public static final int ACCESSIBILITY_SEMANTICS = 250;
+ // public static final int ACCESSIBILITY_CUSTOM_ACTION = 251;
////////////////////////////////////////
// Draw commands
@@ -223,6 +229,8 @@ public class Operations {
public static final int MODIFIER_ZINDEX = 223;
public static final int MODIFIER_GRAPHICS_LAYER = 224;
public static final int MODIFIER_SCROLL = 226;
+ public static final int MODIFIER_MARQUEE = 228;
+ public static final int MODIFIER_RIPPLE = 229;
public static final int LOOP_START = 215;
public static final int LOOP_END = 216;
@@ -327,6 +335,8 @@ public class Operations {
map.put(MODIFIER_ZINDEX, ZIndexModifierOperation::read);
map.put(MODIFIER_GRAPHICS_LAYER, GraphicsLayerModifierOperation::read);
map.put(MODIFIER_SCROLL, ScrollModifierOperation::read);
+ map.put(MODIFIER_MARQUEE, MarqueeModifierOperation::read);
+ map.put(MODIFIER_RIPPLE, RippleModifierOperation::read);
map.put(OPERATIONS_LIST_END, OperationsListEnd::read);
@@ -362,5 +372,8 @@ public class Operations {
map.put(PATH_TWEEN, PathTween::read);
map.put(PATH_CREATE, PathCreate::read);
map.put(PATH_ADD, PathAppend::read);
+
+ map.put(ACCESSIBILITY_SEMANTICS, CoreSemantics::read);
+ // map.put(ACCESSIBILITY_CUSTOM_ACTION, CoreSemantics::read);
}
}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeBuffer.java b/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeBuffer.java
index 3a5d68db8a3787f2c8b3e8453f297c07d348c594..0ae7a94b948d4abdd2420f8cd948233401c68867 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeBuffer.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeBuffer.java
@@ -15,7 +15,6 @@
*/
package com.android.internal.widget.remotecompose.core;
-import static com.android.internal.widget.remotecompose.core.operations.utilities.AnimatedFloatExpression.ADD;
import static com.android.internal.widget.remotecompose.core.operations.utilities.AnimatedFloatExpression.MUL;
import android.annotation.NonNull;
@@ -81,6 +80,7 @@ import com.android.internal.widget.remotecompose.core.operations.layout.Componen
import com.android.internal.widget.remotecompose.core.operations.layout.LayoutComponentContent;
import com.android.internal.widget.remotecompose.core.operations.layout.LoopEnd;
import com.android.internal.widget.remotecompose.core.operations.layout.LoopOperation;
+import com.android.internal.widget.remotecompose.core.operations.layout.OperationsListEnd;
import com.android.internal.widget.remotecompose.core.operations.layout.RootLayoutComponent;
import com.android.internal.widget.remotecompose.core.operations.layout.managers.BoxLayout;
import com.android.internal.widget.remotecompose.core.operations.layout.managers.CanvasLayout;
@@ -92,8 +92,10 @@ import com.android.internal.widget.remotecompose.core.operations.layout.modifier
import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.BorderModifierOperation;
import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.ClipRectModifierOperation;
import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.GraphicsLayerModifierOperation;
+import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.MarqueeModifierOperation;
import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.OffsetModifierOperation;
import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.PaddingModifierOperation;
+import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.RippleModifierOperation;
import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.RoundedClipRectModifierOperation;
import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.ScrollModifierOperation;
import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.ZIndexModifierOperation;
@@ -1610,7 +1612,7 @@ public class RemoteComposeBuffer {
* create and animation based on description and return as an array of floats. see
* addAnimatedFloat
*
- * @param duration the duration of the aimation
+ * @param duration the duration of the animation in seconds
* @param type the type of animation
* @param spec the parameters of the animation if any
* @param initialValue the initial value if it animates to a start
@@ -1699,6 +1701,9 @@ public class RemoteComposeBuffer {
float notchMax = this.reserveFloatVariable();
float touchExpressionDirection =
direction != 0 ? RemoteContext.FLOAT_TOUCH_POS_X : RemoteContext.FLOAT_TOUCH_POS_Y;
+
+ ScrollModifierOperation.apply(mBuffer, direction, positionId, max, notchMax);
+
this.addTouchExpression(
positionId,
0f,
@@ -1707,20 +1712,13 @@ public class RemoteComposeBuffer {
0f,
3,
new float[] {
- touchExpressionDirection,
- -1,
- // TODO: remove this CONTINUOUS_SEC hack...
- MUL,
- RemoteContext.FLOAT_CONTINUOUS_SEC,
- 0f,
- MUL,
- ADD
+ touchExpressionDirection, -1, MUL,
},
TouchExpression.STOP_NOTCHES_EVEN,
new float[] {notches, notchMax},
null);
- ScrollModifierOperation.apply(mBuffer, direction, positionId, max, notchMax);
+ OperationsListEnd.apply(mBuffer);
}
/**
@@ -1786,6 +1784,38 @@ public class RemoteComposeBuffer {
ZIndexModifierOperation.apply(mBuffer, value);
}
+ /** Add a ripple effect on touch down as a modifier */
+ public void addModifierRipple() {
+ RippleModifierOperation.apply(mBuffer);
+ }
+
+ /**
+ * Add a marquee modifier
+ *
+ * @param iterations
+ * @param animationMode
+ * @param repeatDelayMillis
+ * @param initialDelayMillis
+ * @param spacing
+ * @param velocity
+ */
+ public void addModifierMarquee(
+ int iterations,
+ int animationMode,
+ float repeatDelayMillis,
+ float initialDelayMillis,
+ float spacing,
+ float velocity) {
+ MarqueeModifierOperation.apply(
+ mBuffer,
+ iterations,
+ animationMode,
+ repeatDelayMillis,
+ initialDelayMillis,
+ spacing,
+ velocity);
+ }
+
/**
* Add a graphics layer
*
diff --git a/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeState.java b/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeState.java
index f5f9e214723b8785f332763069a2fd2997244e70..5c3df7e95a1faa63e54aaf240ee6b104e481f060 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeState.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeState.java
@@ -48,6 +48,10 @@ public class RemoteComposeState implements CollectionsAccess {
private final IntMap mDataMapMap = new IntMap<>();
private final IntMap