summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--INPUT_OWNERS1
-rw-r--r--OWNERS1
-rw-r--r--PERFORMANCE_OWNERS1
-rw-r--r--ZYGOTE_OWNERS2
-rw-r--r--apct-tests/perftests/core/src/android/conscrypt/conscrypt/ClientSocketPerfTest.java2
-rw-r--r--apct-tests/perftests/core/src/android/conscrypt/conscrypt/EndpointFactory.java4
-rw-r--r--apct-tests/perftests/core/src/android/conscrypt/conscrypt/ServerEndpoint.java10
-rw-r--r--apct-tests/perftests/core/src/android/conscrypt/conscrypt/ServerSocketPerfTest.java3
-rw-r--r--apct-tests/perftests/multiuser/Android.bp12
-rw-r--r--api/Android.bp7
-rw-r--r--api/StubLibraries.bp259
-rw-r--r--api/api.go81
-rw-r--r--api/api_test.go111
-rw-r--r--core/TEST_MAPPING13
-rw-r--r--core/java/android/app/OWNERS3
-rw-r--r--core/java/android/app/TEST_MAPPING39
-rw-r--r--core/java/android/app/appfunctions/OWNERS6
-rw-r--r--core/java/android/content/TEST_MAPPING19
-rw-r--r--core/java/android/database/OWNERS4
-rw-r--r--core/java/android/database/sqlite/TEST_MAPPING13
-rw-r--r--core/java/android/hardware/camera2/impl/CameraDeviceImpl.java2
-rw-r--r--core/java/android/os/OWNERS3
-rw-r--r--core/java/android/os/TEST_MAPPING13
-rw-r--r--core/java/android/security/net/config/SystemCertificateSource.java4
-rw-r--r--core/java/android/util/TEST_MAPPING20
-rw-r--r--core/java/android/util/apk/TEST_MAPPING7
-rw-r--r--core/java/android/view/SurfaceControlRegistry.java2
-rw-r--r--core/java/android/view/textclassifier/TEST_MAPPING10
-rw-r--r--core/java/com/android/internal/content/om/TEST_MAPPING7
-rw-r--r--core/java/com/android/internal/infra/TEST_MAPPING7
-rw-r--r--core/java/com/android/internal/jank/TEST_MAPPING13
-rw-r--r--core/java/com/android/internal/os/TEST_MAPPING32
-rw-r--r--core/java/com/android/internal/power/TEST_MAPPING6
-rw-r--r--core/java/com/android/internal/security/TEST_MAPPING10
-rw-r--r--core/java/com/android/internal/util/TEST_MAPPING23
-rw-r--r--core/java/com/android/internal/widget/OWNERS4
-rw-r--r--core/jni/OWNERS5
-rw-r--r--core/jni/TEST_MAPPING10
-rw-r--r--core/tests/coretests/src/android/content/TEST_MAPPING13
-rw-r--r--core/tests/coretests/src/android/content/integrity/TEST_MAPPING7
-rw-r--r--core/tests/coretests/src/android/content/pm/TEST_MAPPING16
-rw-r--r--core/tests/coretests/src/android/content/res/TEST_MAPPING19
-rw-r--r--core/tests/coretests/src/android/service/TEST_MAPPING12
-rw-r--r--core/tests/coretests/src/android/view/contentcapture/TEST_MAPPING13
-rw-r--r--core/tests/coretests/src/android/view/contentprotection/TEST_MAPPING13
-rw-r--r--core/tests/coretests/src/com/android/internal/content/res/TEST_MAPPING16
-rw-r--r--core/tests/coretests/src/com/android/internal/jank/CujTest.java45
-rw-r--r--data/etc/Android.bp6
-rw-r--r--data/etc/oem-defined-uids.xml38
-rw-r--r--data/keyboards/Vendor_054c_Product_05c4.idc10
-rw-r--r--data/keyboards/Vendor_054c_Product_09cc.idc8
-rw-r--r--data/keyboards/Vendor_054c_Product_0ce6.idc31
-rw-r--r--data/keyboards/Vendor_054c_Product_0df2.idc31
-rw-r--r--graphics/java/android/graphics/drawable/TEST_MAPPING8
-rw-r--r--libs/WindowManager/Shell/OWNERS2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/compatui/OWNERS4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/OWNERS3
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/freeform/OWNERS6
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/OWNERS2
-rw-r--r--libs/WindowManager/Shell/tests/OWNERS5
-rw-r--r--media/jni/JetPlayer.h8
-rw-r--r--native/graphics/jni/Android.bp27
-rw-r--r--native/graphics/jni/fuzz/fuzz_imagedecoder.cpp65
-rw-r--r--nfc/api/current.txt2
-rw-r--r--nfc/java/android/nfc/NfcActivityManager.java25
-rw-r--r--nfc/java/android/nfc/NfcAdapter.java186
-rw-r--r--nfc/java/android/nfc/NfcOemExtension.java30
-rw-r--r--nfc/java/android/nfc/cardemulation/CardEmulation.java631
-rw-r--r--nfc/java/android/nfc/cardemulation/HostApduService.java44
-rw-r--r--nfc/java/android/nfc/flags.aconfig8
-rw-r--r--packages/SoundPicker/src/com/android/soundpicker/RingtonePickerActivity.java4
-rw-r--r--packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/model/A11yMenuShortcut.java53
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/rotation/FloatingRotationButton.java8
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/rotation/FloatingRotationButtonView.java16
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/OWNERS11
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/OWNERS16
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/OWNERS2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/OWNERS3
-rw-r--r--services/Android.bp6
-rw-r--r--services/accessibility/TEST_MAPPING16
-rw-r--r--services/appfunctions/OWNERS1
-rw-r--r--services/core/Android.bp19
-rw-r--r--services/core/java/com/android/server/BatteryService.java6
-rw-r--r--services/core/java/com/android/server/SystemConfig.java28
-rw-r--r--services/core/java/com/android/server/am/AppRestrictionController.java8
-rw-r--r--services/core/java/com/android/server/am/OWNERS1
-rw-r--r--services/core/java/com/android/server/am/TEST_MAPPING6
-rw-r--r--services/core/java/com/android/server/hdmi/DelayedMessageBuffer.java12
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java28
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java19
-rw-r--r--services/core/java/com/android/server/input/OWNERS1
-rw-r--r--services/core/java/com/android/server/net/NetworkPolicyManagerService.java131
-rw-r--r--services/core/java/com/android/server/net/flags.aconfig10
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java14
-rw-r--r--services/core/java/com/android/server/pm/Settings.java15
-rw-r--r--services/core/java/com/android/server/wm/WallpaperController.java4
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java38
-rw-r--r--services/core/jni/OWNERS3
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/am/OWNERS1
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt1
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java29
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java105
-rw-r--r--services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java67
-rw-r--r--services/usage/java/com/android/server/usage/TEST_MAPPING7
-rw-r--r--test-mock/Android.bp4
-rw-r--r--tools/systemfeatures/Android.bp63
-rw-r--r--tools/systemfeatures/OWNERS1
-rw-r--r--tools/systemfeatures/README.md11
-rw-r--r--tools/systemfeatures/src/com/android/systemfeatures/SystemFeaturesGenerator.kt218
-rw-r--r--tools/systemfeatures/tests/Context.java27
-rw-r--r--tools/systemfeatures/tests/PackageManager.java30
-rw-r--r--tools/systemfeatures/tests/SystemFeaturesGeneratorTest.java135
112 files changed, 1649 insertions, 1632 deletions
diff --git a/INPUT_OWNERS b/INPUT_OWNERS
index 06ead06fc13a..9b1016e7b7e9 100644
--- a/INPUT_OWNERS
+++ b/INPUT_OWNERS
@@ -1,4 +1,5 @@
# Bug component: 136048
+# Please assign bugs to android-framework-input-triage@.
arpitks@google.com
asmitapoddar@google.com
hcutts@google.com
diff --git a/OWNERS b/OWNERS
index bde7ab22a043..096da29c2b21 100644
--- a/OWNERS
+++ b/OWNERS
@@ -14,6 +14,7 @@ michaelwr@google.com #{LAST_RESORT_SUGGESTION}
nandana@google.com #{LAST_RESORT_SUGGESTION}
narayan@google.com #{LAST_RESORT_SUGGESTION}
ogunwale@google.com #{LAST_RESORT_SUGGESTION}
+omakoto@google.com #{LAST_RESORT_SUGGESTION}
roosa@google.com #{LAST_RESORT_SUGGESTION}
smoreland@google.com #{LAST_RESORT_SUGGESTION}
yamasani@google.com #{LAST_RESORT_SUGGESTION}
diff --git a/PERFORMANCE_OWNERS b/PERFORMANCE_OWNERS
index 48a020130445..02b0a1ec75e7 100644
--- a/PERFORMANCE_OWNERS
+++ b/PERFORMANCE_OWNERS
@@ -6,3 +6,4 @@ philipcuadra@google.com
shayba@google.com
jdduke@google.com
shombert@google.com
+kevinjeon@google.com
diff --git a/ZYGOTE_OWNERS b/ZYGOTE_OWNERS
index f6d15e03a892..6918c16840dd 100644
--- a/ZYGOTE_OWNERS
+++ b/ZYGOTE_OWNERS
@@ -1,4 +1,4 @@
chriswailes@google.com
+hboehm@google.com
maco@google.com
-narayan@google.com
ngeoffray@google.com
diff --git a/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ClientSocketPerfTest.java b/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ClientSocketPerfTest.java
index 2643bae4060f..f20b1706129b 100644
--- a/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ClientSocketPerfTest.java
+++ b/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ClientSocketPerfTest.java
@@ -142,7 +142,7 @@ public final class ClientSocketPerfTest {
// Always use the same server for consistency across the benchmarks.
server = config.serverFactory().newServer(
- ChannelType.CHANNEL, config.messageSize(), config.protocol().getProtocols(),
+ config.messageSize(), config.protocol().getProtocols(),
ciphers(config));
server.setMessageProcessor(new ServerEndpoint.MessageProcessor() {
diff --git a/apct-tests/perftests/core/src/android/conscrypt/conscrypt/EndpointFactory.java b/apct-tests/perftests/core/src/android/conscrypt/conscrypt/EndpointFactory.java
index 0655f45726ba..ba2acb8a5205 100644
--- a/apct-tests/perftests/core/src/android/conscrypt/conscrypt/EndpointFactory.java
+++ b/apct-tests/perftests/core/src/android/conscrypt/conscrypt/EndpointFactory.java
@@ -43,10 +43,10 @@ public enum EndpointFactory {
factories.clientFactory, channelType, port, protocols, ciphers);
}
- public ServerEndpoint newServer(ChannelType channelType, int messageSize,
+ public ServerEndpoint newServer(int messageSize,
String[] protocols, String[] ciphers) throws IOException {
return new ServerEndpoint(factories.serverFactory, factories.serverSocketFactory,
- channelType, messageSize, protocols, ciphers);
+ messageSize, protocols, ciphers);
}
private static final class Factories {
diff --git a/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ServerEndpoint.java b/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ServerEndpoint.java
index 3631c3f29287..1e4f12460936 100644
--- a/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ServerEndpoint.java
+++ b/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ServerEndpoint.java
@@ -34,8 +34,6 @@ import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
-import org.conscrypt.ChannelType;
-
/**
* A simple socket-based test server.
*/
@@ -63,7 +61,6 @@ final class ServerEndpoint {
}
private final ServerSocket serverSocket;
- private final ChannelType channelType;
private final SSLSocketFactory socketFactory;
private final int messageSize;
private final String[] protocols;
@@ -78,11 +75,10 @@ final class ServerEndpoint {
private volatile Future<?> processFuture;
ServerEndpoint(SSLSocketFactory socketFactory, SSLServerSocketFactory serverSocketFactory,
- ChannelType channelType, int messageSize, String[] protocols,
+ int messageSize, String[] protocols,
String[] cipherSuites) throws IOException {
- this.serverSocket = channelType.newServerSocket(serverSocketFactory);
+ this.serverSocket = serverSocketFactory.createServerSocket();
this.socketFactory = socketFactory;
- this.channelType = channelType;
this.messageSize = messageSize;
this.protocols = protocols;
this.cipherSuites = cipherSuites;
@@ -134,7 +130,7 @@ final class ServerEndpoint {
if (stopping) {
return;
}
- socket = channelType.accept(serverSocket, socketFactory);
+ socket = (SSLSocket) serverSocket.accept();
socket.setEnabledProtocols(protocols);
socket.setEnabledCipherSuites(cipherSuites);
diff --git a/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ServerSocketPerfTest.java b/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ServerSocketPerfTest.java
index 4f285ff4eb94..af3c405eab82 100644
--- a/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ServerSocketPerfTest.java
+++ b/apct-tests/perftests/core/src/android/conscrypt/conscrypt/ServerSocketPerfTest.java
@@ -130,8 +130,7 @@ public final class ServerSocketPerfTest {
final ChannelType channelType = config.channelType();
- server = config.serverFactory().newServer(
- channelType, config.messageSize(),
+ server = config.serverFactory().newServer(config.messageSize(),
new String[] {"TLSv1.3", "TLSv1.2"}, ciphers(config));
server.setMessageProcessor(new MessageProcessor() {
@Override
diff --git a/apct-tests/perftests/multiuser/Android.bp b/apct-tests/perftests/multiuser/Android.bp
index 1653edc77de9..9eea712b33dd 100644
--- a/apct-tests/perftests/multiuser/Android.bp
+++ b/apct-tests/perftests/multiuser/Android.bp
@@ -38,3 +38,15 @@ android_test {
],
certificate: "platform",
}
+
+filegroup {
+ name: "multi_user_trace_config",
+ srcs: [
+ "trace_configs/trace_config_multi_user.textproto",
+ ],
+}
+
+prebuilt_etc {
+ name: "trace_config_multi_user.textproto",
+ src: ":multi_user_trace_config",
+}
diff --git a/api/Android.bp b/api/Android.bp
index 4b26eb48f5de..d9966fd87ac3 100644
--- a/api/Android.bp
+++ b/api/Android.bp
@@ -284,7 +284,7 @@ packages_to_document = [
// These are libs from framework-internal-utils that are required (i.e. being referenced)
// from framework-non-updatable-sources. Add more here when there's a need.
// DO NOT add the entire framework-internal-utils. It might cause unnecessary circular
-// dependencies gets bigger.
+// dependencies when the list gets bigger.
android_non_updatable_stubs_libs = [
"android.hardware.cas-V1.2-java",
"android.hardware.health-V1.0-java-constants",
@@ -381,6 +381,11 @@ non_updatable_api_deps_on_modules = [
"sdk_system_current_android",
]
+java_defaults {
+ name: "module-classpath-java-defaults",
+ libs: non_updatable_api_deps_on_modules,
+}
+
// Defaults with module APIs in the classpath (mostly from prebuilts).
// Suitable for compiling android-non-updatable.
stubs_defaults {
diff --git a/api/StubLibraries.bp b/api/StubLibraries.bp
index 8dfddf0e13c8..d991da59f167 100644
--- a/api/StubLibraries.bp
+++ b/api/StubLibraries.bp
@@ -563,8 +563,12 @@ java_library {
java_defaults {
name: "android-non-updatable_from_text_defaults",
+ defaults: ["android-non-updatable-stubs-libs-defaults"],
static_libs: ["framework-res-package-jar"],
libs: ["stub-annotations"],
+ sdk_version: "none",
+ system_modules: "none",
+ previous_api: ":android.api.public.latest",
}
java_defaults {
@@ -582,10 +586,10 @@ java_api_library {
"api-stubs-docs-non-updatable.api.contribution",
],
defaults: ["android-non-updatable_everything_from_text_defaults"],
- full_api_surface_stub: "android_stubs_current.from-text",
// Use full Android API not just the non-updatable API as the latter is incomplete
// and can result in incorrect behavior.
previous_api: ":android.api.combined.public.latest",
+ libs: ["all-modules-public-stubs"],
}
java_api_library {
@@ -596,10 +600,10 @@ java_api_library {
"system-api-stubs-docs-non-updatable.api.contribution",
],
defaults: ["android-non-updatable_everything_from_text_defaults"],
- full_api_surface_stub: "android_system_stubs_current.from-text",
// Use full Android API not just the non-updatable API as the latter is incomplete
// and can result in incorrect behavior.
previous_api: ":android.api.combined.system.latest",
+ libs: ["all-modules-system-stubs"],
}
java_api_library {
@@ -611,10 +615,10 @@ java_api_library {
"test-api-stubs-docs-non-updatable.api.contribution",
],
defaults: ["android-non-updatable_everything_from_text_defaults"],
- full_api_surface_stub: "android_test_stubs_current.from-text",
// Use full Android API not just the non-updatable API as the latter is incomplete
// and can result in incorrect behavior.
previous_api: ":android.api.combined.test.latest",
+ libs: ["all-modules-system-stubs"],
}
java_api_library {
@@ -625,8 +629,10 @@ java_api_library {
"system-api-stubs-docs-non-updatable.api.contribution",
"module-lib-api-stubs-docs-non-updatable.api.contribution",
],
- defaults: ["android-non-updatable_everything_from_text_defaults"],
- full_api_surface_stub: "android_module_lib_stubs_current_full.from-text",
+ defaults: [
+ "module-classpath-java-defaults",
+ "android-non-updatable_everything_from_text_defaults",
+ ],
// Use full Android API not just the non-updatable API as the latter is incomplete
// and can result in incorrect behavior.
previous_api: ":android.api.combined.module-lib.latest",
@@ -644,14 +650,16 @@ java_api_library {
"test-api-stubs-docs-non-updatable.api.contribution",
"module-lib-api-stubs-docs-non-updatable.api.contribution",
],
- defaults: ["android-non-updatable_everything_from_text_defaults"],
- full_api_surface_stub: "android_test_module_lib_stubs_current.from-text",
+ defaults: [
+ "module-classpath-java-defaults",
+ "android-non-updatable_everything_from_text_defaults",
+ ],
// No need to specify previous_api as this is not used for compiling against.
-
// This module is only used for hiddenapi, and other modules should not
// depend on this module.
visibility: ["//visibility:private"],
+ libs: ["all-modules-system-stubs"],
}
java_defaults {
@@ -665,7 +673,7 @@ java_defaults {
}
java_library {
- name: "android_stubs_current.from-source",
+ name: "android_stubs_current",
static_libs: [
"all-modules-public-stubs",
"android-non-updatable.stubs",
@@ -675,7 +683,7 @@ java_library {
}
java_library {
- name: "android_stubs_current_exportable.from-source",
+ name: "android_stubs_current_exportable",
static_libs: [
"all-modules-public-stubs-exportable",
"android-non-updatable.stubs.exportable",
@@ -685,7 +693,7 @@ java_library {
}
java_library {
- name: "android_system_stubs_current.from-source",
+ name: "android_system_stubs_current",
static_libs: [
"all-modules-system-stubs",
"android-non-updatable.stubs.system",
@@ -698,7 +706,7 @@ java_library {
}
java_library {
- name: "android_system_stubs_current_exportable.from-source",
+ name: "android_system_stubs_current_exportable",
static_libs: [
"all-modules-system-stubs-exportable",
"android-non-updatable.stubs.exportable.system",
@@ -722,7 +730,7 @@ java_library {
}
java_library {
- name: "android_test_stubs_current.from-source",
+ name: "android_test_stubs_current",
static_libs: [
// Updatable modules do not have test APIs, but we want to include their SystemApis, like we
// include the SystemApi of framework-non-updatable-sources.
@@ -739,7 +747,7 @@ java_library {
}
java_library {
- name: "android_test_stubs_current_exportable.from-source",
+ name: "android_test_stubs_current_exportable",
static_libs: [
// Updatable modules do not have test APIs, but we want to include their SystemApis, like we
// include the SystemApi of framework-non-updatable-sources.
@@ -760,7 +768,7 @@ java_library {
// This module does not need to be copied to dist
java_library {
- name: "android_test_frameworks_core_stubs_current.from-source",
+ name: "android_test_frameworks_core_stubs_current",
static_libs: [
"all-updatable-modules-system-stubs",
"android-non-updatable.stubs.test",
@@ -772,7 +780,7 @@ java_library {
}
java_library {
- name: "android_module_lib_stubs_current.from-source",
+ name: "android_module_lib_stubs_current",
defaults: [
"android.jar_defaults",
],
@@ -785,7 +793,7 @@ java_library {
}
java_library {
- name: "android_module_lib_stubs_current_exportable.from-source",
+ name: "android_module_lib_stubs_current_exportable",
defaults: [
"android.jar_defaults",
"android_stubs_dists_default",
@@ -801,20 +809,20 @@ java_library {
}
java_library {
- name: "android_system_server_stubs_current.from-source",
+ name: "android_system_server_stubs_current",
defaults: [
"android.jar_defaults",
],
srcs: [":services-non-updatable-stubs"],
installable: false,
static_libs: [
- "android_module_lib_stubs_current.from-source",
+ "android_module_lib_stubs_current",
],
visibility: ["//frameworks/base/services"],
}
java_library {
- name: "android_system_server_stubs_current_exportable.from-source",
+ name: "android_system_server_stubs_current_exportable",
defaults: [
"android.jar_defaults",
"android_stubs_dists_default",
@@ -822,7 +830,7 @@ java_library {
srcs: [":services-non-updatable-stubs{.exportable}"],
installable: false,
static_libs: [
- "android_module_lib_stubs_current_exportable.from-source",
+ "android_module_lib_stubs_current_exportable",
],
dist: {
dir: "apistubs/android/system-server",
@@ -897,215 +905,6 @@ java_genrule {
},
}
-//
-// Java API defaults and libraries for single tree build
-//
-
-java_defaults {
- name: "stub-annotation-defaults",
- libs: [
- "stub-annotations",
- ],
- static_libs: [
- // stub annotations do not contribute to the API surfaces but are statically
- // linked in the stubs for API surfaces (see frameworks/base/StubLibraries.bp).
- // This is because annotation processors insist on loading the classes for any
- // annotations found, thus should exist inside android.jar.
- "private-stub-annotations-jar",
- ],
- is_stubs_module: true,
-}
-
-// Listing of API domains contribution and dependencies per API surfaces
-java_defaults {
- name: "android_test_stubs_current_contributions",
- api_surface: "test",
- api_contributions: [
- "framework-virtualization.stubs.source.test.api.contribution",
- "framework-location.stubs.source.test.api.contribution",
- ],
-}
-
-java_defaults {
- name: "android_test_frameworks_core_stubs_current_contributions",
- api_surface: "test",
- api_contributions: [
- "test-api-stubs-docs-non-updatable.api.contribution",
- ],
-}
-
-java_defaults {
- name: "android_module_lib_stubs_current_contributions",
- api_surface: "module-lib",
- api_contributions: [
- "api-stubs-docs-non-updatable.api.contribution",
- "system-api-stubs-docs-non-updatable.api.contribution",
- "module-lib-api-stubs-docs-non-updatable.api.contribution",
- "art.module.public.api.stubs.source.api.contribution",
- "art.module.public.api.stubs.source.system.api.contribution",
- "art.module.public.api.stubs.source.module_lib.api.contribution",
- "i18n.module.public.api.stubs.source.api.contribution",
- "i18n.module.public.api.stubs.source.system.api.contribution",
- "i18n.module.public.api.stubs.source.module_lib.api.contribution",
- ],
- previous_api: ":android.api.combined.module-lib.latest",
-}
-
-// Java API library definitions per API surface
-java_api_library {
- name: "android_stubs_current.from-text",
- api_surface: "public",
- defaults: [
- // This module is dynamically created at frameworks/base/api/api.go
- // instead of being written out, in order to minimize edits in the codebase
- // when there is a change in the list of modules.
- // that contributes to an api surface.
- "android_stubs_current_contributions",
- "stub-annotation-defaults",
- ],
- api_contributions: [
- "api-stubs-docs-non-updatable.api.contribution",
- ],
- visibility: ["//visibility:public"],
- enable_validation: false,
- stubs_type: "everything",
-}
-
-java_api_library {
- name: "android_system_stubs_current.from-text",
- api_surface: "system",
- defaults: [
- "android_stubs_current_contributions",
- "android_system_stubs_current_contributions",
- "stub-annotation-defaults",
- ],
- api_contributions: [
- "api-stubs-docs-non-updatable.api.contribution",
- "system-api-stubs-docs-non-updatable.api.contribution",
- ],
- visibility: ["//visibility:public"],
- enable_validation: false,
- stubs_type: "everything",
-}
-
-java_api_library {
- name: "android_test_stubs_current.from-text",
- api_surface: "test",
- defaults: [
- "android_stubs_current_contributions",
- "android_system_stubs_current_contributions",
- "android_test_stubs_current_contributions",
- "stub-annotation-defaults",
- ],
- api_contributions: [
- "api-stubs-docs-non-updatable.api.contribution",
- "system-api-stubs-docs-non-updatable.api.contribution",
- "test-api-stubs-docs-non-updatable.api.contribution",
- ],
- visibility: ["//visibility:public"],
- enable_validation: false,
- stubs_type: "everything",
-}
-
-java_api_library {
- name: "android_test_frameworks_core_stubs_current.from-text",
- api_surface: "test",
- defaults: [
- "android_stubs_current_contributions",
- "android_system_stubs_current_contributions",
- "android_test_frameworks_core_stubs_current_contributions",
- ],
- libs: [
- "stub-annotations",
- ],
- api_contributions: [
- "api-stubs-docs-non-updatable.api.contribution",
- "system-api-stubs-docs-non-updatable.api.contribution",
- ],
- enable_validation: false,
- stubs_type: "everything",
-}
-
-java_api_library {
- name: "android_module_lib_stubs_current_full.from-text",
- api_surface: "module-lib",
- defaults: [
- "android_stubs_current_contributions",
- "android_system_stubs_current_contributions",
- "android_module_lib_stubs_current_contributions_full",
- ],
- libs: [
- "stub-annotations",
- ],
- api_contributions: [
- "api-stubs-docs-non-updatable.api.contribution",
- "system-api-stubs-docs-non-updatable.api.contribution",
- "module-lib-api-stubs-docs-non-updatable.api.contribution",
- ],
- visibility: ["//visibility:public"],
- enable_validation: false,
- stubs_type: "everything",
-}
-
-java_api_library {
- name: "android_module_lib_stubs_current.from-text",
- api_surface: "module-lib",
- defaults: [
- "android_module_lib_stubs_current_contributions",
- ],
- libs: [
- "android_module_lib_stubs_current_full.from-text",
- "stub-annotations",
- ],
- visibility: ["//visibility:public"],
- enable_validation: false,
- stubs_type: "everything",
-}
-
-java_api_library {
- name: "android_test_module_lib_stubs_current.from-text",
- api_surface: "module-lib",
- defaults: [
- "android_stubs_current_contributions",
- "android_system_stubs_current_contributions",
- "android_test_stubs_current_contributions",
- "android_module_lib_stubs_current_contributions",
- ],
- libs: [
- "android_module_lib_stubs_current_full.from-text",
- "stub-annotations",
- ],
- api_contributions: [
- "test-api-stubs-docs-non-updatable.api.contribution",
- ],
-
- // This module is only used to build android-non-updatable.stubs.test_module_lib
- // and other modules should not depend on this module.
- visibility: [
- "//visibility:private",
- ],
- enable_validation: false,
- stubs_type: "everything",
-}
-
-java_api_library {
- name: "android_system_server_stubs_current.from-text",
- api_surface: "system-server",
- api_contributions: [
- "services-non-updatable-stubs.api.contribution",
- ],
- libs: [
- "android_module_lib_stubs_current.from-text",
- "stub-annotations",
- ],
- static_libs: [
- "android_module_lib_stubs_current.from-text",
- ],
- visibility: ["//visibility:public"],
- enable_validation: false,
- stubs_type: "everything",
-}
-
////////////////////////////////////////////////////////////////////////
// api-versions.xml generation, for public and system. This API database
// also contains the android.test.* APIs.
diff --git a/api/api.go b/api/api.go
index b6b1a7e44510..5b7f534443fb 100644
--- a/api/api.go
+++ b/api/api.go
@@ -15,9 +15,7 @@
package api
import (
- "fmt"
"sort"
- "strings"
"github.com/google/blueprint/proptools"
@@ -464,79 +462,6 @@ func createMergedTxts(ctx android.LoadHookContext, bootclasspath, system_server_
}
}
-func createApiContributionDefaults(ctx android.LoadHookContext, modules []string) {
- defaultsSdkKinds := []android.SdkKind{
- android.SdkPublic, android.SdkSystem, android.SdkModule,
- }
- for _, sdkKind := range defaultsSdkKinds {
- props := defaultsProps{}
- props.Name = proptools.StringPtr(
- sdkKind.DefaultJavaLibraryName() + "_contributions")
- if sdkKind == android.SdkModule {
- props.Name = proptools.StringPtr(
- sdkKind.DefaultJavaLibraryName() + "_contributions_full")
- }
- props.Api_surface = proptools.StringPtr(sdkKind.String())
- apiSuffix := ""
- if sdkKind != android.SdkPublic {
- apiSuffix = "." + strings.ReplaceAll(sdkKind.String(), "-", "_")
- }
- props.Api_contributions = transformArray(
- modules, "", fmt.Sprintf(".stubs.source%s.api.contribution", apiSuffix))
- props.Defaults_visibility = []string{"//visibility:public"}
- props.Previous_api = proptools.StringPtr(":android.api.combined." + sdkKind.String() + ".latest")
- ctx.CreateModule(java.DefaultsFactory, &props)
- }
-}
-
-func createFullApiLibraries(ctx android.LoadHookContext) {
- javaLibraryNames := []string{
- "android_stubs_current",
- "android_system_stubs_current",
- "android_test_stubs_current",
- "android_test_frameworks_core_stubs_current",
- "android_module_lib_stubs_current",
- "android_system_server_stubs_current",
- }
-
- for _, libraryName := range javaLibraryNames {
- props := libraryProps{}
- props.Name = proptools.StringPtr(libraryName)
- staticLib := libraryName + ".from-source"
- if ctx.Config().BuildFromTextStub() {
- staticLib = libraryName + ".from-text"
- }
- props.Static_libs = []string{staticLib}
- props.Defaults = []string{"android.jar_defaults"}
- props.Visibility = []string{"//visibility:public"}
- props.Is_stubs_module = proptools.BoolPtr(true)
-
- ctx.CreateModule(java.LibraryFactory, &props)
- }
-}
-
-func createFullExportableApiLibraries(ctx android.LoadHookContext) {
- javaLibraryNames := []string{
- "android_stubs_current_exportable",
- "android_system_stubs_current_exportable",
- "android_test_stubs_current_exportable",
- "android_module_lib_stubs_current_exportable",
- "android_system_server_stubs_current_exportable",
- }
-
- for _, libraryName := range javaLibraryNames {
- props := libraryProps{}
- props.Name = proptools.StringPtr(libraryName)
- staticLib := libraryName + ".from-source"
- props.Static_libs = []string{staticLib}
- props.Defaults = []string{"android.jar_defaults"}
- props.Visibility = []string{"//visibility:public"}
- props.Is_stubs_module = proptools.BoolPtr(true)
-
- ctx.CreateModule(java.LibraryFactory, &props)
- }
-}
-
func (a *CombinedApis) createInternalModules(ctx android.LoadHookContext) {
bootclasspath := a.bootclasspath(ctx)
system_server_classpath := a.systemServerClasspath(ctx)
@@ -562,12 +487,6 @@ func (a *CombinedApis) createInternalModules(ctx android.LoadHookContext) {
createMergedAnnotationsFilegroups(ctx, bootclasspath, system_server_classpath)
createPublicStubsSourceFilegroup(ctx, bootclasspath)
-
- createApiContributionDefaults(ctx, bootclasspath)
-
- createFullApiLibraries(ctx)
-
- createFullExportableApiLibraries(ctx)
}
func combinedApisModuleFactory() android.Module {
diff --git a/api/api_test.go b/api/api_test.go
index 47d167093b39..fb26f821eec1 100644
--- a/api/api_test.go
+++ b/api/api_test.go
@@ -52,6 +52,12 @@ func gatherRequiredDepsForTest() string {
"core.current.stubs",
"ext",
"framework",
+ "android_stubs_current",
+ "android_system_stubs_current",
+ "android_test_stubs_current",
+ "android_test_frameworks_core_stubs_current",
+ "android_module_lib_stubs_current",
+ "android_system_server_stubs_current",
"android_stubs_current.from-text",
"android_system_stubs_current.from-text",
"android_test_stubs_current.from-text",
@@ -190,61 +196,60 @@ func TestCombinedApisDefaults(t *testing.T) {
}
}),
).RunTestWithBp(t, `
- java_sdk_library {
- name: "framework-foo",
- srcs: ["a.java"],
- public: {
- enabled: true,
- },
- system: {
- enabled: true,
- },
- test: {
- enabled: true,
- },
- module_lib: {
- enabled: true,
- },
- api_packages: [
- "foo",
- ],
- sdk_version: "core_current",
- annotations_enabled: true,
- }
+ java_sdk_library {
+ name: "framework-foo",
+ srcs: ["a.java"],
+ public: {
+ enabled: true,
+ },
+ system: {
+ enabled: true,
+ },
+ test: {
+ enabled: true,
+ },
+ module_lib: {
+ enabled: true,
+ },
+ api_packages: [
+ "foo",
+ ],
+ sdk_version: "core_current",
+ annotations_enabled: true,
+ }
+ java_sdk_library {
+ name: "framework-bar",
+ srcs: ["a.java"],
+ public: {
+ enabled: true,
+ },
+ system: {
+ enabled: true,
+ },
+ test: {
+ enabled: true,
+ },
+ module_lib: {
+ enabled: true,
+ },
+ api_packages: [
+ "foo",
+ ],
+ sdk_version: "core_current",
+ annotations_enabled: true,
+ }
- java_sdk_library {
- name: "framework-bar",
- srcs: ["a.java"],
- public: {
- enabled: true,
- },
- system: {
- enabled: true,
- },
- test: {
- enabled: true,
- },
- module_lib: {
- enabled: true,
- },
- api_packages: [
- "foo",
+ combined_apis {
+ name: "foo",
+ bootclasspath: [
+ "framework-bar",
+ ] + select(boolean_var_for_testing(), {
+ true: [
+ "framework-foo",
],
- sdk_version: "core_current",
- annotations_enabled: true,
- }
-
- combined_apis {
- name: "foo",
- bootclasspath: [
- "framework-bar",
- ] + select(boolean_var_for_testing(), {
- true: [
- "framework-foo",
- ],
- default: [],
- }),
- }
+ default: [],
+ }),
+ }
`)
subModuleDependsOnSelectAppendedModule := java.CheckModuleHasDependency(t,
diff --git a/core/TEST_MAPPING b/core/TEST_MAPPING
index fd571c95f568..b78659cd611d 100644
--- a/core/TEST_MAPPING
+++ b/core/TEST_MAPPING
@@ -1,18 +1,7 @@
{
"presubmit": [
{
- "name": "FrameworksCoreTests",
- "options": [
- {
- "include-filter": "android.view.inputmethod"
- },
- {
- "include-filter": "com.android.internal.inputmethod"
- },
- {
- "exclude-annotation": "androidx.test.filters.FlakyTest"
- }
- ],
+ "name": "FrameworksCoreTests_inputmethod",
"file_patterns": [
"core/java/com/android/internal/inputmethod/.*",
"core/java/android/view/inputmethod/.*",
diff --git a/core/java/android/app/OWNERS b/core/java/android/app/OWNERS
index 1200b4b45712..adeb0451cd43 100644
--- a/core/java/android/app/OWNERS
+++ b/core/java/android/app/OWNERS
@@ -94,6 +94,9 @@ per-file IEphemeralResolver.aidl = file:/services/core/java/com/android/server/p
per-file IInstantAppResolver.aidl = file:/services/core/java/com/android/server/pm/OWNERS
per-file InstantAppResolveInfo.aidl = file:/services/core/java/com/android/server/pm/OWNERS
+# Performance
+per-file PropertyInvalidatedCache.java = file:/PERFORMANCE_OWNERS
+
# Pinner
per-file pinner-client.aconfig = file:/core/java/android/app/pinner/OWNERS
diff --git a/core/java/android/app/TEST_MAPPING b/core/java/android/app/TEST_MAPPING
index a29c196d88de..e86435e77eb7 100644
--- a/core/java/android/app/TEST_MAPPING
+++ b/core/java/android/app/TEST_MAPPING
@@ -153,18 +153,7 @@
"file_patterns": ["(/|^)ContextImpl.java"]
},
{
- "name": "FrameworksCoreTests",
- "options": [
- {
- "exclude-annotation": "androidx.test.filters.FlakyTest"
- },
- {
- "exclude-annotation": "org.junit.Ignore"
- },
- {
- "include-filter": "android.content.ContextTest"
- }
- ],
+ "name": "FrameworksCoreTests_context",
"file_patterns": ["(/|^)ContextImpl.java"]
},
{
@@ -177,35 +166,13 @@
]
},
{
- "name": "FrameworksCoreTests",
- "options": [
- {
- "exclude-annotation": "androidx.test.filters.FlakyTest"
- },
- {
- "exclude-annotation": "org.junit.Ignore"
- },
- {
- "include-filter": "android.app.KeyguardManagerTest"
- }
- ],
+ "name": "FrameworksCoreTests_keyguard_manager",
"file_patterns": [
"(/|^)KeyguardManager.java"
]
},
{
- "name": "FrameworksCoreTests",
- "options": [
- {
- "exclude-annotation": "androidx.test.filters.FlakyTest"
- },
- {
- "exclude-annotation": "org.junit.Ignore"
- },
- {
- "include-filter": "android.app.PropertyInvalidatedCacheTests"
- }
- ],
+ "name": "FrameworksCoreTests_property_invalidated_cache",
"file_patterns": [
"(/|^)PropertyInvalidatedCache.java"
]
diff --git a/core/java/android/app/appfunctions/OWNERS b/core/java/android/app/appfunctions/OWNERS
new file mode 100644
index 000000000000..c6827cc93222
--- /dev/null
+++ b/core/java/android/app/appfunctions/OWNERS
@@ -0,0 +1,6 @@
+avayvod@google.com
+oadesina@google.com
+toki@google.com
+tonymak@google.com
+mingweiliao@google.com
+anothermark@google.com
diff --git a/core/java/android/content/TEST_MAPPING b/core/java/android/content/TEST_MAPPING
index a2cfbf5aa5bd..baf32a519645 100644
--- a/core/java/android/content/TEST_MAPPING
+++ b/core/java/android/content/TEST_MAPPING
@@ -22,24 +22,7 @@
"file_patterns": ["(/|^)Context.java", "(/|^)ContextWrapper.java"]
},
{
- "name": "FrameworksCoreTests",
- "options": [
- {
- "exclude-annotation": "androidx.test.filters.FlakyTest"
- },
- {
- "exclude-annotation": "org.junit.Ignore"
- },
- {
- "include-filter": "android.content.ContextTest"
- },
- {
- "include-filter": "android.content.ComponentCallbacksControllerTest"
- },
- {
- "include-filter": "android.content.ContextWrapperTest"
- }
- ],
+ "name": "FrameworksCoreTests_android_content",
"file_patterns": ["(/|^)Context.java", "(/|^)ContextWrapper.java", "(/|^)ComponentCallbacksController.java"]
},
{
diff --git a/core/java/android/database/OWNERS b/core/java/android/database/OWNERS
index 53f5bb0ab492..50b7015e6b5c 100644
--- a/core/java/android/database/OWNERS
+++ b/core/java/android/database/OWNERS
@@ -1,6 +1,2 @@
include /SQLITE_OWNERS
-omakoto@google.com
-jsharkey@android.com
-yamasani@google.com
-
diff --git a/core/java/android/database/sqlite/TEST_MAPPING b/core/java/android/database/sqlite/TEST_MAPPING
index 9dcf4e592454..659cf6cd9cf3 100644
--- a/core/java/android/database/sqlite/TEST_MAPPING
+++ b/core/java/android/database/sqlite/TEST_MAPPING
@@ -1,18 +1,7 @@
{
"presubmit": [
{
- "name": "FrameworksCoreTests",
- "options": [
- {
- "exclude-annotation": "androidx.test.filters.FlakyTest"
- },
- {
- "exclude-annotation": "org.junit.Ignore"
- },
- {
- "include-filter": "android.database.sqlite.SQLiteRawStatementTest"
- }
- ],
+ "name": "FrameworksCoreTests_sqlite",
"file_patterns": [
"(/|^)SQLiteRawStatement.java",
"(/|^)SQLiteDatabase.java",
diff --git a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
index 97c03ed8b0c7..b909ab84ba10 100644
--- a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
@@ -849,7 +849,7 @@ public class CameraDeviceImpl extends CameraDevice
checkIfCameraClosedOrInError();
for (String physicalId : physicalCameraIdSet) {
- if (physicalId == getId()) {
+ if (Objects.equals(physicalId, getId())) {
throw new IllegalStateException("Physical id matches the logical id!");
}
}
diff --git a/core/java/android/os/OWNERS b/core/java/android/os/OWNERS
index 6d6757d5afd1..7d3076d6611f 100644
--- a/core/java/android/os/OWNERS
+++ b/core/java/android/os/OWNERS
@@ -106,6 +106,9 @@ per-file SystemConfigManager.java = file:/PACKAGE_MANAGER_OWNERS
# ProfilingService
per-file ProfilingServiceManager.java = file:/PERFORMANCE_OWNERS
+# Performance
+per-file IpcDataCache.java = file:/PERFORMANCE_OWNERS
+
# Memory
per-file OomKillRecord.java = file:/MEMORY_OWNERS
diff --git a/core/java/android/os/TEST_MAPPING b/core/java/android/os/TEST_MAPPING
index b5029a6aaff3..c84ebde6e999 100644
--- a/core/java/android/os/TEST_MAPPING
+++ b/core/java/android/os/TEST_MAPPING
@@ -73,11 +73,7 @@
"PowerComponents\\.java",
"[^/]*BatteryConsumer[^/]*\\.java"
],
- "name": "FrameworksCoreTests",
- "options": [
- { "include-filter": "com.android.internal.os.BatteryStatsTests" },
- { "exclude-annotation": "com.android.internal.os.SkipPresubmit" }
- ]
+ "name": "FrameworksCoreTests_battery_stats"
},
{
"file_patterns": [
@@ -132,12 +128,7 @@
},
{
"file_patterns": ["Environment[^/]*\\.java"],
- "name": "FrameworksCoreTests",
- "options": [
- {
- "include-filter": "android.os.EnvironmentTest"
- }
- ]
+ "name": "FrameworksCoreTests_environment"
}
],
"postsubmit": [
diff --git a/core/java/android/security/net/config/SystemCertificateSource.java b/core/java/android/security/net/config/SystemCertificateSource.java
index 3a254c1d92fc..bdda42a389eb 100644
--- a/core/java/android/security/net/config/SystemCertificateSource.java
+++ b/core/java/android/security/net/config/SystemCertificateSource.java
@@ -19,6 +19,8 @@ package android.security.net.config;
import android.os.Environment;
import android.os.UserHandle;
+import com.android.internal.util.ArrayUtils;
+
import java.io.File;
/**
@@ -45,7 +47,7 @@ public final class SystemCertificateSource extends DirectoryCertificateSource {
}
File updatable_dir = new File("/apex/com.android.conscrypt/cacerts");
if (updatable_dir.exists()
- && !(updatable_dir.list().length == 0)) {
+ && !(ArrayUtils.isEmpty(updatable_dir.list()))) {
return updatable_dir;
}
return new File(System.getenv("ANDROID_ROOT") + "/etc/security/cacerts");
diff --git a/core/java/android/util/TEST_MAPPING b/core/java/android/util/TEST_MAPPING
index c681f86ce439..64b2e6eeccc7 100644
--- a/core/java/android/util/TEST_MAPPING
+++ b/core/java/android/util/TEST_MAPPING
@@ -1,27 +1,11 @@
{
"presubmit": [
{
- "name": "FrameworksCoreTests",
- "options": [
- {
- "include-filter": "android.util.CharsetUtilsTest"
- },
- {
- "include-filter": "com.android.internal.util.FastDataTest"
- }
- ],
+ "name": "FrameworksCoreTests_util_data_charset",
"file_patterns": ["CharsetUtils|FastData"]
},
{
- "name": "FrameworksCoreTests",
- "options": [
- {
- "include-filter": "android.util.XmlTest"
- },
- {
- "include-filter": "android.util.BinaryXmlTest"
- }
- ],
+ "name": "FrameworksCoreTests_xml",
"file_patterns": ["Xml"]
}
],
diff --git a/core/java/android/util/apk/TEST_MAPPING b/core/java/android/util/apk/TEST_MAPPING
index 7668eec474ab..3ae470ad8a95 100644
--- a/core/java/android/util/apk/TEST_MAPPING
+++ b/core/java/android/util/apk/TEST_MAPPING
@@ -1,12 +1,7 @@
{
"presubmit": [
{
- "name": "FrameworksCoreTests",
- "options": [
- {
- "include-filter": "android.util.apk.SourceStampVerifierTest"
- }
- ]
+ "name": "FrameworksCoreTests_util_apk"
}
],
"presubmit-large": [
diff --git a/core/java/android/view/SurfaceControlRegistry.java b/core/java/android/view/SurfaceControlRegistry.java
index 127d4a70a564..b7f3ee337a03 100644
--- a/core/java/android/view/SurfaceControlRegistry.java
+++ b/core/java/android/view/SurfaceControlRegistry.java
@@ -71,7 +71,7 @@ public class SurfaceControlRegistry {
}
// Sort entries by time registered when dumping
// TODO: Or should it sort by name?
- entries.sort((o1, o2) -> (int) (o1.getValue() - o2.getValue()));
+ entries.sort((o1, o2) -> Long.compare(o1.getValue(), o2.getValue()));
final int size = Math.min(entries.size(), limit);
pw.println("SurfaceControlRegistry");
diff --git a/core/java/android/view/textclassifier/TEST_MAPPING b/core/java/android/view/textclassifier/TEST_MAPPING
index 2f9e737dc213..050c65191cad 100644
--- a/core/java/android/view/textclassifier/TEST_MAPPING
+++ b/core/java/android/view/textclassifier/TEST_MAPPING
@@ -1,15 +1,7 @@
{
"presubmit": [
{
- "name": "FrameworksCoreTests",
- "options": [
- {
- "include-filter": "android.view.textclassifier"
- },
- {
- "exclude-annotation": "androidx.test.filters.FlakyTest"
- }
- ]
+ "name": "FrameworksCoreTests_textclassifier"
},
{
"name": "CtsTextClassifierTestCases",
diff --git a/core/java/com/android/internal/content/om/TEST_MAPPING b/core/java/com/android/internal/content/om/TEST_MAPPING
index ab3abb1c935a..c27c3251e100 100644
--- a/core/java/com/android/internal/content/om/TEST_MAPPING
+++ b/core/java/com/android/internal/content/om/TEST_MAPPING
@@ -1,12 +1,7 @@
{
"presubmit": [
{
- "name": "FrameworksCoreTests",
- "options": [
- {
- "include-filter": "com.android.internal.content."
- }
- ]
+ "name": "FrameworksCoreTests_internal_content"
},
{
"name": "SelfTargetingOverlayDeviceTests"
diff --git a/core/java/com/android/internal/infra/TEST_MAPPING b/core/java/com/android/internal/infra/TEST_MAPPING
index c09181f2f496..e4550c0db135 100644
--- a/core/java/com/android/internal/infra/TEST_MAPPING
+++ b/core/java/com/android/internal/infra/TEST_MAPPING
@@ -20,12 +20,7 @@
]
},
{
- "name": "FrameworksCoreTests",
- "options": [
- {
- "include-filter": "com.android.internal.infra."
- }
- ]
+ "name": "FrameworksCoreTests_internal_infra"
}
]
}
diff --git a/core/java/com/android/internal/jank/TEST_MAPPING b/core/java/com/android/internal/jank/TEST_MAPPING
index 4e00ff19e9d9..e7f3dc38e44b 100644
--- a/core/java/com/android/internal/jank/TEST_MAPPING
+++ b/core/java/com/android/internal/jank/TEST_MAPPING
@@ -1,18 +1,7 @@
{
"presubmit": [
{
- "name": "FrameworksCoreTests",
- "options": [
- {
- "include-filter": "com.android.internal.jank"
- },
- {
- "exclude-annotation": "androidx.test.filters.FlakyTest"
- },
- {
- "exclude-annotation": "org.junit.Ignore"
- }
- ],
+ "name": "FrameworksCoreTests_internal_jank",
"file_patterns": [
"core/java/com/android/internal/jank/.*",
"core/tests/coretests/src/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 d552e0b8c643..cc17807c9be6 100644
--- a/core/java/com/android/internal/os/TEST_MAPPING
+++ b/core/java/com/android/internal/os/TEST_MAPPING
@@ -6,11 +6,7 @@
"Kernel[^/]*\\.java",
"[^/]*Power[^/]*\\.java"
],
- "name": "FrameworksCoreTests",
- "options": [
- { "include-filter": "com.android.internal.os.BatteryStatsTests" },
- { "exclude-annotation": "com.android.internal.os.SkipPresubmit" }
- ]
+ "name": "FrameworksCoreTests_battery_stats"
},
{
"file_patterns": [
@@ -24,11 +20,7 @@
"file_patterns": [
"BinderDeathDispatcher\\.java"
],
- "name": "FrameworksCoreTests",
- "options": [
- { "include-filter": "com.android.internal.os.BinderDeathDispatcherTest" },
- { "exclude-annotation": "com.android.internal.os.SkipPresubmit" }
- ]
+ "name": "FrameworksCoreTests_internal_os_binder"
},
{
"file_patterns": [
@@ -50,25 +42,7 @@
"name": "PowerStatsTests"
},
{
- "name": "FrameworksCoreTests",
- "options": [
- {
- "include-filter": "com.android.internal.os.KernelCpuUidFreqTimeReaderTest"
- },
- {
- "include-filter": "com.android.internal.os.KernelCpuUidActiveTimeReaderTest"
- },
- {
- "include-filter": "com.android.internal.os.KernelCpuUidClusterTimeReaderTest"
- },
- {
- "include-filter": "com.android.internal.os.KernelSingleUidTimeReaderTest"
- },
- {
- "include-filter": "com.android.internal.os.KernelCpuUidBpfMapReaderTest"
- }
-
- ],
+ "name": "FrameworksCoreTests_internal_os_kernel",
"file_patterns": [
"KernelCpuUidTimeReader\\.java",
"KernelCpuUidBpfMapReader\\.java",
diff --git a/core/java/com/android/internal/power/TEST_MAPPING b/core/java/com/android/internal/power/TEST_MAPPING
index 1946f5cc99eb..3f184b22a299 100644
--- a/core/java/com/android/internal/power/TEST_MAPPING
+++ b/core/java/com/android/internal/power/TEST_MAPPING
@@ -1,11 +1,7 @@
{
"presubmit": [
{
- "name": "FrameworksCoreTests",
- "options": [
- { "include-filter": "com.android.internal.os.BatteryStatsTests" },
- { "exclude-annotation": "com.android.internal.os.SkipPresubmit" }
- ]
+ "name": "FrameworksCoreTests_battery_stats"
},
{
"name": "PowerStatsTests"
diff --git a/core/java/com/android/internal/security/TEST_MAPPING b/core/java/com/android/internal/security/TEST_MAPPING
index 0af3b03edefc..5bd9d2e4512d 100644
--- a/core/java/com/android/internal/security/TEST_MAPPING
+++ b/core/java/com/android/internal/security/TEST_MAPPING
@@ -1,15 +1,7 @@
{
"presubmit": [
{
- "name": "FrameworksCoreTests",
- "options": [
- {
- "include-filter": "com.android.internal.security."
- },
- {
- "include-annotation": "android.platform.test.annotations.Presubmit"
- }
- ]
+ "name": "FrameworksCoreTests_internal_security"
},
{
"name": "UpdatableSystemFontTest",
diff --git a/core/java/com/android/internal/util/TEST_MAPPING b/core/java/com/android/internal/util/TEST_MAPPING
index 00a8118c0e4b..a0221f3beff2 100644
--- a/core/java/com/android/internal/util/TEST_MAPPING
+++ b/core/java/com/android/internal/util/TEST_MAPPING
@@ -5,30 +5,11 @@
"file_patterns": ["ScreenshotHelper"]
},
{
- "name": "FrameworksCoreTests",
- "options": [
- {
- "include-filter": "android.util.XmlTest"
- },
- {
- "include-filter": "android.util.BinaryXmlTest"
- }
- ],
+ "name": "FrameworksCoreTests_xml",
"file_patterns": ["Xml"]
},
{
- "name": "FrameworksCoreTests",
- "options": [
- {
- "include-filter": "com.android.internal.util.LatencyTrackerTest"
- },
- {
- "exclude-annotation": "androidx.test.filters.FlakyTest"
- },
- {
- "exclude-annotation": "org.junit.Ignore"
- }
- ],
+ "name": "FrameworksCoreTests_internal_util_latency_tracker",
"file_patterns": ["LatencyTracker.java"]
}
]
diff --git a/core/java/com/android/internal/widget/OWNERS b/core/java/com/android/internal/widget/OWNERS
index cf2f202a03ac..2d1c2f032d16 100644
--- a/core/java/com/android/internal/widget/OWNERS
+++ b/core/java/com/android/internal/widget/OWNERS
@@ -3,7 +3,9 @@ per-file RecyclerView.java = mount@google.com
per-file ViewPager.java = mount@google.com
# LockSettings related
-per-file *LockPattern* = file:/services/core/java/com/android/server/locksettings/OWNERS
+per-file LockPatternChecker.java = file:/services/core/java/com/android/server/locksettings/OWNERS
+per-file LockPatternUtils.java = file:/services/core/java/com/android/server/locksettings/OWNERS
+per-file LockPatternView.java = file:/packages/SystemUI/OWNERS
per-file *LockScreen* = file:/services/core/java/com/android/server/locksettings/OWNERS
per-file *Lockscreen* = file:/services/core/java/com/android/server/locksettings/OWNERS
per-file *LockSettings* = file:/services/core/java/com/android/server/locksettings/OWNERS
diff --git a/core/jni/OWNERS b/core/jni/OWNERS
index 30ce63cfc744..6e67c3776e51 100644
--- a/core/jni/OWNERS
+++ b/core/jni/OWNERS
@@ -50,6 +50,10 @@ per-file EphemeralStorage* = file:platform/system/libhwbinder:/OWNERS
# Sensor
per-file android_hardware_SensorManager* = arthuri@google.com, bduddie@google.com, stange@google.com
+# Security
+per-file android_os_SELinux.cpp = file:/core/java/android/security/OWNERS
+per-file android_security_* = file:/core/java/android/security/OWNERS
+
per-file *Zygote* = file:/ZYGOTE_OWNERS
per-file core_jni_helpers.* = file:/ZYGOTE_OWNERS
per-file fd_utils.* = file:/ZYGOTE_OWNERS
@@ -66,7 +70,6 @@ per-file android_opengl_* = file:/opengl/java/android/opengl/OWNERS
per-file android_os_storage_* = file:/core/java/android/os/storage/OWNERS
per-file android_os_Trace* = file:/TRACE_OWNERS
per-file android_se_* = file:/omapi/java/android/se/OWNERS
-per-file android_security_* = file:/core/java/android/security/OWNERS
per-file android_view_* = file:/core/java/android/view/OWNERS
per-file com_android_internal_net_* = file:/services/core/java/com/android/server/net/OWNERS
diff --git a/core/jni/TEST_MAPPING b/core/jni/TEST_MAPPING
index ea0b01e16bdf..fa73a4d2d5a9 100644
--- a/core/jni/TEST_MAPPING
+++ b/core/jni/TEST_MAPPING
@@ -1,15 +1,7 @@
{
"presubmit": [
{
- "name": "FrameworksCoreTests",
- "options": [
- {
- "include-filter": "android.util.CharsetUtilsTest"
- },
- {
- "include-filter": "com.android.internal.util.FastDataTest"
- }
- ],
+ "name": "FrameworksCoreTests_util_data_charset",
"file_patterns": ["CharsetUtils|FastData"]
},
{
diff --git a/core/tests/coretests/src/android/content/TEST_MAPPING b/core/tests/coretests/src/android/content/TEST_MAPPING
index bbc2458f5d8b..fd9fda3ab96a 100644
--- a/core/tests/coretests/src/android/content/TEST_MAPPING
+++ b/core/tests/coretests/src/android/content/TEST_MAPPING
@@ -1,18 +1,7 @@
{
"presubmit": [
{
- "name": "FrameworksCoreTests",
- "options": [
- {
- "include-filter": "android.content.ContentCaptureOptionsTest"
- },
- {
- "exclude-annotation": "androidx.test.filters.FlakyTest"
- },
- {
- "exclude-annotation": "org.junit.Ignore"
- }
- ]
+ "name": "FrameworksCoreTests_content_capture_options"
}
]
}
diff --git a/core/tests/coretests/src/android/content/integrity/TEST_MAPPING b/core/tests/coretests/src/android/content/integrity/TEST_MAPPING
index 2920716f5d5d..d22fe84f3d84 100644
--- a/core/tests/coretests/src/android/content/integrity/TEST_MAPPING
+++ b/core/tests/coretests/src/android/content/integrity/TEST_MAPPING
@@ -1,12 +1,7 @@
{
"presubmit": [
{
- "name": "FrameworksCoreTests",
- "options": [
- {
- "include-filter": "android.content.integrity."
- }
- ]
+ "name": "FrameworksCoreTests_android_content_integrity"
}
]
}
diff --git a/core/tests/coretests/src/android/content/pm/TEST_MAPPING b/core/tests/coretests/src/android/content/pm/TEST_MAPPING
index 978d80cb52f6..9ab438ef9fd2 100644
--- a/core/tests/coretests/src/android/content/pm/TEST_MAPPING
+++ b/core/tests/coretests/src/android/content/pm/TEST_MAPPING
@@ -1,21 +1,7 @@
{
"presubmit": [
{
- "name": "FrameworksCoreTests",
- "options": [
- {
- "include-filter": "android.content.pm."
- },
- {
- "include-annotation": "android.platform.test.annotations.Presubmit"
- },
- {
- "exclude-annotation": "androidx.test.filters.FlakyTest"
- },
- {
- "exclude-annotation": "org.junit.Ignore"
- }
- ]
+ "name": "FrameworksCoreTests_android_content_pm_PreSubmit"
}
],
"postsubmit": [
diff --git a/core/tests/coretests/src/android/content/res/TEST_MAPPING b/core/tests/coretests/src/android/content/res/TEST_MAPPING
index 4ea6e40a7225..25927de55d33 100644
--- a/core/tests/coretests/src/android/content/res/TEST_MAPPING
+++ b/core/tests/coretests/src/android/content/res/TEST_MAPPING
@@ -1,24 +1,7 @@
{
"presubmit": [
{
- "name": "FrameworksCoreTests",
- "options": [
- {
- "include-filter": "android.content.res."
- },
- {
- "include-annotation": "android.platform.test.annotations.Presubmit"
- },
- {
- "exclude-annotation": "android.platform.test.annotations.Postsubmit"
- },
- {
- "exclude-annotation": "androidx.test.filters.FlakyTest"
- },
- {
- "exclude-annotation": "org.junit.Ignore"
- }
- ]
+ "name": "FrameworksCoreTests_android_content_res"
}
],
"postsubmit": [
diff --git a/core/tests/coretests/src/android/service/TEST_MAPPING b/core/tests/coretests/src/android/service/TEST_MAPPING
index bec72d988e74..21f248d3d799 100644
--- a/core/tests/coretests/src/android/service/TEST_MAPPING
+++ b/core/tests/coretests/src/android/service/TEST_MAPPING
@@ -1,17 +1,7 @@
{
"presubmit": [
{
- "name": "FrameworksCoreTests",
- "options": [
- {"include-filter": "android.service.controls"},
- {"include-filter": "android.service.controls.actions"},
- {"include-filter": "android.service.controls.templates"},
- {"include-filter": "android.service.euicc"},
- {"include-filter": "android.service.notification"},
- {"include-filter": "android.service.quicksettings"},
- {"include-filter": "android.service.settings.suggestions"},
- {"exclude-annotation": "org.junit.Ignore"}
- ]
+ "name": "FrameworksCoreTests_android_service"
}
]
}
diff --git a/core/tests/coretests/src/android/view/contentcapture/TEST_MAPPING b/core/tests/coretests/src/android/view/contentcapture/TEST_MAPPING
index f8beac2814db..c2cf40dc4ebe 100644
--- a/core/tests/coretests/src/android/view/contentcapture/TEST_MAPPING
+++ b/core/tests/coretests/src/android/view/contentcapture/TEST_MAPPING
@@ -1,18 +1,7 @@
{
"presubmit": [
{
- "name": "FrameworksCoreTests",
- "options": [
- {
- "include-filter": "android.view.contentcapture"
- },
- {
- "exclude-annotation": "androidx.test.filters.FlakyTest"
- },
- {
- "exclude-annotation": "org.junit.Ignore"
- }
- ]
+ "name": "FrameworksCoreTests_android_view_contentcapture"
}
]
}
diff --git a/core/tests/coretests/src/android/view/contentprotection/TEST_MAPPING b/core/tests/coretests/src/android/view/contentprotection/TEST_MAPPING
index 3cd4e17d820b..3ef1ac1e6978 100644
--- a/core/tests/coretests/src/android/view/contentprotection/TEST_MAPPING
+++ b/core/tests/coretests/src/android/view/contentprotection/TEST_MAPPING
@@ -1,18 +1,7 @@
{
"presubmit": [
{
- "name": "FrameworksCoreTests",
- "options": [
- {
- "include-filter": "android.view.contentprotection"
- },
- {
- "exclude-annotation": "androidx.test.filters.FlakyTest"
- },
- {
- "exclude-annotation": "org.junit.Ignore"
- }
- ]
+ "name": "FrameworksCoreTests_android_view_contentprotection"
}
]
}
diff --git a/core/tests/coretests/src/com/android/internal/content/res/TEST_MAPPING b/core/tests/coretests/src/com/android/internal/content/res/TEST_MAPPING
index 9aed8be4f10f..4a46244e0162 100644
--- a/core/tests/coretests/src/com/android/internal/content/res/TEST_MAPPING
+++ b/core/tests/coretests/src/com/android/internal/content/res/TEST_MAPPING
@@ -1,21 +1,7 @@
{
"presubmit": [
{
- "name": "FrameworksCoreTests",
- "options": [
- {
- "include-filter": "com.android.internal.content."
- },
- {
- "include-annotation": "android.platform.test.annotations.Presubmit"
- },
- {
- "exclude-annotation": "androidx.test.filters.FlakyTest"
- },
- {
- "exclude-annotation": "org.junit.Ignore"
- }
- ]
+ "name": "FrameworksCoreTests_com_android_internal_content_Presubmit"
}
]
}
diff --git a/core/tests/coretests/src/com/android/internal/jank/CujTest.java b/core/tests/coretests/src/com/android/internal/jank/CujTest.java
index bf35ed0a1601..2362a4c925f9 100644
--- a/core/tests/coretests/src/com/android/internal/jank/CujTest.java
+++ b/core/tests/coretests/src/com/android/internal/jank/CujTest.java
@@ -35,7 +35,6 @@ import org.junit.Test;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Arrays;
-import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -47,26 +46,30 @@ import java.util.stream.Stream;
public class CujTest {
private static final String ENUM_NAME_PREFIX =
"UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__";
- private static final Set<String> DEPRECATED_VALUES = new HashSet<>() {
- {
- add(ENUM_NAME_PREFIX + "IME_INSETS_ANIMATION");
- }
- };
- private static final Map<Integer, String> ENUM_NAME_EXCEPTION_MAP = new HashMap<>() {
- {
- put(Cuj.CUJ_NOTIFICATION_ADD, getEnumName("SHADE_NOTIFICATION_ADD"));
- put(Cuj.CUJ_NOTIFICATION_HEADS_UP_APPEAR, getEnumName("SHADE_HEADS_UP_APPEAR"));
- put(Cuj.CUJ_NOTIFICATION_APP_START, getEnumName("SHADE_APP_LAUNCH"));
- put(Cuj.CUJ_NOTIFICATION_HEADS_UP_DISAPPEAR, getEnumName("SHADE_HEADS_UP_DISAPPEAR"));
- put(Cuj.CUJ_NOTIFICATION_REMOVE, getEnumName("SHADE_NOTIFICATION_REMOVE"));
- put(Cuj.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE, getEnumName("NOTIFICATION_SHADE_SWIPE"));
- put(Cuj.CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE, getEnumName("SHADE_QS_EXPAND_COLLAPSE"));
- put(Cuj.CUJ_NOTIFICATION_SHADE_QS_SCROLL_SWIPE, getEnumName("SHADE_QS_SCROLL_SWIPE"));
- put(Cuj.CUJ_NOTIFICATION_SHADE_ROW_EXPAND, getEnumName("SHADE_ROW_EXPAND"));
- put(Cuj.CUJ_NOTIFICATION_SHADE_ROW_SWIPE, getEnumName("SHADE_ROW_SWIPE"));
- put(Cuj.CUJ_NOTIFICATION_SHADE_SCROLL_FLING, getEnumName("SHADE_SCROLL_FLING"));
- }
- };
+ private static final Set<String> DEPRECATED_VALUES = Set.of(
+ ENUM_NAME_PREFIX + "IME_INSETS_ANIMATION"
+ );
+ private static final Map<Integer, String> ENUM_NAME_EXCEPTION_MAP = Map.ofEntries(
+ Map.entry(Cuj.CUJ_NOTIFICATION_ADD, getEnumName("SHADE_NOTIFICATION_ADD")),
+ Map.entry(Cuj.CUJ_NOTIFICATION_HEADS_UP_APPEAR, getEnumName("SHADE_HEADS_UP_APPEAR")),
+ Map.entry(Cuj.CUJ_NOTIFICATION_APP_START, getEnumName("SHADE_APP_LAUNCH")),
+ Map.entry(
+ Cuj.CUJ_NOTIFICATION_HEADS_UP_DISAPPEAR,
+ getEnumName("SHADE_HEADS_UP_DISAPPEAR")),
+ Map.entry(Cuj.CUJ_NOTIFICATION_REMOVE, getEnumName("SHADE_NOTIFICATION_REMOVE")),
+ Map.entry(
+ Cuj.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE,
+ getEnumName("NOTIFICATION_SHADE_SWIPE")),
+ Map.entry(
+ Cuj.CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE,
+ getEnumName("SHADE_QS_EXPAND_COLLAPSE")),
+ Map.entry(
+ Cuj.CUJ_NOTIFICATION_SHADE_QS_SCROLL_SWIPE,
+ getEnumName("SHADE_QS_SCROLL_SWIPE")),
+ Map.entry(Cuj.CUJ_NOTIFICATION_SHADE_ROW_EXPAND, getEnumName("SHADE_ROW_EXPAND")),
+ Map.entry(Cuj.CUJ_NOTIFICATION_SHADE_ROW_SWIPE, getEnumName("SHADE_ROW_SWIPE")),
+ Map.entry(Cuj.CUJ_NOTIFICATION_SHADE_SCROLL_FLING, getEnumName("SHADE_SCROLL_FLING"))
+ );
@Rule
public final Expect mExpect = Expect.create();
diff --git a/data/etc/Android.bp b/data/etc/Android.bp
index 1410950966e9..564b87b09cc9 100644
--- a/data/etc/Android.bp
+++ b/data/etc/Android.bp
@@ -78,6 +78,12 @@ prebuilt_etc {
src: "package-shareduid-allowlist.xml",
}
+prebuilt_etc {
+ name: "oem-defined-uids.xml",
+ sub_dir: "sysconfig",
+ src: "oem-defined-uids.xml",
+}
+
// Privapp permission whitelist files
prebuilt_etc {
diff --git a/data/etc/oem-defined-uids.xml b/data/etc/oem-defined-uids.xml
new file mode 100644
index 000000000000..87435b9cd04a
--- /dev/null
+++ b/data/etc/oem-defined-uids.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ 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.
+ -->
+
+<!--
+This XML defines a list of UIDs for OEMs to register as shared UIDs. They will be registered at the
+start of the system, which allows OEMs to create services with these UIDs. The range of these UIDs
+must be in the OEM reserved range.
+
+OEM must provide a preloaded app that is installed at boot time to retain the newly registered UID
+by adding a android:sharedUserId tag in the manifest of the preloaded app, with the value of the tag
+set to the name of the UID defined in this config file. Otherwise, the uid will be cleared at the
+end of the boot and this config file will take no effect.
+
+- The "name" XML attribute refers to the name of the shared UID. It must start with "android.uid.".
+- The "uid" XML attribute refers to the value of the shared UID. It must be in range [2900, 2999].
+
+Example usage
+ <oem-defined-uid name="android.uid.vendordata" uid="2918"/>
+ Indicates that a shared UID named "android.uid.vendordata" will be added to the system with the
+ UID of 2918.
+-->
+
+<config>
+</config>
diff --git a/data/keyboards/Vendor_054c_Product_05c4.idc b/data/keyboards/Vendor_054c_Product_05c4.idc
index 2da622745baf..45b5207c6730 100644
--- a/data/keyboards/Vendor_054c_Product_05c4.idc
+++ b/data/keyboards/Vendor_054c_Product_05c4.idc
@@ -51,7 +51,7 @@ sensor.gyroscope.power = 0.8
# fingers, it prevents tapping to click because it thinks the finger's moving
# too fast.
#
-# Since this touchpad doesn't seem to have to drumroll issues, we can safely
+# Since this touchpad doesn't seem to have drumroll issues, we can safely
# disable drumroll detection.
gestureProp.Drumroll_Suppression_Enable = 0
@@ -60,3 +60,11 @@ gestureProp.Drumroll_Suppression_Enable = 0
# from the palm classifier to increase the usable area of the pad.
gestureProp.Palm_Edge_Zone_Width = 0
gestureProp.Tap_Exclusion_Border_Width = 0
+
+# Touchpad is small, scale up the pointer movements to make it more practical
+# to use.
+gestureProp.Point_X_Out_Scale = 2.5
+gestureProp.Point_Y_Out_Scale = 2.5
+
+# TODO(b/351326684): Ideally "Scroll X Out Scale" and "Scroll Y Out Scale"
+# should be adjusted as well. Currently not supported in IDC files.
diff --git a/data/keyboards/Vendor_054c_Product_09cc.idc b/data/keyboards/Vendor_054c_Product_09cc.idc
index 2a1a4fc62b24..45b5207c6730 100644
--- a/data/keyboards/Vendor_054c_Product_09cc.idc
+++ b/data/keyboards/Vendor_054c_Product_09cc.idc
@@ -60,3 +60,11 @@ gestureProp.Drumroll_Suppression_Enable = 0
# from the palm classifier to increase the usable area of the pad.
gestureProp.Palm_Edge_Zone_Width = 0
gestureProp.Tap_Exclusion_Border_Width = 0
+
+# Touchpad is small, scale up the pointer movements to make it more practical
+# to use.
+gestureProp.Point_X_Out_Scale = 2.5
+gestureProp.Point_Y_Out_Scale = 2.5
+
+# TODO(b/351326684): Ideally "Scroll X Out Scale" and "Scroll Y Out Scale"
+# should be adjusted as well. Currently not supported in IDC files.
diff --git a/data/keyboards/Vendor_054c_Product_0ce6.idc b/data/keyboards/Vendor_054c_Product_0ce6.idc
new file mode 100644
index 000000000000..48027e715649
--- /dev/null
+++ b/data/keyboards/Vendor_054c_Product_0ce6.idc
@@ -0,0 +1,31 @@
+# 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.
+
+#
+# Sony Playstation(R) DualSense 5 Controller
+#
+
+## Touchpad ##
+
+# Because of the way this touchpad is positioned, touches around the edges are
+# no more likely to be palms than ones in the middle, so remove the edge zones
+# from the palm classifier to increase the usable area of the pad.
+gestureProp.Palm_Edge_Zone_Width = 0
+gestureProp.Tap_Exclusion_Border_Width = 0
+
+gestureProp.Point_X_Out_Scale = 2.0
+gestureProp.Point_Y_Out_Scale = 2.0
+
+# TODO(b/351326684): Ideally "Scroll X Out Scale" and "Scroll Y Out Scale"
+# should be adjusted as well. Currently not supported in IDC files.
diff --git a/data/keyboards/Vendor_054c_Product_0df2.idc b/data/keyboards/Vendor_054c_Product_0df2.idc
new file mode 100644
index 000000000000..4bcf0bef458a
--- /dev/null
+++ b/data/keyboards/Vendor_054c_Product_0df2.idc
@@ -0,0 +1,31 @@
+# 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.
+
+#
+# Sony Playstation(R) DualSense Edge 5 Controller
+#
+
+## Touchpad ##
+
+# Because of the way this touchpad is positioned, touches around the edges are
+# no more likely to be palms than ones in the middle, so remove the edge zones
+# from the palm classifier to increase the usable area of the pad.
+gestureProp.Palm_Edge_Zone_Width = 0
+gestureProp.Tap_Exclusion_Border_Width = 0
+
+gestureProp.Point_X_Out_Scale = 2.0
+gestureProp.Point_Y_Out_Scale = 2.0
+
+# TODO(b/351326684): Ideally "Scroll X Out Scale" and "Scroll Y Out Scale"
+# should be adjusted as well. Currently not supported in IDC files.
diff --git a/graphics/java/android/graphics/drawable/TEST_MAPPING b/graphics/java/android/graphics/drawable/TEST_MAPPING
index 1018702e01c5..4f064522b037 100644
--- a/graphics/java/android/graphics/drawable/TEST_MAPPING
+++ b/graphics/java/android/graphics/drawable/TEST_MAPPING
@@ -12,13 +12,7 @@
},
{
- "name": "FrameworksCoreTests",
- "file_patterns": ["(/|^)Icon\\.java"],
- "options" : [
- {
- "include-filter": "android.graphics.drawable.IconTest"
- }
- ]
+ "name": "FrameworksCoreTests_drawable"
}
]
}
diff --git a/libs/WindowManager/Shell/OWNERS b/libs/WindowManager/Shell/OWNERS
index cb422eab372b..c6044a45200d 100644
--- a/libs/WindowManager/Shell/OWNERS
+++ b/libs/WindowManager/Shell/OWNERS
@@ -1,5 +1,5 @@
xutan@google.com
# Give submodule owners in shell resource approval
-per-file res*/*/*.xml = atsjenk@google.com, hwwang@google.com, jorgegil@google.com, lbill@google.com, madym@google.com, vaniadesmonda@google.com, pbdr@google.com, tkachenkoi@google.com, mpodolian@google.com, liranb@google.com
+per-file res*/*/*.xml = atsjenk@google.com, hwwang@google.com, jorgegil@google.com, lbill@google.com, madym@google.com, vaniadesmonda@google.com, pbdr@google.com, tkachenkoi@google.com, mpodolian@google.com, liranb@google.com, pragyabajoria@google.com, uysalorhan@google.com, gsennton@google.com, mattsziklay@google.com, mdehaini@google.com
per-file res*/*/tv_*.xml = bronger@google.com
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/OWNERS b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/OWNERS
new file mode 100644
index 000000000000..1875675296a8
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/OWNERS
@@ -0,0 +1,4 @@
+# WM shell sub-module compat ui owners
+mariiasand@google.com
+gracielawputri@google.com
+mcarli@google.com
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/OWNERS b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/OWNERS
index b01b2b7ad520..afdda8ff865e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/OWNERS
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/OWNERS
@@ -5,3 +5,6 @@ madym@google.com
pbdr@google.com
tkachenkoi@google.com
vaniadesmonda@google.com
+pragyabajoria@google.com
+uysalorhan@google.com
+gsennton@google.com
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/OWNERS b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/OWNERS
index 8a0eea0a9bdd..83b5bf658459 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/OWNERS
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/OWNERS
@@ -5,3 +5,9 @@ madym@google.com
nmusgrave@google.com
pbdr@google.com
tkachenkoi@google.com
+vaniadesmonda@google.com
+pragyabajoria@google.com
+uysalorhan@google.com
+gsennton@google.com
+mattsziklay@google.com
+mdehaini@google.com
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/OWNERS b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/OWNERS
index 4417209b85ed..3f828f547920 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/OWNERS
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/OWNERS
@@ -1 +1,3 @@
jorgegil@google.com
+mattsziklay@google.com
+mdehaini@google.com
diff --git a/libs/WindowManager/Shell/tests/OWNERS b/libs/WindowManager/Shell/tests/OWNERS
index 2a0a28ebcaa2..a7206fad0256 100644
--- a/libs/WindowManager/Shell/tests/OWNERS
+++ b/libs/WindowManager/Shell/tests/OWNERS
@@ -13,3 +13,8 @@ vaniadesmonda@google.com
pbdr@google.com
tkachenkoi@google.com
mpodolian@google.com
+pragyabajoria@google.com
+uysalorhan@google.com
+gsennton@google.com
+mattsziklay@google.com
+mdehaini@google.com
diff --git a/media/jni/JetPlayer.h b/media/jni/JetPlayer.h
index bb569bcad7be..4cc266dec445 100644
--- a/media/jni/JetPlayer.h
+++ b/media/jni/JetPlayer.h
@@ -40,7 +40,7 @@ public:
static const int JET_NUMQUEUEDSEGMENT_UPDATE = 3;
static const int JET_PAUSE_UPDATE = 4;
- JetPlayer(void *javaJetPlayer,
+ explicit JetPlayer(void *javaJetPlayer,
int maxTracks = 32,
int trackBufferSize = 1200);
~JetPlayer();
@@ -69,7 +69,6 @@ private:
void fireUpdateOnStatusChange();
void fireEventsFromJetQueue();
- JetPlayer() {} // no default constructor
void dump();
void dumpJetStatus(S_JET_STATUS* pJetStatus);
@@ -96,7 +95,7 @@ private:
class JetPlayerThread : public Thread {
public:
- JetPlayerThread(JetPlayer *player) : mPlayer(player) {
+ explicit JetPlayerThread(JetPlayer *player) : mPlayer(player) {
}
protected:
@@ -106,8 +105,7 @@ private:
JetPlayer *mPlayer;
bool threadLoop() {
- int result;
- result = mPlayer->render();
+ mPlayer->render();
return false;
}
diff --git a/native/graphics/jni/Android.bp b/native/graphics/jni/Android.bp
index 8f16f762f7ef..0fb3049f63d8 100644
--- a/native/graphics/jni/Android.bp
+++ b/native/graphics/jni/Android.bp
@@ -127,3 +127,30 @@ cc_fuzz {
"-DPNG_MUTATOR_DEFINE_LIBFUZZER_CUSTOM_MUTATOR",
],
}
+
+cc_fuzz {
+ name: "imagedecoder_heif_fuzzer",
+ defaults: ["imagedecoder_fuzzer_defaults"],
+ team: "trendy_team_android_core_graphics_stack",
+ shared_libs: [
+ "libfakeservicemanager",
+ ],
+ target: {
+ android: {
+ shared_libs: [
+ "libmediaplayerservice",
+ "libmediaextractorservice",
+ ],
+ },
+ host: {
+ static_libs: [
+ "libbinder_random_parcel",
+ "libcutils",
+ ],
+ },
+ },
+ include_dirs: ["frameworks/av/services/mediaextractor"],
+ cflags: [
+ "-DFUZZ_HEIF_FORMAT",
+ ],
+}
diff --git a/native/graphics/jni/fuzz/fuzz_imagedecoder.cpp b/native/graphics/jni/fuzz/fuzz_imagedecoder.cpp
index 6743997fb152..f739e4a1d1a2 100644
--- a/native/graphics/jni/fuzz/fuzz_imagedecoder.cpp
+++ b/native/graphics/jni/fuzz/fuzz_imagedecoder.cpp
@@ -18,6 +18,16 @@
#include <binder/IPCThreadState.h>
#include <fuzzer/FuzzedDataProvider.h>
+#ifdef FUZZ_HEIF_FORMAT
+#include <fakeservicemanager/FakeServiceManager.h>
+#ifdef __ANDROID__
+#include <MediaExtractorService.h>
+#include <MediaPlayerService.h>
+#else
+#include <fuzzbinder/random_binder.h>
+#endif //__ANDROID__
+#endif // FUZZ_HEIF_FORMAT
+
#ifdef PNG_MUTATOR_DEFINE_LIBFUZZER_CUSTOM_MUTATOR
#include <fuzz/png_mutator.h>
#endif
@@ -31,8 +41,42 @@ struct PixelFreer {
using PixelPointer = std::unique_ptr<void, PixelFreer>;
+#ifndef FUZZ_HEIF_FORMAT
+#define FOURCC(c1, c2, c3, c4) ((c1) << 24 | (c2) << 16 | (c3) << 8 | (c4))
+/** Reverse all 4 bytes in a 32bit value.
+ e.g. 0x12345678 -> 0x78563412
+*/
+static uint32_t endianSwap32(uint32_t value) {
+ return ((value & 0xFF) << 24) | ((value & 0xFF00) << 8) | ((value & 0xFF0000) >> 8) |
+ (value >> 24);
+}
+
+static bool isFtyp(const uint8_t* data, size_t size) {
+ constexpr int32_t headerSize = 8;
+ constexpr int32_t chunkTypeOffset = 4;
+ constexpr int32_t ftypFourCCVal = FOURCC('f', 't', 'y', 'p');
+ if (size >= headerSize) {
+ const uint32_t* chunk = reinterpret_cast<const uint32_t*>(data + chunkTypeOffset);
+ if (endianSwap32(*chunk) == ftypFourCCVal) {
+ return true;
+ }
+ }
+ return false;
+}
+#endif
+
AImageDecoder* init(const uint8_t* data, size_t size, bool useFileDescriptor) {
AImageDecoder* decoder = nullptr;
+#ifndef FUZZ_HEIF_FORMAT
+ if (isFtyp(data, size)) {
+ /* We want to ignore HEIF data when fuzzing non-HEIF image decoders. Use 'FTYP'
+ * as a signal to ignore, though note that this excludes more than just HEIF.
+ * But when this code was added, `AImageDecoder` did not support any formats
+ * in 'FTYP' besides HEIF.
+ */
+ return nullptr;
+ }
+#endif // FUZZ_HEIF_FORMAT
if (useFileDescriptor) {
constexpr char testFd[] = "tempFd";
int32_t fileDesc = open(testFd, O_RDWR | O_CREAT | O_TRUNC);
@@ -47,6 +91,27 @@ AImageDecoder* init(const uint8_t* data, size_t size, bool useFileDescriptor) {
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
FuzzedDataProvider dataProvider = FuzzedDataProvider(data, size);
+#ifdef FUZZ_HEIF_FORMAT
+ /**
+ * For image formats like HEIF, a new metadata object is
+ * created which requires "media.player" service running
+ */
+ static std::once_flag callOnceHEIF;
+ std::call_once(callOnceHEIF, [&]() {
+ android::sp<android::IServiceManager> fakeServiceManager =
+ new android::FakeServiceManager();
+ setDefaultServiceManager(fakeServiceManager);
+#ifdef __ANDROID__
+ android::MediaPlayerService::instantiate();
+ android::MediaExtractorService::instantiate();
+#else
+ auto binderExtractor = android::getRandomBinder(&dataProvider);
+ auto binderPlayer = android::getRandomBinder(&dataProvider);
+ fakeServiceManager->addService(android::String16("media.extractor"), binderExtractor);
+ fakeServiceManager->addService(android::String16("media.player"), binderPlayer);
+#endif //__ANDROID__
+ });
+#endif // FUZZ_HEIF_FORMAT
/**
* Use maximum of 80% of buffer for creating decoder and save at least
* 20% buffer for fuzzing other APIs
diff --git a/nfc/api/current.txt b/nfc/api/current.txt
index cf7aea405756..b0d1f71e749f 100644
--- a/nfc/api/current.txt
+++ b/nfc/api/current.txt
@@ -232,6 +232,8 @@ package android.nfc.cardemulation {
method public final void notifyUnhandled();
method public final android.os.IBinder onBind(android.content.Intent);
method public abstract void onDeactivated(int);
+ method @FlaggedApi("android.nfc.nfc_event_listener") public void onObserveModeStateChanged(boolean);
+ method @FlaggedApi("android.nfc.nfc_event_listener") public void onPreferredServiceChanged(boolean);
method public abstract byte[] processCommandApdu(byte[], android.os.Bundle);
method @FlaggedApi("android.nfc.nfc_read_polling_loop") public void processPollingFrames(@NonNull java.util.List<android.nfc.cardemulation.PollingFrame>);
method public final void sendResponseApdu(byte[]);
diff --git a/nfc/java/android/nfc/NfcActivityManager.java b/nfc/java/android/nfc/NfcActivityManager.java
index 0e40db612708..0eb846d6c72a 100644
--- a/nfc/java/android/nfc/NfcActivityManager.java
+++ b/nfc/java/android/nfc/NfcActivityManager.java
@@ -236,11 +236,7 @@ public final class NfcActivityManager extends IAppCallback.Stub
public void setReaderMode(Binder token, int flags, Bundle extras) {
if (DBG) Log.d(TAG, "Setting reader mode");
- try {
- NfcAdapter.sService.setReaderMode(token, this, flags, extras);
- } catch (RemoteException e) {
- mAdapter.attemptDeadServiceRecovery(e);
- }
+ NfcAdapter.callService(() -> NfcAdapter.sService.setReaderMode(token, this, flags, extras));
}
/**
@@ -248,19 +244,11 @@ public final class NfcActivityManager extends IAppCallback.Stub
* Makes IPC call - do not hold lock.
*/
void requestNfcServiceCallback() {
- try {
- NfcAdapter.sService.setAppCallback(this);
- } catch (RemoteException e) {
- mAdapter.attemptDeadServiceRecovery(e);
- }
+ NfcAdapter.callService(() -> NfcAdapter.sService.setAppCallback(this));
}
void verifyNfcPermission() {
- try {
- NfcAdapter.sService.verifyNfcPermission();
- } catch (RemoteException e) {
- mAdapter.attemptDeadServiceRecovery(e);
- }
+ NfcAdapter.callService(() -> NfcAdapter.sService.verifyNfcPermission());
}
@Override
@@ -406,11 +394,8 @@ public final class NfcActivityManager extends IAppCallback.Stub
}
private void changeDiscoveryTech(Binder token, int pollTech, int listenTech) {
- try {
- NfcAdapter.sService.updateDiscoveryTechnology(token, pollTech, listenTech);
- } catch (RemoteException e) {
- mAdapter.attemptDeadServiceRecovery(e);
- }
+ NfcAdapter.callService(
+ () -> NfcAdapter.sService.updateDiscoveryTechnology(token, pollTech, listenTech));
}
}
diff --git a/nfc/java/android/nfc/NfcAdapter.java b/nfc/java/android/nfc/NfcAdapter.java
index 0ffab4ba3eaf..b36b705245cd 100644
--- a/nfc/java/android/nfc/NfcAdapter.java
+++ b/nfc/java/android/nfc/NfcAdapter.java
@@ -922,8 +922,8 @@ public final class NfcAdapter {
* @hide
*/
@UnsupportedAppUsage
- public INfcAdapter getService() {
- isEnabled(); // NOP call to recover sService if it is stale
+ public static INfcAdapter getService() {
+ isEnabledStatic(); // NOP call to recover sService if it is stale
return sService;
}
@@ -931,8 +931,8 @@ public final class NfcAdapter {
* Returns the binder interface to the tag service.
* @hide
*/
- public INfcTag getTagService() {
- isEnabled(); // NOP call to recover sTagService if it is stale
+ public static INfcTag getTagService() {
+ isEnabledStatic(); // NOP call to recover sTagService if it is stale
return sTagService;
}
@@ -940,8 +940,8 @@ public final class NfcAdapter {
* Returns the binder interface to the card emulation service.
* @hide
*/
- public INfcCardEmulation getCardEmulationService() {
- isEnabled();
+ public static INfcCardEmulation getCardEmulationService() {
+ isEnabledStatic();
return sCardEmulationService;
}
@@ -949,8 +949,8 @@ public final class NfcAdapter {
* Returns the binder interface to the NFC-F card emulation service.
* @hide
*/
- public INfcFCardEmulation getNfcFCardEmulationService() {
- isEnabled();
+ public static INfcFCardEmulation getNfcFCardEmulationService() {
+ isEnabledStatic();
return sNfcFCardEmulationService;
}
@@ -973,14 +973,14 @@ public final class NfcAdapter {
* @hide
*/
@UnsupportedAppUsage
- public void attemptDeadServiceRecovery(Exception e) {
+ public static void attemptDeadServiceRecovery(RemoteException e) {
Log.e(TAG, "NFC service dead - attempting to recover", e);
INfcAdapter service = getServiceInterface();
if (service == null) {
Log.e(TAG, "could not retrieve NFC service during service recovery");
// nothing more can be done now, sService is still stale, we'll hit
// this recovery path again later
- return;
+ e.rethrowAsRuntimeException();
}
// assigning to sService is not thread-safe, but this is best-effort code
// and on a well-behaved system should never happen
@@ -993,7 +993,7 @@ public final class NfcAdapter {
Log.e(TAG, "could not retrieve NFC tag service during service recovery");
// nothing more can be done now, sService is still stale, we'll hit
// this recovery path again later
- return;
+ ee.rethrowAsRuntimeException();
}
}
@@ -1014,24 +1014,27 @@ public final class NfcAdapter {
"could not retrieve NFC-F card emulation service during service recovery");
}
}
-
- return;
}
- private boolean isCardEmulationEnabled() {
+ private static boolean isCardEmulationEnabled() {
if (sHasCeFeature) {
return (sCardEmulationService != null || sNfcFCardEmulationService != null);
}
return false;
}
- private boolean isTagReadingEnabled() {
+ private static boolean isTagReadingEnabled() {
if (sHasNfcFeature) {
return sTagService != null;
}
return false;
}
+ private static boolean isEnabledStatic() {
+ boolean serviceState = callServiceReturn(() -> sService.getState() == STATE_ON, false);
+ return serviceState
+ && (isTagReadingEnabled() || isCardEmulationEnabled() || sHasNfcWlcFeature);
+ }
/**
* Return true if this NFC Adapter has any features enabled.
@@ -1046,24 +1049,7 @@ public final class NfcAdapter {
* @return true if this NFC Adapter has any features enabled
*/
public boolean isEnabled() {
- boolean serviceState = false;
- try {
- serviceState = sService.getState() == STATE_ON;
- } catch (RemoteException e) {
- attemptDeadServiceRecovery(e);
- // Try one more time
- if (sService == null) {
- Log.e(TAG, "Failed to recover NFC Service.");
- return false;
- }
- try {
- serviceState = sService.getState() == STATE_ON;
- } catch (RemoteException ee) {
- Log.e(TAG, "Failed to recover NFC Service.");
- }
- }
- return serviceState
- && (isTagReadingEnabled() || isCardEmulationEnabled() || sHasNfcWlcFeature);
+ return isEnabledStatic();
}
/**
@@ -1157,11 +1143,7 @@ public final class NfcAdapter {
* @hide
*/
public void pausePolling(int timeoutInMs) {
- try {
- sService.pausePolling(timeoutInMs);
- } catch (RemoteException e) {
- attemptDeadServiceRecovery(e);
- }
+ callService(() -> sService.pausePolling(timeoutInMs));
}
@@ -1222,11 +1204,7 @@ public final class NfcAdapter {
* @hide
*/
public void resumePolling() {
- try {
- sService.resumePolling();
- } catch (RemoteException e) {
- attemptDeadServiceRecovery(e);
- }
+ callService(() -> sService.resumePolling());
}
/**
@@ -1645,15 +1623,10 @@ public final class NfcAdapter {
if (activity == null || intent == null) {
throw new NullPointerException();
}
- try {
- TechListParcel parcel = null;
- if (techLists != null && techLists.length > 0) {
- parcel = new TechListParcel(techLists);
- }
- sService.setForegroundDispatch(intent, filters, parcel);
- } catch (RemoteException e) {
- attemptDeadServiceRecovery(e);
- }
+ final TechListParcel parcel = (techLists != null && techLists.length > 0)
+ ? new TechListParcel(techLists)
+ : null;
+ callService(() -> sService.setForegroundDispatch(intent, filters, parcel));
}
/**
@@ -1677,11 +1650,7 @@ public final class NfcAdapter {
throw new UnsupportedOperationException();
}
}
- try {
- sService.setForegroundDispatch(null, null, null);
- } catch (RemoteException e) {
- attemptDeadServiceRecovery(e);
- }
+ callService(() -> sService.setForegroundDispatch(null, null, null));
}
/**
@@ -1762,11 +1731,7 @@ public final class NfcAdapter {
}
Binder token = new Binder();
int flags = enable ? ENABLE_POLLING_FLAGS : DISABLE_POLLING_FLAGS;
- try {
- NfcAdapter.sService.setReaderMode(token, null, flags, null);
- } catch (RemoteException e) {
- attemptDeadServiceRecovery(e);
- }
+ callService(() -> sService.setReaderMode(token, null, flags, null));
}
/**
@@ -1838,12 +1803,8 @@ public final class NfcAdapter {
&& ((pollTechnology & FLAG_SET_DEFAULT_TECH) == FLAG_SET_DEFAULT_TECH
|| (listenTechnology & FLAG_SET_DEFAULT_TECH) == FLAG_SET_DEFAULT_TECH)) {
Binder token = new Binder();
- try {
- NfcAdapter.sService.updateDiscoveryTechnology(token,
- pollTechnology, listenTechnology);
- } catch (RemoteException e) {
- attemptDeadServiceRecovery(e);
- }
+ callService( () ->
+ sService.updateDiscoveryTechnology(token, pollTechnology, listenTechnology));
} else {
mNfcActivityManager.setDiscoveryTech(activity, pollTechnology, listenTechnology);
}
@@ -2227,11 +2188,7 @@ public final class NfcAdapter {
if (tag == null) {
throw new NullPointerException("tag cannot be null");
}
- try {
- sService.dispatch(tag);
- } catch (RemoteException e) {
- attemptDeadServiceRecovery(e);
- }
+ callService(() -> sService.dispatch(tag));
}
/**
@@ -2267,8 +2224,10 @@ public final class NfcAdapter {
synchronized (mLock) {
if (mNfcUnlockHandlers.containsKey(unlockHandler)) {
// update the tag technologies
- sService.removeNfcUnlockHandler(mNfcUnlockHandlers.get(unlockHandler));
- mNfcUnlockHandlers.remove(unlockHandler);
+ callService(() -> {
+ sService.removeNfcUnlockHandler(mNfcUnlockHandlers.get(unlockHandler));
+ mNfcUnlockHandlers.remove(unlockHandler);
+ });
}
INfcUnlockHandler.Stub iHandler = new INfcUnlockHandler.Stub() {
@@ -2277,20 +2236,18 @@ public final class NfcAdapter {
return unlockHandler.onUnlockAttempted(tag);
}
};
-
- sService.addNfcUnlockHandler(iHandler,
- Tag.getTechCodesFromStrings(tagTechnologies));
- mNfcUnlockHandlers.put(unlockHandler, iHandler);
+ return callServiceReturn(() -> {
+ sService.addNfcUnlockHandler(
+ iHandler, Tag.getTechCodesFromStrings(tagTechnologies));
+ mNfcUnlockHandlers.put(unlockHandler, iHandler);
+ return true;
+ }, false);
}
- } catch (RemoteException e) {
- attemptDeadServiceRecovery(e);
- return false;
} catch (IllegalArgumentException e) {
Log.e(TAG, "Unable to register LockscreenDispatch", e);
return false;
}
- return true;
}
/**
@@ -2307,17 +2264,14 @@ public final class NfcAdapter {
throw new UnsupportedOperationException();
}
}
- try {
- synchronized (mLock) {
- if (mNfcUnlockHandlers.containsKey(unlockHandler)) {
+ synchronized (mLock) {
+ if (mNfcUnlockHandlers.containsKey(unlockHandler)) {
+ return callServiceReturn(() -> {
sService.removeNfcUnlockHandler(mNfcUnlockHandlers.remove(unlockHandler));
- }
-
- return true;
+ return true;
+ }, false);
}
- } catch (RemoteException e) {
- attemptDeadServiceRecovery(e);
- return false;
+ return true;
}
}
@@ -2525,26 +2479,8 @@ public final class NfcAdapter {
Log.e(TAG, "TagIntentAppPreference is not supported");
throw new UnsupportedOperationException();
}
- try {
- Map<String, Boolean> result = (Map<String, Boolean>) sService
- .getTagIntentAppPreferenceForUser(userId);
- return result;
- } catch (RemoteException e) {
- attemptDeadServiceRecovery(e);
- // Try one more time
- if (sService == null) {
- Log.e(TAG, "Failed to recover NFC Service.");
- return Collections.emptyMap();
- }
- try {
- Map<String, Boolean> result = (Map<String, Boolean>) sService
- .getTagIntentAppPreferenceForUser(userId);
- return result;
- } catch (RemoteException ee) {
- Log.e(TAG, "Failed to recover NFC Service.");
- }
- return Collections.emptyMap();
- }
+ return callServiceReturn( () ->
+ sService.getTagIntentAppPreferenceForUser(userId), Collections.emptyMap());
}
/**
@@ -2590,50 +2526,44 @@ public final class NfcAdapter {
callService(() -> sService.notifyTestHceData(technology, data));
}
+ /** @hide */
interface ServiceCall {
void call() throws RemoteException;
}
-
- void callService(ServiceCall call) {
+ /** @hide */
+ static void callService(ServiceCall call) {
try {
if (sService == null) {
- attemptDeadServiceRecovery(null);
+ attemptDeadServiceRecovery(new RemoteException("NFC Service is null"));
}
call.call();
} catch (RemoteException e) {
attemptDeadServiceRecovery(e);
- // Try one more time
- if (sService == null) {
- Log.e(TAG, "Failed to recover NFC Service.");
- return;
- }
try {
call.call();
} catch (RemoteException ee) {
- Log.e(TAG, "Failed to recover NFC Service.");
+ ee.rethrowAsRuntimeException();
}
}
}
+ /** @hide */
interface ServiceCallReturn<T> {
T call() throws RemoteException;
}
- <T> T callServiceReturn(ServiceCallReturn<T> call, T defaultReturn) {
+ /** @hide */
+ static <T> T callServiceReturn(ServiceCallReturn<T> call, T defaultReturn) {
try {
if (sService == null) {
- attemptDeadServiceRecovery(null);
+ attemptDeadServiceRecovery(new RemoteException("NFC Service is null"));
}
return call.call();
} catch (RemoteException e) {
attemptDeadServiceRecovery(e);
// Try one more time
- if (sService == null) {
- Log.e(TAG, "Failed to recover NFC Service.");
- return defaultReturn;
- }
try {
return call.call();
} catch (RemoteException ee) {
- Log.e(TAG, "Failed to recover NFC Service.");
+ ee.rethrowAsRuntimeException();
}
}
return defaultReturn;
diff --git a/nfc/java/android/nfc/NfcOemExtension.java b/nfc/java/android/nfc/NfcOemExtension.java
index f6138a63fae4..2ec819cdc1a9 100644
--- a/nfc/java/android/nfc/NfcOemExtension.java
+++ b/nfc/java/android/nfc/NfcOemExtension.java
@@ -89,13 +89,11 @@ public final class NfcOemExtension {
+ "registering");
throw new IllegalArgumentException();
}
- try {
+ NfcAdapter.callService(() -> {
NfcAdapter.sService.registerOemExtensionCallback(mOemNfcExtensionCallback);
mCallback = callback;
mExecutor = executor;
- } catch (RemoteException e) {
- mAdapter.attemptDeadServiceRecovery(e);
- }
+ });
}
}
@@ -117,13 +115,11 @@ public final class NfcOemExtension {
Log.e(TAG, "Callback not registered");
throw new IllegalArgumentException();
}
- try {
+ NfcAdapter.callService(() -> {
NfcAdapter.sService.unregisterOemExtensionCallback(mOemNfcExtensionCallback);
mCallback = null;
mExecutor = null;
- } catch (RemoteException e) {
- mAdapter.attemptDeadServiceRecovery(e);
- }
+ });
}
}
@@ -134,11 +130,7 @@ public final class NfcOemExtension {
@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
@RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
public void clearPreference() {
- try {
- NfcAdapter.sService.clearPreference();
- } catch (RemoteException e) {
- mAdapter.attemptDeadServiceRecovery(e);
- }
+ NfcAdapter.callService(() -> NfcAdapter.sService.clearPreference());
}
/**
@@ -147,11 +139,7 @@ public final class NfcOemExtension {
@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
@RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
public void synchronizeScreenState() {
- try {
- NfcAdapter.sService.setScreenState();
- } catch (RemoteException e) {
- mAdapter.attemptDeadServiceRecovery(e);
- }
+ NfcAdapter.callService(() -> NfcAdapter.sService.setScreenState());
}
/**
@@ -162,11 +150,7 @@ public final class NfcOemExtension {
@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
@RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
public void maybeTriggerFirmwareUpdate() {
- try {
- NfcAdapter.sService.checkFirmware();
- } catch (RemoteException e) {
- mAdapter.attemptDeadServiceRecovery(e);
- }
+ NfcAdapter.callService(() -> NfcAdapter.sService.checkFirmware());
}
private final class NfcOemExtensionCallback extends INfcOemExtensionCallback.Stub {
diff --git a/nfc/java/android/nfc/cardemulation/CardEmulation.java b/nfc/java/android/nfc/cardemulation/CardEmulation.java
index 2fe2ce39813b..e0438ce9258c 100644
--- a/nfc/java/android/nfc/cardemulation/CardEmulation.java
+++ b/nfc/java/android/nfc/cardemulation/CardEmulation.java
@@ -219,24 +219,9 @@ public final class CardEmulation {
* <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
*/
public boolean isDefaultServiceForCategory(ComponentName service, String category) {
- try {
- return sService.isDefaultServiceForCategory(mContext.getUser().getIdentifier(),
- service, category);
- } catch (RemoteException e) {
- // Try one more time
- recoverService();
- if (sService == null) {
- Log.e(TAG, "Failed to recover CardEmulationService.");
- return false;
- }
- try {
- return sService.isDefaultServiceForCategory(mContext.getUser().getIdentifier(),
- service, category);
- } catch (RemoteException ee) {
- Log.e(TAG, "Failed to recover CardEmulationService.");
- return false;
- }
- }
+ return callServiceReturn(() ->
+ sService.isDefaultServiceForCategory(
+ mContext.getUser().getIdentifier(), service, category), false);
}
/**
@@ -251,24 +236,9 @@ public final class CardEmulation {
* <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
*/
public boolean isDefaultServiceForAid(ComponentName service, String aid) {
- try {
- return sService.isDefaultServiceForAid(mContext.getUser().getIdentifier(),
- service, aid);
- } catch (RemoteException e) {
- // Try one more time
- recoverService();
- if (sService == null) {
- Log.e(TAG, "Failed to recover CardEmulationService.");
- return false;
- }
- try {
- return sService.isDefaultServiceForAid(mContext.getUser().getIdentifier(),
- service, aid);
- } catch (RemoteException ee) {
- Log.e(TAG, "Failed to reach CardEmulationService.");
- return false;
- }
- }
+ return callServiceReturn(() ->
+ sService.isDefaultServiceForAid(
+ mContext.getUser().getIdentifier(), service, aid), false);
}
/**
@@ -331,22 +301,8 @@ public final class CardEmulation {
*/
public int getSelectionModeForCategory(String category) {
if (CATEGORY_PAYMENT.equals(category)) {
- boolean paymentRegistered = false;
- try {
- paymentRegistered = sService.isDefaultPaymentRegistered();
- } catch (RemoteException e) {
- recoverService();
- if (sService == null) {
- Log.e(TAG, "Failed to recover CardEmulationService.");
- return SELECTION_MODE_ALWAYS_ASK;
- }
- try {
- paymentRegistered = sService.isDefaultPaymentRegistered();
- } catch (RemoteException ee) {
- Log.e(TAG, "Failed to reach CardEmulationService.");
- return SELECTION_MODE_ALWAYS_ASK;
- }
- }
+ boolean paymentRegistered = callServiceReturn(() ->
+ sService.isDefaultPaymentRegistered(), false);
if (paymentRegistered) {
return SELECTION_MODE_PREFER_DEFAULT;
} else {
@@ -369,13 +325,9 @@ public final class CardEmulation {
@FlaggedApi(Flags.FLAG_NFC_OBSERVE_MODE)
public boolean setShouldDefaultToObserveModeForService(@NonNull ComponentName service,
boolean enable) {
- try {
- return sService.setShouldDefaultToObserveModeForService(
- mContext.getUser().getIdentifier(), service, enable);
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to reach CardEmulationService.");
- }
- return false;
+ return callServiceReturn(() ->
+ sService.setShouldDefaultToObserveModeForService(
+ mContext.getUser().getIdentifier(), service, enable), false);
}
/**
@@ -396,27 +348,11 @@ public final class CardEmulation {
@FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP)
public boolean registerPollingLoopFilterForService(@NonNull ComponentName service,
@NonNull String pollingLoopFilter, boolean autoTransact) {
- pollingLoopFilter = validatePollingLoopFilter(pollingLoopFilter);
-
- try {
- return sService.registerPollingLoopFilterForService(mContext.getUser().getIdentifier(),
- service, pollingLoopFilter, autoTransact);
- } catch (RemoteException e) {
- // Try one more time
- recoverService();
- if (sService == null) {
- Log.e(TAG, "Failed to recover CardEmulationService.");
- return false;
- }
- try {
- return sService.registerPollingLoopFilterForService(
- mContext.getUser().getIdentifier(), service,
- pollingLoopFilter, autoTransact);
- } catch (RemoteException ee) {
- Log.e(TAG, "Failed to reach CardEmulationService.");
- return false;
- }
- }
+ final String pollingLoopFilterV = validatePollingLoopFilter(pollingLoopFilter);
+ return callServiceReturn(() ->
+ sService.registerPollingLoopFilterForService(
+ mContext.getUser().getIdentifier(), service, pollingLoopFilterV, autoTransact),
+ false);
}
/**
@@ -431,27 +367,10 @@ public final class CardEmulation {
@FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP)
public boolean removePollingLoopFilterForService(@NonNull ComponentName service,
@NonNull String pollingLoopFilter) {
- pollingLoopFilter = validatePollingLoopFilter(pollingLoopFilter);
-
- try {
- return sService.removePollingLoopFilterForService(mContext.getUser().getIdentifier(),
- service, pollingLoopFilter);
- } catch (RemoteException e) {
- // Try one more time
- recoverService();
- if (sService == null) {
- Log.e(TAG, "Failed to recover CardEmulationService.");
- return false;
- }
- try {
- return sService.removePollingLoopFilterForService(
- mContext.getUser().getIdentifier(), service,
- pollingLoopFilter);
- } catch (RemoteException ee) {
- Log.e(TAG, "Failed to reach CardEmulationService.");
- return false;
- }
- }
+ final String pollingLoopFilterV = validatePollingLoopFilter(pollingLoopFilter);
+ return callServiceReturn(() ->
+ sService.removePollingLoopFilterForService(
+ mContext.getUser().getIdentifier(), service, pollingLoopFilterV), false);
}
@@ -477,28 +396,13 @@ public final class CardEmulation {
@FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP)
public boolean registerPollingLoopPatternFilterForService(@NonNull ComponentName service,
@NonNull String pollingLoopPatternFilter, boolean autoTransact) {
- pollingLoopPatternFilter = validatePollingLoopPatternFilter(pollingLoopPatternFilter);
-
- try {
- return sService.registerPollingLoopPatternFilterForService(
- mContext.getUser().getIdentifier(),
- service, pollingLoopPatternFilter, autoTransact);
- } catch (RemoteException e) {
- // Try one more time
- recoverService();
- if (sService == null) {
- Log.e(TAG, "Failed to recover CardEmulationService.");
- return false;
- }
- try {
- return sService.registerPollingLoopPatternFilterForService(
- mContext.getUser().getIdentifier(), service,
- pollingLoopPatternFilter, autoTransact);
- } catch (RemoteException ee) {
- Log.e(TAG, "Failed to reach CardEmulationService.");
- return false;
- }
- }
+ final String pollingLoopPatternFilterV =
+ validatePollingLoopPatternFilter(pollingLoopPatternFilter);
+ return callServiceReturn(() ->
+ sService.registerPollingLoopPatternFilterForService(
+ mContext.getUser().getIdentifier(), service, pollingLoopPatternFilterV,
+ autoTransact),
+ false);
}
/**
@@ -518,27 +422,11 @@ public final class CardEmulation {
@FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP)
public boolean removePollingLoopPatternFilterForService(@NonNull ComponentName service,
@NonNull String pollingLoopPatternFilter) {
- pollingLoopPatternFilter = validatePollingLoopPatternFilter(pollingLoopPatternFilter);
-
- try {
- return sService.removePollingLoopPatternFilterForService(
- mContext.getUser().getIdentifier(), service, pollingLoopPatternFilter);
- } catch (RemoteException e) {
- // Try one more time
- recoverService();
- if (sService == null) {
- Log.e(TAG, "Failed to recover CardEmulationService.");
- return false;
- }
- try {
- return sService.removePollingLoopPatternFilterForService(
- mContext.getUser().getIdentifier(), service,
- pollingLoopPatternFilter);
- } catch (RemoteException ee) {
- Log.e(TAG, "Failed to reach CardEmulationService.");
- return false;
- }
- }
+ final String pollingLoopPatternFilterV =
+ validatePollingLoopPatternFilter(pollingLoopPatternFilter);
+ return callServiceReturn(() ->
+ sService.removePollingLoopPatternFilterForService(
+ mContext.getUser().getIdentifier(), service, pollingLoopPatternFilterV), false);
}
/**
@@ -563,25 +451,10 @@ public final class CardEmulation {
*/
public boolean registerAidsForService(ComponentName service, String category,
List<String> aids) {
- AidGroup aidGroup = new AidGroup(aids, category);
- try {
- return sService.registerAidGroupForService(mContext.getUser().getIdentifier(),
- service, aidGroup);
- } catch (RemoteException e) {
- // Try one more time
- recoverService();
- if (sService == null) {
- Log.e(TAG, "Failed to recover CardEmulationService.");
- return false;
- }
- try {
- return sService.registerAidGroupForService(mContext.getUser().getIdentifier(),
- service, aidGroup);
- } catch (RemoteException ee) {
- Log.e(TAG, "Failed to reach CardEmulationService.");
- return false;
- }
- }
+ final AidGroup aidGroup = new AidGroup(aids, category);
+ return callServiceReturn(() ->
+ sService.registerAidGroupForService(
+ mContext.getUser().getIdentifier(), service, aidGroup), false);
}
/**
@@ -603,27 +476,9 @@ public final class CardEmulation {
@RequiresPermission(android.Manifest.permission.NFC)
@NonNull
public boolean unsetOffHostForService(@NonNull ComponentName service) {
- NfcAdapter adapter = NfcAdapter.getDefaultAdapter(mContext);
- if (adapter == null) {
- return false;
- }
-
- try {
- return sService.unsetOffHostForService(mContext.getUser().getIdentifier(), service);
- } catch (RemoteException e) {
- // Try one more time
- recoverService();
- if (sService == null) {
- Log.e(TAG, "Failed to recover CardEmulationService.");
- return false;
- }
- try {
- return sService.unsetOffHostForService(mContext.getUser().getIdentifier(), service);
- } catch (RemoteException ee) {
- Log.e(TAG, "Failed to reach CardEmulationService.");
- return false;
- }
- }
+ return callServiceReturn(() ->
+ sService.unsetOffHostForService(
+ mContext.getUser().getIdentifier(), service), false);
}
/**
@@ -662,8 +517,6 @@ public final class CardEmulation {
@NonNull
public boolean setOffHostForService(@NonNull ComponentName service,
@NonNull String offHostSecureElement) {
- boolean validSecureElement = false;
-
NfcAdapter adapter = NfcAdapter.getDefaultAdapter(mContext);
if (adapter == null || offHostSecureElement == null) {
return false;
@@ -684,25 +537,10 @@ public final class CardEmulation {
} else if (offHostSecureElement.equals("SIM")) {
offHostSecureElement = "SIM1";
}
-
- try {
- return sService.setOffHostForService(mContext.getUser().getIdentifier(), service,
- offHostSecureElement);
- } catch (RemoteException e) {
- // Try one more time
- recoverService();
- if (sService == null) {
- Log.e(TAG, "Failed to recover CardEmulationService.");
- return false;
- }
- try {
- return sService.setOffHostForService(mContext.getUser().getIdentifier(), service,
- offHostSecureElement);
- } catch (RemoteException ee) {
- Log.e(TAG, "Failed to reach CardEmulationService.");
- return false;
- }
- }
+ final String offHostSecureElementV = new String(offHostSecureElement);
+ return callServiceReturn(() ->
+ sService.setOffHostForService(
+ mContext.getUser().getIdentifier(), service, offHostSecureElementV), false);
}
/**
@@ -720,25 +558,10 @@ public final class CardEmulation {
* @return The list of AIDs registered for this category, or null if it couldn't be found.
*/
public List<String> getAidsForService(ComponentName service, String category) {
- try {
- AidGroup group = sService.getAidGroupForService(mContext.getUser().getIdentifier(),
- service, category);
- return (group != null ? group.getAids() : null);
- } catch (RemoteException e) {
- recoverService();
- if (sService == null) {
- Log.e(TAG, "Failed to recover CardEmulationService.");
- return null;
- }
- try {
- AidGroup group = sService.getAidGroupForService(mContext.getUser().getIdentifier(),
- service, category);
- return (group != null ? group.getAids() : null);
- } catch (RemoteException ee) {
- Log.e(TAG, "Failed to recover CardEmulationService.");
- return null;
- }
- }
+ AidGroup group = callServiceReturn(() ->
+ sService.getAidGroupForService(
+ mContext.getUser().getIdentifier(), service, category), null);
+ return (group != null ? group.getAids() : null);
}
/**
@@ -757,24 +580,9 @@ public final class CardEmulation {
* @return whether the group was successfully removed.
*/
public boolean removeAidsForService(ComponentName service, String category) {
- try {
- return sService.removeAidGroupForService(mContext.getUser().getIdentifier(), service,
- category);
- } catch (RemoteException e) {
- // Try one more time
- recoverService();
- if (sService == null) {
- Log.e(TAG, "Failed to recover CardEmulationService.");
- return false;
- }
- try {
- return sService.removeAidGroupForService(mContext.getUser().getIdentifier(),
- service, category);
- } catch (RemoteException ee) {
- Log.e(TAG, "Failed to reach CardEmulationService.");
- return false;
- }
- }
+ return callServiceReturn(() ->
+ sService.removeAidGroupForService(
+ mContext.getUser().getIdentifier(), service, category), false);
}
/**
@@ -811,22 +619,7 @@ public final class CardEmulation {
if (activity == null || service == null) {
throw new NullPointerException("activity or service or category is null");
}
- try {
- return sService.setPreferredService(service);
- } catch (RemoteException e) {
- // Try one more time
- recoverService();
- if (sService == null) {
- Log.e(TAG, "Failed to recover CardEmulationService.");
- return false;
- }
- try {
- return sService.setPreferredService(service);
- } catch (RemoteException ee) {
- Log.e(TAG, "Failed to reach CardEmulationService.");
- return false;
- }
- }
+ return callServiceReturn(() -> sService.setPreferredService(service), false);
}
/**
@@ -843,22 +636,7 @@ public final class CardEmulation {
if (activity == null) {
throw new NullPointerException("activity is null");
}
- try {
- return sService.unsetPreferredService();
- } catch (RemoteException e) {
- // Try one more time
- recoverService();
- if (sService == null) {
- Log.e(TAG, "Failed to recover CardEmulationService.");
- return false;
- }
- try {
- return sService.unsetPreferredService();
- } catch (RemoteException ee) {
- Log.e(TAG, "Failed to reach CardEmulationService.");
- return false;
- }
- }
+ return callServiceReturn(() -> sService.unsetPreferredService(), false);
}
/**
@@ -872,21 +650,7 @@ public final class CardEmulation {
* @return whether AID prefix registering is supported on this device.
*/
public boolean supportsAidPrefixRegistration() {
- try {
- return sService.supportsAidPrefixRegistration();
- } catch (RemoteException e) {
- recoverService();
- if (sService == null) {
- Log.e(TAG, "Failed to recover CardEmulationService.");
- return false;
- }
- try {
- return sService.supportsAidPrefixRegistration();
- } catch (RemoteException ee) {
- Log.e(TAG, "Failed to reach CardEmulationService.");
- return false;
- }
- }
+ return callServiceReturn(() -> sService.supportsAidPrefixRegistration(), false);
}
/**
@@ -897,25 +661,9 @@ public final class CardEmulation {
@RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO)
@Nullable
public List<String> getAidsForPreferredPaymentService() {
- try {
- ApduServiceInfo serviceInfo = sService.getPreferredPaymentService(
- mContext.getUser().getIdentifier());
- return (serviceInfo != null ? serviceInfo.getAids() : null);
- } catch (RemoteException e) {
- recoverService();
- if (sService == null) {
- Log.e(TAG, "Failed to recover CardEmulationService.");
- throw e.rethrowFromSystemServer();
- }
- try {
- ApduServiceInfo serviceInfo =
- sService.getPreferredPaymentService(mContext.getUser().getIdentifier());
- return (serviceInfo != null ? serviceInfo.getAids() : null);
- } catch (RemoteException ee) {
- Log.e(TAG, "Failed to recover CardEmulationService.");
- throw e.rethrowFromSystemServer();
- }
- }
+ ApduServiceInfo serviceInfo = callServiceReturn(() ->
+ sService.getPreferredPaymentService(mContext.getUser().getIdentifier()), null);
+ return (serviceInfo != null ? serviceInfo.getAids() : null);
}
/**
@@ -944,40 +692,16 @@ public final class CardEmulation {
@RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO)
@Nullable
public String getRouteDestinationForPreferredPaymentService() {
- try {
- ApduServiceInfo serviceInfo = sService.getPreferredPaymentService(
- mContext.getUser().getIdentifier());
- if (serviceInfo != null) {
- if (!serviceInfo.isOnHost()) {
- return serviceInfo.getOffHostSecureElement() == null ?
- "OffHost" : serviceInfo.getOffHostSecureElement();
- }
- return "Host";
- }
- return null;
- } catch (RemoteException e) {
- recoverService();
- if (sService == null) {
- Log.e(TAG, "Failed to recover CardEmulationService.");
- throw e.rethrowFromSystemServer();
- }
- try {
- ApduServiceInfo serviceInfo =
- sService.getPreferredPaymentService(mContext.getUser().getIdentifier());
- if (serviceInfo != null) {
- if (!serviceInfo.isOnHost()) {
- return serviceInfo.getOffHostSecureElement() == null ?
- "Offhost" : serviceInfo.getOffHostSecureElement();
- }
- return "Host";
- }
- return null;
-
- } catch (RemoteException ee) {
- Log.e(TAG, "Failed to recover CardEmulationService.");
- throw e.rethrowFromSystemServer();
+ ApduServiceInfo serviceInfo = callServiceReturn(() ->
+ sService.getPreferredPaymentService(mContext.getUser().getIdentifier()), null);
+ if (serviceInfo != null) {
+ if (!serviceInfo.isOnHost()) {
+ return serviceInfo.getOffHostSecureElement() == null ?
+ "OffHost" : serviceInfo.getOffHostSecureElement();
}
+ return "Host";
}
+ return null;
}
/**
@@ -995,115 +719,44 @@ public final class CardEmulation {
@RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO)
@Nullable
public CharSequence getDescriptionForPreferredPaymentService() {
- try {
- ApduServiceInfo serviceInfo = sService.getPreferredPaymentService(
- mContext.getUser().getIdentifier());
- return (serviceInfo != null ? serviceInfo.getDescription() : null);
- } catch (RemoteException e) {
- recoverService();
- if (sService == null) {
- Log.e(TAG, "Failed to recover CardEmulationService.");
- throw e.rethrowFromSystemServer();
- }
- try {
- ApduServiceInfo serviceInfo =
- sService.getPreferredPaymentService(mContext.getUser().getIdentifier());
- return (serviceInfo != null ? serviceInfo.getDescription() : null);
- } catch (RemoteException ee) {
- Log.e(TAG, "Failed to recover CardEmulationService.");
- throw e.rethrowFromSystemServer();
- }
- }
+ ApduServiceInfo serviceInfo = callServiceReturn(() ->
+ sService.getPreferredPaymentService(mContext.getUser().getIdentifier()), null);
+ return (serviceInfo != null ? serviceInfo.getDescription() : null);
}
/**
* @hide
*/
public boolean setDefaultServiceForCategory(ComponentName service, String category) {
- try {
- return sService.setDefaultServiceForCategory(mContext.getUser().getIdentifier(),
- service, category);
- } catch (RemoteException e) {
- // Try one more time
- recoverService();
- if (sService == null) {
- Log.e(TAG, "Failed to recover CardEmulationService.");
- return false;
- }
- try {
- return sService.setDefaultServiceForCategory(mContext.getUser().getIdentifier(),
- service, category);
- } catch (RemoteException ee) {
- Log.e(TAG, "Failed to reach CardEmulationService.");
- return false;
- }
- }
+ return callServiceReturn(() ->
+ sService.setDefaultServiceForCategory(
+ mContext.getUser().getIdentifier(), service, category), false);
}
/**
* @hide
*/
public boolean setDefaultForNextTap(ComponentName service) {
- try {
- return sService.setDefaultForNextTap(mContext.getUser().getIdentifier(), service);
- } catch (RemoteException e) {
- // Try one more time
- recoverService();
- if (sService == null) {
- Log.e(TAG, "Failed to recover CardEmulationService.");
- return false;
- }
- try {
- return sService.setDefaultForNextTap(mContext.getUser().getIdentifier(), service);
- } catch (RemoteException ee) {
- Log.e(TAG, "Failed to reach CardEmulationService.");
- return false;
- }
- }
+ return callServiceReturn(() ->
+ sService.setDefaultForNextTap(
+ mContext.getUser().getIdentifier(), service), false);
}
/**
* @hide
*/
public boolean setDefaultForNextTap(int userId, ComponentName service) {
- try {
- return sService.setDefaultForNextTap(userId, service);
- } catch (RemoteException e) {
- // Try one more time
- recoverService();
- if (sService == null) {
- Log.e(TAG, "Failed to recover CardEmulationService.");
- return false;
- }
- try {
- return sService.setDefaultForNextTap(userId, service);
- } catch (RemoteException ee) {
- Log.e(TAG, "Failed to reach CardEmulationService.");
- return false;
- }
- }
+ return callServiceReturn(() ->
+ sService.setDefaultForNextTap(userId, service), false);
}
/**
* @hide
*/
public List<ApduServiceInfo> getServices(String category) {
- try {
- return sService.getServices(mContext.getUser().getIdentifier(), category);
- } catch (RemoteException e) {
- // Try one more time
- recoverService();
- if (sService == null) {
- Log.e(TAG, "Failed to recover CardEmulationService.");
- return null;
- }
- try {
- return sService.getServices(mContext.getUser().getIdentifier(), category);
- } catch (RemoteException ee) {
- Log.e(TAG, "Failed to reach CardEmulationService.");
- return null;
- }
- }
+ return callServiceReturn(() ->
+ sService.getServices(
+ mContext.getUser().getIdentifier(), category), null);
}
/**
@@ -1117,22 +770,8 @@ public final class CardEmulation {
@FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
@NonNull
public List<ApduServiceInfo> getServices(@NonNull String category, @UserIdInt int userId) {
- try {
- return sService.getServices(userId, category);
- } catch (RemoteException e) {
- // Try one more time
- recoverService();
- if (sService == null) {
- Log.e(TAG, "Failed to recover CardEmulationService.");
- return null;
- }
- try {
- return sService.getServices(userId, category);
- } catch (RemoteException ee) {
- Log.e(TAG, "Failed to reach CardEmulationService.");
- return null;
- }
- }
+ return callServiceReturn(() ->
+ sService.getServices(userId, category), null);
}
/**
@@ -1222,22 +861,8 @@ public final class CardEmulation {
if (service == null) {
throw new NullPointerException("activity or service or category is null");
}
- try {
- return sService.setServiceEnabledForCategoryOther(userId, service, status);
- } catch (RemoteException e) {
- // Try one more time
- recoverService();
- if (sService == null) {
- Log.e(TAG, "Failed to recover CardEmulationService.");
- return false;
- }
- try {
- return sService.setServiceEnabledForCategoryOther(userId, service, status);
- } catch (RemoteException ee) {
- Log.e(TAG, "Failed to reach CardEmulationService.");
- return false;
- }
- }
+ return callServiceReturn(() ->
+ sService.setServiceEnabledForCategoryOther(userId, service, status), false);
}
/**
@@ -1269,22 +894,9 @@ public final class CardEmulation {
if (!activity.isResumed()) {
throw new IllegalArgumentException("Activity must be resumed.");
}
- try {
- return sService.overrideRoutingTable(UserHandle.myUserId(), protocol, technology);
- } catch (RemoteException e) {
- // Try one more time
- recoverService();
- if (sService == null) {
- Log.e(TAG, "Failed to recover CardEmulationService.");
- return false;
- }
- try {
- return sService.overrideRoutingTable(UserHandle.myUserId(), protocol, technology);
- } catch (RemoteException ee) {
- Log.e(TAG, "Failed to reach CardEmulationService.");
- return false;
- }
- }
+ return callServiceReturn(() ->
+ sService.overrideRoutingTable(
+ mContext.getUser().getIdentifier(), protocol, technology), false);
}
/**
@@ -1303,27 +915,9 @@ public final class CardEmulation {
if (!activity.isResumed()) {
throw new IllegalArgumentException("Activity must be resumed.");
}
- try {
- return sService.recoverRoutingTable(UserHandle.myUserId());
- } catch (RemoteException e) {
- // Try one more time
- recoverService();
- if (sService == null) {
- Log.e(TAG, "Failed to recover CardEmulationService.");
- return false;
- }
- try {
- return sService.recoverRoutingTable(UserHandle.myUserId());
- } catch (RemoteException ee) {
- Log.e(TAG, "Failed to reach CardEmulationService.");
- return false;
- }
- }
- }
-
- void recoverService() {
- NfcAdapter adapter = NfcAdapter.getDefaultAdapter(mContext);
- sService = adapter.getCardEmulationService();
+ return callServiceReturn(() ->
+ sService.recoverRoutingTable(
+ mContext.getUser().getIdentifier()), false);
}
/**
@@ -1351,4 +945,53 @@ public final class CardEmulation {
return ComponentName.unflattenFromString(defaultPaymentComponent);
}
+
+ /** @hide */
+ interface ServiceCall {
+ void call() throws RemoteException;
+ }
+ /** @hide */
+ public static void callService(ServiceCall call) {
+ try {
+ if (sService == null) {
+ NfcAdapter.attemptDeadServiceRecovery(
+ new RemoteException("NFC CardEmulation Service is null"));
+ sService = NfcAdapter.getCardEmulationService();
+ }
+ call.call();
+ } catch (RemoteException e) {
+ NfcAdapter.attemptDeadServiceRecovery(e);
+ sService = NfcAdapter.getCardEmulationService();
+ try {
+ call.call();
+ } catch (RemoteException ee) {
+ ee.rethrowAsRuntimeException();
+ }
+ }
+ }
+ /** @hide */
+ interface ServiceCallReturn<T> {
+ T call() throws RemoteException;
+ }
+ /** @hide */
+ public static <T> T callServiceReturn(ServiceCallReturn<T> call, T defaultReturn) {
+ try {
+ if (sService == null) {
+ NfcAdapter.attemptDeadServiceRecovery(
+ new RemoteException("NFC CardEmulation Service is null"));
+ sService = NfcAdapter.getCardEmulationService();
+ }
+ return call.call();
+ } catch (RemoteException e) {
+ NfcAdapter.attemptDeadServiceRecovery(e);
+ sService = NfcAdapter.getCardEmulationService();
+ // Try one more time
+ try {
+ return call.call();
+ } catch (RemoteException ee) {
+ ee.rethrowAsRuntimeException();
+ }
+ }
+ return defaultReturn;
+ }
}
diff --git a/nfc/java/android/nfc/cardemulation/HostApduService.java b/nfc/java/android/nfc/cardemulation/HostApduService.java
index c3c74a6fd265..cd8e19c54565 100644
--- a/nfc/java/android/nfc/cardemulation/HostApduService.java
+++ b/nfc/java/android/nfc/cardemulation/HostApduService.java
@@ -242,6 +242,16 @@ public abstract class HostApduService extends Service {
/**
* @hide
*/
+ public static final int MSG_OBSERVE_MODE_CHANGE = 5;
+
+ /**
+ * @hide
+ */
+ public static final int MSG_PREFERRED_SERVICE_CHANGED = 6;
+
+ /**
+ * @hide
+ */
public static final String KEY_DATA = "data";
/**
@@ -333,7 +343,17 @@ public abstract class HostApduService extends Service {
processPollingFrames(pollingFrames);
}
break;
- default:
+ case MSG_OBSERVE_MODE_CHANGE:
+ if (android.nfc.Flags.nfcEventListener()) {
+ onObserveModeStateChanged(msg.arg1 == 1);
+ }
+ break;
+ case MSG_PREFERRED_SERVICE_CHANGED:
+ if (android.nfc.Flags.nfcEventListener()) {
+ onPreferredServiceChanged(msg.arg1 == 1);
+ }
+ break;
+ default:
super.handleMessage(msg);
}
}
@@ -441,4 +461,26 @@ public abstract class HostApduService extends Service {
* @param reason Either {@link #DEACTIVATION_LINK_LOSS} or {@link #DEACTIVATION_DESELECTED}
*/
public abstract void onDeactivated(int reason);
+
+
+ /**
+ * This method is called when this service is the preferred Nfc service and
+ * Observe mode has been enabled or disabled.
+ *
+ * @param isEnabled true if observe mode has been enabled, false if it has been disabled
+ */
+ @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER)
+ public void onObserveModeStateChanged(boolean isEnabled) {
+
+ }
+
+ /**
+ * This method is called when this service gains or loses preferred Nfc service status.
+ *
+ * @param isPreferred true is this service has become the preferred Nfc service,
+ * false if it is no longer the preferred service
+ */
+ @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER)
+ public void onPreferredServiceChanged(boolean isPreferred) {
+ }
}
diff --git a/nfc/java/android/nfc/flags.aconfig b/nfc/java/android/nfc/flags.aconfig
index 45036a5f214b..29699fcc03fa 100644
--- a/nfc/java/android/nfc/flags.aconfig
+++ b/nfc/java/android/nfc/flags.aconfig
@@ -2,6 +2,14 @@ package: "android.nfc"
container: "system"
flag {
+ name: "nfc_event_listener"
+ is_exported: true
+ namespace: "nfc"
+ description: "Enable NFC Event listener APIs"
+ bug: "356447790"
+}
+
+flag {
name: "enable_nfc_mainline"
is_exported: true
namespace: "nfc"
diff --git a/packages/SoundPicker/src/com/android/soundpicker/RingtonePickerActivity.java b/packages/SoundPicker/src/com/android/soundpicker/RingtonePickerActivity.java
index 0dd9275503a9..8c3cce4087c1 100644
--- a/packages/SoundPicker/src/com/android/soundpicker/RingtonePickerActivity.java
+++ b/packages/SoundPicker/src/com/android/soundpicker/RingtonePickerActivity.java
@@ -255,8 +255,8 @@ public final class RingtonePickerActivity extends AlertActivity implements
p.mTitle = getString(com.android.internal.R.string.ringtone_picker_title);
}
} else {
- // Make sure intents don't inject HTML elements.
- p.mTitle = Html.escapeHtml(p.mTitle.toString());
+ // Make sure intents don't inject spannable elements.
+ p.mTitle = p.mTitle.toString();
}
setupAlert();
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/model/A11yMenuShortcut.java b/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/model/A11yMenuShortcut.java
index 66a2fae0c4c3..c698d18bfde8 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/model/A11yMenuShortcut.java
+++ b/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/model/A11yMenuShortcut.java
@@ -19,7 +19,6 @@ import android.util.Log;
import com.android.systemui.accessibility.accessibilitymenu.R;
-import java.util.HashMap;
import java.util.Map;
/**
@@ -52,80 +51,80 @@ public class A11yMenuShortcut {
private static final int LABEL_TEXT_INDEX = 3;
/** Map stores all shortcut resource IDs that is in matching order of defined shortcut. */
- private static final Map<ShortcutId, int[]> sShortcutResource = new HashMap<>() {{
- put(ShortcutId.ID_ASSISTANT_VALUE, new int[] {
+ private static final Map<ShortcutId, int[]> sShortcutResource = Map.ofEntries(
+ Map.entry(ShortcutId.ID_ASSISTANT_VALUE, new int[] {
R.drawable.ic_logo_a11y_assistant_24dp,
R.color.assistant_color,
R.string.assistant_utterance,
R.string.assistant_label,
- });
- put(ShortcutId.ID_A11YSETTING_VALUE, new int[] {
+ }),
+ Map.entry(ShortcutId.ID_A11YSETTING_VALUE, new int[] {
R.drawable.ic_logo_a11y_settings_24dp,
R.color.a11y_settings_color,
R.string.a11y_settings_label,
R.string.a11y_settings_label,
- });
- put(ShortcutId.ID_POWER_VALUE, new int[] {
+ }),
+ Map.entry(ShortcutId.ID_POWER_VALUE, new int[] {
R.drawable.ic_logo_a11y_power_24dp,
R.color.power_color,
R.string.power_utterance,
R.string.power_label,
- });
- put(ShortcutId.ID_RECENT_VALUE, new int[] {
+ }),
+ Map.entry(ShortcutId.ID_RECENT_VALUE, new int[] {
R.drawable.ic_logo_a11y_recent_apps_24dp,
R.color.recent_apps_color,
R.string.recent_apps_label,
R.string.recent_apps_label,
- });
- put(ShortcutId.ID_LOCKSCREEN_VALUE, new int[] {
+ }),
+ Map.entry(ShortcutId.ID_LOCKSCREEN_VALUE, new int[] {
R.drawable.ic_logo_a11y_lock_24dp,
R.color.lockscreen_color,
R.string.lockscreen_label,
R.string.lockscreen_label,
- });
- put(ShortcutId.ID_QUICKSETTING_VALUE, new int[] {
+ }),
+ Map.entry(ShortcutId.ID_QUICKSETTING_VALUE, new int[] {
R.drawable.ic_logo_a11y_quick_settings_24dp,
R.color.quick_settings_color,
R.string.quick_settings_label,
R.string.quick_settings_label,
- });
- put(ShortcutId.ID_NOTIFICATION_VALUE, new int[] {
+ }),
+ Map.entry(ShortcutId.ID_NOTIFICATION_VALUE, new int[] {
R.drawable.ic_logo_a11y_notifications_24dp,
R.color.notifications_color,
R.string.notifications_label,
R.string.notifications_label,
- });
- put(ShortcutId.ID_SCREENSHOT_VALUE, new int[] {
+ }),
+ Map.entry(ShortcutId.ID_SCREENSHOT_VALUE, new int[] {
R.drawable.ic_logo_a11y_screenshot_24dp,
R.color.screenshot_color,
R.string.screenshot_utterance,
R.string.screenshot_label,
- });
- put(ShortcutId.ID_BRIGHTNESS_UP_VALUE, new int[] {
+ }),
+ Map.entry(ShortcutId.ID_BRIGHTNESS_UP_VALUE, new int[] {
R.drawable.ic_logo_a11y_brightness_up_24dp,
R.color.brightness_color,
R.string.brightness_up_label,
R.string.brightness_up_label,
- });
- put(ShortcutId.ID_BRIGHTNESS_DOWN_VALUE, new int[] {
+ }),
+ Map.entry(ShortcutId.ID_BRIGHTNESS_DOWN_VALUE, new int[] {
R.drawable.ic_logo_a11y_brightness_down_24dp,
R.color.brightness_color,
R.string.brightness_down_label,
R.string.brightness_down_label,
- });
- put(ShortcutId.ID_VOLUME_UP_VALUE, new int[] {
+ }),
+ Map.entry(ShortcutId.ID_VOLUME_UP_VALUE, new int[] {
R.drawable.ic_logo_a11y_volume_up_24dp,
R.color.volume_color,
R.string.volume_up_label,
R.string.volume_up_label,
- });
- put(ShortcutId.ID_VOLUME_DOWN_VALUE, new int[] {
+ }),
+ Map.entry(ShortcutId.ID_VOLUME_DOWN_VALUE, new int[] {
R.drawable.ic_logo_a11y_volume_down_24dp,
R.color.volume_color,
R.string.volume_down_label,
R.string.volume_down_label,
- });
- }};
+ })
+ );
/** Shortcut id used to identify. */
private int mShortcutId = ShortcutId.UNSPECIFIED_ID_VALUE.ordinal();
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/FloatingRotationButton.java b/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/FloatingRotationButton.java
index 317201d2c2d9..f358ba2d3ccd 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/FloatingRotationButton.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/FloatingRotationButton.java
@@ -125,6 +125,7 @@ public class FloatingRotationButton implements RotationButton {
taskbarMarginLeft, taskbarMarginBottom, floatingRotationButtonPositionLeft);
final int diameter = res.getDimensionPixelSize(mButtonDiameterResource);
+ mKeyButtonView.setDiameter(diameter);
mContainerSize = diameter + Math.max(defaultMargin, Math.max(taskbarMarginLeft,
taskbarMarginBottom));
}
@@ -195,6 +196,7 @@ public class FloatingRotationButton implements RotationButton {
public void updateIcon(int lightIconColor, int darkIconColor) {
mAnimatedDrawable = (AnimatedVectorDrawable) mKeyButtonView.getContext()
.getDrawable(mRotationButtonController.getIconResId());
+ mAnimatedDrawable.setBounds(0, 0, mKeyButtonView.getWidth(), mKeyButtonView.getHeight());
mKeyButtonView.setImageDrawable(mAnimatedDrawable);
mKeyButtonView.setColors(lightIconColor, darkIconColor);
}
@@ -248,8 +250,14 @@ public class FloatingRotationButton implements RotationButton {
updateDimensionResources();
if (mIsShowing) {
+ updateIcon(mRotationButtonController.getLightIconColor(),
+ mRotationButtonController.getDarkIconColor());
final LayoutParams layoutParams = adjustViewPositionAndCreateLayoutParams();
mWindowManager.updateViewLayout(mKeyButtonContainer, layoutParams);
+ if (mAnimatedDrawable != null) {
+ mAnimatedDrawable.reset();
+ mAnimatedDrawable.start();
+ }
}
}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/FloatingRotationButtonView.java b/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/FloatingRotationButtonView.java
index 2145166e9bc5..75412f94ccb1 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/FloatingRotationButtonView.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/FloatingRotationButtonView.java
@@ -37,6 +37,7 @@ public class FloatingRotationButtonView extends ImageView {
private static final float BACKGROUND_ALPHA = 0.92f;
private KeyButtonRipple mRipple;
+ private int mDiameter;
private final Paint mOvalBgPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
private final Configuration mLastConfiguration;
@@ -93,10 +94,25 @@ public class FloatingRotationButtonView extends ImageView {
mRipple.setDarkIntensity(darkIntensity);
}
+ /**
+ * Sets the view's diameter.
+ *
+ * @param diameter the diameter value for the view
+ */
+ void setDiameter(int diameter) {
+ mDiameter = diameter;
+ }
+
@Override
public void draw(Canvas canvas) {
int d = Math.min(getWidth(), getHeight());
canvas.drawOval(0, 0, d, d, mOvalBgPaint);
super.draw(canvas);
}
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ setMeasuredDimension(mDiameter, mDiameter);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/OWNERS b/packages/SystemUI/src/com/android/systemui/keyguard/OWNERS
new file mode 100644
index 000000000000..443e98762c47
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/OWNERS
@@ -0,0 +1,11 @@
+set noparent
+
+# Bug component: 78010
+
+amiko@google.com
+beverlyt@google.com
+bhinegardner@google.com
+chandruis@google.com
+jglazier@google.com
+mpietal@google.com
+tsuji@google.com
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/OWNERS b/packages/SystemUI/src/com/android/systemui/statusbar/OWNERS
new file mode 100644
index 000000000000..c4f539a4acdf
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/OWNERS
@@ -0,0 +1,16 @@
+set noparent
+
+# Bug component: 78010
+
+caitlinshk@google.com
+evanlaird@google.com
+pixel@google.com
+
+per-file *Biometrics* = set noparent
+per-file *Biometrics* = file:../keyguard/OWNERS
+per-file *Doze* = set noparent
+per-file *Doze* = file:../keyguard/OWNERS
+per-file *Keyboard* = set noparent
+per-file *Keyboard* = file:../keyguard/OWNERS
+per-file *Keyguard* = set noparent
+per-file *Keyguard* = file:../keyguard/OWNERS \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/OWNERS b/packages/SystemUI/src/com/android/systemui/statusbar/phone/OWNERS
index 4657e9b84550..92a333e9ec2a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/OWNERS
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/OWNERS
@@ -1,6 +1,6 @@
per-file *Notification* = set noparent
per-file *Notification* = file:../notification/OWNERS
-per-file NotificationIcon* = ccassidy@google.com, evanlaird@google.com, pixel@google.com
+per-file NotificationIcon* = file:../OWNERS
per-file NotificationShadeWindowControllerImpl.java = dupin@google.com, cinek@google.com, beverlyt@google.com, pixel@google.com, juliacr@google.com
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/OWNERS b/packages/SystemUI/tests/src/com/android/systemui/statusbar/OWNERS
new file mode 100644
index 000000000000..1c52b8d25347
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/OWNERS
@@ -0,0 +1,3 @@
+set noparent
+
+include /packages/SystemUI/src/com/android/systemui/statusbar/OWNERS
diff --git a/services/Android.bp b/services/Android.bp
index a0d345430a4a..76fc1ba77c9b 100644
--- a/services/Android.bp
+++ b/services/Android.bp
@@ -108,6 +108,8 @@ filegroup {
filegroup {
name: "services-non-updatable-sources",
srcs: [
+ ":incremental_aidl",
+ ":services.core-aidl-sources",
":services.core-sources",
":services.core-sources-am-wm",
"core/java/com/android/server/am/package.html",
@@ -356,4 +358,8 @@ non_updatable_exportable_droidstubs {
},
},
api_surface: "system-server",
+ sdk_version: "module_current",
+ libs: [
+ "framework-annotations-lib",
+ ],
}
diff --git a/services/accessibility/TEST_MAPPING b/services/accessibility/TEST_MAPPING
index 299d33fbbe6d..38b4148f202b 100644
--- a/services/accessibility/TEST_MAPPING
+++ b/services/accessibility/TEST_MAPPING
@@ -36,21 +36,7 @@
]
},
{
- "name": "FrameworksCoreTests",
- "options": [
- {
- "include-filter": "android.accessibilityservice"
- },
- {
- "include-filter": "android.view.accessibility"
- },
- {
- "include-filter": "com.android.internal.accessibility"
- },
- {
- "exclude-annotation": "androidx.test.filters.FlakyTest"
- }
- ]
+ "name": "FrameworksCoreTests_accessibility_NO_FLAKES"
}
],
"postsubmit": [
diff --git a/services/appfunctions/OWNERS b/services/appfunctions/OWNERS
new file mode 100644
index 000000000000..b3108944a3ce
--- /dev/null
+++ b/services/appfunctions/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/app/appfunctions/OWNERS
diff --git a/services/core/Android.bp b/services/core/Android.bp
index fa323fd04837..9fbd8aa217dc 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -30,6 +30,18 @@ filegroup {
],
}
+filegroup {
+ name: "services.core-aidl-sources",
+ srcs: [
+ ":dumpstate_aidl",
+ ":framework_native_aidl",
+ ":gsiservice_aidl",
+ ":installd_aidl",
+ ":storaged_aidl",
+ ":vold_aidl",
+ ],
+}
+
java_library_static {
name: "services-config-update",
srcs: [
@@ -151,14 +163,9 @@ java_library_static {
":android.hardware.tv.hdmi.earc-V1-java-source",
":statslog-art-java-gen",
":statslog-contexthub-java-gen",
+ ":services.core-aidl-sources",
":services.core-sources",
":services.core.protologsrc",
- ":dumpstate_aidl",
- ":framework_native_aidl",
- ":gsiservice_aidl",
- ":installd_aidl",
- ":storaged_aidl",
- ":vold_aidl",
":platform-compat-config",
":platform-compat-overrides",
":display-device-config",
diff --git a/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java
index 797993647be7..ab333b9928a0 100644
--- a/services/core/java/com/android/server/BatteryService.java
+++ b/services/core/java/com/android/server/BatteryService.java
@@ -157,7 +157,7 @@ public final class BatteryService extends SystemService {
private int mLastMaxChargingVoltage;
private int mLastChargeCounter;
private int mLastBatteryCycleCount;
- private int mLastCharingState;
+ private int mLastChargingState;
/**
* The last seen charging policy. This requires the
* {@link android.Manifest.permission#BATTERY_STATS} permission and should therefore not be
@@ -555,7 +555,7 @@ public final class BatteryService extends SystemService {
|| mHealthInfo.batteryChargeCounterUah != mLastChargeCounter
|| mInvalidCharger != mLastInvalidCharger
|| mHealthInfo.batteryCycleCount != mLastBatteryCycleCount
- || mHealthInfo.chargingState != mLastCharingState)) {
+ || mHealthInfo.chargingState != mLastChargingState)) {
if (mPlugType != mLastPlugType) {
if (mLastPlugType == BATTERY_PLUGGED_NONE) {
@@ -738,7 +738,7 @@ public final class BatteryService extends SystemService {
mLastBatteryLevelCritical = mBatteryLevelCritical;
mLastInvalidCharger = mInvalidCharger;
mLastBatteryCycleCount = mHealthInfo.batteryCycleCount;
- mLastCharingState = mHealthInfo.chargingState;
+ mLastChargingState = mHealthInfo.chargingState;
}
}
diff --git a/services/core/java/com/android/server/SystemConfig.java b/services/core/java/com/android/server/SystemConfig.java
index 6f45f2a51103..95fb187741f9 100644
--- a/services/core/java/com/android/server/SystemConfig.java
+++ b/services/core/java/com/android/server/SystemConfig.java
@@ -371,6 +371,10 @@ public class SystemConfig {
// exempt from ECM (i.e., they will never be considered "restricted").
private final ArraySet<SignedPackage> mEnhancedConfirmationTrustedInstallers = new ArraySet<>();
+ // A map of UIDs defined by OEMs, mapping from name to value. The UIDs will be registered at the
+ // start of the system which allows OEMs to create and register their system services.
+ @NonNull private final ArrayMap<String, Integer> mOemDefinedUids = new ArrayMap<>();
+
/**
* Map of system pre-defined, uniquely named actors; keys are namespace,
* value maps actor name to package name.
@@ -594,6 +598,10 @@ public class SystemConfig {
return mEnhancedConfirmationTrustedInstallers;
}
+ @NonNull
+ public ArrayMap<String, Integer> getOemDefinedUids() {
+ return mOemDefinedUids;
+ }
/**
* Only use for testing. Do NOT use in production code.
* @param readPermissions false to create an empty SystemConfig; true to read the permissions.
@@ -1622,6 +1630,26 @@ public class SystemConfig {
}
}
} break;
+ case "oem-defined-uid": {
+ final String uidName = parser.getAttributeValue(null, "name");
+ final String uidValue = parser.getAttributeValue(null, "uid");
+ if (TextUtils.isEmpty(uidName)) {
+ Slog.w(TAG, "<" + name + "> without valid uid name in " + permFile
+ + " at " + parser.getPositionDescription());
+ } else if (TextUtils.isEmpty(uidValue)) {
+ Slog.w(TAG, "<" + name + "> without valid uid value in " + permFile
+ + " at " + parser.getPositionDescription());
+ } else {
+ try {
+ final int oemDefinedUid = Integer.parseInt(uidValue);
+ mOemDefinedUids.put(uidName, oemDefinedUid);
+ } catch (NumberFormatException e) {
+ Slog.w(TAG, "<" + name + "> with invalid uid value: "
+ + uidValue + " in " + permFile
+ + " at " + parser.getPositionDescription());
+ }
+ }
+ } break;
case "enhanced-confirmation-trusted-package": {
if (android.permission.flags.Flags.enhancedConfirmationModeApisEnabled()) {
SignedPackage signedPackage = parseEnhancedConfirmationTrustedPackage(
diff --git a/services/core/java/com/android/server/am/AppRestrictionController.java b/services/core/java/com/android/server/am/AppRestrictionController.java
index 88f6bc91d1ff..5827c7fef6ee 100644
--- a/services/core/java/com/android/server/am/AppRestrictionController.java
+++ b/services/core/java/com/android/server/am/AppRestrictionController.java
@@ -297,7 +297,7 @@ public final class AppRestrictionController {
/**
* Cache the package name and information about if it's a system module.
*/
- @GuardedBy("mLock")
+ @GuardedBy("mSystemModulesCache")
private final HashMap<String, Boolean> mSystemModulesCache = new HashMap<>();
/**
@@ -1588,7 +1588,7 @@ public final class AppRestrictionController {
if (moduleInfos == null) {
return;
}
- synchronized (mLock) {
+ synchronized (mSystemModulesCache) {
for (ModuleInfo info : moduleInfos) {
mSystemModulesCache.put(info.getPackageName(), Boolean.TRUE);
}
@@ -1596,7 +1596,7 @@ public final class AppRestrictionController {
}
private boolean isSystemModule(String packageName) {
- synchronized (mLock) {
+ synchronized (mSystemModulesCache) {
final Boolean val = mSystemModulesCache.get(packageName);
if (val != null) {
return val.booleanValue();
@@ -1624,7 +1624,7 @@ public final class AppRestrictionController {
}
}
// Update the cache.
- synchronized (mLock) {
+ synchronized (mSystemModulesCache) {
mSystemModulesCache.put(packageName, isSystemModule);
}
return isSystemModule;
diff --git a/services/core/java/com/android/server/am/OWNERS b/services/core/java/com/android/server/am/OWNERS
index 11db302ebbd5..4b95a62df057 100644
--- a/services/core/java/com/android/server/am/OWNERS
+++ b/services/core/java/com/android/server/am/OWNERS
@@ -38,6 +38,7 @@ per-file CarUserSwitchingDialog.java = file:platform/packages/services/Car:/OWNE
per-file ContentProviderHelper.java = varunshah@google.com, omakoto@google.com, jsharkey@google.com, yamasani@google.com
per-file CachedAppOptimizer.java = file:/PERFORMANCE_OWNERS
+per-file Freezer.java = file:/PERFORMANCE_OWNERS
# Multiuser
per-file User* = file:/MULTIUSER_OWNERS
diff --git a/services/core/java/com/android/server/am/TEST_MAPPING b/services/core/java/com/android/server/am/TEST_MAPPING
index feab2c05cad6..75dc7de61212 100644
--- a/services/core/java/com/android/server/am/TEST_MAPPING
+++ b/services/core/java/com/android/server/am/TEST_MAPPING
@@ -78,11 +78,7 @@
},
{
"file_patterns": ["Battery[^/]*\\.java", "MeasuredEnergy[^/]*\\.java"],
- "name": "FrameworksCoreTests",
- "options": [
- { "include-filter": "com.android.internal.os.BatteryStatsTests" },
- { "exclude-annotation": "com.android.internal.os.SkipPresubmit" }
- ]
+ "name": "FrameworksCoreTests_battery_stats"
},
{
"file_patterns": ["Battery[^/]*\\.java", "MeasuredEnergy[^/]*\\.java"],
diff --git a/services/core/java/com/android/server/hdmi/DelayedMessageBuffer.java b/services/core/java/com/android/server/hdmi/DelayedMessageBuffer.java
index 46b4f48165f9..44907457f649 100644
--- a/services/core/java/com/android/server/hdmi/DelayedMessageBuffer.java
+++ b/services/core/java/com/android/server/hdmi/DelayedMessageBuffer.java
@@ -17,8 +17,10 @@
package com.android.server.hdmi;
import android.hardware.hdmi.HdmiDeviceInfo;
+
import java.util.ArrayList;
import java.util.Iterator;
+import java.util.List;
/**
* Buffer storage to keep incoming messages for later processing. Used to
@@ -83,6 +85,16 @@ final class DelayedMessageBuffer {
return false;
}
+ List<HdmiCecMessage> getBufferedMessagesWithOpcode(int opcode) {
+ List<HdmiCecMessage> messages = new ArrayList<>();
+ for (HdmiCecMessage message : mBuffer) {
+ if (message.getOpcode() == opcode) {
+ messages.add(message);
+ }
+ }
+ return messages;
+ }
+
void processAllMessages() {
// Use the copied buffer.
ArrayList<HdmiCecMessage> copiedBuffer = new ArrayList<>(mBuffer);
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
index 54490899ab5f..6bc55886936e 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
@@ -205,7 +205,9 @@ public final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
resetSelectRequestBuffer();
launchDeviceDiscovery();
startQueuedActions();
- if (!mDelayedMessageBuffer.isBuffered(Constants.MESSAGE_ACTIVE_SOURCE)) {
+ List<HdmiCecMessage> bufferedActiveSource = mDelayedMessageBuffer
+ .getBufferedMessagesWithOpcode(Constants.MESSAGE_ACTIVE_SOURCE);
+ if (bufferedActiveSource.isEmpty()) {
addAndStartAction(new RequestActiveSourceAction(this, new IHdmiControlCallback.Stub() {
@Override
public void onComplete(int result) {
@@ -220,7 +222,31 @@ public final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
}
}
}));
+ } else {
+ addCecDeviceForBufferedActiveSource(bufferedActiveSource.get(0));
+ }
+ }
+
+ // Add a new CEC device with known information from the buffered <Active Source> message. This
+ // helps TvInputCallback#onInputAdded to be called such that the message can be processed and
+ // the TV to switch to the new active input.
+ @ServiceThreadOnly
+ private void addCecDeviceForBufferedActiveSource(HdmiCecMessage bufferedActiveSource) {
+ assertRunOnServiceThread();
+ if (bufferedActiveSource == null) {
+ return;
}
+ int source = bufferedActiveSource.getSource();
+ int physicalAddress = HdmiUtils.twoBytesToInt(bufferedActiveSource.getParams());
+ List<Integer> deviceTypes = HdmiUtils.getTypeFromAddress(source);
+ HdmiDeviceInfo newDevice = HdmiDeviceInfo.cecDeviceBuilder()
+ .setLogicalAddress(source)
+ .setPhysicalAddress(physicalAddress)
+ .setDisplayName(HdmiUtils.getDefaultDeviceName(source))
+ .setDeviceType(deviceTypes.get(0))
+ .setVendorId(Constants.VENDOR_ID_UNKNOWN)
+ .build();
+ mService.getHdmiCecNetwork().addCecDevice(newDevice);
}
@ServiceThreadOnly
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java b/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java
index a9dff18e99a0..18a6e3dd7470 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java
@@ -486,6 +486,7 @@ public class HdmiCecMessageValidator {
* @return true if the hour is valid
*/
private static boolean isValidHour(int value) {
+ value = bcdToDecimal(value);
return isWithinRange(value, 0, 23);
}
@@ -497,6 +498,7 @@ public class HdmiCecMessageValidator {
* @return true if the minute is valid
*/
private static boolean isValidMinute(int value) {
+ value = bcdToDecimal(value);
return isWithinRange(value, 0, 59);
}
@@ -508,10 +510,24 @@ public class HdmiCecMessageValidator {
* @return true if the duration hours is valid
*/
private static boolean isValidDurationHours(int value) {
+ value = bcdToDecimal(value);
return isWithinRange(value, 0, 99);
}
/**
+ * Convert BCD value to decimal value.
+ *
+ * @param value BCD value
+ * @return decimal value
+ */
+ private static int bcdToDecimal(int value) {
+ int tens = (value & 0xF0) >> 4;
+ int ones = (value & 0x0F);
+
+ return tens * 10 + ones;
+ }
+
+ /**
* Check if the given value is a valid recording sequence. A valid value is adheres to range
* description defined in CEC 1.4 Specification : Operand Descriptions (Section 17)
*
@@ -524,8 +540,7 @@ public class HdmiCecMessageValidator {
if ((value & 0x80) != 0x00) {
return false;
}
- // Validate than not more than one bit is set
- return (Integer.bitCount(value) <= 1);
+ return true;
}
/**
diff --git a/services/core/java/com/android/server/input/OWNERS b/services/core/java/com/android/server/input/OWNERS
index 4c20c4dc9d35..e2834ec246b6 100644
--- a/services/core/java/com/android/server/input/OWNERS
+++ b/services/core/java/com/android/server/input/OWNERS
@@ -1 +1,2 @@
+# Bug component: 136048
include /INPUT_OWNERS
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 365c9b51a395..7d2915ba48a2 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -530,6 +530,12 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
*/
private boolean mUseDifferentDelaysForBackgroundChain;
+ /**
+ * Core uids and apps without the internet permission will not have any firewall rules applied
+ * to them.
+ */
+ private boolean mNeverApplyRulesToCoreUids;
+
// See main javadoc for instructions on how to use these locks.
final Object mUidRulesFirstLock = new Object();
final Object mNetworkPoliciesSecondLock = new Object();
@@ -622,16 +628,6 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
@GuardedBy("mUidRulesFirstLock")
final SparseIntArray mUidFirewallStandbyRules = new SparseIntArray();
- @GuardedBy("mUidRulesFirstLock")
- final SparseIntArray mUidFirewallDozableRules = new SparseIntArray();
- @GuardedBy("mUidRulesFirstLock")
- final SparseIntArray mUidFirewallPowerSaveRules = new SparseIntArray();
- @GuardedBy("mUidRulesFirstLock")
- final SparseIntArray mUidFirewallBackgroundRules = new SparseIntArray();
- @GuardedBy("mUidRulesFirstLock")
- final SparseIntArray mUidFirewallRestrictedModeRules = new SparseIntArray();
- @GuardedBy("mUidRulesFirstLock")
- final SparseIntArray mUidFirewallLowPowerStandbyModeRules = new SparseIntArray();
/** Set of states for the child firewall chains. True if the chain is active. */
@GuardedBy("mUidRulesFirstLock")
@@ -770,7 +766,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
/** List of apps indexed by uid and whether they have the internet permission */
@GuardedBy("mUidRulesFirstLock")
- private final SparseBooleanArray mInternetPermissionMap = new SparseBooleanArray();
+ @VisibleForTesting
+ final SparseBooleanArray mInternetPermissionMap = new SparseBooleanArray();
/**
* Map of uid -> UidStateCallbackInfo objects holding the data received from
@@ -1048,6 +1045,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
mUseMeteredFirewallChains = Flags.useMeteredFirewallChains();
mUseDifferentDelaysForBackgroundChain = Flags.useDifferentDelaysForBackgroundChain();
+ mNeverApplyRulesToCoreUids = Flags.neverApplyRulesToCoreUids();
synchronized (mUidRulesFirstLock) {
synchronized (mNetworkPoliciesSecondLock) {
@@ -4098,6 +4096,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
+ mUseMeteredFirewallChains);
fout.println(Flags.FLAG_USE_DIFFERENT_DELAYS_FOR_BACKGROUND_CHAIN + ": "
+ mUseDifferentDelaysForBackgroundChain);
+ fout.println(Flags.FLAG_NEVER_APPLY_RULES_TO_CORE_UIDS + ": "
+ + mNeverApplyRulesToCoreUids);
fout.println();
fout.println("mRestrictBackgroundLowPowerMode: " + mRestrictBackgroundLowPowerMode);
@@ -4589,7 +4589,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
@VisibleForTesting
@GuardedBy("mUidRulesFirstLock")
void updateRestrictedModeAllowlistUL() {
- mUidFirewallRestrictedModeRules.clear();
+ final SparseIntArray uidRules = new SparseIntArray();
forEachUid("updateRestrictedModeAllowlist", uid -> {
synchronized (mUidRulesFirstLock) {
final int effectiveBlockedReasons = updateBlockedReasonsForRestrictedModeUL(
@@ -4599,13 +4599,13 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
// setUidFirewallRulesUL will allowlist all uids that are passed to it, so only add
// non-default rules.
if (newFirewallRule != FIREWALL_RULE_DEFAULT) {
- mUidFirewallRestrictedModeRules.append(uid, newFirewallRule);
+ uidRules.append(uid, newFirewallRule);
}
}
});
if (mRestrictedNetworkingMode) {
// firewall rules only need to be set when this mode is being enabled.
- setUidFirewallRulesUL(FIREWALL_CHAIN_RESTRICTED, mUidFirewallRestrictedModeRules);
+ setUidFirewallRulesUL(FIREWALL_CHAIN_RESTRICTED, uidRules);
}
enableFirewallChainUL(FIREWALL_CHAIN_RESTRICTED, mRestrictedNetworkingMode);
}
@@ -4689,8 +4689,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
void updateRulesForPowerSaveUL() {
Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForPowerSaveUL");
try {
- updateRulesForAllowlistedPowerSaveUL(mRestrictPower, FIREWALL_CHAIN_POWERSAVE,
- mUidFirewallPowerSaveRules);
+ updateRulesForAllowlistedPowerSaveUL(mRestrictPower, FIREWALL_CHAIN_POWERSAVE);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
}
@@ -4705,8 +4704,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
void updateRulesForDeviceIdleUL() {
Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForDeviceIdleUL");
try {
- updateRulesForAllowlistedPowerSaveUL(mDeviceIdleMode, FIREWALL_CHAIN_DOZABLE,
- mUidFirewallDozableRules);
+ updateRulesForAllowlistedPowerSaveUL(mDeviceIdleMode, FIREWALL_CHAIN_DOZABLE);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_NETWORK);
}
@@ -4720,13 +4718,11 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
// NOTE: since both fw_dozable and fw_powersave uses the same map
// (mPowerSaveTempWhitelistAppIds) for allowlisting, we can reuse their logic in this method.
@GuardedBy("mUidRulesFirstLock")
- private void updateRulesForAllowlistedPowerSaveUL(boolean enabled, int chain,
- SparseIntArray rules) {
+ private void updateRulesForAllowlistedPowerSaveUL(boolean enabled, int chain) {
if (enabled) {
// Sync the allowlists before enabling the chain. We don't care about the rules if
// we are disabling the chain.
- final SparseIntArray uidRules = rules;
- uidRules.clear();
+ final SparseIntArray uidRules = new SparseIntArray();
final List<UserInfo> users = mUserManager.getUsers();
for (int ui = users.size() - 1; ui >= 0; ui--) {
UserInfo user = users.get(ui);
@@ -4755,9 +4751,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
private void updateRulesForBackgroundChainUL() {
Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForBackgroundChainUL");
try {
- final SparseIntArray uidRules = mUidFirewallBackgroundRules;
- uidRules.clear();
-
+ final SparseIntArray uidRules = new SparseIntArray();
final List<UserInfo> users = mUserManager.getUsers();
for (int ui = users.size() - 1; ui >= 0; ui--) {
final UserInfo user = users.get(ui);
@@ -4794,17 +4788,17 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForLowPowerStandbyUL");
try {
if (mLowPowerStandbyActive) {
- mUidFirewallLowPowerStandbyModeRules.clear();
+ final SparseIntArray uidRules = new SparseIntArray();
for (int i = mUidState.size() - 1; i >= 0; i--) {
final int uid = mUidState.keyAt(i);
final int effectiveBlockedReasons = getEffectiveBlockedReasons(uid);
if (hasInternetPermissionUL(uid) && (effectiveBlockedReasons
& BLOCKED_REASON_LOW_POWER_STANDBY) == 0) {
- mUidFirewallLowPowerStandbyModeRules.put(uid, FIREWALL_RULE_ALLOW);
+ uidRules.put(uid, FIREWALL_RULE_ALLOW);
}
}
setUidFirewallRulesUL(FIREWALL_CHAIN_LOW_POWER_STANDBY,
- mUidFirewallLowPowerStandbyModeRules, CHAIN_TOGGLE_ENABLE);
+ uidRules, CHAIN_TOGGLE_ENABLE);
} else {
setUidFirewallRulesUL(FIREWALL_CHAIN_LOW_POWER_STANDBY, null, CHAIN_TOGGLE_DISABLE);
}
@@ -4822,10 +4816,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
final int effectiveBlockedReasons = getEffectiveBlockedReasons(uid);
if (mUidState.contains(uid)
&& (effectiveBlockedReasons & BLOCKED_REASON_LOW_POWER_STANDBY) == 0) {
- mUidFirewallLowPowerStandbyModeRules.put(uid, FIREWALL_RULE_ALLOW);
setUidFirewallRuleUL(FIREWALL_CHAIN_LOW_POWER_STANDBY, uid, FIREWALL_RULE_ALLOW);
} else {
- mUidFirewallLowPowerStandbyModeRules.delete(uid);
setUidFirewallRuleUL(FIREWALL_CHAIN_LOW_POWER_STANDBY, uid, FIREWALL_RULE_DEFAULT);
}
}
@@ -4896,6 +4888,12 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
int[] idleUids = mUsageStats.getIdleUidsForUser(user.id);
for (int uid : idleUids) {
if (!mPowerSaveTempWhitelistAppIds.get(UserHandle.getAppId(uid), false)) {
+ if (mNeverApplyRulesToCoreUids && !isUidValidForRulesUL(uid)) {
+ // This check is needed to keep mUidFirewallStandbyRules free of any
+ // such uids. Doing this keeps it in sync with the actual rules applied
+ // in the underlying connectivity stack.
+ continue;
+ }
// quick check: if this uid doesn't have INTERNET permission, it
// doesn't have network access anyway, so it is a waste to mess
// with it here.
@@ -5198,6 +5196,11 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
@GuardedBy("mUidRulesFirstLock")
private boolean isUidValidForAllowlistRulesUL(int uid) {
+ return isUidValidForRulesUL(uid);
+ }
+
+ @GuardedBy("mUidRulesFirstLock")
+ private boolean isUidValidForRulesUL(int uid) {
return UserHandle.isApp(uid) && hasInternetPermissionUL(uid);
}
@@ -5313,16 +5316,11 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
mActivityManagerInternal.onUidBlockedReasonsChanged(uid, BLOCKED_REASON_NONE);
mUidPolicy.delete(uid);
mUidFirewallStandbyRules.delete(uid);
- mUidFirewallDozableRules.delete(uid);
- mUidFirewallPowerSaveRules.delete(uid);
- mUidFirewallBackgroundRules.delete(uid);
mBackgroundTransitioningUids.delete(uid);
mPowerSaveWhitelistExceptIdleAppIds.delete(uid);
mPowerSaveWhitelistAppIds.delete(uid);
mPowerSaveTempWhitelistAppIds.delete(uid);
mAppIdleTempWhitelistAppIds.delete(uid);
- mUidFirewallRestrictedModeRules.delete(uid);
- mUidFirewallLowPowerStandbyModeRules.delete(uid);
synchronized (mUidStateCallbackInfos) {
mUidStateCallbackInfos.remove(uid);
}
@@ -6217,41 +6215,33 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
}
}
- private void addSdkSandboxUidsIfNeeded(SparseIntArray uidRules) {
- final int size = uidRules.size();
- final SparseIntArray sdkSandboxUids = new SparseIntArray();
- for (int index = 0; index < size; index++) {
- final int uid = uidRules.keyAt(index);
- final int rule = uidRules.valueAt(index);
- if (Process.isApplicationUid(uid)) {
- sdkSandboxUids.put(Process.toSdkSandboxUid(uid), rule);
- }
- }
-
- for (int index = 0; index < sdkSandboxUids.size(); index++) {
- final int uid = sdkSandboxUids.keyAt(index);
- final int rule = sdkSandboxUids.valueAt(index);
- uidRules.put(uid, rule);
- }
- }
-
/**
* Set uid rules on a particular firewall chain. This is going to synchronize the rules given
* here to netd. It will clean up dead rules and make sure the target chain only contains rules
* specified here.
*/
+ @GuardedBy("mUidRulesFirstLock")
private void setUidFirewallRulesUL(int chain, SparseIntArray uidRules) {
- addSdkSandboxUidsIfNeeded(uidRules);
try {
int size = uidRules.size();
- int[] uids = new int[size];
- int[] rules = new int[size];
+ final IntArray uids = new IntArray(size);
+ final IntArray rules = new IntArray(size);
for(int index = size - 1; index >= 0; --index) {
- uids[index] = uidRules.keyAt(index);
- rules[index] = uidRules.valueAt(index);
+ final int uid = uidRules.keyAt(index);
+ if (mNeverApplyRulesToCoreUids && !isUidValidForRulesUL(uid)) {
+ continue;
+ }
+ uids.add(uid);
+ rules.add(uidRules.valueAt(index));
+ if (Process.isApplicationUid(uid)) {
+ uids.add(Process.toSdkSandboxUid(uid));
+ rules.add(uidRules.valueAt(index));
+ }
}
- mNetworkManager.setFirewallUidRules(chain, uids, rules);
- mLogger.firewallRulesChanged(chain, uids, rules);
+ final int[] uidArray = uids.toArray();
+ final int[] ruleArray = rules.toArray();
+ mNetworkManager.setFirewallUidRules(chain, uidArray, ruleArray);
+ mLogger.firewallRulesChanged(chain, uidArray, ruleArray);
} catch (IllegalStateException e) {
Log.wtf(TAG, "problem setting firewall uid rules", e);
} catch (RemoteException e) {
@@ -6264,26 +6254,17 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
*/
@GuardedBy("mUidRulesFirstLock")
private void setUidFirewallRuleUL(int chain, int uid, int rule) {
+ if (mNeverApplyRulesToCoreUids && !isUidValidForRulesUL(uid)) {
+ return;
+ }
if (Trace.isTagEnabled(Trace.TRACE_TAG_NETWORK)) {
Trace.traceBegin(Trace.TRACE_TAG_NETWORK,
"setUidFirewallRuleUL: " + chain + "/" + uid + "/" + rule);
}
try {
- if (chain == FIREWALL_CHAIN_DOZABLE) {
- mUidFirewallDozableRules.put(uid, rule);
- } else if (chain == FIREWALL_CHAIN_STANDBY) {
+ if (chain == FIREWALL_CHAIN_STANDBY) {
mUidFirewallStandbyRules.put(uid, rule);
- } else if (chain == FIREWALL_CHAIN_POWERSAVE) {
- mUidFirewallPowerSaveRules.put(uid, rule);
- } else if (chain == FIREWALL_CHAIN_RESTRICTED) {
- mUidFirewallRestrictedModeRules.put(uid, rule);
- } else if (chain == FIREWALL_CHAIN_LOW_POWER_STANDBY) {
- mUidFirewallLowPowerStandbyModeRules.put(uid, rule);
- } else if (chain == FIREWALL_CHAIN_BACKGROUND) {
- mUidFirewallBackgroundRules.put(uid, rule);
- }
- // Note that we do not need keep a separate cache of uid rules for chains that we do
- // not call #setUidFirewallRulesUL for.
+ }
try {
mNetworkManager.setFirewallUidRule(chain, uid, rule);
@@ -6328,6 +6309,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
* Resets all firewall rules associated with an UID.
*/
private void resetUidFirewallRules(int uid) {
+ // Resetting rules for uids with isUidValidForRulesUL = false should be OK as no rules
+ // should be previously set and the downstream code will skip no-op changes.
try {
mNetworkManager.setFirewallUidRule(FIREWALL_CHAIN_DOZABLE, uid,
FIREWALL_RULE_DEFAULT);
diff --git a/services/core/java/com/android/server/net/flags.aconfig b/services/core/java/com/android/server/net/flags.aconfig
index 586baf022897..7f04e665567e 100644
--- a/services/core/java/com/android/server/net/flags.aconfig
+++ b/services/core/java/com/android/server/net/flags.aconfig
@@ -27,3 +27,13 @@ flag {
purpose: PURPOSE_BUGFIX
}
}
+
+flag {
+ name: "never_apply_rules_to_core_uids"
+ namespace: "backstage_power"
+ description: "Removes all rule bookkeeping and evaluation logic for core uids and uids without the internet permission"
+ bug: "356956588"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index c814a1ef1c13..7ddec79130d1 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -2073,6 +2073,10 @@ public class PackageManagerService implements PackageSender, TestUtilityService
// CHECKSTYLE:ON IndentationCheck
t.traceEnd();
+ t.traceBegin("get system config");
+ SystemConfig systemConfig = injector.getSystemConfig();
+ t.traceEnd();
+
t.traceBegin("addSharedUsers");
mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
@@ -2092,6 +2096,13 @@ public class PackageManagerService implements PackageSender, TestUtilityService
ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
mSettings.addSharedUserLPw("android.uid.uwb", UWB_UID,
ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
+ final ArrayMap<String, Integer> oemDefinedUids = systemConfig.getOemDefinedUids();
+ final int numOemDefinedUids = oemDefinedUids.size();
+ for (int i = 0; i < numOemDefinedUids; i++) {
+ mSettings.addOemSharedUserLPw(oemDefinedUids.keyAt(i), oemDefinedUids.valueAt(i),
+ ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
+ }
+
t.traceEnd();
String separateProcesses = SystemProperties.get("debug.separate_processes");
@@ -2124,10 +2135,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService
mContext.getSystemService(DisplayManager.class)
.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(mMetrics);
- t.traceBegin("get system config");
- SystemConfig systemConfig = injector.getSystemConfig();
mAvailableFeatures = systemConfig.getAvailableFeatures();
- t.traceEnd();
mProtectedPackages = new ProtectedPackages(mContext);
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index fd99c7a4b4b4..200d004805c7 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -969,6 +969,21 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile
return null;
}
+ SharedUserSetting addOemSharedUserLPw(String name, int uid, int pkgFlags, int pkgPrivateFlags) {
+ if (!name.startsWith("android.uid")) {
+ PackageManagerService.reportSettingsProblem(Log.ERROR,
+ "Failed to add oem defined shared user because of invalid name: " + name);
+ return null;
+ }
+ // OEM defined uids must be in the OEM reserved range
+ if (uid < 2900 || uid > 2999) {
+ PackageManagerService.reportSettingsProblem(Log.ERROR,
+ "Failed to add oem defined shared user because of invalid uid: " + uid);
+ return null;
+ }
+ return addSharedUserLPw(name, uid, pkgFlags, pkgPrivateFlags);
+ }
+
SharedUserSetting addSharedUserLPw(String name, int uid, int pkgFlags, int pkgPrivateFlags) {
SharedUserSetting s = mSharedUsers.get(name);
if (s != null) {
diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java
index c2b847cd08d7..f56b68b50ed9 100644
--- a/services/core/java/com/android/server/wm/WallpaperController.java
+++ b/services/core/java/com/android/server/wm/WallpaperController.java
@@ -183,8 +183,8 @@ class WallpaperController {
if (DEBUG_WALLPAPER) Slog.v(TAG, "Found recents animation wallpaper target: " + w);
mFindResults.setWallpaperTarget(w);
return true;
- } else if (hasWallpaper && w.isOnScreen()
- && (mWallpaperTarget == w || w.isDrawFinishedLw())) {
+ } else if (hasWallpaper
+ && (w.mActivityRecord != null ? w.isOnScreen() : w.isReadyForDisplay())) {
if (DEBUG_WALLPAPER) Slog.v(TAG, "Found wallpaper target: " + w);
mFindResults.setWallpaperTarget(w);
mFindResults.setIsWallpaperTargetForLetterbox(w.hasWallpaperForLetterboxBackground());
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 18ac0e748536..4bea18ab5772 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -2341,6 +2341,8 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
mWmService.mDisplayManagerInternal.onPresentation(dc.getDisplay().getDisplayId(),
/*isShown=*/ false);
}
+ // Check if window provides non decor insets before clearing its provided insets.
+ final boolean windowProvidesDisplayDecorInsets = providesDisplayDecorInsets();
// Remove this window from mTapExcludeProvidingWindows. If it was not registered, this will
// not do anything.
@@ -2354,6 +2356,18 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
mWmService.postWindowRemoveCleanupLocked(this);
consumeInsetsChange();
+
+ // Update the orientation when removing a window affecting the display orientation.
+ // Also recompute configuration if it provides screen decor insets.
+ boolean needToSendNewConfiguration = dc.getLastOrientationSource() == this
+ && dc.updateOrientation();
+ if (windowProvidesDisplayDecorInsets) {
+ needToSendNewConfiguration |= dc.getDisplayPolicy().updateDecorInsetsInfo();
+ }
+
+ if (needToSendNewConfiguration) {
+ dc.sendNewConfiguration();
+ }
}
@Override
@@ -2406,16 +2420,10 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
mActivityRecord != null && mActivityRecord.isAnimating(PARENTS | TRANSITION),
mWmService.mDisplayFrozen, Debug.getCallers(6));
- // Visibility of the removed window. Will be used later to update orientation later on.
- boolean wasVisible = false;
-
// First, see if we need to run an animation. If we do, we have to hold off on removing the
// window until the animation is done. If the display is frozen, just remove immediately,
// since the animation wouldn't be seen.
if (mHasSurface && mToken.okToAnimate()) {
- // If we are not currently running the exit animation, we need to see about starting one
- wasVisible = isVisible();
-
// Remove immediately if there is display transition because the animation is
// usually unnoticeable (e.g. covered by rotation animation) and the animation
// bounds could be inconsistent, such as depending on when the window applies
@@ -2425,7 +2433,9 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
// look weird if its orientation is changed.
&& !inRelaunchingActivity();
- if (wasVisible && isDisplayed()) {
+ // If we are not currently running the exit animation,
+ // we need to see about starting one
+ if (isVisible() && isDisplayed()) {
final int transit = (!startingWindow) ? TRANSIT_EXIT : TRANSIT_PREVIEW_DONE;
// Try starting an animation.
@@ -2474,21 +2484,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
}
}
- // Check if window provides non decor insets before clearing its provided insets.
- final boolean windowProvidesDisplayDecorInsets = providesDisplayDecorInsets();
-
removeImmediately();
- // Removing a visible window may affect the display orientation so just update it if
- // needed. Also recompute configuration if it provides screen decor insets.
- boolean needToSendNewConfiguration = wasVisible && displayContent.updateOrientation();
- if (windowProvidesDisplayDecorInsets) {
- needToSendNewConfiguration |=
- displayContent.getDisplayPolicy().updateDecorInsetsInfo();
- }
-
- if (needToSendNewConfiguration) {
- displayContent.sendNewConfiguration();
- }
mWmService.updateFocusedWindowLocked(isFocused()
? UPDATE_FOCUS_REMOVING_FOCUS
: UPDATE_FOCUS_NORMAL,
diff --git a/services/core/jni/OWNERS b/services/core/jni/OWNERS
index 02cba21b8269..3a83b461e8b9 100644
--- a/services/core/jni/OWNERS
+++ b/services/core/jni/OWNERS
@@ -30,7 +30,8 @@ per-file com_android_server_power_stats_* = file:/BATTERY_STATS_OWNERS
per-file com_android_server_security_* = file:/core/java/android/security/OWNERS
per-file com_android_server_tv_* = file:/media/java/android/media/tv/OWNERS
per-file com_android_server_vibrator_* = file:/services/core/java/com/android/server/vibrator/OWNERS
-per-file com_android_server_am_CachedAppOptimizer.cpp = timmurray@google.com, edgararriaga@google.com, dualli@google.com, carmenjackson@google.com, philipcuadra@google.com
+per-file com_android_server_am_CachedAppOptimizer.cpp = file:/PERFORMANCE_OWNERS
+per-file com_android_server_am_Freezer.cpp = file:/PERFORMANCE_OWNERS
per-file com_android_server_companion_virtual_InputController.cpp = file:/services/companion/java/com/android/server/companion/virtual/OWNERS
# Memory
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/OWNERS b/services/tests/mockingservicestests/src/com/android/server/am/OWNERS
index 2cbc226da780..4fac647c4ceb 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/OWNERS
+++ b/services/tests/mockingservicestests/src/com/android/server/am/OWNERS
@@ -1,3 +1,4 @@
include /services/core/java/com/android/server/am/OWNERS
per-file ApplicationStartInfoTest.java = yforta@google.com, carmenjackson@google.com, jji@google.com
+per-file CachedAppOptimizerTest.java = file:/PERFORMANCE_OWNERS
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt b/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt
index 538c0ee52424..c1e2600a8512 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt
@@ -313,6 +313,7 @@ class MockSystem(withSession: (StaticMockitoSessionBuilder) -> Unit = {}) {
whenever(mocks.systemConfig.defaultVrComponents).thenReturn(ArraySet())
whenever(mocks.systemConfig.hiddenApiWhitelistedApps).thenReturn(ArraySet())
whenever(mocks.systemConfig.appMetadataFilePaths).thenReturn(ArrayMap())
+ whenever(mocks.systemConfig.oemDefinedUids).thenReturn(ArrayMap())
wheneverStatic { SystemProperties.set(anyString(), anyString()) }.thenDoNothing()
wheneverStatic { SystemProperties.getBoolean("fw.free_cache_v2", true) }.thenReturn(true)
wheneverStatic { Environment.getApexDirectory() }.thenReturn(apexDirectory)
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java
index 01c4d1fa6b5c..a4e636c01d65 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java
@@ -26,6 +26,7 @@ import static com.android.server.hdmi.Constants.ADDR_TV;
import static com.android.server.hdmi.HdmiCecLocalDevice.ActiveSource;
import static com.android.server.hdmi.HdmiControlService.INITIATED_BY_ENABLE_CEC;
import static com.android.server.hdmi.HdmiControlService.INITIATED_BY_WAKE_UP_MESSAGE;
+import static com.android.server.hdmi.HdmiControlService.WAKE_UP_SCREEN_ON;
import static com.google.common.truth.Truth.assertThat;
@@ -1907,4 +1908,32 @@ public class HdmiCecLocalDeviceTvTest {
// NewDeviceAction did not start and <Give OSD Name> was not sent.
assertThat(mNativeWrapper.getResultMessages()).doesNotContain(giveOsdName);
}
+
+ @Test
+ public void onOneTouchPlay_wakeUp_addCecDevice() {
+ assertThat(mHdmiControlService.getHdmiCecNetwork().getDeviceInfoList(false))
+ .isEmpty();
+ mHdmiCecLocalDeviceTv.mService.getHdmiCecConfig().setIntValue(
+ HdmiControlManager.CEC_SETTING_NAME_TV_WAKE_ON_ONE_TOUCH_PLAY,
+ HdmiControlManager.TV_WAKE_ON_ONE_TOUCH_PLAY_ENABLED);
+ mPowerManager.setInteractive(false);
+ mTestLooper.dispatchAll();
+
+ HdmiCecMessage textViewOn = HdmiCecMessageBuilder.buildTextViewOn(ADDR_PLAYBACK_1,
+ mTvLogicalAddress);
+ HdmiCecMessage activeSource = HdmiCecMessageBuilder.buildActiveSource(ADDR_PLAYBACK_1,
+ 0x1000);
+ assertThat(mHdmiCecLocalDeviceTv.dispatchMessage(textViewOn)).isEqualTo(Constants.HANDLED);
+ assertThat(mHdmiCecLocalDeviceTv.dispatchMessage(activeSource)).isEqualTo(
+ Constants.HANDLED);
+ mTestLooper.dispatchAll();
+ assertThat(mPowerManager.isInteractive()).isTrue();
+
+ // FakePowerManagerWrapper#wakeUp() doesn't broadcast Intent.ACTION_SCREEN_ON so we have to
+ // manually call this method.
+ mHdmiControlService.onWakeUp(WAKE_UP_SCREEN_ON);
+ mTestLooper.dispatchAll();
+ assertThat(mHdmiControlService.getHdmiCecNetwork().getDeviceInfoList(false))
+ .hasSize(1);
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java
index 0aa72d00be1b..2446d2efd736 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java
@@ -239,6 +239,9 @@ public class HdmiCecMessageValidatorTest {
public void isValid_setAnalogueTimer_clearAnalogueTimer() {
assertMessageValidity("04:33:0C:08:10:1E:04:30:08:00:13:AD:06").isEqualTo(OK);
assertMessageValidity("04:34:04:0C:16:0F:08:37:00:02:EA:60:03:34").isEqualTo(OK);
+ // Allow [Recording Sequence] set multiple days of the week.
+ // e.g. Monday (0x02) | Tuesday (0x04) -> Monday or Tuesday (0x06)
+ assertMessageValidity("04:34:04:0C:16:0F:08:37:06:02:EA:60:03:34").isEqualTo(OK);
assertMessageValidity("0F:33:0C:08:10:1E:04:30:08:00:13:AD:06")
.isEqualTo(ERROR_DESTINATION);
@@ -246,120 +249,120 @@ public class HdmiCecMessageValidatorTest {
assertMessageValidity("04:33:0C:08:10:1E:04:30:08:13:AD:06")
.isEqualTo(ERROR_PARAMETER_SHORT);
// Out of range Day of Month
- assertMessageValidity("04:34:20:0C:16:0F:08:37:00:02:EA:60:03").isEqualTo(ERROR_PARAMETER);
+ assertMessageValidity("04:34:20:0C:22:15:08:55:00:02:EA:60:03").isEqualTo(ERROR_PARAMETER);
// Out of range Month of Year
- assertMessageValidity("04:33:0C:00:10:1E:04:30:08:00:13:AD:06").isEqualTo(ERROR_PARAMETER);
+ assertMessageValidity("04:33:0C:00:16:30:04:48:08:00:13:AD:06").isEqualTo(ERROR_PARAMETER);
// Out of range Start Time - Hour
- assertMessageValidity("04:34:04:0C:18:0F:08:37:00:02:EA:60:03").isEqualTo(ERROR_PARAMETER);
+ assertMessageValidity("04:34:04:0C:24:15:08:55:00:02:EA:60:03").isEqualTo(ERROR_PARAMETER);
// Out of range Start Time - Minute
- assertMessageValidity("04:33:0C:08:10:50:04:30:08:00:13:AD:06").isEqualTo(ERROR_PARAMETER);
+ assertMessageValidity("04:33:0C:08:16:60:04:48:08:00:13:AD:06").isEqualTo(ERROR_PARAMETER);
// Out of range Duration - Duration Hours
- assertMessageValidity("04:34:04:0C:16:0F:64:37:00:02:EA:60:03").isEqualTo(ERROR_PARAMETER);
+ assertMessageValidity("04:34:04:0C:22:15:9A:55:00:02:EA:60:03").isEqualTo(ERROR_PARAMETER);
// Out of range Duration - Minute
- assertMessageValidity("04:33:0C:08:10:1E:04:64:08:00:13:AD:06").isEqualTo(ERROR_PARAMETER);
+ assertMessageValidity("04:33:0C:08:16:30:04:60:08:00:13:AD:06").isEqualTo(ERROR_PARAMETER);
// Invalid Recording Sequence
- assertMessageValidity("04:34:04:0C:16:0F:08:37:88:02:EA:60:03").isEqualTo(ERROR_PARAMETER);
+ assertMessageValidity("04:34:04:0C:22:15:08:55:88:02:EA:60:03").isEqualTo(ERROR_PARAMETER);
// Invalid Recording Sequence
- assertMessageValidity("04:33:0C:08:10:1E:04:30:A2:00:13:AD:06").isEqualTo(ERROR_PARAMETER);
+ assertMessageValidity("04:33:0C:08:16:30:04:48:A2:00:13:AD:06").isEqualTo(ERROR_PARAMETER);
// Out of range Analogue Broadcast Type
- assertMessageValidity("04:34:04:0C:16:0F:08:37:00:03:EA:60:03").isEqualTo(ERROR_PARAMETER);
+ assertMessageValidity("04:34:04:0C:22:15:08:55:00:03:EA:60:03").isEqualTo(ERROR_PARAMETER);
// Out of range Analogue Frequency
- assertMessageValidity("04:33:0C:08:10:1E:04:30:08:00:FF:FF:06").isEqualTo(ERROR_PARAMETER);
+ assertMessageValidity("04:33:0C:08:16:30:04:48:08:00:FF:FF:06").isEqualTo(ERROR_PARAMETER);
// Out of range Broadcast System
- assertMessageValidity("04:34:04:0C:16:0F:08:37:00:02:EA:60:20").isEqualTo(ERROR_PARAMETER);
+ assertMessageValidity("04:34:04:0C:22:15:08:55:00:02:EA:60:20").isEqualTo(ERROR_PARAMETER);
}
@Test
public void isValid_setDigitalTimer_clearDigitalTimer() {
// Services identified by Digital IDs - ARIB Broadcast System
- assertMessageValidity("04:99:0C:08:15:05:04:1E:00:00:C4:C2:11:D8:75:30").isEqualTo(OK);
+ assertMessageValidity("04:99:0C:08:21:05:04:30:00:00:C4:C2:11:D8:75:30").isEqualTo(OK);
// Service identified by Digital IDs - ATSC Broadcast System
- assertMessageValidity("04:97:1E:07:12:20:50:28:01:01:8B:5E:39:5A").isEqualTo(OK);
+ assertMessageValidity("04:97:1E:07:18:32:80:40:01:01:8B:5E:39:5A").isEqualTo(OK);
// Service identified by Digital IDs - DVB Broadcast System
- assertMessageValidity("04:99:05:0C:06:0A:19:3B:40:19:8B:44:03:11:04:FC").isEqualTo(OK);
+ assertMessageValidity("04:99:05:0C:06:10:25:59:40:19:8B:44:03:11:04:FC").isEqualTo(OK);
// Service identified by Channel - 1 part channel number
- assertMessageValidity("04:97:12:06:0C:2D:5A:19:08:91:04:00:B1").isEqualTo(OK);
+ assertMessageValidity("04:97:12:06:12:45:90:25:08:91:04:00:B1").isEqualTo(OK);
// Service identified by Channel - 2 part channel number
- assertMessageValidity("04:99:15:09:00:0F:00:2D:04:82:09:C8:72:C8").isEqualTo(OK);
+ assertMessageValidity("04:99:15:09:00:15:00:45:04:82:09:C8:72:C8").isEqualTo(OK);
- assertMessageValidity("4F:97:0C:08:15:05:04:1E:00:00:C4:C2:11:D8:75:30")
+ assertMessageValidity("4F:97:0C:08:21:05:04:30:00:00:C4:C2:11:D8:75:30")
.isEqualTo(ERROR_DESTINATION);
- assertMessageValidity("F0:99:15:09:00:0F:00:2D:04:82:09:C8:72:C8").isEqualTo(ERROR_SOURCE);
+ assertMessageValidity("F0:99:15:09:00:15:00:45:04:82:09:C8:72:C8").isEqualTo(ERROR_SOURCE);
assertMessageValidity("04:97:1E:12:20:58:01:01:8B:5E:39:5A")
.isEqualTo(ERROR_PARAMETER_SHORT);
// Out of range Day of Month
- assertMessageValidity("04:99:24:0C:06:0A:19:3B:40:19:8B:44:03:11:04:FC")
+ assertMessageValidity("04:99:24:0C:06:10:25:59:40:19:8B:44:03:11:04:FC")
.isEqualTo(ERROR_PARAMETER);
// Out of range Month of Year
- assertMessageValidity("04:97:12:10:0C:2D:5A:19:08:91:04:00:B1").isEqualTo(ERROR_PARAMETER);
+ assertMessageValidity("04:97:12:10:12:45:90:25:08:91:04:00:B1").isEqualTo(ERROR_PARAMETER);
// Out of range Start Time - Hour
- assertMessageValidity("04:99:0C:08:20:05:04:1E:00:00:C4:C2:11:D8:75:30")
+ assertMessageValidity("04:99:0C:08:24:05:04:30:00:00:C4:C2:11:D8:75:30")
.isEqualTo(ERROR_PARAMETER);
// Out of range Start Time - Minute
- assertMessageValidity("04:97:15:09:00:4B:00:2D:04:82:09:C8:72:C8")
+ assertMessageValidity("04:97:15:09:00:60:00:45:04:82:09:C8:72:C8")
.isEqualTo(ERROR_PARAMETER);
// Out of range Duration - Duration Hours
- assertMessageValidity("04:99:1E:07:12:20:78:28:01:01:8B:5E:39:5A")
+ assertMessageValidity("04:99:1E:07:18:32:9A:40:01:01:8B:5E:39:5A")
.isEqualTo(ERROR_PARAMETER);
// Out of range Duration - Minute
- assertMessageValidity("04:97:05:0C:06:0A:19:48:40:19:8B:44:03:11:04:FC")
+ assertMessageValidity("04:97:05:0C:06:10:25:60:40:19:8B:44:03:11:04:FC")
.isEqualTo(ERROR_PARAMETER);
// Invalid Recording Sequence
- assertMessageValidity("04:99:12:06:0C:2D:5A:19:90:91:04:00:B1").isEqualTo(ERROR_PARAMETER);
+ assertMessageValidity("04:99:12:06:12:45:90:25:90:91:04:00:B1").isEqualTo(ERROR_PARAMETER);
// Invalid Recording Sequence
- assertMessageValidity("04:97:0C:08:15:05:04:1E:21:00:C4:C2:11:D8:75:30")
+ assertMessageValidity("04:97:0C:08:15:05:04:1E:A1:00:C4:C2:11:D8:75:30")
.isEqualTo(ERROR_PARAMETER);
// Invalid Digital Broadcast System
- assertMessageValidity("04:99:1E:07:12:20:50:28:01:04:8B:5E:39:5A")
+ assertMessageValidity("04:99:1E:07:18:32:80:40:01:04:8B:5E:39:5A")
.isEqualTo(ERROR_PARAMETER);
// Invalid Digital Broadcast System
- assertMessageValidity("04:97:05:0C:06:0A:19:3B:40:93:8B:44:03:11:04:FC")
+ assertMessageValidity("04:97:05:0C:06:10:25:59:40:93:8B:44:03:11:04:FC")
.isEqualTo(ERROR_PARAMETER);
// Insufficient data for ARIB Broadcast system
- assertMessageValidity("04:99:0C:08:15:05:04:1E:00:00:C4:C2:11:D8:75")
+ assertMessageValidity("04:99:0C:08:21:05:04:30:00:00:C4:C2:11:D8:75")
.isEqualTo(ERROR_PARAMETER);
// Insufficient data for ATSC Broadcast system
- assertMessageValidity("04:97:1E:07:12:20:50:28:01:01:8B:5E:39").isEqualTo(ERROR_PARAMETER);
+ assertMessageValidity("04:97:1E:07:18:32:80:40:01:01:8B:5E:39").isEqualTo(ERROR_PARAMETER);
// Insufficient data for DVB Broadcast system
- assertMessageValidity("04:99:05:0C:06:0A:19:3B:40:19:8B:44:03:11:04")
+ assertMessageValidity("04:99:05:0C:06:10:25:59:40:19:8B:44:03:11:04")
.isEqualTo(ERROR_PARAMETER);
// Insufficient data for 2 part channel number
- assertMessageValidity("04:97:15:09:00:0F:00:2D:04:82:09:C8:72").isEqualTo(ERROR_PARAMETER);
+ assertMessageValidity("04:97:15:09:00:15:00:45:04:82:09:C8:72").isEqualTo(ERROR_PARAMETER);
// Invalid Channel Number format
- assertMessageValidity("04:99:12:06:0C:2D:5A:19:08:91:0D:00:B1").isEqualTo(ERROR_PARAMETER);
+ assertMessageValidity("04:99:12:06:12:45:90:25:08:91:0D:00:B1").isEqualTo(ERROR_PARAMETER);
}
@Test
public void isValid_setExternalTimer_clearExternalTimer() {
- assertMessageValidity("40:A1:0C:08:15:05:04:1E:02:04:20").isEqualTo(OK);
- assertMessageValidity("40:A2:14:09:12:28:4B:19:10:05:10:00").isEqualTo(OK);
+ assertMessageValidity("40:A1:0C:08:21:05:04:30:02:04:20").isEqualTo(OK);
+ assertMessageValidity("40:A2:14:09:18:40:75:25:10:05:10:00").isEqualTo(OK);
- assertMessageValidity("4F:A1:0C:08:15:05:04:1E:02:04:20").isEqualTo(ERROR_DESTINATION);
- assertMessageValidity("F4:A2:14:09:12:28:4B:19:10:05:10:00").isEqualTo(ERROR_SOURCE);
- assertMessageValidity("40:A1:0C:08:15:05:04:1E:02:04").isEqualTo(ERROR_PARAMETER_SHORT);
+ assertMessageValidity("4F:A1:0C:08:21:05:04:30:02:04:20").isEqualTo(ERROR_DESTINATION);
+ assertMessageValidity("F4:A2:14:09:18:40:75:25:10:05:10:00").isEqualTo(ERROR_SOURCE);
+ assertMessageValidity("40:A1:0C:08:21:05:04:30:02:04").isEqualTo(ERROR_PARAMETER_SHORT);
// Out of range Day of Month
- assertMessageValidity("40:A2:28:09:12:28:4B:19:10:05:10:00").isEqualTo(ERROR_PARAMETER);
+ assertMessageValidity("40:A2:28:09:18:40:75:25:10:05:10:00").isEqualTo(ERROR_PARAMETER);
// Out of range Month of Year
- assertMessageValidity("40:A1:0C:0F:15:05:04:1E:02:04:20").isEqualTo(ERROR_PARAMETER);
+ assertMessageValidity("40:A1:0C:0F:21:05:04:30:02:04:20").isEqualTo(ERROR_PARAMETER);
// Out of range Start Time - Hour
- assertMessageValidity("40:A2:14:09:1A:28:4B:19:10:05:10:00").isEqualTo(ERROR_PARAMETER);
+ assertMessageValidity("40:A2:14:09:24:40:75:25:10:05:10:00").isEqualTo(ERROR_PARAMETER);
// Out of range Start Time - Minute
- assertMessageValidity("40:A1:0C:08:15:48:04:1E:02:04:20").isEqualTo(ERROR_PARAMETER);
+ assertMessageValidity("40:A1:0C:08:21:60:04:30:02:04:20").isEqualTo(ERROR_PARAMETER);
// Out of range Duration - Duration Hours
- assertMessageValidity("40:A2:14:09:12:28:66:19:10:05:10:00").isEqualTo(ERROR_PARAMETER);
+ assertMessageValidity("40:A2:14:09:18:40:9A:25:10:05:10:00").isEqualTo(ERROR_PARAMETER);
// Out of range Duration - Minute
- assertMessageValidity("40:A1:0C:08:15:05:04:3F:02:04:20").isEqualTo(ERROR_PARAMETER);
+ assertMessageValidity("40:A1:0C:08:21:05:04:60:02:04:20").isEqualTo(ERROR_PARAMETER);
// Invalid Recording Sequence
- assertMessageValidity("40:A2:14:09:12:28:4B:19:84:05:10:00").isEqualTo(ERROR_PARAMETER);
+ assertMessageValidity("40:A2:14:09:18:40:75:25:84:05:10:00").isEqualTo(ERROR_PARAMETER);
// Invalid Recording Sequence
- assertMessageValidity("40:A1:0C:08:15:05:04:1E:14:04:20").isEqualTo(ERROR_PARAMETER);
+ assertMessageValidity("40:A1:0C:08:15:05:04:1E:94:04:20").isEqualTo(ERROR_PARAMETER);
// Invalid external source specifier
- assertMessageValidity("40:A2:14:09:12:28:4B:19:10:08:10:00").isEqualTo(ERROR_PARAMETER);
+ assertMessageValidity("40:A2:14:09:18:40:75:25:10:08:10:00").isEqualTo(ERROR_PARAMETER);
// Invalid External PLug
- assertMessageValidity("04:A1:0C:08:15:05:04:1E:02:04:00").isEqualTo(ERROR_PARAMETER);
+ assertMessageValidity("04:A1:0C:08:21:05:04:30:02:04:00").isEqualTo(ERROR_PARAMETER);
// Invalid Physical Address
- assertMessageValidity("40:A2:14:09:12:28:4B:19:10:05:10:10").isEqualTo(ERROR_PARAMETER);
+ assertMessageValidity("40:A2:14:09:18:40:75:25:10:05:10:10").isEqualTo(ERROR_PARAMETER);
}
@Test
@@ -392,9 +395,9 @@ public class HdmiCecMessageValidatorTest {
// Non programmed - Invalid not programmed error info
assertMessageValidity("40:35:DE").isEqualTo(ERROR_PARAMETER);
// Programmed - Might not be enough space available - Invalid duration hours
- assertMessageValidity("40:35:BB:96:1C").isEqualTo(ERROR_PARAMETER);
+ assertMessageValidity("40:35:BB:9A:28").isEqualTo(ERROR_PARAMETER);
// Not programmed - Duplicate - Invalid duration minutes
- assertMessageValidity("40:35:EE:52:4A").isEqualTo(ERROR_PARAMETER);
+ assertMessageValidity("40:35:EE:82:60").isEqualTo(ERROR_PARAMETER);
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
index 3d6884925098..dddab657be14 100644
--- a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
@@ -108,6 +108,7 @@ import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isA;
import static org.mockito.Mockito.CALLS_REAL_METHODS;
@@ -165,6 +166,7 @@ import android.os.PowerExemptionManager;
import android.os.PowerManager;
import android.os.PowerManagerInternal;
import android.os.PowerSaveState;
+import android.os.Process;
import android.os.RemoteException;
import android.os.SimpleClock;
import android.os.SystemClock;
@@ -197,6 +199,7 @@ import androidx.test.filters.FlakyTest;
import androidx.test.filters.MediumTest;
import androidx.test.runner.AndroidJUnit4;
+import com.android.internal.util.ArrayUtils;
import com.android.internal.util.test.BroadcastInterceptingContext;
import com.android.internal.util.test.BroadcastInterceptingContext.FutureIntent;
import com.android.internal.util.test.FsUtil;
@@ -2310,6 +2313,70 @@ public class NetworkPolicyManagerServiceTest {
assertTrue(mService.isUidNetworkingBlocked(UID_A, false));
}
+ @SuppressWarnings("GuardedBy") // For not holding mUidRulesFirstLock
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_NEVER_APPLY_RULES_TO_CORE_UIDS)
+ public void testRulesNeverAppliedToCoreUids() throws Exception {
+ clearInvocations(mNetworkManager);
+
+ final int coreAppId = Process.FIRST_APPLICATION_UID - 102;
+ final int coreUid = UserHandle.getUid(USER_ID, coreAppId);
+
+ // Enable all restrictions and add this core uid to all allowlists.
+ mService.mDeviceIdleMode = true;
+ mService.mRestrictPower = true;
+ setRestrictBackground(true);
+ expectHasUseRestrictedNetworksPermission(coreUid, true);
+ enableRestrictedMode(true);
+ final NetworkPolicyManagerInternal internal = LocalServices.getService(
+ NetworkPolicyManagerInternal.class);
+ internal.setLowPowerStandbyActive(true);
+ internal.setLowPowerStandbyAllowlist(new int[]{coreUid});
+ internal.onTempPowerSaveWhitelistChange(coreAppId, true, REASON_OTHER, "testing");
+
+ when(mPowerExemptionManager.getAllowListedAppIds(anyBoolean()))
+ .thenReturn(new int[]{coreAppId});
+ mPowerAllowlistReceiver.onReceive(mServiceContext, null);
+
+ // A normal uid would undergo a rule change from denied to allowed on all chains, but we
+ // should not request any rule change for this core uid.
+ verify(mNetworkManager, never()).setFirewallUidRule(anyInt(), eq(coreUid), anyInt());
+ verify(mNetworkManager, never()).setFirewallUidRules(anyInt(),
+ argThat(ar -> ArrayUtils.contains(ar, coreUid)), any(int[].class));
+ }
+
+ @SuppressWarnings("GuardedBy") // For not holding mUidRulesFirstLock
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_NEVER_APPLY_RULES_TO_CORE_UIDS)
+ public void testRulesNeverAppliedToUidsWithoutInternetPermission() throws Exception {
+ clearInvocations(mNetworkManager);
+
+ mService.mInternetPermissionMap.clear();
+ expectHasInternetPermission(UID_A, false);
+
+ // Enable all restrictions and add this uid to all allowlists.
+ mService.mDeviceIdleMode = true;
+ mService.mRestrictPower = true;
+ setRestrictBackground(true);
+ expectHasUseRestrictedNetworksPermission(UID_A, true);
+ enableRestrictedMode(true);
+ final NetworkPolicyManagerInternal internal = LocalServices.getService(
+ NetworkPolicyManagerInternal.class);
+ internal.setLowPowerStandbyActive(true);
+ internal.setLowPowerStandbyAllowlist(new int[]{UID_A});
+ internal.onTempPowerSaveWhitelistChange(APP_ID_A, true, REASON_OTHER, "testing");
+
+ when(mPowerExemptionManager.getAllowListedAppIds(anyBoolean()))
+ .thenReturn(new int[]{APP_ID_A});
+ mPowerAllowlistReceiver.onReceive(mServiceContext, null);
+
+ // A normal uid would undergo a rule change from denied to allowed on all chains, but we
+ // should not request any rule this uid without the INTERNET permission.
+ verify(mNetworkManager, never()).setFirewallUidRule(anyInt(), eq(UID_A), anyInt());
+ verify(mNetworkManager, never()).setFirewallUidRules(anyInt(),
+ argThat(ar -> ArrayUtils.contains(ar, UID_A)), any(int[].class));
+ }
+
private boolean isUidState(int uid, int procState, int procStateSeq, int capability) {
final NetworkPolicyManager.UidState uidState = mService.getUidStateForTest(uid);
if (uidState == null) {
diff --git a/services/usage/java/com/android/server/usage/TEST_MAPPING b/services/usage/java/com/android/server/usage/TEST_MAPPING
index 6e845433492b..6ceb7635830f 100644
--- a/services/usage/java/com/android/server/usage/TEST_MAPPING
+++ b/services/usage/java/com/android/server/usage/TEST_MAPPING
@@ -1,12 +1,7 @@
{
"presubmit": [
{
- "name": "FrameworksCoreTests",
- "options": [
- {
- "include-filter": "android.app.usage"
- }
- ]
+ "name": "FrameworksCoreTests_usage"
},
{
"name": "FrameworksServicesTests",
diff --git a/test-mock/Android.bp b/test-mock/Android.bp
index 59766579eee2..71f303311047 100644
--- a/test-mock/Android.bp
+++ b/test-mock/Android.bp
@@ -47,6 +47,10 @@ java_sdk_library {
compile_dex: true,
default_to_stubs: true,
dist_group: "android",
+
+ // This module cannot generate stubs from the api signature files as stubs depends on the
+ // private APIs, which are not visible in the api signature files.
+ build_from_text_stub: false,
}
java_library {
diff --git a/tools/systemfeatures/Android.bp b/tools/systemfeatures/Android.bp
new file mode 100644
index 000000000000..2cebfe9790d0
--- /dev/null
+++ b/tools/systemfeatures/Android.bp
@@ -0,0 +1,63 @@
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "frameworks_base_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["frameworks_base_license"],
+}
+
+java_library_host {
+ name: "systemfeatures-gen-lib",
+ srcs: [
+ "src/**/*.java",
+ "src/**/*.kt",
+ ],
+ static_libs: [
+ "guava",
+ "javapoet",
+ ],
+}
+
+java_binary_host {
+ name: "systemfeatures-gen-tool",
+ main_class: "com.android.systemfeatures.SystemFeaturesGenerator",
+ static_libs: ["systemfeatures-gen-lib"],
+}
+
+// TODO(b/203143243): Add golden diff test for generated sources.
+// Functional runtime behavior is covered in systemfeatures-gen-tests.
+genrule {
+ name: "systemfeatures-gen-tests-srcs",
+ cmd: "$(location systemfeatures-gen-tool) com.android.systemfeatures.RwNoFeatures --readonly=false > $(location RwNoFeatures.java) && " +
+ "$(location systemfeatures-gen-tool) com.android.systemfeatures.RoNoFeatures --readonly=true > $(location RoNoFeatures.java) && " +
+ "$(location systemfeatures-gen-tool) com.android.systemfeatures.RwFeatures --readonly=false --feature=WATCH:1 --feature=WIFI:0 --feature=VULKAN:-1 --feature=AUTO: > $(location RwFeatures.java) && " +
+ "$(location systemfeatures-gen-tool) com.android.systemfeatures.RoFeatures --readonly=true --feature=WATCH:1 --feature=WIFI:0 --feature=VULKAN:-1 --feature=AUTO: > $(location RoFeatures.java)",
+ out: [
+ "RwNoFeatures.java",
+ "RoNoFeatures.java",
+ "RwFeatures.java",
+ "RoFeatures.java",
+ ],
+ tools: ["systemfeatures-gen-tool"],
+}
+
+java_test_host {
+ name: "systemfeatures-gen-tests",
+ test_suites: ["general-tests"],
+ srcs: [
+ "tests/**/*.java",
+ ":systemfeatures-gen-tests-srcs",
+ ],
+ test_options: {
+ unit_test: true,
+ },
+ static_libs: [
+ "aconfig-annotations-lib",
+ "framework-annotations-lib",
+ "junit",
+ "objenesis",
+ "mockito",
+ "truth",
+ ],
+}
diff --git a/tools/systemfeatures/OWNERS b/tools/systemfeatures/OWNERS
new file mode 100644
index 000000000000..66c8506f58be
--- /dev/null
+++ b/tools/systemfeatures/OWNERS
@@ -0,0 +1 @@
+include /PERFORMANCE_OWNERS
diff --git a/tools/systemfeatures/README.md b/tools/systemfeatures/README.md
new file mode 100644
index 000000000000..5836f81e5fd3
--- /dev/null
+++ b/tools/systemfeatures/README.md
@@ -0,0 +1,11 @@
+# Build-time system feature support
+
+## Overview
+
+System features exposed from `PackageManager` are defined and aggregated as
+`<feature>` xml attributes across various partitions, and are currently queried
+at runtime through the framework. This directory contains tooling that will
+support *build-time* queries of select system features, enabling optimizations
+like code stripping and conditionally dependencies when so configured.
+
+### TODO(b/203143243): Expand readme after landing codegen.
diff --git a/tools/systemfeatures/src/com/android/systemfeatures/SystemFeaturesGenerator.kt b/tools/systemfeatures/src/com/android/systemfeatures/SystemFeaturesGenerator.kt
new file mode 100644
index 000000000000..9bfda451067f
--- /dev/null
+++ b/tools/systemfeatures/src/com/android/systemfeatures/SystemFeaturesGenerator.kt
@@ -0,0 +1,218 @@
+/*
+ * 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.systemfeatures
+
+import com.google.common.base.CaseFormat
+import com.squareup.javapoet.ClassName
+import com.squareup.javapoet.JavaFile
+import com.squareup.javapoet.MethodSpec
+import com.squareup.javapoet.TypeSpec
+import javax.lang.model.element.Modifier
+
+/*
+ * Simple Java code generator that takes as input a list of defined features and generates an
+ * accessory class based on the provided versions.
+ *
+ * <p>Example:
+ *
+ * <pre>
+ * <cmd> com.foo.RoSystemFeatures --readonly=true \
+ * --feature=WATCH:0 --feature=AUTOMOTIVE: --feature=VULKAN:9348
+ * </pre>
+ *
+ * This generates a class that has the following signature:
+ *
+ * <pre>
+ * package com.foo;
+ * public final class RoSystemFeatures {
+ * @AssumeTrueForR8
+ * public static boolean hasFeatureWatch(Context context);
+ * @AssumeFalseForR8
+ * public static boolean hasFeatureAutomotive(Context context);
+ * @AssumeTrueForR8
+ * public static boolean hasFeatureVulkan(Context context);
+ * public static Boolean maybeHasFeature(String feature, int version);
+ * }
+ * </pre>
+ */
+object SystemFeaturesGenerator {
+ private const val FEATURE_ARG = "--feature="
+ private const val READONLY_ARG = "--readonly="
+ private val PACKAGEMANAGER_CLASS = ClassName.get("android.content.pm", "PackageManager")
+ private val CONTEXT_CLASS = ClassName.get("android.content", "Context")
+ private val ASSUME_TRUE_CLASS =
+ ClassName.get("com.android.aconfig.annotations", "AssumeTrueForR8")
+ private val ASSUME_FALSE_CLASS =
+ ClassName.get("com.android.aconfig.annotations", "AssumeFalseForR8")
+
+ private fun usage() {
+ println("Usage: SystemFeaturesGenerator <outputClassName> [options]")
+ println(" Options:")
+ println(" --readonly=true|false Whether to encode features as build-time constants")
+ println(" --feature=\$NAME:\$VER A feature+version pair (blank version == disabled)")
+ }
+
+ /** Main entrypoint for build-time system feature codegen. */
+ @JvmStatic
+ fun main(args: Array<String>) {
+ if (args.size < 1) {
+ usage()
+ return
+ }
+
+ var readonly = false
+ var outputClassName: ClassName? = null
+ val features = mutableListOf<FeatureInfo>()
+ for (arg in args) {
+ when {
+ arg.startsWith(READONLY_ARG) ->
+ readonly = arg.substring(READONLY_ARG.length).toBoolean()
+ arg.startsWith(FEATURE_ARG) -> {
+ features.add(parseFeatureArg(arg))
+ }
+ else -> outputClassName = ClassName.bestGuess(arg)
+ }
+ }
+
+ outputClassName
+ ?: run {
+ println("Output class name must be provided.")
+ usage()
+ return
+ }
+
+ val classBuilder =
+ TypeSpec.classBuilder(outputClassName)
+ .addModifiers(Modifier.PUBLIC, Modifier.FINAL)
+ .addJavadoc("@hide")
+
+ addFeatureMethodsToClass(classBuilder, readonly, features)
+ addMaybeFeatureMethodToClass(classBuilder, readonly, features)
+
+ // TODO(b/203143243): Add validation of build vs runtime values to ensure consistency.
+ JavaFile.builder(outputClassName.packageName(), classBuilder.build())
+ .build()
+ .writeTo(System.out)
+ }
+
+ /*
+ * Parses a feature argument of the form "--feature=$NAME:$VER", where "$VER" is optional.
+ * * "--feature=WATCH:0" -> Feature enabled w/ version 0 (default version when enabled)
+ * * "--feature=WATCH:7" -> Feature enabled w/ version 7
+ * * "--feature=WATCH:" -> Feature disabled
+ */
+ private fun parseFeatureArg(arg: String): FeatureInfo {
+ val featureArgs = arg.substring(FEATURE_ARG.length).split(":")
+ val name = featureArgs[0].let { if (!it.startsWith("FEATURE_")) "FEATURE_$it" else it }
+ val version = featureArgs.getOrNull(1)?.toIntOrNull()
+ return FeatureInfo(name, version)
+ }
+
+ /*
+ * Adds per-feature query methods to the class with the form:
+ * {@code public static boolean hasFeatureX(Context context)},
+ * returning the fallback value from PackageManager if not readonly.
+ */
+ private fun addFeatureMethodsToClass(
+ builder: TypeSpec.Builder,
+ readonly: Boolean,
+ features: List<FeatureInfo>
+ ) {
+ for (feature in features) {
+ // Turn "FEATURE_FOO" into "hasFeatureFoo".
+ val methodName =
+ "has" + CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, feature.name)
+ val methodBuilder =
+ MethodSpec.methodBuilder(methodName)
+ .addModifiers(Modifier.PUBLIC, Modifier.STATIC)
+ .returns(Boolean::class.java)
+ .addParameter(CONTEXT_CLASS, "context")
+
+ if (readonly) {
+ val featureEnabled = compareValues(feature.version, 0) >= 0
+ methodBuilder.addAnnotation(
+ if (featureEnabled) ASSUME_TRUE_CLASS else ASSUME_FALSE_CLASS
+ )
+ methodBuilder.addStatement("return $featureEnabled")
+ } else {
+ methodBuilder.addStatement(
+ "return hasFeatureFallback(context, \$T.\$N)",
+ PACKAGEMANAGER_CLASS,
+ feature.name
+ )
+ }
+ builder.addMethod(methodBuilder.build())
+ }
+
+ if (!readonly) {
+ builder.addMethod(
+ MethodSpec.methodBuilder("hasFeatureFallback")
+ .addModifiers(Modifier.PRIVATE, Modifier.STATIC)
+ .returns(Boolean::class.java)
+ .addParameter(CONTEXT_CLASS, "context")
+ .addParameter(String::class.java, "featureName")
+ .addStatement(
+ "return context.getPackageManager().hasSystemFeature(featureName, 0)"
+ )
+ .build()
+ )
+ }
+ }
+
+ /*
+ * Adds a generic query method to the class with the form: {@code public static boolean
+ * maybeHasFeature(String featureName, int version)}, returning null if the feature version is
+ * undefined or not readonly.
+ *
+ * This method is useful for internal usage within the framework, e.g., from the implementation
+ * of {@link android.content.pm.PackageManager#hasSystemFeature(Context)}, when we may only
+ * want a valid result if it's defined as readonly, and we want a custom fallback otherwise
+ * (e.g., to the existing runtime binder query).
+ */
+ private fun addMaybeFeatureMethodToClass(
+ builder: TypeSpec.Builder,
+ readonly: Boolean,
+ features: List<FeatureInfo>
+ ) {
+ val methodBuilder =
+ MethodSpec.methodBuilder("maybeHasFeature")
+ .addModifiers(Modifier.PUBLIC, Modifier.STATIC)
+ .addAnnotation(ClassName.get("android.annotation", "Nullable"))
+ .returns(Boolean::class.javaObjectType) // Use object type for nullability
+ .addParameter(String::class.java, "featureName")
+ .addParameter(Int::class.java, "version")
+
+ if (readonly) {
+ methodBuilder.beginControlFlow("switch (featureName)")
+ for (feature in features) {
+ methodBuilder.addCode("case \$T.\$N: ", PACKAGEMANAGER_CLASS, feature.name)
+ if (feature.version != null) {
+ methodBuilder.addStatement("return \$L >= version", feature.version)
+ } else {
+ methodBuilder.addStatement("return false")
+ }
+ }
+ methodBuilder.addCode("default: ")
+ methodBuilder.addStatement("break")
+ methodBuilder.endControlFlow()
+ }
+ methodBuilder.addStatement("return null")
+ builder.addMethod(methodBuilder.build())
+ }
+
+ private data class FeatureInfo(val name: String, val version: Int?)
+}
diff --git a/tools/systemfeatures/tests/Context.java b/tools/systemfeatures/tests/Context.java
new file mode 100644
index 000000000000..630bc0771a01
--- /dev/null
+++ b/tools/systemfeatures/tests/Context.java
@@ -0,0 +1,27 @@
+/*
+ * 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.content;
+
+import android.content.pm.PackageManager;
+
+/** Stub for testing. */
+public class Context {
+ /** @hide */
+ public PackageManager getPackageManager() {
+ return null;
+ }
+}
diff --git a/tools/systemfeatures/tests/PackageManager.java b/tools/systemfeatures/tests/PackageManager.java
new file mode 100644
index 000000000000..645d500bc762
--- /dev/null
+++ b/tools/systemfeatures/tests/PackageManager.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content.pm;
+
+/** Stub for testing */
+public class PackageManager {
+ public static final String FEATURE_AUTO = "automotive";
+ public static final String FEATURE_VULKAN = "vulkan";
+ public static final String FEATURE_WATCH = "watch";
+ public static final String FEATURE_WIFI = "wifi";
+
+ /** @hide */
+ public boolean hasSystemFeature(String featureName, int version) {
+ return false;
+ }
+}
diff --git a/tools/systemfeatures/tests/SystemFeaturesGeneratorTest.java b/tools/systemfeatures/tests/SystemFeaturesGeneratorTest.java
new file mode 100644
index 000000000000..547d2cbd26f9
--- /dev/null
+++ b/tools/systemfeatures/tests/SystemFeaturesGeneratorTest.java
@@ -0,0 +1,135 @@
+/*
+ * 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.systemfeatures;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.anyString;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+
+@RunWith(JUnit4.class)
+public class SystemFeaturesGeneratorTest {
+
+ @Rule public final MockitoRule mockito = MockitoJUnit.rule();
+
+ @Mock private Context mContext;
+ @Mock private PackageManager mPackageManager;
+
+ @Before
+ public void setUp() {
+ when(mContext.getPackageManager()).thenReturn(mPackageManager);
+ }
+
+ @Test
+ public void testReadonlyDisabledNoDefinedFeatures() {
+ // Always report null for conditional queries if readonly codegen is disabled.
+ assertThat(RwNoFeatures.maybeHasFeature(PackageManager.FEATURE_WATCH, 0)).isNull();
+ assertThat(RwNoFeatures.maybeHasFeature(PackageManager.FEATURE_WIFI, 0)).isNull();
+ assertThat(RwNoFeatures.maybeHasFeature(PackageManager.FEATURE_VULKAN, 0)).isNull();
+ assertThat(RwNoFeatures.maybeHasFeature(PackageManager.FEATURE_AUTO, 0)).isNull();
+ assertThat(RwNoFeatures.maybeHasFeature("com.arbitrary.feature", 0)).isNull();
+ }
+
+ @Test
+ public void testReadonlyNoDefinedFeatures() {
+ // If no features are explicitly declared as readonly available, always report
+ // null for conditional queries.
+ assertThat(RoNoFeatures.maybeHasFeature(PackageManager.FEATURE_WATCH, 0)).isNull();
+ assertThat(RoNoFeatures.maybeHasFeature(PackageManager.FEATURE_WIFI, 0)).isNull();
+ assertThat(RoNoFeatures.maybeHasFeature(PackageManager.FEATURE_VULKAN, 0)).isNull();
+ assertThat(RoNoFeatures.maybeHasFeature(PackageManager.FEATURE_AUTO, 0)).isNull();
+ assertThat(RoNoFeatures.maybeHasFeature("com.arbitrary.feature", 0)).isNull();
+ }
+
+ @Test
+ public void testReadonlyDisabledWithDefinedFeatures() {
+ // Always fall back to the PackageManager for defined, explicit features queries.
+ when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_WATCH, 0)).thenReturn(true);
+ assertThat(RwFeatures.hasFeatureWatch(mContext)).isTrue();
+
+ when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_WATCH, 0)).thenReturn(false);
+ assertThat(RwFeatures.hasFeatureWatch(mContext)).isFalse();
+
+ when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI, 0)).thenReturn(true);
+ assertThat(RwFeatures.hasFeatureWifi(mContext)).isTrue();
+
+ when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_VULKAN, 0)).thenReturn(false);
+ assertThat(RwFeatures.hasFeatureVulkan(mContext)).isFalse();
+
+ when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTO, 0)).thenReturn(false);
+ assertThat(RwFeatures.hasFeatureAuto(mContext)).isFalse();
+
+ // For defined and undefined features, conditional queries should report null (unknown).
+ assertThat(RwFeatures.maybeHasFeature(PackageManager.FEATURE_WATCH, 0)).isNull();
+ assertThat(RwFeatures.maybeHasFeature(PackageManager.FEATURE_WIFI, 0)).isNull();
+ assertThat(RwFeatures.maybeHasFeature(PackageManager.FEATURE_VULKAN, 0)).isNull();
+ assertThat(RwFeatures.maybeHasFeature(PackageManager.FEATURE_AUTO, 0)).isNull();
+ assertThat(RwFeatures.maybeHasFeature("com.arbitrary.feature", 0)).isNull();
+ }
+
+ @Test
+ public void testReadonlyWithDefinedFeatures() {
+ // Always use the build-time feature version for defined, explicit feature queries, never
+ // falling back to the runtime query.
+ assertThat(RoFeatures.hasFeatureWatch(mContext)).isTrue();
+ assertThat(RoFeatures.hasFeatureWifi(mContext)).isTrue();
+ assertThat(RoFeatures.hasFeatureVulkan(mContext)).isFalse();
+ assertThat(RoFeatures.hasFeatureAuto(mContext)).isFalse();
+ verify(mPackageManager, never()).hasSystemFeature(anyString(), anyInt());
+
+ // For defined feature types, conditional queries should reflect the build-time versions.
+ // VERSION=1
+ assertThat(RoFeatures.maybeHasFeature(PackageManager.FEATURE_WATCH, -1)).isTrue();
+ assertThat(RoFeatures.maybeHasFeature(PackageManager.FEATURE_WATCH, 0)).isTrue();
+ assertThat(RoFeatures.maybeHasFeature(PackageManager.FEATURE_WATCH, 100)).isFalse();
+
+ // VERSION=0
+ assertThat(RoFeatures.maybeHasFeature(PackageManager.FEATURE_WIFI, -1)).isTrue();
+ assertThat(RoFeatures.maybeHasFeature(PackageManager.FEATURE_WIFI, 0)).isTrue();
+ assertThat(RoFeatures.maybeHasFeature(PackageManager.FEATURE_WIFI, 100)).isFalse();
+
+ // VERSION=-1
+ assertThat(RoFeatures.maybeHasFeature(PackageManager.FEATURE_VULKAN, -1)).isTrue();
+ assertThat(RoFeatures.maybeHasFeature(PackageManager.FEATURE_VULKAN, 0)).isFalse();
+ assertThat(RoFeatures.maybeHasFeature(PackageManager.FEATURE_VULKAN, 100)).isFalse();
+
+ // DISABLED
+ assertThat(RoFeatures.maybeHasFeature(PackageManager.FEATURE_AUTO, -1)).isFalse();
+ assertThat(RoFeatures.maybeHasFeature(PackageManager.FEATURE_AUTO, 0)).isFalse();
+ assertThat(RoFeatures.maybeHasFeature(PackageManager.FEATURE_AUTO, 100)).isFalse();
+
+ // For undefined types, conditional queries should report null (unknown).
+ assertThat(RoFeatures.maybeHasFeature("com.arbitrary.feature", -1)).isNull();
+ assertThat(RoFeatures.maybeHasFeature("com.arbitrary.feature", 0)).isNull();
+ assertThat(RoFeatures.maybeHasFeature("com.arbitrary.feature", 100)).isNull();
+ }
+}