summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apex/jobscheduler/service/java/com/android/server/tare/Agent.java8
-rw-r--r--api/StubLibraries.bp6
-rw-r--r--core/api/Android.bp5
-rw-r--r--core/api/current.txt4
-rw-r--r--core/api/lint-baseline.txt521
-rw-r--r--core/api/module-lib-lint-baseline.txt54
-rw-r--r--core/api/system-current.txt2
-rw-r--r--core/api/system-lint-baseline.txt3140
-rw-r--r--core/java/android/hardware/radio/ProgramList.java96
-rw-r--r--core/java/android/os/UserManager.java20
-rw-r--r--core/java/android/security/FileIntegrityManager.java2
-rw-r--r--core/java/android/service/voice/HotwordTrainingAudio.java53
-rw-r--r--core/java/android/view/WindowManager.java50
-rw-r--r--core/res/AndroidManifest.xml7
-rw-r--r--core/res/res/values/config.xml4
-rw-r--r--core/tests/BroadcastRadioTests/src/android/hardware/radio/ProgramListTest.java165
-rw-r--r--core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/AidlTestUtils.java5
-rw-r--r--core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/ConversionUtilsTest.java72
-rw-r--r--core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/ProgramInfoCacheTest.java253
-rw-r--r--core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/TunerSessionTest.java246
-rw-r--r--core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/ProgramInfoCacheTest.java230
-rw-r--r--core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/StartProgramListUpdatesFanoutTest.java149
-rw-r--r--core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/TestUtils.java50
-rw-r--r--core/tests/coretests/src/android/app/activity/ActivityThreadTest.java2
-rw-r--r--data/etc/services.core.protolog.json6
-rw-r--r--graphics/java/android/graphics/Bitmap.java2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java1
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java28
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java65
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/transition/TransitionAnimationHelper.java9
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java6
-rw-r--r--media/java/android/media/MediaPlayer.java6
-rw-r--r--media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerUnitTest.java49
-rw-r--r--packages/SettingsLib/Tile/src/com/android/settingslib/drawer/TileUtils.java4
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java43
-rw-r--r--packages/SystemUI/OWNERS6
-rw-r--r--packages/SystemUI/TEST_MAPPING73
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/ribbon/ui/composable/Ribbon.kt92
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt95
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/statusbar/phone/SystemUIDialogFactoryExt.kt3
-rw-r--r--packages/SystemUI/res/layout/media_projection_app_selector.xml3
-rw-r--r--packages/SystemUI/res/values/ids.xml5
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java22
-rw-r--r--packages/SystemUI/src/com/android/systemui/display/ui/view/MirroringConfirmationDialog.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/flags/Flags.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/backlight/ui/view/KeyboardBacklightDialog.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt9
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/DefaultKeyguardBlueprint.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/ShortcutsBesideUdfpsKeyguardBlueprint.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AodNotificationIconsSection.kt106
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultLockIconSection.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultNotificationStackScrollLayoutSection.kt58
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultStatusViewSection.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/RemoteInputController.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/RemoteInputControllerLogger.kt9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialogFactory.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowController.java6
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerBaseTest.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/blueprints/DefaultKeyguardBlueprintTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java27
-rw-r--r--services/accessibility/Android.bp16
-rw-r--r--services/accessibility/accessibility.aconfig7
-rw-r--r--services/accessibility/java/com/android/server/accessibility/ProxyManager.java116
-rw-r--r--services/autofill/java/com/android/server/autofill/AutofillManagerServiceShellCommand.java32
-rw-r--r--services/core/Android.bp1
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java8
-rw-r--r--services/core/java/com/android/server/am/OomAdjuster.java4
-rw-r--r--services/core/java/com/android/server/biometrics/AuthenticationStatsCollector.java47
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/BiometricNotificationUtils.java1
-rw-r--r--services/core/java/com/android/server/broadcastradio/aidl/ConversionUtils.java35
-rw-r--r--services/core/java/com/android/server/broadcastradio/aidl/ProgramInfoCache.java161
-rw-r--r--services/core/java/com/android/server/broadcastradio/aidl/RadioModule.java7
-rw-r--r--services/core/java/com/android/server/broadcastradio/aidl/TunerSession.java3
-rw-r--r--services/core/java/com/android/server/broadcastradio/hal2/Convert.java11
-rw-r--r--services/core/java/com/android/server/broadcastradio/hal2/ProgramInfoCache.java168
-rw-r--r--services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java6
-rw-r--r--services/core/java/com/android/server/broadcastradio/hal2/TunerSession.java3
-rw-r--r--services/core/java/com/android/server/pm/DeletePackageHelper.java3
-rw-r--r--services/core/java/com/android/server/pm/PackageArchiverService.java167
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerService.java14
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerSession.java3
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerServiceUtils.java3
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerShellCommand.java98
-rw-r--r--services/core/java/com/android/server/pm/PackageSetting.java22
-rw-r--r--services/core/java/com/android/server/pm/RemovePackageHelper.java16
-rw-r--r--services/core/java/com/android/server/pm/Settings.java11
-rw-r--r--services/core/java/com/android/server/pm/pkg/ArchiveState.java25
-rw-r--r--services/core/java/com/android/server/security/FileIntegrityService.java7
-rw-r--r--services/core/java/com/android/server/wm/ActivityClientController.java4
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskManagerService.java3
-rw-r--r--services/core/java/com/android/server/wm/ContentRecorder.java13
-rw-r--r--services/core/java/com/android/server/wm/DisplayPolicy.java11
-rw-r--r--services/core/java/com/android/server/wm/InsetsPolicy.java19
-rw-r--r--services/core/java/com/android/server/wm/Session.java5
-rw-r--r--services/core/java/com/android/server/wm/Transition.java5
-rw-r--r--services/core/jni/com_android_server_input_InputManagerService.cpp5
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java7
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/pm/PackageArchiverServiceTest.java83
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/tare/AgentTest.java50
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/ProxyManagerTest.java61
-rw-r--r--services/tests/servicestests/src/com/android/server/biometrics/AuthenticationStatsCollectorTest.java31
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java18
-rw-r--r--services/tests/vibrator/src/com/android/server/vibrator/VibratorManagerServiceTest.java5
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java66
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java10
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java8
-rw-r--r--tools/aapt2/format/Archive_test.cpp110
-rw-r--r--tools/aapt2/io/File.h9
-rw-r--r--tools/aapt2/io/FileSystem.cpp20
-rw-r--r--tools/aapt2/io/FileSystem.h1
-rw-r--r--tools/aapt2/io/ZipArchive.cpp8
-rw-r--r--tools/aapt2/io/ZipArchive.h1
-rw-r--r--tools/aapt2/test/Common.h4
-rw-r--r--tools/lint/common/Android.bp27
-rw-r--r--tools/lint/common/src/main/java/com/google/android/lint/aidl/AidlImplementationDetector.kt (renamed from tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/AidlImplementationDetector.kt)0
-rw-r--r--tools/lint/common/src/main/java/com/google/android/lint/aidl/Constants.kt (renamed from tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/Constants.kt)3
-rw-r--r--tools/lint/common/src/main/java/com/google/android/lint/aidl/EnforcePermissionUtils.kt (renamed from tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionUtils.kt)0
-rw-r--r--tools/lint/fix/soong_lint_fix.py103
-rw-r--r--tools/lint/framework/Android.bp21
-rw-r--r--tools/lint/global/Android.bp21
-rw-r--r--tools/lint/utils/Android.bp45
-rw-r--r--tools/lint/utils/checks/src/main/java/com/google/android/lint/AndroidUtilsIssueRegistry.kt43
-rw-r--r--tools/lint/utils/checks/src/main/java/com/google/android/lint/aidl/AnnotatedAidlCounter.kt96
-rw-r--r--tools/lint/utils/checks/src/test/java/com/google/android/lint/aidl/AnnotatedAidlCounterTest.kt99
127 files changed, 6674 insertions, 1274 deletions
diff --git a/apex/jobscheduler/service/java/com/android/server/tare/Agent.java b/apex/jobscheduler/service/java/com/android/server/tare/Agent.java
index dcc324deaac6..5c60562398ee 100644
--- a/apex/jobscheduler/service/java/com/android/server/tare/Agent.java
+++ b/apex/jobscheduler/service/java/com/android/server/tare/Agent.java
@@ -75,7 +75,7 @@ class Agent {
private static final String ALARM_TAG_AFFORDABILITY_CHECK = "*tare.affordability_check*";
private final Object mLock;
- private final Handler mHandler;
+ private final AgentHandler mHandler;
private final Analyst mAnalyst;
private final InternalResourceService mIrs;
private final Scribe mScribe;
@@ -992,6 +992,7 @@ class Agent {
void tearDownLocked() {
mCurrentOngoingEvents.clear();
mBalanceThresholdAlarmQueue.removeAllAlarms();
+ mHandler.removeAllMessages();
}
@VisibleForTesting
@@ -1290,6 +1291,11 @@ class Agent {
break;
}
}
+
+ void removeAllMessages() {
+ removeMessages(MSG_CHECK_ALL_AFFORDABILITY);
+ removeMessages(MSG_CHECK_INDIVIDUAL_AFFORDABILITY);
+ }
}
@GuardedBy("mLock")
diff --git a/api/StubLibraries.bp b/api/StubLibraries.bp
index e481fe9971fc..2f84df70fc40 100644
--- a/api/StubLibraries.bp
+++ b/api/StubLibraries.bp
@@ -33,7 +33,7 @@ droidstubs {
"android-non-updatable-stubs-defaults",
"module-classpath-stubs-defaults",
],
- args: metalava_framework_docs_args,
+ args: metalava_framework_docs_args + "--error UnflaggedApi ",
check_api: {
current: {
api_file: ":non-updatable-current.txt",
@@ -47,6 +47,7 @@ droidstubs {
api_lint: {
enabled: true,
new_since: ":android.api.public.latest",
+ baseline_file: ":non-updatable-lint-baseline.txt",
},
},
dists: [
@@ -73,7 +74,8 @@ priv_apps_in_stubs = " --show-for-stub-purposes-annotation android.annotation.Sy
"client=android.annotation.SystemApi.Client.PRIVILEGED_APPS" +
"\\)"
-test = " --show-annotation android.annotation.TestApi"
+test = " --show-annotation android.annotation.TestApi" +
+ " --hide UnflaggedApi" // TODO(b/297362755): TestApi lint doesn't ignore existing APIs.
module_libs = " --show-annotation android.annotation.SystemApi\\(" +
"client=android.annotation.SystemApi.Client.MODULE_LIBRARIES" +
diff --git a/core/api/Android.bp b/core/api/Android.bp
index 71a2ca2903f6..907916a125da 100644
--- a/core/api/Android.bp
+++ b/core/api/Android.bp
@@ -38,6 +38,11 @@ filegroup {
}
filegroup {
+ name: "non-updatable-lint-baseline.txt",
+ srcs: ["lint-baseline.txt"],
+}
+
+filegroup {
name: "non-updatable-system-current.txt",
srcs: ["system-current.txt"],
}
diff --git a/core/api/current.txt b/core/api/current.txt
index 8de8ab895962..d92c69346efd 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -15096,7 +15096,7 @@ package android.graphics {
method public int getByteCount();
method @NonNull public android.graphics.Color getColor(int, int);
method @Nullable public android.graphics.ColorSpace getColorSpace();
- method @NonNull public android.graphics.Bitmap.Config getConfig();
+ method @Nullable public android.graphics.Bitmap.Config getConfig();
method public int getDensity();
method @Nullable public android.graphics.Gainmap getGainmap();
method public int getGenerationId();
@@ -38645,7 +38645,7 @@ package android.security {
public final class FileIntegrityManager {
method @FlaggedApi(Flags.FLAG_FSVERITY_API) @Nullable public byte[] getFsVerityDigest(@NonNull java.io.File) throws java.io.IOException;
method public boolean isApkVeritySupported();
- method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.INSTALL_PACKAGES, android.Manifest.permission.REQUEST_INSTALL_PACKAGES}) public boolean isAppSourceCertificateTrusted(@NonNull java.security.cert.X509Certificate) throws java.security.cert.CertificateEncodingException;
+ method @RequiresPermission(anyOf={android.Manifest.permission.INSTALL_PACKAGES, android.Manifest.permission.REQUEST_INSTALL_PACKAGES}) public boolean isAppSourceCertificateTrusted(@NonNull java.security.cert.X509Certificate) throws java.security.cert.CertificateEncodingException;
method @FlaggedApi(Flags.FLAG_FSVERITY_API) public void setupFsVerity(@NonNull java.io.File) throws java.io.IOException;
}
diff --git a/core/api/lint-baseline.txt b/core/api/lint-baseline.txt
new file mode 100644
index 000000000000..6b7910afc347
--- /dev/null
+++ b/core/api/lint-baseline.txt
@@ -0,0 +1,521 @@
+// Baseline format: 1.0
+UnflaggedApi: android.accessibilityservice.AccessibilityService#OVERLAY_RESULT_INTERNAL_ERROR:
+ New API must be flagged with @FlaggedApi: field android.accessibilityservice.AccessibilityService.OVERLAY_RESULT_INTERNAL_ERROR
+UnflaggedApi: android.accessibilityservice.AccessibilityService#OVERLAY_RESULT_INVALID:
+ New API must be flagged with @FlaggedApi: field android.accessibilityservice.AccessibilityService.OVERLAY_RESULT_INVALID
+UnflaggedApi: android.accessibilityservice.AccessibilityService#OVERLAY_RESULT_SUCCESS:
+ New API must be flagged with @FlaggedApi: field android.accessibilityservice.AccessibilityService.OVERLAY_RESULT_SUCCESS
+UnflaggedApi: android.accessibilityservice.AccessibilityService#attachAccessibilityOverlayToDisplay(int, android.view.SurfaceControl, java.util.concurrent.Executor, java.util.function.IntConsumer):
+ New API must be flagged with @FlaggedApi: method android.accessibilityservice.AccessibilityService.attachAccessibilityOverlayToDisplay(int,android.view.SurfaceControl,java.util.concurrent.Executor,java.util.function.IntConsumer)
+UnflaggedApi: android.accessibilityservice.AccessibilityService#attachAccessibilityOverlayToWindow(int, android.view.SurfaceControl, java.util.concurrent.Executor, java.util.function.IntConsumer):
+ New API must be flagged with @FlaggedApi: method android.accessibilityservice.AccessibilityService.attachAccessibilityOverlayToWindow(int,android.view.SurfaceControl,java.util.concurrent.Executor,java.util.function.IntConsumer)
+UnflaggedApi: android.app.Activity#onRequestPermissionsResult(int, String[], int[], int):
+ New API must be flagged with @FlaggedApi: method android.app.Activity.onRequestPermissionsResult(int,String[],int[],int)
+UnflaggedApi: android.app.Activity#requestPermissions(String[], int, int):
+ New API must be flagged with @FlaggedApi: method android.app.Activity.requestPermissions(String[],int,int)
+UnflaggedApi: android.app.Activity#setAllowCrossUidActivitySwitchFromBelow(boolean):
+ New API must be flagged with @FlaggedApi: method android.app.Activity.setAllowCrossUidActivitySwitchFromBelow(boolean)
+UnflaggedApi: android.app.Activity#shouldShowRequestPermissionRationale(String, int):
+ New API must be flagged with @FlaggedApi: method android.app.Activity.shouldShowRequestPermissionRationale(String,int)
+UnflaggedApi: android.app.ActivityManager#addStartInfoTimestamp(int, long):
+ New API must be flagged with @FlaggedApi: method android.app.ActivityManager.addStartInfoTimestamp(int,long)
+UnflaggedApi: android.app.ActivityManager#clearApplicationStartInfoCompletionListener():
+ New API must be flagged with @FlaggedApi: method android.app.ActivityManager.clearApplicationStartInfoCompletionListener()
+UnflaggedApi: android.app.ActivityManager#getHistoricalProcessStartReasons(int):
+ New API must be flagged with @FlaggedApi: method android.app.ActivityManager.getHistoricalProcessStartReasons(int)
+UnflaggedApi: android.app.ActivityManager#setApplicationStartInfoCompletionListener(java.util.concurrent.Executor, java.util.function.Consumer<android.app.ApplicationStartInfo>):
+ New API must be flagged with @FlaggedApi: method android.app.ActivityManager.setApplicationStartInfoCompletionListener(java.util.concurrent.Executor,java.util.function.Consumer<android.app.ApplicationStartInfo>)
+UnflaggedApi: android.app.ApplicationStartInfo:
+ New API must be flagged with @FlaggedApi: class android.app.ApplicationStartInfo
+UnflaggedApi: android.app.ApplicationStartInfo#CREATOR:
+ New API must be flagged with @FlaggedApi: field android.app.ApplicationStartInfo.CREATOR
+UnflaggedApi: android.app.ApplicationStartInfo#LAUNCH_MODE_SINGLE_INSTANCE:
+ New API must be flagged with @FlaggedApi: field android.app.ApplicationStartInfo.LAUNCH_MODE_SINGLE_INSTANCE
+UnflaggedApi: android.app.ApplicationStartInfo#LAUNCH_MODE_SINGLE_INSTANCE_PER_TASK:
+ New API must be flagged with @FlaggedApi: field android.app.ApplicationStartInfo.LAUNCH_MODE_SINGLE_INSTANCE_PER_TASK
+UnflaggedApi: android.app.ApplicationStartInfo#LAUNCH_MODE_SINGLE_TASK:
+ New API must be flagged with @FlaggedApi: field android.app.ApplicationStartInfo.LAUNCH_MODE_SINGLE_TASK
+UnflaggedApi: android.app.ApplicationStartInfo#LAUNCH_MODE_SINGLE_TOP:
+ New API must be flagged with @FlaggedApi: field android.app.ApplicationStartInfo.LAUNCH_MODE_SINGLE_TOP
+UnflaggedApi: android.app.ApplicationStartInfo#LAUNCH_MODE_STANDARD:
+ New API must be flagged with @FlaggedApi: field android.app.ApplicationStartInfo.LAUNCH_MODE_STANDARD
+UnflaggedApi: android.app.ApplicationStartInfo#STARTUP_STATE_ERROR:
+ New API must be flagged with @FlaggedApi: field android.app.ApplicationStartInfo.STARTUP_STATE_ERROR
+UnflaggedApi: android.app.ApplicationStartInfo#STARTUP_STATE_FIRST_FRAME_DRAWN:
+ New API must be flagged with @FlaggedApi: field android.app.ApplicationStartInfo.STARTUP_STATE_FIRST_FRAME_DRAWN
+UnflaggedApi: android.app.ApplicationStartInfo#STARTUP_STATE_STARTED:
+ New API must be flagged with @FlaggedApi: field android.app.ApplicationStartInfo.STARTUP_STATE_STARTED
+UnflaggedApi: android.app.ApplicationStartInfo#START_REASON_ALARM:
+ New API must be flagged with @FlaggedApi: field android.app.ApplicationStartInfo.START_REASON_ALARM
+UnflaggedApi: android.app.ApplicationStartInfo#START_REASON_BACKUP:
+ New API must be flagged with @FlaggedApi: field android.app.ApplicationStartInfo.START_REASON_BACKUP
+UnflaggedApi: android.app.ApplicationStartInfo#START_REASON_BOOT_COMPLETE:
+ New API must be flagged with @FlaggedApi: field android.app.ApplicationStartInfo.START_REASON_BOOT_COMPLETE
+UnflaggedApi: android.app.ApplicationStartInfo#START_REASON_BROADCAST:
+ New API must be flagged with @FlaggedApi: field android.app.ApplicationStartInfo.START_REASON_BROADCAST
+UnflaggedApi: android.app.ApplicationStartInfo#START_REASON_CONTENT_PROVIDER:
+ New API must be flagged with @FlaggedApi: field android.app.ApplicationStartInfo.START_REASON_CONTENT_PROVIDER
+UnflaggedApi: android.app.ApplicationStartInfo#START_REASON_JOB:
+ New API must be flagged with @FlaggedApi: field android.app.ApplicationStartInfo.START_REASON_JOB
+UnflaggedApi: android.app.ApplicationStartInfo#START_REASON_LAUNCHER:
+ New API must be flagged with @FlaggedApi: field android.app.ApplicationStartInfo.START_REASON_LAUNCHER
+UnflaggedApi: android.app.ApplicationStartInfo#START_REASON_LAUNCHER_RECENTS:
+ New API must be flagged with @FlaggedApi: field android.app.ApplicationStartInfo.START_REASON_LAUNCHER_RECENTS
+UnflaggedApi: android.app.ApplicationStartInfo#START_REASON_OTHER:
+ New API must be flagged with @FlaggedApi: field android.app.ApplicationStartInfo.START_REASON_OTHER
+UnflaggedApi: android.app.ApplicationStartInfo#START_REASON_PUSH:
+ New API must be flagged with @FlaggedApi: field android.app.ApplicationStartInfo.START_REASON_PUSH
+UnflaggedApi: android.app.ApplicationStartInfo#START_REASON_SERVICE:
+ New API must be flagged with @FlaggedApi: field android.app.ApplicationStartInfo.START_REASON_SERVICE
+UnflaggedApi: android.app.ApplicationStartInfo#START_REASON_START_ACTIVITY:
+ New API must be flagged with @FlaggedApi: field android.app.ApplicationStartInfo.START_REASON_START_ACTIVITY
+UnflaggedApi: android.app.ApplicationStartInfo#START_TIMESTAMP_APPLICATION_ONCREATE:
+ New API must be flagged with @FlaggedApi: field android.app.ApplicationStartInfo.START_TIMESTAMP_APPLICATION_ONCREATE
+UnflaggedApi: android.app.ApplicationStartInfo#START_TIMESTAMP_BIND_APPLICATION:
+ New API must be flagged with @FlaggedApi: field android.app.ApplicationStartInfo.START_TIMESTAMP_BIND_APPLICATION
+UnflaggedApi: android.app.ApplicationStartInfo#START_TIMESTAMP_FIRST_FRAME:
+ New API must be flagged with @FlaggedApi: field android.app.ApplicationStartInfo.START_TIMESTAMP_FIRST_FRAME
+UnflaggedApi: android.app.ApplicationStartInfo#START_TIMESTAMP_FORK:
+ New API must be flagged with @FlaggedApi: field android.app.ApplicationStartInfo.START_TIMESTAMP_FORK
+UnflaggedApi: android.app.ApplicationStartInfo#START_TIMESTAMP_FULLY_DRAWN:
+ New API must be flagged with @FlaggedApi: field android.app.ApplicationStartInfo.START_TIMESTAMP_FULLY_DRAWN
+UnflaggedApi: android.app.ApplicationStartInfo#START_TIMESTAMP_INITIAL_RENDERTHREAD_FRAME:
+ New API must be flagged with @FlaggedApi: field android.app.ApplicationStartInfo.START_TIMESTAMP_INITIAL_RENDERTHREAD_FRAME
+UnflaggedApi: android.app.ApplicationStartInfo#START_TIMESTAMP_LAUNCH:
+ New API must be flagged with @FlaggedApi: field android.app.ApplicationStartInfo.START_TIMESTAMP_LAUNCH
+UnflaggedApi: android.app.ApplicationStartInfo#START_TIMESTAMP_RESERVED_RANGE_DEVELOPER:
+ New API must be flagged with @FlaggedApi: field android.app.ApplicationStartInfo.START_TIMESTAMP_RESERVED_RANGE_DEVELOPER
+UnflaggedApi: android.app.ApplicationStartInfo#START_TIMESTAMP_RESERVED_RANGE_DEVELOPER_START:
+ New API must be flagged with @FlaggedApi: field android.app.ApplicationStartInfo.START_TIMESTAMP_RESERVED_RANGE_DEVELOPER_START
+UnflaggedApi: android.app.ApplicationStartInfo#START_TIMESTAMP_RESERVED_RANGE_SYSTEM:
+ New API must be flagged with @FlaggedApi: field android.app.ApplicationStartInfo.START_TIMESTAMP_RESERVED_RANGE_SYSTEM
+UnflaggedApi: android.app.ApplicationStartInfo#START_TIMESTAMP_SURFACEFLINGER_COMPOSITION_COMPLETE:
+ New API must be flagged with @FlaggedApi: field android.app.ApplicationStartInfo.START_TIMESTAMP_SURFACEFLINGER_COMPOSITION_COMPLETE
+UnflaggedApi: android.app.ApplicationStartInfo#START_TYPE_COLD:
+ New API must be flagged with @FlaggedApi: field android.app.ApplicationStartInfo.START_TYPE_COLD
+UnflaggedApi: android.app.ApplicationStartInfo#START_TYPE_HOT:
+ New API must be flagged with @FlaggedApi: field android.app.ApplicationStartInfo.START_TYPE_HOT
+UnflaggedApi: android.app.ApplicationStartInfo#START_TYPE_WARM:
+ New API must be flagged with @FlaggedApi: field android.app.ApplicationStartInfo.START_TYPE_WARM
+UnflaggedApi: android.app.ApplicationStartInfo#describeContents():
+ New API must be flagged with @FlaggedApi: method android.app.ApplicationStartInfo.describeContents()
+UnflaggedApi: android.app.ApplicationStartInfo#getDefiningUid():
+ New API must be flagged with @FlaggedApi: method android.app.ApplicationStartInfo.getDefiningUid()
+UnflaggedApi: android.app.ApplicationStartInfo#getIntent():
+ New API must be flagged with @FlaggedApi: method android.app.ApplicationStartInfo.getIntent()
+UnflaggedApi: android.app.ApplicationStartInfo#getLaunchMode():
+ New API must be flagged with @FlaggedApi: method android.app.ApplicationStartInfo.getLaunchMode()
+UnflaggedApi: android.app.ApplicationStartInfo#getPackageUid():
+ New API must be flagged with @FlaggedApi: method android.app.ApplicationStartInfo.getPackageUid()
+UnflaggedApi: android.app.ApplicationStartInfo#getPid():
+ New API must be flagged with @FlaggedApi: method android.app.ApplicationStartInfo.getPid()
+UnflaggedApi: android.app.ApplicationStartInfo#getProcessName():
+ New API must be flagged with @FlaggedApi: method android.app.ApplicationStartInfo.getProcessName()
+UnflaggedApi: android.app.ApplicationStartInfo#getRealUid():
+ New API must be flagged with @FlaggedApi: method android.app.ApplicationStartInfo.getRealUid()
+UnflaggedApi: android.app.ApplicationStartInfo#getReason():
+ New API must be flagged with @FlaggedApi: method android.app.ApplicationStartInfo.getReason()
+UnflaggedApi: android.app.ApplicationStartInfo#getStartType():
+ New API must be flagged with @FlaggedApi: method android.app.ApplicationStartInfo.getStartType()
+UnflaggedApi: android.app.ApplicationStartInfo#getStartupState():
+ New API must be flagged with @FlaggedApi: method android.app.ApplicationStartInfo.getStartupState()
+UnflaggedApi: android.app.ApplicationStartInfo#getStartupTimestamps():
+ New API must be flagged with @FlaggedApi: method android.app.ApplicationStartInfo.getStartupTimestamps()
+UnflaggedApi: android.app.ApplicationStartInfo#writeToParcel(android.os.Parcel, int):
+ New API must be flagged with @FlaggedApi: method android.app.ApplicationStartInfo.writeToParcel(android.os.Parcel,int)
+UnflaggedApi: android.app.Notification.TvExtender:
+ New API must be flagged with @FlaggedApi: class android.app.Notification.TvExtender
+UnflaggedApi: android.app.Notification.TvExtender#TvExtender():
+ New API must be flagged with @FlaggedApi: constructor android.app.Notification.TvExtender()
+UnflaggedApi: android.app.Notification.TvExtender#TvExtender(android.app.Notification):
+ New API must be flagged with @FlaggedApi: constructor android.app.Notification.TvExtender(android.app.Notification)
+UnflaggedApi: android.app.Notification.TvExtender#extend(android.app.Notification.Builder):
+ New API must be flagged with @FlaggedApi: method android.app.Notification.TvExtender.extend(android.app.Notification.Builder)
+UnflaggedApi: android.app.Notification.TvExtender#getChannelId():
+ New API must be flagged with @FlaggedApi: method android.app.Notification.TvExtender.getChannelId()
+UnflaggedApi: android.app.Notification.TvExtender#getContentIntent():
+ New API must be flagged with @FlaggedApi: method android.app.Notification.TvExtender.getContentIntent()
+UnflaggedApi: android.app.Notification.TvExtender#getDeleteIntent():
+ New API must be flagged with @FlaggedApi: method android.app.Notification.TvExtender.getDeleteIntent()
+UnflaggedApi: android.app.Notification.TvExtender#isAvailableOnTv():
+ New API must be flagged with @FlaggedApi: method android.app.Notification.TvExtender.isAvailableOnTv()
+UnflaggedApi: android.app.Notification.TvExtender#isSuppressShowOverApps():
+ New API must be flagged with @FlaggedApi: method android.app.Notification.TvExtender.isSuppressShowOverApps()
+UnflaggedApi: android.app.Notification.TvExtender#setChannelId(String):
+ New API must be flagged with @FlaggedApi: method android.app.Notification.TvExtender.setChannelId(String)
+UnflaggedApi: android.app.Notification.TvExtender#setContentIntent(android.app.PendingIntent):
+ New API must be flagged with @FlaggedApi: method android.app.Notification.TvExtender.setContentIntent(android.app.PendingIntent)
+UnflaggedApi: android.app.Notification.TvExtender#setDeleteIntent(android.app.PendingIntent):
+ New API must be flagged with @FlaggedApi: method android.app.Notification.TvExtender.setDeleteIntent(android.app.PendingIntent)
+UnflaggedApi: android.app.Notification.TvExtender#setSuppressShowOverApps(boolean):
+ New API must be flagged with @FlaggedApi: method android.app.Notification.TvExtender.setSuppressShowOverApps(boolean)
+UnflaggedApi: android.companion.AssociationInfo#getTag():
+ New API must be flagged with @FlaggedApi: method android.companion.AssociationInfo.getTag()
+UnflaggedApi: android.companion.CompanionDeviceManager#clearAssociationTag(int):
+ New API must be flagged with @FlaggedApi: method android.companion.CompanionDeviceManager.clearAssociationTag(int)
+UnflaggedApi: android.companion.CompanionDeviceManager#setAssociationTag(int, String):
+ New API must be flagged with @FlaggedApi: method android.companion.CompanionDeviceManager.setAssociationTag(int,String)
+UnflaggedApi: android.companion.CompanionDeviceService#DEVICE_EVENT_BLE_APPEARED:
+ New API must be flagged with @FlaggedApi: field android.companion.CompanionDeviceService.DEVICE_EVENT_BLE_APPEARED
+UnflaggedApi: android.companion.CompanionDeviceService#DEVICE_EVENT_BLE_DISAPPEARED:
+ New API must be flagged with @FlaggedApi: field android.companion.CompanionDeviceService.DEVICE_EVENT_BLE_DISAPPEARED
+UnflaggedApi: android.companion.CompanionDeviceService#DEVICE_EVENT_BT_CONNECTED:
+ New API must be flagged with @FlaggedApi: field android.companion.CompanionDeviceService.DEVICE_EVENT_BT_CONNECTED
+UnflaggedApi: android.companion.CompanionDeviceService#DEVICE_EVENT_BT_DISCONNECTED:
+ New API must be flagged with @FlaggedApi: field android.companion.CompanionDeviceService.DEVICE_EVENT_BT_DISCONNECTED
+UnflaggedApi: android.companion.CompanionDeviceService#DEVICE_EVENT_SELF_MANAGED_APPEARED:
+ New API must be flagged with @FlaggedApi: field android.companion.CompanionDeviceService.DEVICE_EVENT_SELF_MANAGED_APPEARED
+UnflaggedApi: android.companion.CompanionDeviceService#DEVICE_EVENT_SELF_MANAGED_DISAPPEARED:
+ New API must be flagged with @FlaggedApi: field android.companion.CompanionDeviceService.DEVICE_EVENT_SELF_MANAGED_DISAPPEARED
+UnflaggedApi: android.companion.CompanionDeviceService#onDeviceEvent(android.companion.AssociationInfo, int):
+ New API must be flagged with @FlaggedApi: method android.companion.CompanionDeviceService.onDeviceEvent(android.companion.AssociationInfo,int)
+UnflaggedApi: android.companion.virtual.VirtualDevice#getPersistentDeviceId():
+ New API must be flagged with @FlaggedApi: method android.companion.virtual.VirtualDevice.getPersistentDeviceId()
+UnflaggedApi: android.companion.virtual.VirtualDeviceManager.VirtualDeviceListener#onVirtualDeviceClosed(int):
+ New API must be flagged with @FlaggedApi: method android.companion.virtual.VirtualDeviceManager.VirtualDeviceListener.onVirtualDeviceClosed(int)
+UnflaggedApi: android.companion.virtual.VirtualDeviceManager.VirtualDeviceListener#onVirtualDeviceCreated(int):
+ New API must be flagged with @FlaggedApi: method android.companion.virtual.VirtualDeviceManager.VirtualDeviceListener.onVirtualDeviceCreated(int)
+UnflaggedApi: android.content.AttributionSource#getDeviceId():
+ New API must be flagged with @FlaggedApi: method android.content.AttributionSource.getDeviceId()
+UnflaggedApi: android.content.AttributionSource.Builder#setDeviceId(int):
+ New API must be flagged with @FlaggedApi: method android.content.AttributionSource.Builder.setDeviceId(int)
+UnflaggedApi: android.content.AttributionSource.Builder#setNextAttributionSource(android.content.AttributionSource):
+ New API must be flagged with @FlaggedApi: method android.content.AttributionSource.Builder.setNextAttributionSource(android.content.AttributionSource)
+UnflaggedApi: android.content.ContextParams#shouldRegisterAttributionSource():
+ New API must be flagged with @FlaggedApi: method android.content.ContextParams.shouldRegisterAttributionSource()
+UnflaggedApi: android.content.ContextParams.Builder#setShouldRegisterAttributionSource(boolean):
+ New API must be flagged with @FlaggedApi: method android.content.ContextParams.Builder.setShouldRegisterAttributionSource(boolean)
+UnflaggedApi: android.content.Intent#EXTRA_ARCHIVAL:
+ New API must be flagged with @FlaggedApi: field android.content.Intent.EXTRA_ARCHIVAL
+UnflaggedApi: android.content.om.FabricatedOverlay#setResourceValue(String, android.content.res.AssetFileDescriptor, String):
+ New API must be flagged with @FlaggedApi: method android.content.om.FabricatedOverlay.setResourceValue(String,android.content.res.AssetFileDescriptor,String)
+UnflaggedApi: android.content.pm.PackageManager#FEATURE_THREAD_NETWORK:
+ New API must be flagged with @FlaggedApi: field android.content.pm.PackageManager.FEATURE_THREAD_NETWORK
+UnflaggedApi: android.database.sqlite.SQLiteDatabase#beginTransactionReadOnly():
+ New API must be flagged with @FlaggedApi: method android.database.sqlite.SQLiteDatabase.beginTransactionReadOnly()
+UnflaggedApi: android.database.sqlite.SQLiteDatabase#beginTransactionWithListenerReadOnly(android.database.sqlite.SQLiteTransactionListener):
+ New API must be flagged with @FlaggedApi: method android.database.sqlite.SQLiteDatabase.beginTransactionWithListenerReadOnly(android.database.sqlite.SQLiteTransactionListener)
+UnflaggedApi: android.database.sqlite.SQLiteDatabase#createRawStatement(String):
+ New API must be flagged with @FlaggedApi: method android.database.sqlite.SQLiteDatabase.createRawStatement(String)
+UnflaggedApi: android.database.sqlite.SQLiteDatabase#getLastChangedRowCount():
+ New API must be flagged with @FlaggedApi: method android.database.sqlite.SQLiteDatabase.getLastChangedRowCount()
+UnflaggedApi: android.database.sqlite.SQLiteDatabase#getLastInsertRowId():
+ New API must be flagged with @FlaggedApi: method android.database.sqlite.SQLiteDatabase.getLastInsertRowId()
+UnflaggedApi: android.database.sqlite.SQLiteDatabase#getTotalChangedRowCount():
+ New API must be flagged with @FlaggedApi: method android.database.sqlite.SQLiteDatabase.getTotalChangedRowCount()
+UnflaggedApi: android.database.sqlite.SQLiteRawStatement:
+ New API must be flagged with @FlaggedApi: class android.database.sqlite.SQLiteRawStatement
+UnflaggedApi: android.database.sqlite.SQLiteRawStatement#SQLITE_DATA_TYPE_BLOB:
+ New API must be flagged with @FlaggedApi: field android.database.sqlite.SQLiteRawStatement.SQLITE_DATA_TYPE_BLOB
+UnflaggedApi: android.database.sqlite.SQLiteRawStatement#SQLITE_DATA_TYPE_FLOAT:
+ New API must be flagged with @FlaggedApi: field android.database.sqlite.SQLiteRawStatement.SQLITE_DATA_TYPE_FLOAT
+UnflaggedApi: android.database.sqlite.SQLiteRawStatement#SQLITE_DATA_TYPE_INTEGER:
+ New API must be flagged with @FlaggedApi: field android.database.sqlite.SQLiteRawStatement.SQLITE_DATA_TYPE_INTEGER
+UnflaggedApi: android.database.sqlite.SQLiteRawStatement#SQLITE_DATA_TYPE_NULL:
+ New API must be flagged with @FlaggedApi: field android.database.sqlite.SQLiteRawStatement.SQLITE_DATA_TYPE_NULL
+UnflaggedApi: android.database.sqlite.SQLiteRawStatement#SQLITE_DATA_TYPE_TEXT:
+ New API must be flagged with @FlaggedApi: field android.database.sqlite.SQLiteRawStatement.SQLITE_DATA_TYPE_TEXT
+UnflaggedApi: android.database.sqlite.SQLiteRawStatement#bindBlob(int, byte[]):
+ New API must be flagged with @FlaggedApi: method android.database.sqlite.SQLiteRawStatement.bindBlob(int,byte[])
+UnflaggedApi: android.database.sqlite.SQLiteRawStatement#bindBlob(int, byte[], int, int):
+ New API must be flagged with @FlaggedApi: method android.database.sqlite.SQLiteRawStatement.bindBlob(int,byte[],int,int)
+UnflaggedApi: android.database.sqlite.SQLiteRawStatement#bindDouble(int, double):
+ New API must be flagged with @FlaggedApi: method android.database.sqlite.SQLiteRawStatement.bindDouble(int,double)
+UnflaggedApi: android.database.sqlite.SQLiteRawStatement#bindInt(int, int):
+ New API must be flagged with @FlaggedApi: method android.database.sqlite.SQLiteRawStatement.bindInt(int,int)
+UnflaggedApi: android.database.sqlite.SQLiteRawStatement#bindLong(int, long):
+ New API must be flagged with @FlaggedApi: method android.database.sqlite.SQLiteRawStatement.bindLong(int,long)
+UnflaggedApi: android.database.sqlite.SQLiteRawStatement#bindNull(int):
+ New API must be flagged with @FlaggedApi: method android.database.sqlite.SQLiteRawStatement.bindNull(int)
+UnflaggedApi: android.database.sqlite.SQLiteRawStatement#bindText(int, String):
+ New API must be flagged with @FlaggedApi: method android.database.sqlite.SQLiteRawStatement.bindText(int,String)
+UnflaggedApi: android.database.sqlite.SQLiteRawStatement#clearBindings():
+ New API must be flagged with @FlaggedApi: method android.database.sqlite.SQLiteRawStatement.clearBindings()
+UnflaggedApi: android.database.sqlite.SQLiteRawStatement#close():
+ New API must be flagged with @FlaggedApi: method android.database.sqlite.SQLiteRawStatement.close()
+UnflaggedApi: android.database.sqlite.SQLiteRawStatement#getColumnBlob(int):
+ New API must be flagged with @FlaggedApi: method android.database.sqlite.SQLiteRawStatement.getColumnBlob(int)
+UnflaggedApi: android.database.sqlite.SQLiteRawStatement#getColumnDouble(int):
+ New API must be flagged with @FlaggedApi: method android.database.sqlite.SQLiteRawStatement.getColumnDouble(int)
+UnflaggedApi: android.database.sqlite.SQLiteRawStatement#getColumnInt(int):
+ New API must be flagged with @FlaggedApi: method android.database.sqlite.SQLiteRawStatement.getColumnInt(int)
+UnflaggedApi: android.database.sqlite.SQLiteRawStatement#getColumnLength(int):
+ New API must be flagged with @FlaggedApi: method android.database.sqlite.SQLiteRawStatement.getColumnLength(int)
+UnflaggedApi: android.database.sqlite.SQLiteRawStatement#getColumnLong(int):
+ New API must be flagged with @FlaggedApi: method android.database.sqlite.SQLiteRawStatement.getColumnLong(int)
+UnflaggedApi: android.database.sqlite.SQLiteRawStatement#getColumnName(int):
+ New API must be flagged with @FlaggedApi: method android.database.sqlite.SQLiteRawStatement.getColumnName(int)
+UnflaggedApi: android.database.sqlite.SQLiteRawStatement#getColumnText(int):
+ New API must be flagged with @FlaggedApi: method android.database.sqlite.SQLiteRawStatement.getColumnText(int)
+UnflaggedApi: android.database.sqlite.SQLiteRawStatement#getColumnType(int):
+ New API must be flagged with @FlaggedApi: method android.database.sqlite.SQLiteRawStatement.getColumnType(int)
+UnflaggedApi: android.database.sqlite.SQLiteRawStatement#getParameterCount():
+ New API must be flagged with @FlaggedApi: method android.database.sqlite.SQLiteRawStatement.getParameterCount()
+UnflaggedApi: android.database.sqlite.SQLiteRawStatement#getParameterIndex(String):
+ New API must be flagged with @FlaggedApi: method android.database.sqlite.SQLiteRawStatement.getParameterIndex(String)
+UnflaggedApi: android.database.sqlite.SQLiteRawStatement#getParameterName(int):
+ New API must be flagged with @FlaggedApi: method android.database.sqlite.SQLiteRawStatement.getParameterName(int)
+UnflaggedApi: android.database.sqlite.SQLiteRawStatement#getResultColumnCount():
+ New API must be flagged with @FlaggedApi: method android.database.sqlite.SQLiteRawStatement.getResultColumnCount()
+UnflaggedApi: android.database.sqlite.SQLiteRawStatement#isOpen():
+ New API must be flagged with @FlaggedApi: method android.database.sqlite.SQLiteRawStatement.isOpen()
+UnflaggedApi: android.database.sqlite.SQLiteRawStatement#readColumnBlob(int, byte[], int, int, int):
+ New API must be flagged with @FlaggedApi: method android.database.sqlite.SQLiteRawStatement.readColumnBlob(int,byte[],int,int,int)
+UnflaggedApi: android.database.sqlite.SQLiteRawStatement#reset():
+ New API must be flagged with @FlaggedApi: method android.database.sqlite.SQLiteRawStatement.reset()
+UnflaggedApi: android.database.sqlite.SQLiteRawStatement#step():
+ New API must be flagged with @FlaggedApi: method android.database.sqlite.SQLiteRawStatement.step()
+UnflaggedApi: android.database.sqlite.SQLiteRawStatement#toString():
+ New API must be flagged with @FlaggedApi: method android.database.sqlite.SQLiteRawStatement.toString()
+UnflaggedApi: android.graphics.Gainmap#Gainmap(android.graphics.Gainmap, android.graphics.Bitmap):
+ New API must be flagged with @FlaggedApi: constructor android.graphics.Gainmap(android.graphics.Gainmap,android.graphics.Bitmap)
+UnflaggedApi: android.graphics.Path#computeBounds(android.graphics.RectF):
+ New API must be flagged with @FlaggedApi: method android.graphics.Path.computeBounds(android.graphics.RectF)
+UnflaggedApi: android.graphics.fonts.FontFamily.Builder#buildVariableFamily():
+ New API must be flagged with @FlaggedApi: method android.graphics.fonts.FontFamily.Builder.buildVariableFamily()
+UnflaggedApi: android.graphics.text.LineBreakConfig#LINE_BREAK_STYLE_UNSPECIFIED:
+ New API must be flagged with @FlaggedApi: field android.graphics.text.LineBreakConfig.LINE_BREAK_STYLE_UNSPECIFIED
+UnflaggedApi: android.graphics.text.LineBreakConfig#LINE_BREAK_WORD_STYLE_UNSPECIFIED:
+ New API must be flagged with @FlaggedApi: field android.graphics.text.LineBreakConfig.LINE_BREAK_WORD_STYLE_UNSPECIFIED
+UnflaggedApi: android.graphics.text.LineBreakConfig#merge(android.graphics.text.LineBreakConfig):
+ New API must be flagged with @FlaggedApi: method android.graphics.text.LineBreakConfig.merge(android.graphics.text.LineBreakConfig)
+UnflaggedApi: android.graphics.text.LineBreakConfig.Builder#merge(android.graphics.text.LineBreakConfig):
+ New API must be flagged with @FlaggedApi: method android.graphics.text.LineBreakConfig.Builder.merge(android.graphics.text.LineBreakConfig)
+UnflaggedApi: android.graphics.text.LineBreaker.Builder#setUseBoundsForWidth(boolean):
+ New API must be flagged with @FlaggedApi: method android.graphics.text.LineBreaker.Builder.setUseBoundsForWidth(boolean)
+UnflaggedApi: android.graphics.text.PositionedGlyphs#NO_OVERRIDE:
+ New API must be flagged with @FlaggedApi: field android.graphics.text.PositionedGlyphs.NO_OVERRIDE
+UnflaggedApi: android.graphics.text.PositionedGlyphs#getFakeBold(int):
+ New API must be flagged with @FlaggedApi: method android.graphics.text.PositionedGlyphs.getFakeBold(int)
+UnflaggedApi: android.graphics.text.PositionedGlyphs#getFakeItalic(int):
+ New API must be flagged with @FlaggedApi: method android.graphics.text.PositionedGlyphs.getFakeItalic(int)
+UnflaggedApi: android.graphics.text.PositionedGlyphs#getItalicOverride(int):
+ New API must be flagged with @FlaggedApi: method android.graphics.text.PositionedGlyphs.getItalicOverride(int)
+UnflaggedApi: android.graphics.text.PositionedGlyphs#getWeightOverride(int):
+ New API must be flagged with @FlaggedApi: method android.graphics.text.PositionedGlyphs.getWeightOverride(int)
+UnflaggedApi: android.media.MediaRoute2Info#TYPE_REMOTE_CAR:
+ New API must be flagged with @FlaggedApi: field android.media.MediaRoute2Info.TYPE_REMOTE_CAR
+UnflaggedApi: android.media.MediaRoute2Info#TYPE_REMOTE_COMPUTER:
+ New API must be flagged with @FlaggedApi: field android.media.MediaRoute2Info.TYPE_REMOTE_COMPUTER
+UnflaggedApi: android.media.MediaRoute2Info#TYPE_REMOTE_GAME_CONSOLE:
+ New API must be flagged with @FlaggedApi: field android.media.MediaRoute2Info.TYPE_REMOTE_GAME_CONSOLE
+UnflaggedApi: android.media.MediaRoute2Info#TYPE_REMOTE_SMARTPHONE:
+ New API must be flagged with @FlaggedApi: field android.media.MediaRoute2Info.TYPE_REMOTE_SMARTPHONE
+UnflaggedApi: android.media.MediaRoute2Info#TYPE_REMOTE_SMARTWATCH:
+ New API must be flagged with @FlaggedApi: field android.media.MediaRoute2Info.TYPE_REMOTE_SMARTWATCH
+UnflaggedApi: android.media.MediaRoute2Info#TYPE_REMOTE_TABLET:
+ New API must be flagged with @FlaggedApi: field android.media.MediaRoute2Info.TYPE_REMOTE_TABLET
+UnflaggedApi: android.media.MediaRoute2Info#TYPE_REMOTE_TABLET_DOCKED:
+ New API must be flagged with @FlaggedApi: field android.media.MediaRoute2Info.TYPE_REMOTE_TABLET_DOCKED
+UnflaggedApi: android.media.midi.MidiUmpDeviceService:
+ New API must be flagged with @FlaggedApi: class android.media.midi.MidiUmpDeviceService
+UnflaggedApi: android.media.midi.MidiUmpDeviceService#MidiUmpDeviceService():
+ New API must be flagged with @FlaggedApi: constructor android.media.midi.MidiUmpDeviceService()
+UnflaggedApi: android.media.midi.MidiUmpDeviceService#SERVICE_INTERFACE:
+ New API must be flagged with @FlaggedApi: field android.media.midi.MidiUmpDeviceService.SERVICE_INTERFACE
+UnflaggedApi: android.media.midi.MidiUmpDeviceService#getDeviceInfo():
+ New API must be flagged with @FlaggedApi: method android.media.midi.MidiUmpDeviceService.getDeviceInfo()
+UnflaggedApi: android.media.midi.MidiUmpDeviceService#getOutputPortReceivers():
+ New API must be flagged with @FlaggedApi: method android.media.midi.MidiUmpDeviceService.getOutputPortReceivers()
+UnflaggedApi: android.media.midi.MidiUmpDeviceService#onBind(android.content.Intent):
+ New API must be flagged with @FlaggedApi: method android.media.midi.MidiUmpDeviceService.onBind(android.content.Intent)
+UnflaggedApi: android.media.midi.MidiUmpDeviceService#onClose():
+ New API must be flagged with @FlaggedApi: method android.media.midi.MidiUmpDeviceService.onClose()
+UnflaggedApi: android.media.midi.MidiUmpDeviceService#onCreate():
+ New API must be flagged with @FlaggedApi: method android.media.midi.MidiUmpDeviceService.onCreate()
+UnflaggedApi: android.media.midi.MidiUmpDeviceService#onDeviceStatusChanged(android.media.midi.MidiDeviceStatus):
+ New API must be flagged with @FlaggedApi: method android.media.midi.MidiUmpDeviceService.onDeviceStatusChanged(android.media.midi.MidiDeviceStatus)
+UnflaggedApi: android.media.midi.MidiUmpDeviceService#onGetInputPortReceivers():
+ New API must be flagged with @FlaggedApi: method android.media.midi.MidiUmpDeviceService.onGetInputPortReceivers()
+UnflaggedApi: android.os.Build.VERSION_CODES#VANILLA_ICE_CREAM:
+ New API must be flagged with @FlaggedApi: field android.os.Build.VERSION_CODES.VANILLA_ICE_CREAM
+UnflaggedApi: android.os.PerformanceHintManager.Session#setPreferPowerEfficiency(boolean):
+ New API must be flagged with @FlaggedApi: method android.os.PerformanceHintManager.Session.setPreferPowerEfficiency(boolean)
+UnflaggedApi: android.os.UserManager#DISALLOW_NEAR_FIELD_COMMUNICATION_RADIO:
+ New API must be flagged with @FlaggedApi: field android.os.UserManager.DISALLOW_NEAR_FIELD_COMMUNICATION_RADIO
+UnflaggedApi: android.provider.Settings#ACTION_CREDENTIAL_PROVIDER:
+ New API must be flagged with @FlaggedApi: field android.provider.Settings.ACTION_CREDENTIAL_PROVIDER
+UnflaggedApi: android.telecom.Call.Details#PROPERTY_IS_TRANSACTIONAL:
+ New API must be flagged with @FlaggedApi: field android.telecom.Call.Details.PROPERTY_IS_TRANSACTIONAL
+UnflaggedApi: android.telecom.Call.Details#getId():
+ New API must be flagged with @FlaggedApi: method android.telecom.Call.Details.getId()
+UnflaggedApi: android.telephony.CarrierConfigManager#KEY_CARRIER_SUPPORTED_SATELLITE_SERVICES_PER_PROVIDER_BUNDLE:
+ New API must be flagged with @FlaggedApi: field android.telephony.CarrierConfigManager.KEY_CARRIER_SUPPORTED_SATELLITE_SERVICES_PER_PROVIDER_BUNDLE
+UnflaggedApi: android.telephony.DisconnectCause#SATELLITE_ENABLED:
+ New API must be flagged with @FlaggedApi: field android.telephony.DisconnectCause.SATELLITE_ENABLED
+UnflaggedApi: android.telephony.NetworkRegistrationInfo#SERVICE_TYPE_MMS:
+ New API must be flagged with @FlaggedApi: field android.telephony.NetworkRegistrationInfo.SERVICE_TYPE_MMS
+UnflaggedApi: android.telephony.NetworkRegistrationInfo#isNonTerrestrialNetwork():
+ New API must be flagged with @FlaggedApi: method android.telephony.NetworkRegistrationInfo.isNonTerrestrialNetwork()
+UnflaggedApi: android.telephony.PhoneNumberUtils#isWpsCallNumber(String):
+ New API must be flagged with @FlaggedApi: method android.telephony.PhoneNumberUtils.isWpsCallNumber(String)
+UnflaggedApi: android.telephony.ServiceState#isUsingNonTerrestrialNetwork():
+ New API must be flagged with @FlaggedApi: method android.telephony.ServiceState.isUsingNonTerrestrialNetwork()
+UnflaggedApi: android.telephony.TelephonyManager#EVENT_DISPLAY_SOS_MESSAGE:
+ New API must be flagged with @FlaggedApi: field android.telephony.TelephonyManager.EVENT_DISPLAY_SOS_MESSAGE
+UnflaggedApi: android.telephony.TelephonyManager#PURCHASE_PREMIUM_CAPABILITY_RESULT_USER_DISABLED:
+ New API must be flagged with @FlaggedApi: field android.telephony.TelephonyManager.PURCHASE_PREMIUM_CAPABILITY_RESULT_USER_DISABLED
+UnflaggedApi: android.text.BoringLayout#computeDrawingBoundingBox():
+ New API must be flagged with @FlaggedApi: method android.text.BoringLayout.computeDrawingBoundingBox()
+UnflaggedApi: android.text.BoringLayout.Metrics#getDrawingBoundingBox():
+ New API must be flagged with @FlaggedApi: method android.text.BoringLayout.Metrics.getDrawingBoundingBox()
+UnflaggedApi: android.text.DynamicLayout#getLineBreakConfig():
+ New API must be flagged with @FlaggedApi: method android.text.DynamicLayout.getLineBreakConfig()
+UnflaggedApi: android.text.DynamicLayout.Builder#setLineBreakConfig(android.graphics.text.LineBreakConfig):
+ New API must be flagged with @FlaggedApi: method android.text.DynamicLayout.Builder.setLineBreakConfig(android.graphics.text.LineBreakConfig)
+UnflaggedApi: android.text.DynamicLayout.Builder#setUseBoundsForWidth(boolean):
+ New API must be flagged with @FlaggedApi: method android.text.DynamicLayout.Builder.setUseBoundsForWidth(boolean)
+UnflaggedApi: android.text.Layout#computeDrawingBoundingBox():
+ New API must be flagged with @FlaggedApi: method android.text.Layout.computeDrawingBoundingBox()
+UnflaggedApi: android.text.Layout#getBreakStrategy():
+ New API must be flagged with @FlaggedApi: method android.text.Layout.getBreakStrategy()
+UnflaggedApi: android.text.Layout#getEllipsize():
+ New API must be flagged with @FlaggedApi: method android.text.Layout.getEllipsize()
+UnflaggedApi: android.text.Layout#getHyphenationFrequency():
+ New API must be flagged with @FlaggedApi: method android.text.Layout.getHyphenationFrequency()
+UnflaggedApi: android.text.Layout#getJustificationMode():
+ New API must be flagged with @FlaggedApi: method android.text.Layout.getJustificationMode()
+UnflaggedApi: android.text.Layout#getLeftIndents():
+ New API must be flagged with @FlaggedApi: method android.text.Layout.getLeftIndents()
+UnflaggedApi: android.text.Layout#getLineBreakConfig():
+ New API must be flagged with @FlaggedApi: method android.text.Layout.getLineBreakConfig()
+UnflaggedApi: android.text.Layout#getLineSpacingAmount():
+ New API must be flagged with @FlaggedApi: method android.text.Layout.getLineSpacingAmount()
+UnflaggedApi: android.text.Layout#getLineSpacingMultiplier():
+ New API must be flagged with @FlaggedApi: method android.text.Layout.getLineSpacingMultiplier()
+UnflaggedApi: android.text.Layout#getMaxLines():
+ New API must be flagged with @FlaggedApi: method android.text.Layout.getMaxLines()
+UnflaggedApi: android.text.Layout#getRightIndents():
+ New API must be flagged with @FlaggedApi: method android.text.Layout.getRightIndents()
+UnflaggedApi: android.text.Layout#getTextDirectionHeuristic():
+ New API must be flagged with @FlaggedApi: method android.text.Layout.getTextDirectionHeuristic()
+UnflaggedApi: android.text.Layout#getUseBoundsForWidth():
+ New API must be flagged with @FlaggedApi: method android.text.Layout.getUseBoundsForWidth()
+UnflaggedApi: android.text.Layout#isFontPaddingIncluded():
+ New API must be flagged with @FlaggedApi: method android.text.Layout.isFontPaddingIncluded()
+UnflaggedApi: android.text.Layout.Builder:
+ New API must be flagged with @FlaggedApi: class android.text.Layout.Builder
+UnflaggedApi: android.text.Layout.Builder#Builder(CharSequence, int, int, android.text.TextPaint, int):
+ New API must be flagged with @FlaggedApi: constructor android.text.Layout.Builder(CharSequence,int,int,android.text.TextPaint,int)
+UnflaggedApi: android.text.Layout.Builder#build():
+ New API must be flagged with @FlaggedApi: method android.text.Layout.Builder.build()
+UnflaggedApi: android.text.Layout.Builder#setAlignment(android.text.Layout.Alignment):
+ New API must be flagged with @FlaggedApi: method android.text.Layout.Builder.setAlignment(android.text.Layout.Alignment)
+UnflaggedApi: android.text.Layout.Builder#setBreakStrategy(int):
+ New API must be flagged with @FlaggedApi: method android.text.Layout.Builder.setBreakStrategy(int)
+UnflaggedApi: android.text.Layout.Builder#setEllipsize(android.text.TextUtils.TruncateAt):
+ New API must be flagged with @FlaggedApi: method android.text.Layout.Builder.setEllipsize(android.text.TextUtils.TruncateAt)
+UnflaggedApi: android.text.Layout.Builder#setEllipsizedWidth(int):
+ New API must be flagged with @FlaggedApi: method android.text.Layout.Builder.setEllipsizedWidth(int)
+UnflaggedApi: android.text.Layout.Builder#setFallbackLineSpacingEnabled(boolean):
+ New API must be flagged with @FlaggedApi: method android.text.Layout.Builder.setFallbackLineSpacingEnabled(boolean)
+UnflaggedApi: android.text.Layout.Builder#setFontPaddingIncluded(boolean):
+ New API must be flagged with @FlaggedApi: method android.text.Layout.Builder.setFontPaddingIncluded(boolean)
+UnflaggedApi: android.text.Layout.Builder#setHyphenationFrequency(int):
+ New API must be flagged with @FlaggedApi: method android.text.Layout.Builder.setHyphenationFrequency(int)
+UnflaggedApi: android.text.Layout.Builder#setJustificationMode(int):
+ New API must be flagged with @FlaggedApi: method android.text.Layout.Builder.setJustificationMode(int)
+UnflaggedApi: android.text.Layout.Builder#setLeftIndents(int[]):
+ New API must be flagged with @FlaggedApi: method android.text.Layout.Builder.setLeftIndents(int[])
+UnflaggedApi: android.text.Layout.Builder#setLineBreakConfig(android.graphics.text.LineBreakConfig):
+ New API must be flagged with @FlaggedApi: method android.text.Layout.Builder.setLineBreakConfig(android.graphics.text.LineBreakConfig)
+UnflaggedApi: android.text.Layout.Builder#setLineSpacingAmount(float):
+ New API must be flagged with @FlaggedApi: method android.text.Layout.Builder.setLineSpacingAmount(float)
+UnflaggedApi: android.text.Layout.Builder#setLineSpacingMultiplier(float):
+ New API must be flagged with @FlaggedApi: method android.text.Layout.Builder.setLineSpacingMultiplier(float)
+UnflaggedApi: android.text.Layout.Builder#setMaxLines(int):
+ New API must be flagged with @FlaggedApi: method android.text.Layout.Builder.setMaxLines(int)
+UnflaggedApi: android.text.Layout.Builder#setRightIndents(int[]):
+ New API must be flagged with @FlaggedApi: method android.text.Layout.Builder.setRightIndents(int[])
+UnflaggedApi: android.text.Layout.Builder#setTextDirectionHeuristic(android.text.TextDirectionHeuristic):
+ New API must be flagged with @FlaggedApi: method android.text.Layout.Builder.setTextDirectionHeuristic(android.text.TextDirectionHeuristic)
+UnflaggedApi: android.text.Layout.Builder#setUseBoundsForWidth(boolean):
+ New API must be flagged with @FlaggedApi: method android.text.Layout.Builder.setUseBoundsForWidth(boolean)
+UnflaggedApi: android.text.StaticLayout#computeDrawingBoundingBox():
+ New API must be flagged with @FlaggedApi: method android.text.StaticLayout.computeDrawingBoundingBox()
+UnflaggedApi: android.text.StaticLayout.Builder#setUseBoundsForWidth(boolean):
+ New API must be flagged with @FlaggedApi: method android.text.StaticLayout.Builder.setUseBoundsForWidth(boolean)
+UnflaggedApi: android.text.style.LineBreakConfigSpan:
+ New API must be flagged with @FlaggedApi: class android.text.style.LineBreakConfigSpan
+UnflaggedApi: android.text.style.LineBreakConfigSpan#LineBreakConfigSpan(android.graphics.text.LineBreakConfig):
+ New API must be flagged with @FlaggedApi: constructor android.text.style.LineBreakConfigSpan(android.graphics.text.LineBreakConfig)
+UnflaggedApi: android.text.style.LineBreakConfigSpan#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.text.style.LineBreakConfigSpan.equals(Object)
+UnflaggedApi: android.text.style.LineBreakConfigSpan#getLineBreakConfig():
+ New API must be flagged with @FlaggedApi: method android.text.style.LineBreakConfigSpan.getLineBreakConfig()
+UnflaggedApi: android.text.style.LineBreakConfigSpan#hashCode():
+ New API must be flagged with @FlaggedApi: method android.text.style.LineBreakConfigSpan.hashCode()
+UnflaggedApi: android.text.style.LineBreakConfigSpan#toString():
+ New API must be flagged with @FlaggedApi: method android.text.style.LineBreakConfigSpan.toString()
+UnflaggedApi: android.view.HapticScrollFeedbackProvider#HapticScrollFeedbackProvider(android.view.View):
+ New API must be flagged with @FlaggedApi: constructor android.view.HapticScrollFeedbackProvider(android.view.View)
+UnflaggedApi: android.view.HapticScrollFeedbackProvider#onScrollLimit(int, int, int, boolean):
+ New API must be flagged with @FlaggedApi: method android.view.HapticScrollFeedbackProvider.onScrollLimit(int,int,int,boolean)
+UnflaggedApi: android.view.HapticScrollFeedbackProvider#onScrollProgress(int, int, int, int):
+ New API must be flagged with @FlaggedApi: method android.view.HapticScrollFeedbackProvider.onScrollProgress(int,int,int,int)
+UnflaggedApi: android.view.HapticScrollFeedbackProvider#onSnapToItem(int, int, int):
+ New API must be flagged with @FlaggedApi: method android.view.HapticScrollFeedbackProvider.onSnapToItem(int,int,int)
+UnflaggedApi: android.view.ScrollFeedbackProvider#onScrollLimit(android.view.MotionEvent, int, boolean):
+ New API must be flagged with @FlaggedApi: method android.view.ScrollFeedbackProvider.onScrollLimit(android.view.MotionEvent,int,boolean)
+UnflaggedApi: android.view.ScrollFeedbackProvider#onScrollLimit(int, int, int, boolean):
+ New API must be flagged with @FlaggedApi: method android.view.ScrollFeedbackProvider.onScrollLimit(int,int,int,boolean)
+UnflaggedApi: android.view.ScrollFeedbackProvider#onScrollProgress(android.view.MotionEvent, int, int):
+ New API must be flagged with @FlaggedApi: method android.view.ScrollFeedbackProvider.onScrollProgress(android.view.MotionEvent,int,int)
+UnflaggedApi: android.view.ScrollFeedbackProvider#onScrollProgress(int, int, int, int):
+ New API must be flagged with @FlaggedApi: method android.view.ScrollFeedbackProvider.onScrollProgress(int,int,int,int)
+UnflaggedApi: android.view.ScrollFeedbackProvider#onSnapToItem(android.view.MotionEvent, int):
+ New API must be flagged with @FlaggedApi: method android.view.ScrollFeedbackProvider.onSnapToItem(android.view.MotionEvent,int)
+UnflaggedApi: android.view.ScrollFeedbackProvider#onSnapToItem(int, int, int):
+ New API must be flagged with @FlaggedApi: method android.view.ScrollFeedbackProvider.onSnapToItem(int,int,int)
+UnflaggedApi: android.view.accessibility.AccessibilityNodeInfo#ACTION_ARGUMENT_SCROLL_AMOUNT_FLOAT:
+ New API must be flagged with @FlaggedApi: field android.view.accessibility.AccessibilityNodeInfo.ACTION_ARGUMENT_SCROLL_AMOUNT_FLOAT
+UnflaggedApi: android.view.accessibility.AccessibilityNodeInfo#isGranularScrollingSupported():
+ New API must be flagged with @FlaggedApi: method android.view.accessibility.AccessibilityNodeInfo.isGranularScrollingSupported()
+UnflaggedApi: android.view.accessibility.AccessibilityNodeInfo#setGranularScrollingSupported(boolean):
+ New API must be flagged with @FlaggedApi: method android.view.accessibility.AccessibilityNodeInfo.setGranularScrollingSupported(boolean)
+UnflaggedApi: android.view.accessibility.AccessibilityNodeInfo.CollectionInfo#CollectionInfo(int, int, boolean, int, int, int):
+ New API must be flagged with @FlaggedApi: constructor android.view.accessibility.AccessibilityNodeInfo.CollectionInfo(int,int,boolean,int,int,int)
+UnflaggedApi: android.view.accessibility.AccessibilityNodeInfo.CollectionInfo#UNDEFINED:
+ New API must be flagged with @FlaggedApi: field android.view.accessibility.AccessibilityNodeInfo.CollectionInfo.UNDEFINED
+UnflaggedApi: android.view.accessibility.AccessibilityNodeInfo.CollectionInfo#getImportantForAccessibilityItemCount():
+ New API must be flagged with @FlaggedApi: method android.view.accessibility.AccessibilityNodeInfo.CollectionInfo.getImportantForAccessibilityItemCount()
+UnflaggedApi: android.view.accessibility.AccessibilityNodeInfo.CollectionInfo#getItemCount():
+ New API must be flagged with @FlaggedApi: method android.view.accessibility.AccessibilityNodeInfo.CollectionInfo.getItemCount()
+UnflaggedApi: android.view.accessibility.AccessibilityNodeInfo.CollectionInfo.Builder:
+ New API must be flagged with @FlaggedApi: class android.view.accessibility.AccessibilityNodeInfo.CollectionInfo.Builder
+UnflaggedApi: android.view.accessibility.AccessibilityNodeInfo.CollectionInfo.Builder#Builder():
+ New API must be flagged with @FlaggedApi: constructor android.view.accessibility.AccessibilityNodeInfo.CollectionInfo.Builder()
+UnflaggedApi: android.view.accessibility.AccessibilityNodeInfo.CollectionInfo.Builder#build():
+ New API must be flagged with @FlaggedApi: method android.view.accessibility.AccessibilityNodeInfo.CollectionInfo.Builder.build()
+UnflaggedApi: android.view.accessibility.AccessibilityNodeInfo.CollectionInfo.Builder#setColumnCount(int):
+ New API must be flagged with @FlaggedApi: method android.view.accessibility.AccessibilityNodeInfo.CollectionInfo.Builder.setColumnCount(int)
+UnflaggedApi: android.view.accessibility.AccessibilityNodeInfo.CollectionInfo.Builder#setHierarchical(boolean):
+ New API must be flagged with @FlaggedApi: method android.view.accessibility.AccessibilityNodeInfo.CollectionInfo.Builder.setHierarchical(boolean)
+UnflaggedApi: android.view.accessibility.AccessibilityNodeInfo.CollectionInfo.Builder#setImportantForAccessibilityItemCount(int):
+ New API must be flagged with @FlaggedApi: method android.view.accessibility.AccessibilityNodeInfo.CollectionInfo.Builder.setImportantForAccessibilityItemCount(int)
+UnflaggedApi: android.view.accessibility.AccessibilityNodeInfo.CollectionInfo.Builder#setItemCount(int):
+ New API must be flagged with @FlaggedApi: method android.view.accessibility.AccessibilityNodeInfo.CollectionInfo.Builder.setItemCount(int)
+UnflaggedApi: android.view.accessibility.AccessibilityNodeInfo.CollectionInfo.Builder#setRowCount(int):
+ New API must be flagged with @FlaggedApi: method android.view.accessibility.AccessibilityNodeInfo.CollectionInfo.Builder.setRowCount(int)
+UnflaggedApi: android.view.accessibility.AccessibilityNodeInfo.CollectionInfo.Builder#setSelectionMode(int):
+ New API must be flagged with @FlaggedApi: method android.view.accessibility.AccessibilityNodeInfo.CollectionInfo.Builder.setSelectionMode(int)
+UnflaggedApi: android.view.animation.AnimationUtils#getExpectedPresentationTimeMillis():
+ New API must be flagged with @FlaggedApi: method android.view.animation.AnimationUtils.getExpectedPresentationTimeMillis()
+UnflaggedApi: android.view.animation.AnimationUtils#getExpectedPresentationTimeNanos():
+ New API must be flagged with @FlaggedApi: method android.view.animation.AnimationUtils.getExpectedPresentationTimeNanos()
+UnflaggedApi: android.view.autofill.AutofillManager#clearAutofillRequestCallback():
+ New API must be flagged with @FlaggedApi: method android.view.autofill.AutofillManager.clearAutofillRequestCallback()
+UnflaggedApi: android.view.autofill.AutofillManager#setAutofillRequestCallback(java.util.concurrent.Executor, android.view.autofill.AutofillRequestCallback):
+ New API must be flagged with @FlaggedApi: method android.view.autofill.AutofillManager.setAutofillRequestCallback(java.util.concurrent.Executor,android.view.autofill.AutofillRequestCallback)
+UnflaggedApi: android.view.autofill.AutofillRequestCallback:
+ New API must be flagged with @FlaggedApi: class android.view.autofill.AutofillRequestCallback
+UnflaggedApi: android.view.autofill.AutofillRequestCallback#onFillRequest(android.view.inputmethod.InlineSuggestionsRequest, android.os.CancellationSignal, android.service.autofill.FillCallback):
+ New API must be flagged with @FlaggedApi: method android.view.autofill.AutofillRequestCallback.onFillRequest(android.view.inputmethod.InlineSuggestionsRequest,android.os.CancellationSignal,android.service.autofill.FillCallback)
+UnflaggedApi: android.view.inputmethod.InlineSuggestionsRequest.Builder#setClientSupported(boolean):
+ New API must be flagged with @FlaggedApi: method android.view.inputmethod.InlineSuggestionsRequest.Builder.setClientSupported(boolean)
+UnflaggedApi: android.view.inputmethod.InlineSuggestionsRequest.Builder#setServiceSupported(boolean):
+ New API must be flagged with @FlaggedApi: method android.view.inputmethod.InlineSuggestionsRequest.Builder.setServiceSupported(boolean)
+UnflaggedApi: android.widget.TextView#getUseBoundsForWidth():
+ New API must be flagged with @FlaggedApi: method android.widget.TextView.getUseBoundsForWidth()
+UnflaggedApi: android.widget.TextView#setUseBoundsForWidth(boolean):
+ New API must be flagged with @FlaggedApi: method android.widget.TextView.setUseBoundsForWidth(boolean)
diff --git a/core/api/module-lib-lint-baseline.txt b/core/api/module-lib-lint-baseline.txt
index 471745ae0c50..a0d38588bc10 100644
--- a/core/api/module-lib-lint-baseline.txt
+++ b/core/api/module-lib-lint-baseline.txt
@@ -45,3 +45,57 @@ SamShouldBeLast: android.os.IBinder#linkToDeath(android.os.IBinder.DeathRecipien
SAM-compatible parameters (such as parameter 1, "recipient", in android.os.IBinder.linkToDeath) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
SamShouldBeLast: android.os.IBinder#unlinkToDeath(android.os.IBinder.DeathRecipient, int):
SAM-compatible parameters (such as parameter 1, "recipient", in android.os.IBinder.unlinkToDeath) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
+
+
+UnflaggedApi: android.Manifest.permission#BLUETOOTH_STACK:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.BLUETOOTH_STACK
+UnflaggedApi: android.Manifest.permission#CONTROL_AUTOMOTIVE_GNSS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.CONTROL_AUTOMOTIVE_GNSS
+UnflaggedApi: android.Manifest.permission#GET_INTENT_SENDER_INTENT:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.GET_INTENT_SENDER_INTENT
+UnflaggedApi: android.Manifest.permission#MAKE_UID_VISIBLE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.MAKE_UID_VISIBLE
+UnflaggedApi: android.Manifest.permission#MANAGE_REMOTE_AUTH:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.MANAGE_REMOTE_AUTH
+UnflaggedApi: android.Manifest.permission#USE_COMPANION_TRANSPORTS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.USE_COMPANION_TRANSPORTS
+UnflaggedApi: android.Manifest.permission#USE_REMOTE_AUTH:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.USE_REMOTE_AUTH
+UnflaggedApi: android.app.Activity#isResumed():
+ New API must be flagged with @FlaggedApi: method android.app.Activity.isResumed()
+UnflaggedApi: android.companion.CompanionDeviceManager#MESSAGE_REQUEST_CONTEXT_SYNC:
+ New API must be flagged with @FlaggedApi: field android.companion.CompanionDeviceManager.MESSAGE_REQUEST_CONTEXT_SYNC
+UnflaggedApi: android.companion.CompanionDeviceManager#MESSAGE_REQUEST_PERMISSION_RESTORE:
+ New API must be flagged with @FlaggedApi: field android.companion.CompanionDeviceManager.MESSAGE_REQUEST_PERMISSION_RESTORE
+UnflaggedApi: android.companion.CompanionDeviceManager#MESSAGE_REQUEST_REMOTE_AUTHENTICATION:
+ New API must be flagged with @FlaggedApi: field android.companion.CompanionDeviceManager.MESSAGE_REQUEST_REMOTE_AUTHENTICATION
+UnflaggedApi: android.companion.CompanionDeviceManager#addOnMessageReceivedListener(java.util.concurrent.Executor, int, android.companion.CompanionDeviceManager.OnMessageReceivedListener):
+ New API must be flagged with @FlaggedApi: method android.companion.CompanionDeviceManager.addOnMessageReceivedListener(java.util.concurrent.Executor,int,android.companion.CompanionDeviceManager.OnMessageReceivedListener)
+UnflaggedApi: android.companion.CompanionDeviceManager#addOnTransportsChangedListener(java.util.concurrent.Executor, android.companion.CompanionDeviceManager.OnTransportsChangedListener):
+ New API must be flagged with @FlaggedApi: method android.companion.CompanionDeviceManager.addOnTransportsChangedListener(java.util.concurrent.Executor,android.companion.CompanionDeviceManager.OnTransportsChangedListener)
+UnflaggedApi: android.companion.CompanionDeviceManager#removeOnMessageReceivedListener(int, android.companion.CompanionDeviceManager.OnMessageReceivedListener):
+ New API must be flagged with @FlaggedApi: method android.companion.CompanionDeviceManager.removeOnMessageReceivedListener(int,android.companion.CompanionDeviceManager.OnMessageReceivedListener)
+UnflaggedApi: android.companion.CompanionDeviceManager#removeOnTransportsChangedListener(android.companion.CompanionDeviceManager.OnTransportsChangedListener):
+ New API must be flagged with @FlaggedApi: method android.companion.CompanionDeviceManager.removeOnTransportsChangedListener(android.companion.CompanionDeviceManager.OnTransportsChangedListener)
+UnflaggedApi: android.companion.CompanionDeviceManager#sendMessage(int, byte[], int[]):
+ New API must be flagged with @FlaggedApi: method android.companion.CompanionDeviceManager.sendMessage(int,byte[],int[])
+UnflaggedApi: android.companion.CompanionDeviceManager.OnMessageReceivedListener:
+ New API must be flagged with @FlaggedApi: class android.companion.CompanionDeviceManager.OnMessageReceivedListener
+UnflaggedApi: android.companion.CompanionDeviceManager.OnMessageReceivedListener#onMessageReceived(int, byte[]):
+ New API must be flagged with @FlaggedApi: method android.companion.CompanionDeviceManager.OnMessageReceivedListener.onMessageReceived(int,byte[])
+UnflaggedApi: android.companion.CompanionDeviceManager.OnTransportsChangedListener:
+ New API must be flagged with @FlaggedApi: class android.companion.CompanionDeviceManager.OnTransportsChangedListener
+UnflaggedApi: android.companion.CompanionDeviceManager.OnTransportsChangedListener#onTransportsChanged(java.util.List<android.companion.AssociationInfo>):
+ New API must be flagged with @FlaggedApi: method android.companion.CompanionDeviceManager.OnTransportsChangedListener.onTransportsChanged(java.util.List<android.companion.AssociationInfo>)
+UnflaggedApi: android.content.Context#REMOTE_AUTH_SERVICE:
+ New API must be flagged with @FlaggedApi: field android.content.Context.REMOTE_AUTH_SERVICE
+UnflaggedApi: android.content.ContextWrapper#createContextForSdkInSandbox(android.content.pm.ApplicationInfo, int):
+ New API must be flagged with @FlaggedApi: method android.content.ContextWrapper.createContextForSdkInSandbox(android.content.pm.ApplicationInfo,int)
+UnflaggedApi: android.media.session.MediaController.PlaybackInfo#PlaybackInfo(int, int, int, int, android.media.AudioAttributes, String):
+ New API must be flagged with @FlaggedApi: constructor android.media.session.MediaController.PlaybackInfo(int,int,int,int,android.media.AudioAttributes,String)
+UnflaggedApi: android.os.IpcDataCache#MODULE_TELEPHONY:
+ New API must be flagged with @FlaggedApi: field android.os.IpcDataCache.MODULE_TELEPHONY
+UnflaggedApi: android.provider.ContactsContract.RawContactsEntity#queryRawContactEntity(android.content.ContentResolver, long):
+ New API must be flagged with @FlaggedApi: method android.provider.ContactsContract.RawContactsEntity.queryRawContactEntity(android.content.ContentResolver,long)
+UnflaggedApi: android.provider.Settings.Config#getAllStrings():
+ New API must be flagged with @FlaggedApi: method android.provider.Settings.Config.getAllStrings()
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index ff44a1b87e18..a5e69abeb9d3 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -12654,7 +12654,7 @@ package android.service.voice {
method @NonNull public android.service.voice.HotwordTrainingAudio build();
method @NonNull public android.service.voice.HotwordTrainingAudio.Builder setAudioFormat(@NonNull android.media.AudioFormat);
method @NonNull public android.service.voice.HotwordTrainingAudio.Builder setAudioType(@NonNull int);
- method @NonNull public android.service.voice.HotwordTrainingAudio.Builder setHotwordAudio(@NonNull byte...);
+ method @NonNull public android.service.voice.HotwordTrainingAudio.Builder setHotwordAudio(@NonNull byte[]);
method @NonNull public android.service.voice.HotwordTrainingAudio.Builder setHotwordOffsetMillis(int);
}
diff --git a/core/api/system-lint-baseline.txt b/core/api/system-lint-baseline.txt
index e7c0a912383f..d62bea86bd06 100644
--- a/core/api/system-lint-baseline.txt
+++ b/core/api/system-lint-baseline.txt
@@ -223,3 +223,3143 @@ SamShouldBeLast: android.view.accessibility.AccessibilityManager#addTouchExplora
SAM-compatible parameters (such as parameter 1, "listener", in android.view.accessibility.AccessibilityManager.addTouchExplorationStateChangeListener) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
SamShouldBeLast: android.webkit.WebChromeClient#onShowFileChooser(android.webkit.WebView, android.webkit.ValueCallback<android.net.Uri[]>, android.webkit.WebChromeClient.FileChooserParams):
SAM-compatible parameters (such as parameter 2, "filePathCallback", in android.webkit.WebChromeClient.onShowFileChooser) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
+
+
+UnflaggedApi: android.Manifest.permission#ACCESS_AMBIENT_CONTEXT_EVENT:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.ACCESS_AMBIENT_CONTEXT_EVENT
+UnflaggedApi: android.Manifest.permission#ACCESS_AMBIENT_LIGHT_STATS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.ACCESS_AMBIENT_LIGHT_STATS
+UnflaggedApi: android.Manifest.permission#ACCESS_BROADCAST_RADIO:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.ACCESS_BROADCAST_RADIO
+UnflaggedApi: android.Manifest.permission#ACCESS_BROADCAST_RESPONSE_STATS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.ACCESS_BROADCAST_RESPONSE_STATS
+UnflaggedApi: android.Manifest.permission#ACCESS_CACHE_FILESYSTEM:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.ACCESS_CACHE_FILESYSTEM
+UnflaggedApi: android.Manifest.permission#ACCESS_CONTEXT_HUB:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.ACCESS_CONTEXT_HUB
+UnflaggedApi: android.Manifest.permission#ACCESS_DRM_CERTIFICATES:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.ACCESS_DRM_CERTIFICATES
+UnflaggedApi: android.Manifest.permission#ACCESS_FPS_COUNTER:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.ACCESS_FPS_COUNTER
+UnflaggedApi: android.Manifest.permission#ACCESS_INSTANT_APPS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.ACCESS_INSTANT_APPS
+UnflaggedApi: android.Manifest.permission#ACCESS_LOCUS_ID_USAGE_STATS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.ACCESS_LOCUS_ID_USAGE_STATS
+UnflaggedApi: android.Manifest.permission#ACCESS_MOCK_LOCATION:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.ACCESS_MOCK_LOCATION
+UnflaggedApi: android.Manifest.permission#ACCESS_MTP:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.ACCESS_MTP
+UnflaggedApi: android.Manifest.permission#ACCESS_NETWORK_CONDITIONS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.ACCESS_NETWORK_CONDITIONS
+UnflaggedApi: android.Manifest.permission#ACCESS_NOTIFICATIONS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.ACCESS_NOTIFICATIONS
+UnflaggedApi: android.Manifest.permission#ACCESS_PDB_STATE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.ACCESS_PDB_STATE
+UnflaggedApi: android.Manifest.permission#ACCESS_RCS_USER_CAPABILITY_EXCHANGE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.ACCESS_RCS_USER_CAPABILITY_EXCHANGE
+UnflaggedApi: android.Manifest.permission#ACCESS_SHARED_LIBRARIES:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.ACCESS_SHARED_LIBRARIES
+UnflaggedApi: android.Manifest.permission#ACCESS_SHORTCUTS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.ACCESS_SHORTCUTS
+UnflaggedApi: android.Manifest.permission#ACCESS_SMARTSPACE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.ACCESS_SMARTSPACE
+UnflaggedApi: android.Manifest.permission#ACCESS_SURFACE_FLINGER:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.ACCESS_SURFACE_FLINGER
+UnflaggedApi: android.Manifest.permission#ACCESS_TUNED_INFO:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.ACCESS_TUNED_INFO
+UnflaggedApi: android.Manifest.permission#ACCESS_TV_DESCRAMBLER:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.ACCESS_TV_DESCRAMBLER
+UnflaggedApi: android.Manifest.permission#ACCESS_TV_SHARED_FILTER:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.ACCESS_TV_SHARED_FILTER
+UnflaggedApi: android.Manifest.permission#ACCESS_TV_TUNER:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.ACCESS_TV_TUNER
+UnflaggedApi: android.Manifest.permission#ACCESS_ULTRASOUND:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.ACCESS_ULTRASOUND
+UnflaggedApi: android.Manifest.permission#ACCESS_VIBRATOR_STATE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.ACCESS_VIBRATOR_STATE
+UnflaggedApi: android.Manifest.permission#ACTIVITY_EMBEDDING:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.ACTIVITY_EMBEDDING
+UnflaggedApi: android.Manifest.permission#ADD_ALWAYS_UNLOCKED_DISPLAY:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.ADD_ALWAYS_UNLOCKED_DISPLAY
+UnflaggedApi: android.Manifest.permission#ADD_TRUSTED_DISPLAY:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.ADD_TRUSTED_DISPLAY
+UnflaggedApi: android.Manifest.permission#ADJUST_RUNTIME_PERMISSIONS_POLICY:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY
+UnflaggedApi: android.Manifest.permission#ALLOCATE_AGGRESSIVE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.ALLOCATE_AGGRESSIVE
+UnflaggedApi: android.Manifest.permission#ALLOW_ANY_CODEC_FOR_PLAYBACK:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.ALLOW_ANY_CODEC_FOR_PLAYBACK
+UnflaggedApi: android.Manifest.permission#ALLOW_PLACE_IN_MULTI_PANE_SETTINGS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.ALLOW_PLACE_IN_MULTI_PANE_SETTINGS
+UnflaggedApi: android.Manifest.permission#ALLOW_SLIPPERY_TOUCHES:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.ALLOW_SLIPPERY_TOUCHES
+UnflaggedApi: android.Manifest.permission#ALWAYS_UPDATE_WALLPAPER:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.ALWAYS_UPDATE_WALLPAPER
+UnflaggedApi: android.Manifest.permission#AMBIENT_WALLPAPER:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.AMBIENT_WALLPAPER
+UnflaggedApi: android.Manifest.permission#APPROVE_INCIDENT_REPORTS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.APPROVE_INCIDENT_REPORTS
+UnflaggedApi: android.Manifest.permission#ASSOCIATE_COMPANION_DEVICES:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.ASSOCIATE_COMPANION_DEVICES
+UnflaggedApi: android.Manifest.permission#BACKGROUND_CAMERA:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.BACKGROUND_CAMERA
+UnflaggedApi: android.Manifest.permission#BACKUP:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.BACKUP
+UnflaggedApi: android.Manifest.permission#BATTERY_PREDICTION:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.BATTERY_PREDICTION
+UnflaggedApi: android.Manifest.permission#BIND_AMBIENT_CONTEXT_DETECTION_SERVICE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.BIND_AMBIENT_CONTEXT_DETECTION_SERVICE
+UnflaggedApi: android.Manifest.permission#BIND_ATTENTION_SERVICE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.BIND_ATTENTION_SERVICE
+UnflaggedApi: android.Manifest.permission#BIND_AUGMENTED_AUTOFILL_SERVICE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.BIND_AUGMENTED_AUTOFILL_SERVICE
+UnflaggedApi: android.Manifest.permission#BIND_CALL_DIAGNOSTIC_SERVICE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.BIND_CALL_DIAGNOSTIC_SERVICE
+UnflaggedApi: android.Manifest.permission#BIND_CALL_STREAMING_SERVICE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.BIND_CALL_STREAMING_SERVICE
+UnflaggedApi: android.Manifest.permission#BIND_CELL_BROADCAST_SERVICE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.BIND_CELL_BROADCAST_SERVICE
+UnflaggedApi: android.Manifest.permission#BIND_CONTENT_CAPTURE_SERVICE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.BIND_CONTENT_CAPTURE_SERVICE
+UnflaggedApi: android.Manifest.permission#BIND_CONTENT_SUGGESTIONS_SERVICE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.BIND_CONTENT_SUGGESTIONS_SERVICE
+UnflaggedApi: android.Manifest.permission#BIND_DIRECTORY_SEARCH:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.BIND_DIRECTORY_SEARCH
+UnflaggedApi: android.Manifest.permission#BIND_DISPLAY_HASHING_SERVICE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.BIND_DISPLAY_HASHING_SERVICE
+UnflaggedApi: android.Manifest.permission#BIND_DOMAIN_VERIFICATION_AGENT:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.BIND_DOMAIN_VERIFICATION_AGENT
+UnflaggedApi: android.Manifest.permission#BIND_EUICC_SERVICE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.BIND_EUICC_SERVICE
+UnflaggedApi: android.Manifest.permission#BIND_EXTERNAL_STORAGE_SERVICE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.BIND_EXTERNAL_STORAGE_SERVICE
+UnflaggedApi: android.Manifest.permission#BIND_FIELD_CLASSIFICATION_SERVICE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.BIND_FIELD_CLASSIFICATION_SERVICE
+UnflaggedApi: android.Manifest.permission#BIND_GBA_SERVICE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.BIND_GBA_SERVICE
+UnflaggedApi: android.Manifest.permission#BIND_HOTWORD_DETECTION_SERVICE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.BIND_HOTWORD_DETECTION_SERVICE
+UnflaggedApi: android.Manifest.permission#BIND_IMS_SERVICE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.BIND_IMS_SERVICE
+UnflaggedApi: android.Manifest.permission#BIND_KEYGUARD_APPWIDGET:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.BIND_KEYGUARD_APPWIDGET
+UnflaggedApi: android.Manifest.permission#BIND_MUSIC_RECOGNITION_SERVICE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.BIND_MUSIC_RECOGNITION_SERVICE
+UnflaggedApi: android.Manifest.permission#BIND_NETWORK_RECOMMENDATION_SERVICE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.BIND_NETWORK_RECOMMENDATION_SERVICE
+UnflaggedApi: android.Manifest.permission#BIND_NOTIFICATION_ASSISTANT_SERVICE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.BIND_NOTIFICATION_ASSISTANT_SERVICE
+UnflaggedApi: android.Manifest.permission#BIND_PHONE_ACCOUNT_SUGGESTION_SERVICE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.BIND_PHONE_ACCOUNT_SUGGESTION_SERVICE
+UnflaggedApi: android.Manifest.permission#BIND_PRINT_RECOMMENDATION_SERVICE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.BIND_PRINT_RECOMMENDATION_SERVICE
+UnflaggedApi: android.Manifest.permission#BIND_REMOTE_LOCKSCREEN_VALIDATION_SERVICE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.BIND_REMOTE_LOCKSCREEN_VALIDATION_SERVICE
+UnflaggedApi: android.Manifest.permission#BIND_RESOLVER_RANKER_SERVICE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.BIND_RESOLVER_RANKER_SERVICE
+UnflaggedApi: android.Manifest.permission#BIND_RESUME_ON_REBOOT_SERVICE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.BIND_RESUME_ON_REBOOT_SERVICE
+UnflaggedApi: android.Manifest.permission#BIND_ROTATION_RESOLVER_SERVICE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.BIND_ROTATION_RESOLVER_SERVICE
+UnflaggedApi: android.Manifest.permission#BIND_RUNTIME_PERMISSION_PRESENTER_SERVICE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.BIND_RUNTIME_PERMISSION_PRESENTER_SERVICE
+UnflaggedApi: android.Manifest.permission#BIND_SATELLITE_SERVICE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.BIND_SATELLITE_SERVICE
+UnflaggedApi: android.Manifest.permission#BIND_SETTINGS_SUGGESTIONS_SERVICE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.BIND_SETTINGS_SUGGESTIONS_SERVICE
+UnflaggedApi: android.Manifest.permission#BIND_SOUND_TRIGGER_DETECTION_SERVICE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.BIND_SOUND_TRIGGER_DETECTION_SERVICE
+UnflaggedApi: android.Manifest.permission#BIND_TELEPHONY_DATA_SERVICE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.BIND_TELEPHONY_DATA_SERVICE
+UnflaggedApi: android.Manifest.permission#BIND_TELEPHONY_NETWORK_SERVICE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.BIND_TELEPHONY_NETWORK_SERVICE
+UnflaggedApi: android.Manifest.permission#BIND_TEXTCLASSIFIER_SERVICE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.BIND_TEXTCLASSIFIER_SERVICE
+UnflaggedApi: android.Manifest.permission#BIND_TIME_ZONE_PROVIDER_SERVICE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.BIND_TIME_ZONE_PROVIDER_SERVICE
+UnflaggedApi: android.Manifest.permission#BIND_TRACE_REPORT_SERVICE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.BIND_TRACE_REPORT_SERVICE
+UnflaggedApi: android.Manifest.permission#BIND_TRANSLATION_SERVICE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.BIND_TRANSLATION_SERVICE
+UnflaggedApi: android.Manifest.permission#BIND_TRUST_AGENT:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.BIND_TRUST_AGENT
+UnflaggedApi: android.Manifest.permission#BIND_TV_REMOTE_SERVICE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.BIND_TV_REMOTE_SERVICE
+UnflaggedApi: android.Manifest.permission#BIND_VISUAL_QUERY_DETECTION_SERVICE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.BIND_VISUAL_QUERY_DETECTION_SERVICE
+UnflaggedApi: android.Manifest.permission#BIND_WALLPAPER_EFFECTS_GENERATION_SERVICE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.BIND_WALLPAPER_EFFECTS_GENERATION_SERVICE
+UnflaggedApi: android.Manifest.permission#BIND_WEARABLE_SENSING_SERVICE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.BIND_WEARABLE_SENSING_SERVICE
+UnflaggedApi: android.Manifest.permission#BLUETOOTH_MAP:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.BLUETOOTH_MAP
+UnflaggedApi: android.Manifest.permission#BRICK:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.BRICK
+UnflaggedApi: android.Manifest.permission#BRIGHTNESS_SLIDER_USAGE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.BRIGHTNESS_SLIDER_USAGE
+UnflaggedApi: android.Manifest.permission#BROADCAST_CLOSE_SYSTEM_DIALOGS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.BROADCAST_CLOSE_SYSTEM_DIALOGS
+UnflaggedApi: android.Manifest.permission#BYPASS_ROLE_QUALIFICATION:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.BYPASS_ROLE_QUALIFICATION
+UnflaggedApi: android.Manifest.permission#CALL_AUDIO_INTERCEPTION:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.CALL_AUDIO_INTERCEPTION
+UnflaggedApi: android.Manifest.permission#CAMERA_DISABLE_TRANSMIT_LED:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.CAMERA_DISABLE_TRANSMIT_LED
+UnflaggedApi: android.Manifest.permission#CAMERA_OPEN_CLOSE_LISTENER:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.CAMERA_OPEN_CLOSE_LISTENER
+UnflaggedApi: android.Manifest.permission#CAPTURE_AUDIO_HOTWORD:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.CAPTURE_AUDIO_HOTWORD
+UnflaggedApi: android.Manifest.permission#CAPTURE_CONSENTLESS_BUGREPORT_ON_USERDEBUG_BUILD:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.CAPTURE_CONSENTLESS_BUGREPORT_ON_USERDEBUG_BUILD
+UnflaggedApi: android.Manifest.permission#CAPTURE_MEDIA_OUTPUT:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.CAPTURE_MEDIA_OUTPUT
+UnflaggedApi: android.Manifest.permission#CAPTURE_TUNER_AUDIO_INPUT:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.CAPTURE_TUNER_AUDIO_INPUT
+UnflaggedApi: android.Manifest.permission#CAPTURE_TV_INPUT:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.CAPTURE_TV_INPUT
+UnflaggedApi: android.Manifest.permission#CAPTURE_VOICE_COMMUNICATION_OUTPUT:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.CAPTURE_VOICE_COMMUNICATION_OUTPUT
+UnflaggedApi: android.Manifest.permission#CHANGE_APP_IDLE_STATE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.CHANGE_APP_IDLE_STATE
+UnflaggedApi: android.Manifest.permission#CHANGE_APP_LAUNCH_TIME_ESTIMATE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.CHANGE_APP_LAUNCH_TIME_ESTIMATE
+UnflaggedApi: android.Manifest.permission#CHANGE_DEVICE_IDLE_TEMP_WHITELIST:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST
+UnflaggedApi: android.Manifest.permission#CHECK_REMOTE_LOCKSCREEN:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.CHECK_REMOTE_LOCKSCREEN
+UnflaggedApi: android.Manifest.permission#CLEAR_APP_USER_DATA:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.CLEAR_APP_USER_DATA
+UnflaggedApi: android.Manifest.permission#COMPANION_APPROVE_WIFI_CONNECTIONS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.COMPANION_APPROVE_WIFI_CONNECTIONS
+UnflaggedApi: android.Manifest.permission#CONFIGURE_DISPLAY_BRIGHTNESS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS
+UnflaggedApi: android.Manifest.permission#CONFIGURE_INTERACT_ACROSS_PROFILES:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.CONFIGURE_INTERACT_ACROSS_PROFILES
+UnflaggedApi: android.Manifest.permission#CONNECTIVITY_USE_RESTRICTED_NETWORKS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS
+UnflaggedApi: android.Manifest.permission#CONTROL_DEVICE_LIGHTS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.CONTROL_DEVICE_LIGHTS
+UnflaggedApi: android.Manifest.permission#CONTROL_DISPLAY_COLOR_TRANSFORMS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS
+UnflaggedApi: android.Manifest.permission#CONTROL_DISPLAY_SATURATION:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.CONTROL_DISPLAY_SATURATION
+UnflaggedApi: android.Manifest.permission#CONTROL_INCALL_EXPERIENCE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.CONTROL_INCALL_EXPERIENCE
+UnflaggedApi: android.Manifest.permission#CONTROL_KEYGUARD_SECURE_NOTIFICATIONS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.CONTROL_KEYGUARD_SECURE_NOTIFICATIONS
+UnflaggedApi: android.Manifest.permission#CONTROL_OEM_PAID_NETWORK_PREFERENCE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.CONTROL_OEM_PAID_NETWORK_PREFERENCE
+UnflaggedApi: android.Manifest.permission#CONTROL_VPN:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.CONTROL_VPN
+UnflaggedApi: android.Manifest.permission#CREATE_USERS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.CREATE_USERS
+UnflaggedApi: android.Manifest.permission#CREATE_VIRTUAL_DEVICE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.CREATE_VIRTUAL_DEVICE
+UnflaggedApi: android.Manifest.permission#CRYPT_KEEPER:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.CRYPT_KEEPER
+UnflaggedApi: android.Manifest.permission#DEVICE_POWER:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.DEVICE_POWER
+UnflaggedApi: android.Manifest.permission#DISABLE_SYSTEM_SOUND_EFFECTS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.DISABLE_SYSTEM_SOUND_EFFECTS
+UnflaggedApi: android.Manifest.permission#DISPATCH_PROVISIONING_MESSAGE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.DISPATCH_PROVISIONING_MESSAGE
+UnflaggedApi: android.Manifest.permission#DOMAIN_VERIFICATION_AGENT:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.DOMAIN_VERIFICATION_AGENT
+UnflaggedApi: android.Manifest.permission#ENTER_CAR_MODE_PRIORITIZED:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.ENTER_CAR_MODE_PRIORITIZED
+UnflaggedApi: android.Manifest.permission#EXEMPT_FROM_AUDIO_RECORD_RESTRICTIONS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.EXEMPT_FROM_AUDIO_RECORD_RESTRICTIONS
+UnflaggedApi: android.Manifest.permission#FORCE_BACK:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.FORCE_BACK
+UnflaggedApi: android.Manifest.permission#FORCE_STOP_PACKAGES:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.FORCE_STOP_PACKAGES
+UnflaggedApi: android.Manifest.permission#GET_APP_METADATA:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.GET_APP_METADATA
+UnflaggedApi: android.Manifest.permission#GET_APP_OPS_STATS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.GET_APP_OPS_STATS
+UnflaggedApi: android.Manifest.permission#GET_HISTORICAL_APP_OPS_STATS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.GET_HISTORICAL_APP_OPS_STATS
+UnflaggedApi: android.Manifest.permission#GET_PROCESS_STATE_AND_OOM_SCORE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE
+UnflaggedApi: android.Manifest.permission#GET_RUNTIME_PERMISSIONS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.GET_RUNTIME_PERMISSIONS
+UnflaggedApi: android.Manifest.permission#GET_TOP_ACTIVITY_INFO:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.GET_TOP_ACTIVITY_INFO
+UnflaggedApi: android.Manifest.permission#GRANT_RUNTIME_PERMISSIONS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS
+UnflaggedApi: android.Manifest.permission#GRANT_RUNTIME_PERMISSIONS_TO_TELEPHONY_DEFAULTS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS_TO_TELEPHONY_DEFAULTS
+UnflaggedApi: android.Manifest.permission#HANDLE_CAR_MODE_CHANGES:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.HANDLE_CAR_MODE_CHANGES
+UnflaggedApi: android.Manifest.permission#HARDWARE_TEST:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.HARDWARE_TEST
+UnflaggedApi: android.Manifest.permission#HDMI_CEC:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.HDMI_CEC
+UnflaggedApi: android.Manifest.permission#INJECT_EVENTS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.INJECT_EVENTS
+UnflaggedApi: android.Manifest.permission#INSTALL_DPC_PACKAGES:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.INSTALL_DPC_PACKAGES
+UnflaggedApi: android.Manifest.permission#INSTALL_DYNAMIC_SYSTEM:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.INSTALL_DYNAMIC_SYSTEM
+UnflaggedApi: android.Manifest.permission#INSTALL_EXISTING_PACKAGES:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.INSTALL_EXISTING_PACKAGES
+UnflaggedApi: android.Manifest.permission#INSTALL_GRANT_RUNTIME_PERMISSIONS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS
+UnflaggedApi: android.Manifest.permission#INSTALL_LOCATION_TIME_ZONE_PROVIDER_SERVICE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.INSTALL_LOCATION_TIME_ZONE_PROVIDER_SERVICE
+UnflaggedApi: android.Manifest.permission#INSTALL_PACKAGE_UPDATES:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.INSTALL_PACKAGE_UPDATES
+UnflaggedApi: android.Manifest.permission#INSTALL_SELF_UPDATES:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.INSTALL_SELF_UPDATES
+UnflaggedApi: android.Manifest.permission#INTENT_FILTER_VERIFICATION_AGENT:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT
+UnflaggedApi: android.Manifest.permission#INTERACT_ACROSS_USERS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.INTERACT_ACROSS_USERS
+UnflaggedApi: android.Manifest.permission#INTERACT_ACROSS_USERS_FULL:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.INTERACT_ACROSS_USERS_FULL
+UnflaggedApi: android.Manifest.permission#INTERNAL_SYSTEM_WINDOW:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.INTERNAL_SYSTEM_WINDOW
+UnflaggedApi: android.Manifest.permission#INVOKE_CARRIER_SETUP:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.INVOKE_CARRIER_SETUP
+UnflaggedApi: android.Manifest.permission#KILL_ALL_BACKGROUND_PROCESSES:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.KILL_ALL_BACKGROUND_PROCESSES
+UnflaggedApi: android.Manifest.permission#KILL_UID:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.KILL_UID
+UnflaggedApi: android.Manifest.permission#LAUNCH_DEVICE_MANAGER_SETUP:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.LAUNCH_DEVICE_MANAGER_SETUP
+UnflaggedApi: android.Manifest.permission#LAUNCH_PERMISSION_SETTINGS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.LAUNCH_PERMISSION_SETTINGS
+UnflaggedApi: android.Manifest.permission#LOCAL_MAC_ADDRESS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.LOCAL_MAC_ADDRESS
+UnflaggedApi: android.Manifest.permission#LOCATION_BYPASS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.LOCATION_BYPASS
+UnflaggedApi: android.Manifest.permission#LOCK_DEVICE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.LOCK_DEVICE
+UnflaggedApi: android.Manifest.permission#LOG_FOREGROUND_RESOURCE_USE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.LOG_FOREGROUND_RESOURCE_USE
+UnflaggedApi: android.Manifest.permission#LOOP_RADIO:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.LOOP_RADIO
+UnflaggedApi: android.Manifest.permission#MANAGE_ACCESSIBILITY:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.MANAGE_ACCESSIBILITY
+UnflaggedApi: android.Manifest.permission#MANAGE_ACTIVITY_TASKS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.MANAGE_ACTIVITY_TASKS
+UnflaggedApi: android.Manifest.permission#MANAGE_APP_HIBERNATION:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.MANAGE_APP_HIBERNATION
+UnflaggedApi: android.Manifest.permission#MANAGE_APP_OPS_RESTRICTIONS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.MANAGE_APP_OPS_RESTRICTIONS
+UnflaggedApi: android.Manifest.permission#MANAGE_APP_PREDICTIONS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.MANAGE_APP_PREDICTIONS
+UnflaggedApi: android.Manifest.permission#MANAGE_APP_TOKENS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.MANAGE_APP_TOKENS
+UnflaggedApi: android.Manifest.permission#MANAGE_AUTO_FILL:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.MANAGE_AUTO_FILL
+UnflaggedApi: android.Manifest.permission#MANAGE_BLUETOOTH_WHEN_WIRELESS_CONSENT_REQUIRED:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.MANAGE_BLUETOOTH_WHEN_WIRELESS_CONSENT_REQUIRED
+UnflaggedApi: android.Manifest.permission#MANAGE_CARRIER_OEM_UNLOCK_STATE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.MANAGE_CARRIER_OEM_UNLOCK_STATE
+UnflaggedApi: android.Manifest.permission#MANAGE_CA_CERTIFICATES:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.MANAGE_CA_CERTIFICATES
+UnflaggedApi: android.Manifest.permission#MANAGE_CLIPBOARD_ACCESS_NOTIFICATION:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.MANAGE_CLIPBOARD_ACCESS_NOTIFICATION
+UnflaggedApi: android.Manifest.permission#MANAGE_CLOUDSEARCH:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.MANAGE_CLOUDSEARCH
+UnflaggedApi: android.Manifest.permission#MANAGE_CONTENT_CAPTURE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.MANAGE_CONTENT_CAPTURE
+UnflaggedApi: android.Manifest.permission#MANAGE_CONTENT_SUGGESTIONS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.MANAGE_CONTENT_SUGGESTIONS
+UnflaggedApi: android.Manifest.permission#MANAGE_DEBUGGING:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.MANAGE_DEBUGGING
+UnflaggedApi: android.Manifest.permission#MANAGE_DEFAULT_APPLICATIONS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.MANAGE_DEFAULT_APPLICATIONS
+UnflaggedApi: android.Manifest.permission#MANAGE_DEVICE_ADMINS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.MANAGE_DEVICE_ADMINS
+UnflaggedApi: android.Manifest.permission#MANAGE_DEVICE_POLICY_APP_EXEMPTIONS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.MANAGE_DEVICE_POLICY_APP_EXEMPTIONS
+UnflaggedApi: android.Manifest.permission#MANAGE_ETHERNET_NETWORKS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.MANAGE_ETHERNET_NETWORKS
+UnflaggedApi: android.Manifest.permission#MANAGE_FACTORY_RESET_PROTECTION:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.MANAGE_FACTORY_RESET_PROTECTION
+UnflaggedApi: android.Manifest.permission#MANAGE_GAME_ACTIVITY:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.MANAGE_GAME_ACTIVITY
+UnflaggedApi: android.Manifest.permission#MANAGE_GAME_MODE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.MANAGE_GAME_MODE
+UnflaggedApi: android.Manifest.permission#MANAGE_HOTWORD_DETECTION:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.MANAGE_HOTWORD_DETECTION
+UnflaggedApi: android.Manifest.permission#MANAGE_IPSEC_TUNNELS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.MANAGE_IPSEC_TUNNELS
+UnflaggedApi: android.Manifest.permission#MANAGE_LOW_POWER_STANDBY:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.MANAGE_LOW_POWER_STANDBY
+UnflaggedApi: android.Manifest.permission#MANAGE_MUSIC_RECOGNITION:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.MANAGE_MUSIC_RECOGNITION
+UnflaggedApi: android.Manifest.permission#MANAGE_NOTIFICATION_LISTENERS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.MANAGE_NOTIFICATION_LISTENERS
+UnflaggedApi: android.Manifest.permission#MANAGE_ONE_TIME_PERMISSION_SESSIONS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.MANAGE_ONE_TIME_PERMISSION_SESSIONS
+UnflaggedApi: android.Manifest.permission#MANAGE_PROFILE_AND_DEVICE_OWNERS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS
+UnflaggedApi: android.Manifest.permission#MANAGE_ROLE_HOLDERS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.MANAGE_ROLE_HOLDERS
+UnflaggedApi: android.Manifest.permission#MANAGE_ROLLBACKS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.MANAGE_ROLLBACKS
+UnflaggedApi: android.Manifest.permission#MANAGE_ROTATION_RESOLVER:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.MANAGE_ROTATION_RESOLVER
+UnflaggedApi: android.Manifest.permission#MANAGE_SAFETY_CENTER:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.MANAGE_SAFETY_CENTER
+UnflaggedApi: android.Manifest.permission#MANAGE_SEARCH_UI:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.MANAGE_SEARCH_UI
+UnflaggedApi: android.Manifest.permission#MANAGE_SENSOR_PRIVACY:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.MANAGE_SENSOR_PRIVACY
+UnflaggedApi: android.Manifest.permission#MANAGE_SMARTSPACE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.MANAGE_SMARTSPACE
+UnflaggedApi: android.Manifest.permission#MANAGE_SOUND_TRIGGER:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.MANAGE_SOUND_TRIGGER
+UnflaggedApi: android.Manifest.permission#MANAGE_SPEECH_RECOGNITION:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.MANAGE_SPEECH_RECOGNITION
+UnflaggedApi: android.Manifest.permission#MANAGE_SUBSCRIPTION_PLANS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.MANAGE_SUBSCRIPTION_PLANS
+UnflaggedApi: android.Manifest.permission#MANAGE_SUBSCRIPTION_USER_ASSOCIATION:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.MANAGE_SUBSCRIPTION_USER_ASSOCIATION
+UnflaggedApi: android.Manifest.permission#MANAGE_TEST_NETWORKS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.MANAGE_TEST_NETWORKS
+UnflaggedApi: android.Manifest.permission#MANAGE_TIME_AND_ZONE_DETECTION:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.MANAGE_TIME_AND_ZONE_DETECTION
+UnflaggedApi: android.Manifest.permission#MANAGE_UI_TRANSLATION:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.MANAGE_UI_TRANSLATION
+UnflaggedApi: android.Manifest.permission#MANAGE_USB:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.MANAGE_USB
+UnflaggedApi: android.Manifest.permission#MANAGE_USERS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.MANAGE_USERS
+UnflaggedApi: android.Manifest.permission#MANAGE_USER_OEM_UNLOCK_STATE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.MANAGE_USER_OEM_UNLOCK_STATE
+UnflaggedApi: android.Manifest.permission#MANAGE_WALLPAPER_EFFECTS_GENERATION:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.MANAGE_WALLPAPER_EFFECTS_GENERATION
+UnflaggedApi: android.Manifest.permission#MANAGE_WEAK_ESCROW_TOKEN:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.MANAGE_WEAK_ESCROW_TOKEN
+UnflaggedApi: android.Manifest.permission#MANAGE_WEARABLE_SENSING_SERVICE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.MANAGE_WEARABLE_SENSING_SERVICE
+UnflaggedApi: android.Manifest.permission#MANAGE_WIFI_COUNTRY_CODE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.MANAGE_WIFI_COUNTRY_CODE
+UnflaggedApi: android.Manifest.permission#MARK_DEVICE_ORGANIZATION_OWNED:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.MARK_DEVICE_ORGANIZATION_OWNED
+UnflaggedApi: android.Manifest.permission#MEDIA_RESOURCE_OVERRIDE_PID:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.MEDIA_RESOURCE_OVERRIDE_PID
+UnflaggedApi: android.Manifest.permission#MIGRATE_HEALTH_CONNECT_DATA:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.MIGRATE_HEALTH_CONNECT_DATA
+UnflaggedApi: android.Manifest.permission#MODIFY_APPWIDGET_BIND_PERMISSIONS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.MODIFY_APPWIDGET_BIND_PERMISSIONS
+UnflaggedApi: android.Manifest.permission#MODIFY_AUDIO_ROUTING:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.MODIFY_AUDIO_ROUTING
+UnflaggedApi: android.Manifest.permission#MODIFY_AUDIO_SETTINGS_PRIVILEGED:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED
+UnflaggedApi: android.Manifest.permission#MODIFY_CELL_BROADCASTS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.MODIFY_CELL_BROADCASTS
+UnflaggedApi: android.Manifest.permission#MODIFY_DAY_NIGHT_MODE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.MODIFY_DAY_NIGHT_MODE
+UnflaggedApi: android.Manifest.permission#MODIFY_PARENTAL_CONTROLS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.MODIFY_PARENTAL_CONTROLS
+UnflaggedApi: android.Manifest.permission#MODIFY_QUIET_MODE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.MODIFY_QUIET_MODE
+UnflaggedApi: android.Manifest.permission#MODIFY_SETTINGS_OVERRIDEABLE_BY_RESTORE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.MODIFY_SETTINGS_OVERRIDEABLE_BY_RESTORE
+UnflaggedApi: android.Manifest.permission#MONITOR_DEVICE_CONFIG_ACCESS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.MONITOR_DEVICE_CONFIG_ACCESS
+UnflaggedApi: android.Manifest.permission#MOVE_PACKAGE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.MOVE_PACKAGE
+UnflaggedApi: android.Manifest.permission#NETWORK_AIRPLANE_MODE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.NETWORK_AIRPLANE_MODE
+UnflaggedApi: android.Manifest.permission#NETWORK_CARRIER_PROVISIONING:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.NETWORK_CARRIER_PROVISIONING
+UnflaggedApi: android.Manifest.permission#NETWORK_FACTORY:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.NETWORK_FACTORY
+UnflaggedApi: android.Manifest.permission#NETWORK_MANAGED_PROVISIONING:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.NETWORK_MANAGED_PROVISIONING
+UnflaggedApi: android.Manifest.permission#NETWORK_SCAN:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.NETWORK_SCAN
+UnflaggedApi: android.Manifest.permission#NETWORK_SETTINGS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.NETWORK_SETTINGS
+UnflaggedApi: android.Manifest.permission#NETWORK_SETUP_WIZARD:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.NETWORK_SETUP_WIZARD
+UnflaggedApi: android.Manifest.permission#NETWORK_SIGNAL_STRENGTH_WAKEUP:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP
+UnflaggedApi: android.Manifest.permission#NETWORK_STACK:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.NETWORK_STACK
+UnflaggedApi: android.Manifest.permission#NETWORK_STATS_PROVIDER:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.NETWORK_STATS_PROVIDER
+UnflaggedApi: android.Manifest.permission#NFC_SET_CONTROLLER_ALWAYS_ON:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON
+UnflaggedApi: android.Manifest.permission#NOTIFICATION_DURING_SETUP:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.NOTIFICATION_DURING_SETUP
+UnflaggedApi: android.Manifest.permission#NOTIFY_TV_INPUTS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.NOTIFY_TV_INPUTS
+UnflaggedApi: android.Manifest.permission#OBSERVE_APP_USAGE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.OBSERVE_APP_USAGE
+UnflaggedApi: android.Manifest.permission#OBSERVE_NETWORK_POLICY:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.OBSERVE_NETWORK_POLICY
+UnflaggedApi: android.Manifest.permission#OBSERVE_ROLE_HOLDERS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.OBSERVE_ROLE_HOLDERS
+UnflaggedApi: android.Manifest.permission#OBSERVE_SENSOR_PRIVACY:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.OBSERVE_SENSOR_PRIVACY
+UnflaggedApi: android.Manifest.permission#OPEN_ACCESSIBILITY_DETAILS_SETTINGS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.OPEN_ACCESSIBILITY_DETAILS_SETTINGS
+UnflaggedApi: android.Manifest.permission#OVERRIDE_COMPAT_CHANGE_CONFIG_ON_RELEASE_BUILD:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.OVERRIDE_COMPAT_CHANGE_CONFIG_ON_RELEASE_BUILD
+UnflaggedApi: android.Manifest.permission#PACKAGE_VERIFICATION_AGENT:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.PACKAGE_VERIFICATION_AGENT
+UnflaggedApi: android.Manifest.permission#PACKET_KEEPALIVE_OFFLOAD:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.PACKET_KEEPALIVE_OFFLOAD
+UnflaggedApi: android.Manifest.permission#PEERS_MAC_ADDRESS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.PEERS_MAC_ADDRESS
+UnflaggedApi: android.Manifest.permission#PERFORM_CDMA_PROVISIONING:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.PERFORM_CDMA_PROVISIONING
+UnflaggedApi: android.Manifest.permission#PERFORM_IMS_SINGLE_REGISTRATION:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION
+UnflaggedApi: android.Manifest.permission#PERFORM_SIM_ACTIVATION:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.PERFORM_SIM_ACTIVATION
+UnflaggedApi: android.Manifest.permission#POWER_SAVER:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.POWER_SAVER
+UnflaggedApi: android.Manifest.permission#PROVIDE_DEFAULT_ENABLED_CREDENTIAL_SERVICE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.PROVIDE_DEFAULT_ENABLED_CREDENTIAL_SERVICE
+UnflaggedApi: android.Manifest.permission#PROVIDE_RESOLVER_RANKER_SERVICE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.PROVIDE_RESOLVER_RANKER_SERVICE
+UnflaggedApi: android.Manifest.permission#PROVIDE_TRUST_AGENT:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.PROVIDE_TRUST_AGENT
+UnflaggedApi: android.Manifest.permission#PROVISION_DEMO_DEVICE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.PROVISION_DEMO_DEVICE
+UnflaggedApi: android.Manifest.permission#QUERY_ADMIN_POLICY:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.QUERY_ADMIN_POLICY
+UnflaggedApi: android.Manifest.permission#QUERY_CLONED_APPS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.QUERY_CLONED_APPS
+UnflaggedApi: android.Manifest.permission#QUERY_USERS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.QUERY_USERS
+UnflaggedApi: android.Manifest.permission#RADIO_SCAN_WITHOUT_LOCATION:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.RADIO_SCAN_WITHOUT_LOCATION
+UnflaggedApi: android.Manifest.permission#READ_ACTIVE_EMERGENCY_SESSION:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION
+UnflaggedApi: android.Manifest.permission#READ_APP_SPECIFIC_LOCALES:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.READ_APP_SPECIFIC_LOCALES
+UnflaggedApi: android.Manifest.permission#READ_CARRIER_APP_INFO:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.READ_CARRIER_APP_INFO
+UnflaggedApi: android.Manifest.permission#READ_CELL_BROADCASTS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.READ_CELL_BROADCASTS
+UnflaggedApi: android.Manifest.permission#READ_CLIPBOARD_IN_BACKGROUND:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.READ_CLIPBOARD_IN_BACKGROUND
+UnflaggedApi: android.Manifest.permission#READ_CONTENT_RATING_SYSTEMS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.READ_CONTENT_RATING_SYSTEMS
+UnflaggedApi: android.Manifest.permission#READ_DEVICE_CONFIG:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.READ_DEVICE_CONFIG
+UnflaggedApi: android.Manifest.permission#READ_DREAM_STATE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.READ_DREAM_STATE
+UnflaggedApi: android.Manifest.permission#READ_GLOBAL_APP_SEARCH_DATA:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.READ_GLOBAL_APP_SEARCH_DATA
+UnflaggedApi: android.Manifest.permission#READ_INSTALLED_SESSION_PATHS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.READ_INSTALLED_SESSION_PATHS
+UnflaggedApi: android.Manifest.permission#READ_INSTALL_SESSIONS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.READ_INSTALL_SESSIONS
+UnflaggedApi: android.Manifest.permission#READ_NETWORK_USAGE_HISTORY:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.READ_NETWORK_USAGE_HISTORY
+UnflaggedApi: android.Manifest.permission#READ_OEM_UNLOCK_STATE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.READ_OEM_UNLOCK_STATE
+UnflaggedApi: android.Manifest.permission#READ_PEOPLE_DATA:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.READ_PEOPLE_DATA
+UnflaggedApi: android.Manifest.permission#READ_PRINT_SERVICES:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.READ_PRINT_SERVICES
+UnflaggedApi: android.Manifest.permission#READ_PRINT_SERVICE_RECOMMENDATIONS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.READ_PRINT_SERVICE_RECOMMENDATIONS
+UnflaggedApi: android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE
+UnflaggedApi: android.Manifest.permission#READ_PROJECTION_STATE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.READ_PROJECTION_STATE
+UnflaggedApi: android.Manifest.permission#READ_RESTRICTED_STATS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.READ_RESTRICTED_STATS
+UnflaggedApi: android.Manifest.permission#READ_RUNTIME_PROFILES:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.READ_RUNTIME_PROFILES
+UnflaggedApi: android.Manifest.permission#READ_SAFETY_CENTER_STATUS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.READ_SAFETY_CENTER_STATUS
+UnflaggedApi: android.Manifest.permission#READ_SEARCH_INDEXABLES:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.READ_SEARCH_INDEXABLES
+UnflaggedApi: android.Manifest.permission#READ_SYSTEM_UPDATE_INFO:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.READ_SYSTEM_UPDATE_INFO
+UnflaggedApi: android.Manifest.permission#READ_WALLPAPER_INTERNAL:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.READ_WALLPAPER_INTERNAL
+UnflaggedApi: android.Manifest.permission#READ_WIFI_CREDENTIAL:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.READ_WIFI_CREDENTIAL
+UnflaggedApi: android.Manifest.permission#READ_WRITE_SYNC_DISABLED_MODE_CONFIG:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.READ_WRITE_SYNC_DISABLED_MODE_CONFIG
+UnflaggedApi: android.Manifest.permission#REAL_GET_TASKS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.REAL_GET_TASKS
+UnflaggedApi: android.Manifest.permission#RECEIVE_BLUETOOTH_MAP:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.RECEIVE_BLUETOOTH_MAP
+UnflaggedApi: android.Manifest.permission#RECEIVE_DATA_ACTIVITY_CHANGE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.RECEIVE_DATA_ACTIVITY_CHANGE
+UnflaggedApi: android.Manifest.permission#RECEIVE_DEVICE_CUSTOMIZATION_READY:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.RECEIVE_DEVICE_CUSTOMIZATION_READY
+UnflaggedApi: android.Manifest.permission#RECEIVE_EMERGENCY_BROADCAST:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.RECEIVE_EMERGENCY_BROADCAST
+UnflaggedApi: android.Manifest.permission#RECEIVE_WIFI_CREDENTIAL_CHANGE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.RECEIVE_WIFI_CREDENTIAL_CHANGE
+UnflaggedApi: android.Manifest.permission#RECORD_BACKGROUND_AUDIO:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.RECORD_BACKGROUND_AUDIO
+UnflaggedApi: android.Manifest.permission#RECOVERY:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.RECOVERY
+UnflaggedApi: android.Manifest.permission#RECOVER_KEYSTORE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.RECOVER_KEYSTORE
+UnflaggedApi: android.Manifest.permission#REGISTER_CALL_PROVIDER:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.REGISTER_CALL_PROVIDER
+UnflaggedApi: android.Manifest.permission#REGISTER_CONNECTION_MANAGER:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.REGISTER_CONNECTION_MANAGER
+UnflaggedApi: android.Manifest.permission#REGISTER_NSD_OFFLOAD_ENGINE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.REGISTER_NSD_OFFLOAD_ENGINE
+UnflaggedApi: android.Manifest.permission#REGISTER_SIM_SUBSCRIPTION:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.REGISTER_SIM_SUBSCRIPTION
+UnflaggedApi: android.Manifest.permission#REGISTER_STATS_PULL_ATOM:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.REGISTER_STATS_PULL_ATOM
+UnflaggedApi: android.Manifest.permission#REMOTE_DISPLAY_PROVIDER:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.REMOTE_DISPLAY_PROVIDER
+UnflaggedApi: android.Manifest.permission#REMOVE_DRM_CERTIFICATES:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.REMOVE_DRM_CERTIFICATES
+UnflaggedApi: android.Manifest.permission#REMOVE_TASKS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.REMOVE_TASKS
+UnflaggedApi: android.Manifest.permission#RENOUNCE_PERMISSIONS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.RENOUNCE_PERMISSIONS
+UnflaggedApi: android.Manifest.permission#REPORT_USAGE_STATS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.REPORT_USAGE_STATS
+UnflaggedApi: android.Manifest.permission#REQUEST_NOTIFICATION_ASSISTANT_SERVICE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.REQUEST_NOTIFICATION_ASSISTANT_SERVICE
+UnflaggedApi: android.Manifest.permission#RESET_PASSWORD:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.RESET_PASSWORD
+UnflaggedApi: android.Manifest.permission#RESTART_WIFI_SUBSYSTEM:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.RESTART_WIFI_SUBSYSTEM
+UnflaggedApi: android.Manifest.permission#RESTORE_RUNTIME_PERMISSIONS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.RESTORE_RUNTIME_PERMISSIONS
+UnflaggedApi: android.Manifest.permission#RESTRICTED_VR_ACCESS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.RESTRICTED_VR_ACCESS
+UnflaggedApi: android.Manifest.permission#RETRIEVE_WINDOW_CONTENT:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.RETRIEVE_WINDOW_CONTENT
+UnflaggedApi: android.Manifest.permission#REVIEW_ACCESSIBILITY_SERVICES:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.REVIEW_ACCESSIBILITY_SERVICES
+UnflaggedApi: android.Manifest.permission#REVOKE_RUNTIME_PERMISSIONS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS
+UnflaggedApi: android.Manifest.permission#ROTATE_SURFACE_FLINGER:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.ROTATE_SURFACE_FLINGER
+UnflaggedApi: android.Manifest.permission#SATELLITE_COMMUNICATION:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.SATELLITE_COMMUNICATION
+UnflaggedApi: android.Manifest.permission#SCHEDULE_PRIORITIZED_ALARM:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.SCHEDULE_PRIORITIZED_ALARM
+UnflaggedApi: android.Manifest.permission#SECURE_ELEMENT_PRIVILEGED_OPERATION:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.SECURE_ELEMENT_PRIVILEGED_OPERATION
+UnflaggedApi: android.Manifest.permission#SEND_CATEGORY_CAR_NOTIFICATIONS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.SEND_CATEGORY_CAR_NOTIFICATIONS
+UnflaggedApi: android.Manifest.permission#SEND_DEVICE_CUSTOMIZATION_READY:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.SEND_DEVICE_CUSTOMIZATION_READY
+UnflaggedApi: android.Manifest.permission#SEND_SAFETY_CENTER_UPDATE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.SEND_SAFETY_CENTER_UPDATE
+UnflaggedApi: android.Manifest.permission#SEND_SHOW_SUSPENDED_APP_DETAILS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.SEND_SHOW_SUSPENDED_APP_DETAILS
+UnflaggedApi: android.Manifest.permission#SEND_SMS_NO_CONFIRMATION:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.SEND_SMS_NO_CONFIRMATION
+UnflaggedApi: android.Manifest.permission#SERIAL_PORT:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.SERIAL_PORT
+UnflaggedApi: android.Manifest.permission#SET_ACTIVITY_WATCHER:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.SET_ACTIVITY_WATCHER
+UnflaggedApi: android.Manifest.permission#SET_CLIP_SOURCE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.SET_CLIP_SOURCE
+UnflaggedApi: android.Manifest.permission#SET_DEFAULT_ACCOUNT_FOR_CONTACTS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.SET_DEFAULT_ACCOUNT_FOR_CONTACTS
+UnflaggedApi: android.Manifest.permission#SET_HARMFUL_APP_WARNINGS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.SET_HARMFUL_APP_WARNINGS
+UnflaggedApi: android.Manifest.permission#SET_LOW_POWER_STANDBY_PORTS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.SET_LOW_POWER_STANDBY_PORTS
+UnflaggedApi: android.Manifest.permission#SET_MEDIA_KEY_LISTENER:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.SET_MEDIA_KEY_LISTENER
+UnflaggedApi: android.Manifest.permission#SET_ORIENTATION:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.SET_ORIENTATION
+UnflaggedApi: android.Manifest.permission#SET_POINTER_SPEED:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.SET_POINTER_SPEED
+UnflaggedApi: android.Manifest.permission#SET_SCREEN_COMPATIBILITY:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.SET_SCREEN_COMPATIBILITY
+UnflaggedApi: android.Manifest.permission#SET_SYSTEM_AUDIO_CAPTION:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.SET_SYSTEM_AUDIO_CAPTION
+UnflaggedApi: android.Manifest.permission#SET_UNRESTRICTED_KEEP_CLEAR_AREAS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.SET_UNRESTRICTED_KEEP_CLEAR_AREAS
+UnflaggedApi: android.Manifest.permission#SET_VOLUME_KEY_LONG_PRESS_LISTENER:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.SET_VOLUME_KEY_LONG_PRESS_LISTENER
+UnflaggedApi: android.Manifest.permission#SET_WALLPAPER_COMPONENT:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.SET_WALLPAPER_COMPONENT
+UnflaggedApi: android.Manifest.permission#SET_WALLPAPER_DIM_AMOUNT:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.SET_WALLPAPER_DIM_AMOUNT
+UnflaggedApi: android.Manifest.permission#SHOW_KEYGUARD_MESSAGE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.SHOW_KEYGUARD_MESSAGE
+UnflaggedApi: android.Manifest.permission#SHUTDOWN:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.SHUTDOWN
+UnflaggedApi: android.Manifest.permission#SIGNAL_REBOOT_READINESS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.SIGNAL_REBOOT_READINESS
+UnflaggedApi: android.Manifest.permission#SOUND_TRIGGER_RUN_IN_BATTERY_SAVER:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.SOUND_TRIGGER_RUN_IN_BATTERY_SAVER
+UnflaggedApi: android.Manifest.permission#STAGE_HEALTH_CONNECT_REMOTE_DATA:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.STAGE_HEALTH_CONNECT_REMOTE_DATA
+UnflaggedApi: android.Manifest.permission#START_ACTIVITIES_FROM_BACKGROUND:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND
+UnflaggedApi: android.Manifest.permission#START_CROSS_PROFILE_ACTIVITIES:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.START_CROSS_PROFILE_ACTIVITIES
+UnflaggedApi: android.Manifest.permission#START_REVIEW_PERMISSION_DECISIONS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.START_REVIEW_PERMISSION_DECISIONS
+UnflaggedApi: android.Manifest.permission#START_TASKS_FROM_RECENTS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.START_TASKS_FROM_RECENTS
+UnflaggedApi: android.Manifest.permission#STATUS_BAR_SERVICE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.STATUS_BAR_SERVICE
+UnflaggedApi: android.Manifest.permission#STOP_APP_SWITCHES:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.STOP_APP_SWITCHES
+UnflaggedApi: android.Manifest.permission#SUBSTITUTE_NOTIFICATION_APP_NAME:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.SUBSTITUTE_NOTIFICATION_APP_NAME
+UnflaggedApi: android.Manifest.permission#SUBSTITUTE_SHARE_TARGET_APP_NAME_AND_ICON:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.SUBSTITUTE_SHARE_TARGET_APP_NAME_AND_ICON
+UnflaggedApi: android.Manifest.permission#SUGGEST_EXTERNAL_TIME:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.SUGGEST_EXTERNAL_TIME
+UnflaggedApi: android.Manifest.permission#SUSPEND_APPS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.SUSPEND_APPS
+UnflaggedApi: android.Manifest.permission#SYSTEM_APPLICATION_OVERLAY:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.SYSTEM_APPLICATION_OVERLAY
+UnflaggedApi: android.Manifest.permission#SYSTEM_CAMERA:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.SYSTEM_CAMERA
+UnflaggedApi: android.Manifest.permission#TETHER_PRIVILEGED:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.TETHER_PRIVILEGED
+UnflaggedApi: android.Manifest.permission#TIS_EXTENSION_INTERFACE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.TIS_EXTENSION_INTERFACE
+UnflaggedApi: android.Manifest.permission#TOGGLE_AUTOMOTIVE_PROJECTION:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.TOGGLE_AUTOMOTIVE_PROJECTION
+UnflaggedApi: android.Manifest.permission#TRIGGER_LOST_MODE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.TRIGGER_LOST_MODE
+UnflaggedApi: android.Manifest.permission#TV_INPUT_HARDWARE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.TV_INPUT_HARDWARE
+UnflaggedApi: android.Manifest.permission#TV_VIRTUAL_REMOTE_CONTROLLER:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.TV_VIRTUAL_REMOTE_CONTROLLER
+UnflaggedApi: android.Manifest.permission#UNLIMITED_SHORTCUTS_API_CALLS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.UNLIMITED_SHORTCUTS_API_CALLS
+UnflaggedApi: android.Manifest.permission#UPDATE_APP_OPS_STATS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.UPDATE_APP_OPS_STATS
+UnflaggedApi: android.Manifest.permission#UPDATE_DEVICE_MANAGEMENT_RESOURCES:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.UPDATE_DEVICE_MANAGEMENT_RESOURCES
+UnflaggedApi: android.Manifest.permission#UPDATE_DOMAIN_VERIFICATION_USER_SELECTION:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.UPDATE_DOMAIN_VERIFICATION_USER_SELECTION
+UnflaggedApi: android.Manifest.permission#UPDATE_FONTS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.UPDATE_FONTS
+UnflaggedApi: android.Manifest.permission#UPDATE_LOCK:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.UPDATE_LOCK
+UnflaggedApi: android.Manifest.permission#UPGRADE_RUNTIME_PERMISSIONS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.UPGRADE_RUNTIME_PERMISSIONS
+UnflaggedApi: android.Manifest.permission#USER_ACTIVITY:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.USER_ACTIVITY
+UnflaggedApi: android.Manifest.permission#USE_COLORIZED_NOTIFICATIONS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.USE_COLORIZED_NOTIFICATIONS
+UnflaggedApi: android.Manifest.permission#USE_RESERVED_DISK:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.USE_RESERVED_DISK
+UnflaggedApi: android.Manifest.permission#UWB_PRIVILEGED:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.UWB_PRIVILEGED
+UnflaggedApi: android.Manifest.permission#WHITELIST_AUTO_REVOKE_PERMISSIONS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.WHITELIST_AUTO_REVOKE_PERMISSIONS
+UnflaggedApi: android.Manifest.permission#WHITELIST_RESTRICTED_PERMISSIONS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS
+UnflaggedApi: android.Manifest.permission#WIFI_ACCESS_COEX_UNSAFE_CHANNELS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.WIFI_ACCESS_COEX_UNSAFE_CHANNELS
+UnflaggedApi: android.Manifest.permission#WIFI_SET_DEVICE_MOBILITY_STATE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.WIFI_SET_DEVICE_MOBILITY_STATE
+UnflaggedApi: android.Manifest.permission#WIFI_UPDATE_COEX_UNSAFE_CHANNELS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.WIFI_UPDATE_COEX_UNSAFE_CHANNELS
+UnflaggedApi: android.Manifest.permission#WIFI_UPDATE_USABILITY_STATS_SCORE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE
+UnflaggedApi: android.Manifest.permission#WRITE_ALLOWLISTED_DEVICE_CONFIG:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.WRITE_ALLOWLISTED_DEVICE_CONFIG
+UnflaggedApi: android.Manifest.permission#WRITE_DEVICE_CONFIG:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.WRITE_DEVICE_CONFIG
+UnflaggedApi: android.Manifest.permission#WRITE_DREAM_STATE:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.WRITE_DREAM_STATE
+UnflaggedApi: android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS
+UnflaggedApi: android.Manifest.permission#WRITE_OBB:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.WRITE_OBB
+UnflaggedApi: android.Manifest.permission#WRITE_SECURITY_LOG:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.WRITE_SECURITY_LOG
+UnflaggedApi: android.Manifest.permission#WRITE_SMS:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission.WRITE_SMS
+UnflaggedApi: android.Manifest.permission_group#UNDEFINED:
+ New API must be flagged with @FlaggedApi: field android.Manifest.permission_group.UNDEFINED
+UnflaggedApi: android.R.array#config_keySystemUuidMapping:
+ New API must be flagged with @FlaggedApi: field android.R.array.config_keySystemUuidMapping
+UnflaggedApi: android.R.array#config_optionalIpSecAlgorithms:
+ New API must be flagged with @FlaggedApi: field android.R.array.config_optionalIpSecAlgorithms
+UnflaggedApi: android.R.attr#allowClearUserDataOnFailedRestore:
+ New API must be flagged with @FlaggedApi: field android.R.attr.allowClearUserDataOnFailedRestore
+UnflaggedApi: android.R.attr#gameSessionService:
+ New API must be flagged with @FlaggedApi: field android.R.attr.gameSessionService
+UnflaggedApi: android.R.attr#hotwordDetectionService:
+ New API must be flagged with @FlaggedApi: field android.R.attr.hotwordDetectionService
+UnflaggedApi: android.R.attr#isVrOnly:
+ New API must be flagged with @FlaggedApi: field android.R.attr.isVrOnly
+UnflaggedApi: android.R.attr#minExtensionVersion:
+ New API must be flagged with @FlaggedApi: field android.R.attr.minExtensionVersion
+UnflaggedApi: android.R.attr#playHomeTransitionSound:
+ New API must be flagged with @FlaggedApi: field android.R.attr.playHomeTransitionSound
+UnflaggedApi: android.R.attr#requiredSystemPropertyName:
+ New API must be flagged with @FlaggedApi: field android.R.attr.requiredSystemPropertyName
+UnflaggedApi: android.R.attr#requiredSystemPropertyValue:
+ New API must be flagged with @FlaggedApi: field android.R.attr.requiredSystemPropertyValue
+UnflaggedApi: android.R.attr#sdkVersion:
+ New API must be flagged with @FlaggedApi: field android.R.attr.sdkVersion
+UnflaggedApi: android.R.attr#supportsAmbientMode:
+ New API must be flagged with @FlaggedApi: field android.R.attr.supportsAmbientMode
+UnflaggedApi: android.R.attr#userRestriction:
+ New API must be flagged with @FlaggedApi: field android.R.attr.userRestriction
+UnflaggedApi: android.R.attr#visualQueryDetectionService:
+ New API must be flagged with @FlaggedApi: field android.R.attr.visualQueryDetectionService
+UnflaggedApi: android.R.bool#config_enableDefaultNotes:
+ New API must be flagged with @FlaggedApi: field android.R.bool.config_enableDefaultNotes
+UnflaggedApi: android.R.bool#config_enableDefaultNotesForWorkProfile:
+ New API must be flagged with @FlaggedApi: field android.R.bool.config_enableDefaultNotesForWorkProfile
+UnflaggedApi: android.R.bool#config_enableQrCodeScannerOnLockScreen:
+ New API must be flagged with @FlaggedApi: field android.R.bool.config_enableQrCodeScannerOnLockScreen
+UnflaggedApi: android.R.bool#config_safetyProtectionEnabled:
+ New API must be flagged with @FlaggedApi: field android.R.bool.config_safetyProtectionEnabled
+UnflaggedApi: android.R.bool#config_sendPackageName:
+ New API must be flagged with @FlaggedApi: field android.R.bool.config_sendPackageName
+UnflaggedApi: android.R.bool#config_showDefaultAssistant:
+ New API must be flagged with @FlaggedApi: field android.R.bool.config_showDefaultAssistant
+UnflaggedApi: android.R.bool#config_showDefaultEmergency:
+ New API must be flagged with @FlaggedApi: field android.R.bool.config_showDefaultEmergency
+UnflaggedApi: android.R.bool#config_showDefaultHome:
+ New API must be flagged with @FlaggedApi: field android.R.bool.config_showDefaultHome
+UnflaggedApi: android.R.color#system_notification_accent_color:
+ New API must be flagged with @FlaggedApi: field android.R.color.system_notification_accent_color
+UnflaggedApi: android.R.dimen#config_restrictedIconSize:
+ New API must be flagged with @FlaggedApi: field android.R.dimen.config_restrictedIconSize
+UnflaggedApi: android.R.dimen#config_viewConfigurationHandwritingGestureLineMargin:
+ New API must be flagged with @FlaggedApi: field android.R.dimen.config_viewConfigurationHandwritingGestureLineMargin
+UnflaggedApi: android.R.drawable#ic_info:
+ New API must be flagged with @FlaggedApi: field android.R.drawable.ic_info
+UnflaggedApi: android.R.drawable#ic_safety_protection:
+ New API must be flagged with @FlaggedApi: field android.R.drawable.ic_safety_protection
+UnflaggedApi: android.R.raw#loaderror:
+ New API must be flagged with @FlaggedApi: field android.R.raw.loaderror
+UnflaggedApi: android.R.raw#nodomain:
+ New API must be flagged with @FlaggedApi: field android.R.raw.nodomain
+UnflaggedApi: android.R.string#config_customMediaKeyDispatcher:
+ New API must be flagged with @FlaggedApi: field android.R.string.config_customMediaKeyDispatcher
+UnflaggedApi: android.R.string#config_customMediaSessionPolicyProvider:
+ New API must be flagged with @FlaggedApi: field android.R.string.config_customMediaSessionPolicyProvider
+UnflaggedApi: android.R.string#config_defaultAssistant:
+ New API must be flagged with @FlaggedApi: field android.R.string.config_defaultAssistant
+UnflaggedApi: android.R.string#config_defaultAutomotiveNavigation:
+ New API must be flagged with @FlaggedApi: field android.R.string.config_defaultAutomotiveNavigation
+UnflaggedApi: android.R.string#config_defaultBrowser:
+ New API must be flagged with @FlaggedApi: field android.R.string.config_defaultBrowser
+UnflaggedApi: android.R.string#config_defaultCallRedirection:
+ New API must be flagged with @FlaggedApi: field android.R.string.config_defaultCallRedirection
+UnflaggedApi: android.R.string#config_defaultCallScreening:
+ New API must be flagged with @FlaggedApi: field android.R.string.config_defaultCallScreening
+UnflaggedApi: android.R.string#config_defaultDialer:
+ New API must be flagged with @FlaggedApi: field android.R.string.config_defaultDialer
+UnflaggedApi: android.R.string#config_defaultNotes:
+ New API must be flagged with @FlaggedApi: field android.R.string.config_defaultNotes
+UnflaggedApi: android.R.string#config_defaultRetailDemo:
+ New API must be flagged with @FlaggedApi: field android.R.string.config_defaultRetailDemo
+UnflaggedApi: android.R.string#config_defaultSms:
+ New API must be flagged with @FlaggedApi: field android.R.string.config_defaultSms
+UnflaggedApi: android.R.string#config_devicePolicyManagement:
+ New API must be flagged with @FlaggedApi: field android.R.string.config_devicePolicyManagement
+UnflaggedApi: android.R.string#config_feedbackIntentExtraKey:
+ New API must be flagged with @FlaggedApi: field android.R.string.config_feedbackIntentExtraKey
+UnflaggedApi: android.R.string#config_feedbackIntentNameKey:
+ New API must be flagged with @FlaggedApi: field android.R.string.config_feedbackIntentNameKey
+UnflaggedApi: android.R.string#config_helpIntentExtraKey:
+ New API must be flagged with @FlaggedApi: field android.R.string.config_helpIntentExtraKey
+UnflaggedApi: android.R.string#config_helpIntentNameKey:
+ New API must be flagged with @FlaggedApi: field android.R.string.config_helpIntentNameKey
+UnflaggedApi: android.R.string#config_helpPackageNameKey:
+ New API must be flagged with @FlaggedApi: field android.R.string.config_helpPackageNameKey
+UnflaggedApi: android.R.string#config_helpPackageNameValue:
+ New API must be flagged with @FlaggedApi: field android.R.string.config_helpPackageNameValue
+UnflaggedApi: android.R.string#config_systemActivityRecognizer:
+ New API must be flagged with @FlaggedApi: field android.R.string.config_systemActivityRecognizer
+UnflaggedApi: android.R.string#config_systemAmbientAudioIntelligence:
+ New API must be flagged with @FlaggedApi: field android.R.string.config_systemAmbientAudioIntelligence
+UnflaggedApi: android.R.string#config_systemAppProtectionService:
+ New API must be flagged with @FlaggedApi: field android.R.string.config_systemAppProtectionService
+UnflaggedApi: android.R.string#config_systemAudioIntelligence:
+ New API must be flagged with @FlaggedApi: field android.R.string.config_systemAudioIntelligence
+UnflaggedApi: android.R.string#config_systemAutomotiveCalendarSyncManager:
+ New API must be flagged with @FlaggedApi: field android.R.string.config_systemAutomotiveCalendarSyncManager
+UnflaggedApi: android.R.string#config_systemAutomotiveCluster:
+ New API must be flagged with @FlaggedApi: field android.R.string.config_systemAutomotiveCluster
+UnflaggedApi: android.R.string#config_systemAutomotiveProjection:
+ New API must be flagged with @FlaggedApi: field android.R.string.config_systemAutomotiveProjection
+UnflaggedApi: android.R.string#config_systemCallStreaming:
+ New API must be flagged with @FlaggedApi: field android.R.string.config_systemCallStreaming
+UnflaggedApi: android.R.string#config_systemCompanionDeviceProvider:
+ New API must be flagged with @FlaggedApi: field android.R.string.config_systemCompanionDeviceProvider
+UnflaggedApi: android.R.string#config_systemContacts:
+ New API must be flagged with @FlaggedApi: field android.R.string.config_systemContacts
+UnflaggedApi: android.R.string#config_systemFinancedDeviceController:
+ New API must be flagged with @FlaggedApi: field android.R.string.config_systemFinancedDeviceController
+UnflaggedApi: android.R.string#config_systemGallery:
+ New API must be flagged with @FlaggedApi: field android.R.string.config_systemGallery
+UnflaggedApi: android.R.string#config_systemNotificationIntelligence:
+ New API must be flagged with @FlaggedApi: field android.R.string.config_systemNotificationIntelligence
+UnflaggedApi: android.R.string#config_systemSettingsIntelligence:
+ New API must be flagged with @FlaggedApi: field android.R.string.config_systemSettingsIntelligence
+UnflaggedApi: android.R.string#config_systemShell:
+ New API must be flagged with @FlaggedApi: field android.R.string.config_systemShell
+UnflaggedApi: android.R.string#config_systemSpeechRecognizer:
+ New API must be flagged with @FlaggedApi: field android.R.string.config_systemSpeechRecognizer
+UnflaggedApi: android.R.string#config_systemSupervision:
+ New API must be flagged with @FlaggedApi: field android.R.string.config_systemSupervision
+UnflaggedApi: android.R.string#config_systemTelevisionNotificationHandler:
+ New API must be flagged with @FlaggedApi: field android.R.string.config_systemTelevisionNotificationHandler
+UnflaggedApi: android.R.string#config_systemTextIntelligence:
+ New API must be flagged with @FlaggedApi: field android.R.string.config_systemTextIntelligence
+UnflaggedApi: android.R.string#config_systemUi:
+ New API must be flagged with @FlaggedApi: field android.R.string.config_systemUi
+UnflaggedApi: android.R.string#config_systemUiIntelligence:
+ New API must be flagged with @FlaggedApi: field android.R.string.config_systemUiIntelligence
+UnflaggedApi: android.R.string#config_systemVisualIntelligence:
+ New API must be flagged with @FlaggedApi: field android.R.string.config_systemVisualIntelligence
+UnflaggedApi: android.R.string#config_systemWearHealthService:
+ New API must be flagged with @FlaggedApi: field android.R.string.config_systemWearHealthService
+UnflaggedApi: android.R.string#config_systemWellbeing:
+ New API must be flagged with @FlaggedApi: field android.R.string.config_systemWellbeing
+UnflaggedApi: android.R.string#config_systemWifiCoexManager:
+ New API must be flagged with @FlaggedApi: field android.R.string.config_systemWifiCoexManager
+UnflaggedApi: android.R.string#safety_protection_display_text:
+ New API must be flagged with @FlaggedApi: field android.R.string.safety_protection_display_text
+UnflaggedApi: android.R.style#Theme_DeviceDefault_DocumentsUI:
+ New API must be flagged with @FlaggedApi: field android.R.style.Theme_DeviceDefault_DocumentsUI
+UnflaggedApi: android.R.style#Theme_Leanback_FormWizard:
+ New API must be flagged with @FlaggedApi: field android.R.style.Theme_Leanback_FormWizard
+UnflaggedApi: android.app.ActivityManager#getExternalHistoricalProcessStartReasons(String, int):
+ New API must be flagged with @FlaggedApi: method android.app.ActivityManager.getExternalHistoricalProcessStartReasons(String,int)
+UnflaggedApi: android.app.AppOpsManager#OPSTR_RECEIVE_SANDBOX_TRIGGER_AUDIO:
+ New API must be flagged with @FlaggedApi: field android.app.AppOpsManager.OPSTR_RECEIVE_SANDBOX_TRIGGER_AUDIO
+UnflaggedApi: android.app.AppOpsManager.AttributedHistoricalOps#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.app.AppOpsManager.AttributedHistoricalOps.equals(Object)
+UnflaggedApi: android.app.AppOpsManager.AttributedHistoricalOps#hashCode():
+ New API must be flagged with @FlaggedApi: method android.app.AppOpsManager.AttributedHistoricalOps.hashCode()
+UnflaggedApi: android.app.AppOpsManager.HistoricalOp#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.app.AppOpsManager.HistoricalOp.equals(Object)
+UnflaggedApi: android.app.AppOpsManager.HistoricalOp#hashCode():
+ New API must be flagged with @FlaggedApi: method android.app.AppOpsManager.HistoricalOp.hashCode()
+UnflaggedApi: android.app.AppOpsManager.HistoricalOps#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.app.AppOpsManager.HistoricalOps.equals(Object)
+UnflaggedApi: android.app.AppOpsManager.HistoricalOps#hashCode():
+ New API must be flagged with @FlaggedApi: method android.app.AppOpsManager.HistoricalOps.hashCode()
+UnflaggedApi: android.app.AppOpsManager.HistoricalOps#toString():
+ New API must be flagged with @FlaggedApi: method android.app.AppOpsManager.HistoricalOps.toString()
+UnflaggedApi: android.app.AppOpsManager.HistoricalPackageOps#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.app.AppOpsManager.HistoricalPackageOps.equals(Object)
+UnflaggedApi: android.app.AppOpsManager.HistoricalPackageOps#hashCode():
+ New API must be flagged with @FlaggedApi: method android.app.AppOpsManager.HistoricalPackageOps.hashCode()
+UnflaggedApi: android.app.AppOpsManager.HistoricalUidOps#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.app.AppOpsManager.HistoricalUidOps.equals(Object)
+UnflaggedApi: android.app.AppOpsManager.HistoricalUidOps#hashCode():
+ New API must be flagged with @FlaggedApi: method android.app.AppOpsManager.HistoricalUidOps.hashCode()
+UnflaggedApi: android.app.GameModeConfiguration#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.app.GameModeConfiguration.equals(Object)
+UnflaggedApi: android.app.GameModeConfiguration#hashCode():
+ New API must be flagged with @FlaggedApi: method android.app.GameModeConfiguration.hashCode()
+UnflaggedApi: android.app.StatusBarManager.DisableInfo#toString():
+ New API must be flagged with @FlaggedApi: method android.app.StatusBarManager.DisableInfo.toString()
+UnflaggedApi: android.app.Vr2dDisplayProperties#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.app.Vr2dDisplayProperties.equals(Object)
+UnflaggedApi: android.app.Vr2dDisplayProperties#hashCode():
+ New API must be flagged with @FlaggedApi: method android.app.Vr2dDisplayProperties.hashCode()
+UnflaggedApi: android.app.Vr2dDisplayProperties#toString():
+ New API must be flagged with @FlaggedApi: method android.app.Vr2dDisplayProperties.toString()
+UnflaggedApi: android.app.admin.AccountTypePolicyKey#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.app.admin.AccountTypePolicyKey.equals(Object)
+UnflaggedApi: android.app.admin.AccountTypePolicyKey#hashCode():
+ New API must be flagged with @FlaggedApi: method android.app.admin.AccountTypePolicyKey.hashCode()
+UnflaggedApi: android.app.admin.AccountTypePolicyKey#toString():
+ New API must be flagged with @FlaggedApi: method android.app.admin.AccountTypePolicyKey.toString()
+UnflaggedApi: android.app.admin.Authority#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.app.admin.Authority.equals(Object)
+UnflaggedApi: android.app.admin.Authority#hashCode():
+ New API must be flagged with @FlaggedApi: method android.app.admin.Authority.hashCode()
+UnflaggedApi: android.app.admin.DeviceAdminAuthority#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.app.admin.DeviceAdminAuthority.equals(Object)
+UnflaggedApi: android.app.admin.DeviceAdminAuthority#hashCode():
+ New API must be flagged with @FlaggedApi: method android.app.admin.DeviceAdminAuthority.hashCode()
+UnflaggedApi: android.app.admin.DeviceAdminAuthority#toString():
+ New API must be flagged with @FlaggedApi: method android.app.admin.DeviceAdminAuthority.toString()
+UnflaggedApi: android.app.admin.DevicePolicyDrawableResource#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.app.admin.DevicePolicyDrawableResource.equals(Object)
+UnflaggedApi: android.app.admin.DevicePolicyDrawableResource#hashCode():
+ New API must be flagged with @FlaggedApi: method android.app.admin.DevicePolicyDrawableResource.hashCode()
+UnflaggedApi: android.app.admin.DevicePolicyKeyguardService#onDestroy():
+ New API must be flagged with @FlaggedApi: method android.app.admin.DevicePolicyKeyguardService.onDestroy()
+UnflaggedApi: android.app.admin.DevicePolicyResources.Strings:
+ New API must be flagged with @FlaggedApi: class android.app.admin.DevicePolicyResources.Strings
+UnflaggedApi: android.app.admin.DevicePolicyResources.Strings.DefaultAppSettings:
+ New API must be flagged with @FlaggedApi: class android.app.admin.DevicePolicyResources.Strings.DefaultAppSettings
+UnflaggedApi: android.app.admin.DevicePolicyResources.Strings.DefaultAppSettings#HOME_MISSING_WORK_PROFILE_SUPPORT_MESSAGE:
+ New API must be flagged with @FlaggedApi: field android.app.admin.DevicePolicyResources.Strings.DefaultAppSettings.HOME_MISSING_WORK_PROFILE_SUPPORT_MESSAGE
+UnflaggedApi: android.app.admin.DevicePolicyResources.Strings.DefaultAppSettings#WORK_PROFILE_DEFAULT_APPS_TITLE:
+ New API must be flagged with @FlaggedApi: field android.app.admin.DevicePolicyResources.Strings.DefaultAppSettings.WORK_PROFILE_DEFAULT_APPS_TITLE
+UnflaggedApi: android.app.admin.DevicePolicyResources.Strings.PermissionSettings:
+ New API must be flagged with @FlaggedApi: class android.app.admin.DevicePolicyResources.Strings.PermissionSettings
+UnflaggedApi: android.app.admin.DevicePolicyResources.Strings.PermissionSettings#BACKGROUND_ACCESS_DISABLED_BY_ADMIN_MESSAGE:
+ New API must be flagged with @FlaggedApi: field android.app.admin.DevicePolicyResources.Strings.PermissionSettings.BACKGROUND_ACCESS_DISABLED_BY_ADMIN_MESSAGE
+UnflaggedApi: android.app.admin.DevicePolicyResources.Strings.PermissionSettings#BACKGROUND_ACCESS_ENABLED_BY_ADMIN_MESSAGE:
+ New API must be flagged with @FlaggedApi: field android.app.admin.DevicePolicyResources.Strings.PermissionSettings.BACKGROUND_ACCESS_ENABLED_BY_ADMIN_MESSAGE
+UnflaggedApi: android.app.admin.DevicePolicyResources.Strings.PermissionSettings#FOREGROUND_ACCESS_ENABLED_BY_ADMIN_MESSAGE:
+ New API must be flagged with @FlaggedApi: field android.app.admin.DevicePolicyResources.Strings.PermissionSettings.FOREGROUND_ACCESS_ENABLED_BY_ADMIN_MESSAGE
+UnflaggedApi: android.app.admin.DevicePolicyResources.Strings.PermissionSettings#LOCATION_AUTO_GRANTED_MESSAGE:
+ New API must be flagged with @FlaggedApi: field android.app.admin.DevicePolicyResources.Strings.PermissionSettings.LOCATION_AUTO_GRANTED_MESSAGE
+UnflaggedApi: android.app.admin.DevicePolicyState#toString():
+ New API must be flagged with @FlaggedApi: method android.app.admin.DevicePolicyState.toString()
+UnflaggedApi: android.app.admin.DevicePolicyStringResource#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.app.admin.DevicePolicyStringResource.equals(Object)
+UnflaggedApi: android.app.admin.DevicePolicyStringResource#hashCode():
+ New API must be flagged with @FlaggedApi: method android.app.admin.DevicePolicyStringResource.hashCode()
+UnflaggedApi: android.app.admin.DpcAuthority#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.app.admin.DpcAuthority.equals(Object)
+UnflaggedApi: android.app.admin.DpcAuthority#hashCode():
+ New API must be flagged with @FlaggedApi: method android.app.admin.DpcAuthority.hashCode()
+UnflaggedApi: android.app.admin.DpcAuthority#toString():
+ New API must be flagged with @FlaggedApi: method android.app.admin.DpcAuthority.toString()
+UnflaggedApi: android.app.admin.EnforcingAdmin#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.app.admin.EnforcingAdmin.equals(Object)
+UnflaggedApi: android.app.admin.EnforcingAdmin#hashCode():
+ New API must be flagged with @FlaggedApi: method android.app.admin.EnforcingAdmin.hashCode()
+UnflaggedApi: android.app.admin.EnforcingAdmin#toString():
+ New API must be flagged with @FlaggedApi: method android.app.admin.EnforcingAdmin.toString()
+UnflaggedApi: android.app.admin.IntentFilterPolicyKey#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.app.admin.IntentFilterPolicyKey.equals(Object)
+UnflaggedApi: android.app.admin.IntentFilterPolicyKey#hashCode():
+ New API must be flagged with @FlaggedApi: method android.app.admin.IntentFilterPolicyKey.hashCode()
+UnflaggedApi: android.app.admin.IntentFilterPolicyKey#toString():
+ New API must be flagged with @FlaggedApi: method android.app.admin.IntentFilterPolicyKey.toString()
+UnflaggedApi: android.app.admin.LockTaskPolicy#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.app.admin.LockTaskPolicy.equals(Object)
+UnflaggedApi: android.app.admin.LockTaskPolicy#hashCode():
+ New API must be flagged with @FlaggedApi: method android.app.admin.LockTaskPolicy.hashCode()
+UnflaggedApi: android.app.admin.LockTaskPolicy#toString():
+ New API must be flagged with @FlaggedApi: method android.app.admin.LockTaskPolicy.toString()
+UnflaggedApi: android.app.admin.NoArgsPolicyKey#toString():
+ New API must be flagged with @FlaggedApi: method android.app.admin.NoArgsPolicyKey.toString()
+UnflaggedApi: android.app.admin.PackagePermissionPolicyKey#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.app.admin.PackagePermissionPolicyKey.equals(Object)
+UnflaggedApi: android.app.admin.PackagePermissionPolicyKey#hashCode():
+ New API must be flagged with @FlaggedApi: method android.app.admin.PackagePermissionPolicyKey.hashCode()
+UnflaggedApi: android.app.admin.PackagePermissionPolicyKey#toString():
+ New API must be flagged with @FlaggedApi: method android.app.admin.PackagePermissionPolicyKey.toString()
+UnflaggedApi: android.app.admin.PackagePolicyKey#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.app.admin.PackagePolicyKey.equals(Object)
+UnflaggedApi: android.app.admin.PackagePolicyKey#hashCode():
+ New API must be flagged with @FlaggedApi: method android.app.admin.PackagePolicyKey.hashCode()
+UnflaggedApi: android.app.admin.PackagePolicyKey#toString():
+ New API must be flagged with @FlaggedApi: method android.app.admin.PackagePolicyKey.toString()
+UnflaggedApi: android.app.admin.PolicyKey#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.app.admin.PolicyKey.equals(Object)
+UnflaggedApi: android.app.admin.PolicyKey#hashCode():
+ New API must be flagged with @FlaggedApi: method android.app.admin.PolicyKey.hashCode()
+UnflaggedApi: android.app.admin.PolicyState#toString():
+ New API must be flagged with @FlaggedApi: method android.app.admin.PolicyState.toString()
+UnflaggedApi: android.app.admin.RoleAuthority#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.app.admin.RoleAuthority.equals(Object)
+UnflaggedApi: android.app.admin.RoleAuthority#hashCode():
+ New API must be flagged with @FlaggedApi: method android.app.admin.RoleAuthority.hashCode()
+UnflaggedApi: android.app.admin.RoleAuthority#toString():
+ New API must be flagged with @FlaggedApi: method android.app.admin.RoleAuthority.toString()
+UnflaggedApi: android.app.admin.UnknownAuthority#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.app.admin.UnknownAuthority.equals(Object)
+UnflaggedApi: android.app.admin.UnknownAuthority#hashCode():
+ New API must be flagged with @FlaggedApi: method android.app.admin.UnknownAuthority.hashCode()
+UnflaggedApi: android.app.admin.UnknownAuthority#toString():
+ New API must be flagged with @FlaggedApi: method android.app.admin.UnknownAuthority.toString()
+UnflaggedApi: android.app.admin.UserRestrictionPolicyKey#toString():
+ New API must be flagged with @FlaggedApi: method android.app.admin.UserRestrictionPolicyKey.toString()
+UnflaggedApi: android.app.ambientcontext.AmbientContextEvent#toString():
+ New API must be flagged with @FlaggedApi: method android.app.ambientcontext.AmbientContextEvent.toString()
+UnflaggedApi: android.app.ambientcontext.AmbientContextEventRequest#toString():
+ New API must be flagged with @FlaggedApi: method android.app.ambientcontext.AmbientContextEventRequest.toString()
+UnflaggedApi: android.app.assist.ActivityId#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.app.assist.ActivityId.equals(Object)
+UnflaggedApi: android.app.assist.ActivityId#hashCode():
+ New API must be flagged with @FlaggedApi: method android.app.assist.ActivityId.hashCode()
+UnflaggedApi: android.app.assist.ActivityId#toString():
+ New API must be flagged with @FlaggedApi: method android.app.assist.ActivityId.toString()
+UnflaggedApi: android.app.assist.AssistStructure.ViewNode#ViewNode():
+ New API must be flagged with @FlaggedApi: constructor android.app.assist.AssistStructure.ViewNode()
+UnflaggedApi: android.app.backup.RestoreDescription#toString():
+ New API must be flagged with @FlaggedApi: method android.app.backup.RestoreDescription.toString()
+UnflaggedApi: android.app.cloudsearch.SearchRequest#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.app.cloudsearch.SearchRequest.equals(Object)
+UnflaggedApi: android.app.cloudsearch.SearchRequest#hashCode():
+ New API must be flagged with @FlaggedApi: method android.app.cloudsearch.SearchRequest.hashCode()
+UnflaggedApi: android.app.cloudsearch.SearchRequest#toString():
+ New API must be flagged with @FlaggedApi: method android.app.cloudsearch.SearchRequest.toString()
+UnflaggedApi: android.app.cloudsearch.SearchResponse#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.app.cloudsearch.SearchResponse.equals(Object)
+UnflaggedApi: android.app.cloudsearch.SearchResponse#hashCode():
+ New API must be flagged with @FlaggedApi: method android.app.cloudsearch.SearchResponse.hashCode()
+UnflaggedApi: android.app.cloudsearch.SearchResult#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.app.cloudsearch.SearchResult.equals(Object)
+UnflaggedApi: android.app.cloudsearch.SearchResult#hashCode():
+ New API must be flagged with @FlaggedApi: method android.app.cloudsearch.SearchResult.hashCode()
+UnflaggedApi: android.app.prediction.AppPredictionContext#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.app.prediction.AppPredictionContext.equals(Object)
+UnflaggedApi: android.app.prediction.AppPredictionSessionId#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.app.prediction.AppPredictionSessionId.equals(Object)
+UnflaggedApi: android.app.prediction.AppPredictionSessionId#hashCode():
+ New API must be flagged with @FlaggedApi: method android.app.prediction.AppPredictionSessionId.hashCode()
+UnflaggedApi: android.app.prediction.AppPredictionSessionId#toString():
+ New API must be flagged with @FlaggedApi: method android.app.prediction.AppPredictionSessionId.toString()
+UnflaggedApi: android.app.prediction.AppPredictor#finalize():
+ New API must be flagged with @FlaggedApi: method android.app.prediction.AppPredictor.finalize()
+UnflaggedApi: android.app.prediction.AppTarget#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.app.prediction.AppTarget.equals(Object)
+UnflaggedApi: android.app.prediction.AppTargetEvent#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.app.prediction.AppTargetEvent.equals(Object)
+UnflaggedApi: android.app.prediction.AppTargetId#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.app.prediction.AppTargetId.equals(Object)
+UnflaggedApi: android.app.prediction.AppTargetId#hashCode():
+ New API must be flagged with @FlaggedApi: method android.app.prediction.AppTargetId.hashCode()
+UnflaggedApi: android.app.search.SearchAction#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.app.search.SearchAction.equals(Object)
+UnflaggedApi: android.app.search.SearchAction#hashCode():
+ New API must be flagged with @FlaggedApi: method android.app.search.SearchAction.hashCode()
+UnflaggedApi: android.app.search.SearchAction#toString():
+ New API must be flagged with @FlaggedApi: method android.app.search.SearchAction.toString()
+UnflaggedApi: android.app.search.SearchSessionId#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.app.search.SearchSessionId.equals(Object)
+UnflaggedApi: android.app.search.SearchSessionId#hashCode():
+ New API must be flagged with @FlaggedApi: method android.app.search.SearchSessionId.hashCode()
+UnflaggedApi: android.app.search.SearchSessionId#toString():
+ New API must be flagged with @FlaggedApi: method android.app.search.SearchSessionId.toString()
+UnflaggedApi: android.app.search.SearchTargetEvent#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.app.search.SearchTargetEvent.equals(Object)
+UnflaggedApi: android.app.search.SearchTargetEvent#hashCode():
+ New API must be flagged with @FlaggedApi: method android.app.search.SearchTargetEvent.hashCode()
+UnflaggedApi: android.app.smartspace.SmartspaceAction#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.app.smartspace.SmartspaceAction.equals(Object)
+UnflaggedApi: android.app.smartspace.SmartspaceAction#hashCode():
+ New API must be flagged with @FlaggedApi: method android.app.smartspace.SmartspaceAction.hashCode()
+UnflaggedApi: android.app.smartspace.SmartspaceAction#toString():
+ New API must be flagged with @FlaggedApi: method android.app.smartspace.SmartspaceAction.toString()
+UnflaggedApi: android.app.smartspace.SmartspaceConfig#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.app.smartspace.SmartspaceConfig.equals(Object)
+UnflaggedApi: android.app.smartspace.SmartspaceConfig#hashCode():
+ New API must be flagged with @FlaggedApi: method android.app.smartspace.SmartspaceConfig.hashCode()
+UnflaggedApi: android.app.smartspace.SmartspaceSessionId#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.app.smartspace.SmartspaceSessionId.equals(Object)
+UnflaggedApi: android.app.smartspace.SmartspaceSessionId#hashCode():
+ New API must be flagged with @FlaggedApi: method android.app.smartspace.SmartspaceSessionId.hashCode()
+UnflaggedApi: android.app.smartspace.SmartspaceSessionId#toString():
+ New API must be flagged with @FlaggedApi: method android.app.smartspace.SmartspaceSessionId.toString()
+UnflaggedApi: android.app.smartspace.SmartspaceTarget#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.app.smartspace.SmartspaceTarget.equals(Object)
+UnflaggedApi: android.app.smartspace.SmartspaceTarget#hashCode():
+ New API must be flagged with @FlaggedApi: method android.app.smartspace.SmartspaceTarget.hashCode()
+UnflaggedApi: android.app.smartspace.SmartspaceTarget#toString():
+ New API must be flagged with @FlaggedApi: method android.app.smartspace.SmartspaceTarget.toString()
+UnflaggedApi: android.app.smartspace.SmartspaceTargetEvent#toString():
+ New API must be flagged with @FlaggedApi: method android.app.smartspace.SmartspaceTargetEvent.toString()
+UnflaggedApi: android.app.smartspace.uitemplatedata.BaseTemplateData#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.app.smartspace.uitemplatedata.BaseTemplateData.equals(Object)
+UnflaggedApi: android.app.smartspace.uitemplatedata.BaseTemplateData#hashCode():
+ New API must be flagged with @FlaggedApi: method android.app.smartspace.uitemplatedata.BaseTemplateData.hashCode()
+UnflaggedApi: android.app.smartspace.uitemplatedata.BaseTemplateData#toString():
+ New API must be flagged with @FlaggedApi: method android.app.smartspace.uitemplatedata.BaseTemplateData.toString()
+UnflaggedApi: android.app.smartspace.uitemplatedata.BaseTemplateData.SubItemInfo#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.app.smartspace.uitemplatedata.BaseTemplateData.SubItemInfo.equals(Object)
+UnflaggedApi: android.app.smartspace.uitemplatedata.BaseTemplateData.SubItemInfo#hashCode():
+ New API must be flagged with @FlaggedApi: method android.app.smartspace.uitemplatedata.BaseTemplateData.SubItemInfo.hashCode()
+UnflaggedApi: android.app.smartspace.uitemplatedata.BaseTemplateData.SubItemInfo#toString():
+ New API must be flagged with @FlaggedApi: method android.app.smartspace.uitemplatedata.BaseTemplateData.SubItemInfo.toString()
+UnflaggedApi: android.app.smartspace.uitemplatedata.BaseTemplateData.SubItemLoggingInfo#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.app.smartspace.uitemplatedata.BaseTemplateData.SubItemLoggingInfo.equals(Object)
+UnflaggedApi: android.app.smartspace.uitemplatedata.BaseTemplateData.SubItemLoggingInfo#hashCode():
+ New API must be flagged with @FlaggedApi: method android.app.smartspace.uitemplatedata.BaseTemplateData.SubItemLoggingInfo.hashCode()
+UnflaggedApi: android.app.smartspace.uitemplatedata.BaseTemplateData.SubItemLoggingInfo#toString():
+ New API must be flagged with @FlaggedApi: method android.app.smartspace.uitemplatedata.BaseTemplateData.SubItemLoggingInfo.toString()
+UnflaggedApi: android.app.smartspace.uitemplatedata.CarouselTemplateData#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.app.smartspace.uitemplatedata.CarouselTemplateData.equals(Object)
+UnflaggedApi: android.app.smartspace.uitemplatedata.CarouselTemplateData#hashCode():
+ New API must be flagged with @FlaggedApi: method android.app.smartspace.uitemplatedata.CarouselTemplateData.hashCode()
+UnflaggedApi: android.app.smartspace.uitemplatedata.CarouselTemplateData#toString():
+ New API must be flagged with @FlaggedApi: method android.app.smartspace.uitemplatedata.CarouselTemplateData.toString()
+UnflaggedApi: android.app.smartspace.uitemplatedata.CarouselTemplateData.CarouselItem#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.app.smartspace.uitemplatedata.CarouselTemplateData.CarouselItem.equals(Object)
+UnflaggedApi: android.app.smartspace.uitemplatedata.CarouselTemplateData.CarouselItem#hashCode():
+ New API must be flagged with @FlaggedApi: method android.app.smartspace.uitemplatedata.CarouselTemplateData.CarouselItem.hashCode()
+UnflaggedApi: android.app.smartspace.uitemplatedata.CarouselTemplateData.CarouselItem#toString():
+ New API must be flagged with @FlaggedApi: method android.app.smartspace.uitemplatedata.CarouselTemplateData.CarouselItem.toString()
+UnflaggedApi: android.app.smartspace.uitemplatedata.CombinedCardsTemplateData#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.app.smartspace.uitemplatedata.CombinedCardsTemplateData.equals(Object)
+UnflaggedApi: android.app.smartspace.uitemplatedata.CombinedCardsTemplateData#hashCode():
+ New API must be flagged with @FlaggedApi: method android.app.smartspace.uitemplatedata.CombinedCardsTemplateData.hashCode()
+UnflaggedApi: android.app.smartspace.uitemplatedata.CombinedCardsTemplateData#toString():
+ New API must be flagged with @FlaggedApi: method android.app.smartspace.uitemplatedata.CombinedCardsTemplateData.toString()
+UnflaggedApi: android.app.smartspace.uitemplatedata.HeadToHeadTemplateData#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.app.smartspace.uitemplatedata.HeadToHeadTemplateData.equals(Object)
+UnflaggedApi: android.app.smartspace.uitemplatedata.HeadToHeadTemplateData#hashCode():
+ New API must be flagged with @FlaggedApi: method android.app.smartspace.uitemplatedata.HeadToHeadTemplateData.hashCode()
+UnflaggedApi: android.app.smartspace.uitemplatedata.HeadToHeadTemplateData#toString():
+ New API must be flagged with @FlaggedApi: method android.app.smartspace.uitemplatedata.HeadToHeadTemplateData.toString()
+UnflaggedApi: android.app.smartspace.uitemplatedata.Icon#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.app.smartspace.uitemplatedata.Icon.equals(Object)
+UnflaggedApi: android.app.smartspace.uitemplatedata.Icon#hashCode():
+ New API must be flagged with @FlaggedApi: method android.app.smartspace.uitemplatedata.Icon.hashCode()
+UnflaggedApi: android.app.smartspace.uitemplatedata.Icon#toString():
+ New API must be flagged with @FlaggedApi: method android.app.smartspace.uitemplatedata.Icon.toString()
+UnflaggedApi: android.app.smartspace.uitemplatedata.SubCardTemplateData#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.app.smartspace.uitemplatedata.SubCardTemplateData.equals(Object)
+UnflaggedApi: android.app.smartspace.uitemplatedata.SubCardTemplateData#hashCode():
+ New API must be flagged with @FlaggedApi: method android.app.smartspace.uitemplatedata.SubCardTemplateData.hashCode()
+UnflaggedApi: android.app.smartspace.uitemplatedata.SubCardTemplateData#toString():
+ New API must be flagged with @FlaggedApi: method android.app.smartspace.uitemplatedata.SubCardTemplateData.toString()
+UnflaggedApi: android.app.smartspace.uitemplatedata.SubImageTemplateData#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.app.smartspace.uitemplatedata.SubImageTemplateData.equals(Object)
+UnflaggedApi: android.app.smartspace.uitemplatedata.SubImageTemplateData#hashCode():
+ New API must be flagged with @FlaggedApi: method android.app.smartspace.uitemplatedata.SubImageTemplateData.hashCode()
+UnflaggedApi: android.app.smartspace.uitemplatedata.SubImageTemplateData#toString():
+ New API must be flagged with @FlaggedApi: method android.app.smartspace.uitemplatedata.SubImageTemplateData.toString()
+UnflaggedApi: android.app.smartspace.uitemplatedata.SubListTemplateData#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.app.smartspace.uitemplatedata.SubListTemplateData.equals(Object)
+UnflaggedApi: android.app.smartspace.uitemplatedata.SubListTemplateData#hashCode():
+ New API must be flagged with @FlaggedApi: method android.app.smartspace.uitemplatedata.SubListTemplateData.hashCode()
+UnflaggedApi: android.app.smartspace.uitemplatedata.SubListTemplateData#toString():
+ New API must be flagged with @FlaggedApi: method android.app.smartspace.uitemplatedata.SubListTemplateData.toString()
+UnflaggedApi: android.app.smartspace.uitemplatedata.TapAction#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.app.smartspace.uitemplatedata.TapAction.equals(Object)
+UnflaggedApi: android.app.smartspace.uitemplatedata.TapAction#hashCode():
+ New API must be flagged with @FlaggedApi: method android.app.smartspace.uitemplatedata.TapAction.hashCode()
+UnflaggedApi: android.app.smartspace.uitemplatedata.TapAction#toString():
+ New API must be flagged with @FlaggedApi: method android.app.smartspace.uitemplatedata.TapAction.toString()
+UnflaggedApi: android.app.smartspace.uitemplatedata.Text#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.app.smartspace.uitemplatedata.Text.equals(Object)
+UnflaggedApi: android.app.smartspace.uitemplatedata.Text#hashCode():
+ New API must be flagged with @FlaggedApi: method android.app.smartspace.uitemplatedata.Text.hashCode()
+UnflaggedApi: android.app.smartspace.uitemplatedata.Text#toString():
+ New API must be flagged with @FlaggedApi: method android.app.smartspace.uitemplatedata.Text.toString()
+UnflaggedApi: android.app.time.ExternalTimeSuggestion#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.app.time.ExternalTimeSuggestion.equals(Object)
+UnflaggedApi: android.app.time.ExternalTimeSuggestion#hashCode():
+ New API must be flagged with @FlaggedApi: method android.app.time.ExternalTimeSuggestion.hashCode()
+UnflaggedApi: android.app.time.ExternalTimeSuggestion#toString():
+ New API must be flagged with @FlaggedApi: method android.app.time.ExternalTimeSuggestion.toString()
+UnflaggedApi: android.app.time.TimeCapabilities#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.app.time.TimeCapabilities.equals(Object)
+UnflaggedApi: android.app.time.TimeCapabilities#hashCode():
+ New API must be flagged with @FlaggedApi: method android.app.time.TimeCapabilities.hashCode()
+UnflaggedApi: android.app.time.TimeCapabilities#toString():
+ New API must be flagged with @FlaggedApi: method android.app.time.TimeCapabilities.toString()
+UnflaggedApi: android.app.time.TimeCapabilitiesAndConfig#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.app.time.TimeCapabilitiesAndConfig.equals(Object)
+UnflaggedApi: android.app.time.TimeCapabilitiesAndConfig#hashCode():
+ New API must be flagged with @FlaggedApi: method android.app.time.TimeCapabilitiesAndConfig.hashCode()
+UnflaggedApi: android.app.time.TimeCapabilitiesAndConfig#toString():
+ New API must be flagged with @FlaggedApi: method android.app.time.TimeCapabilitiesAndConfig.toString()
+UnflaggedApi: android.app.time.TimeConfiguration#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.app.time.TimeConfiguration.equals(Object)
+UnflaggedApi: android.app.time.TimeConfiguration#hashCode():
+ New API must be flagged with @FlaggedApi: method android.app.time.TimeConfiguration.hashCode()
+UnflaggedApi: android.app.time.TimeConfiguration#toString():
+ New API must be flagged with @FlaggedApi: method android.app.time.TimeConfiguration.toString()
+UnflaggedApi: android.app.time.TimeState#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.app.time.TimeState.equals(Object)
+UnflaggedApi: android.app.time.TimeState#hashCode():
+ New API must be flagged with @FlaggedApi: method android.app.time.TimeState.hashCode()
+UnflaggedApi: android.app.time.TimeState#toString():
+ New API must be flagged with @FlaggedApi: method android.app.time.TimeState.toString()
+UnflaggedApi: android.app.time.TimeZoneCapabilities#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.app.time.TimeZoneCapabilities.equals(Object)
+UnflaggedApi: android.app.time.TimeZoneCapabilities#hashCode():
+ New API must be flagged with @FlaggedApi: method android.app.time.TimeZoneCapabilities.hashCode()
+UnflaggedApi: android.app.time.TimeZoneCapabilities#toString():
+ New API must be flagged with @FlaggedApi: method android.app.time.TimeZoneCapabilities.toString()
+UnflaggedApi: android.app.time.TimeZoneCapabilitiesAndConfig#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.app.time.TimeZoneCapabilitiesAndConfig.equals(Object)
+UnflaggedApi: android.app.time.TimeZoneCapabilitiesAndConfig#hashCode():
+ New API must be flagged with @FlaggedApi: method android.app.time.TimeZoneCapabilitiesAndConfig.hashCode()
+UnflaggedApi: android.app.time.TimeZoneCapabilitiesAndConfig#toString():
+ New API must be flagged with @FlaggedApi: method android.app.time.TimeZoneCapabilitiesAndConfig.toString()
+UnflaggedApi: android.app.time.TimeZoneConfiguration#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.app.time.TimeZoneConfiguration.equals(Object)
+UnflaggedApi: android.app.time.TimeZoneConfiguration#hashCode():
+ New API must be flagged with @FlaggedApi: method android.app.time.TimeZoneConfiguration.hashCode()
+UnflaggedApi: android.app.time.TimeZoneConfiguration#toString():
+ New API must be flagged with @FlaggedApi: method android.app.time.TimeZoneConfiguration.toString()
+UnflaggedApi: android.app.time.TimeZoneState#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.app.time.TimeZoneState.equals(Object)
+UnflaggedApi: android.app.time.TimeZoneState#hashCode():
+ New API must be flagged with @FlaggedApi: method android.app.time.TimeZoneState.hashCode()
+UnflaggedApi: android.app.time.TimeZoneState#toString():
+ New API must be flagged with @FlaggedApi: method android.app.time.TimeZoneState.toString()
+UnflaggedApi: android.app.time.UnixEpochTime#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.app.time.UnixEpochTime.equals(Object)
+UnflaggedApi: android.app.time.UnixEpochTime#hashCode():
+ New API must be flagged with @FlaggedApi: method android.app.time.UnixEpochTime.hashCode()
+UnflaggedApi: android.app.time.UnixEpochTime#toString():
+ New API must be flagged with @FlaggedApi: method android.app.time.UnixEpochTime.toString()
+UnflaggedApi: android.app.usage.BroadcastResponseStats#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.app.usage.BroadcastResponseStats.equals(Object)
+UnflaggedApi: android.app.usage.BroadcastResponseStats#hashCode():
+ New API must be flagged with @FlaggedApi: method android.app.usage.BroadcastResponseStats.hashCode()
+UnflaggedApi: android.app.usage.BroadcastResponseStats#toString():
+ New API must be flagged with @FlaggedApi: method android.app.usage.BroadcastResponseStats.toString()
+UnflaggedApi: android.app.usage.CacheQuotaHint#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.app.usage.CacheQuotaHint.equals(Object)
+UnflaggedApi: android.app.usage.CacheQuotaHint#hashCode():
+ New API must be flagged with @FlaggedApi: method android.app.usage.CacheQuotaHint.hashCode()
+UnflaggedApi: android.app.usage.CacheQuotaService#onCreate():
+ New API must be flagged with @FlaggedApi: method android.app.usage.CacheQuotaService.onCreate()
+UnflaggedApi: android.app.usage.UsageEvents.Event#NOTIFICATION_INTERRUPTION:
+ New API must be flagged with @FlaggedApi: field android.app.usage.UsageEvents.Event.NOTIFICATION_INTERRUPTION
+UnflaggedApi: android.app.usage.UsageEvents.Event#NOTIFICATION_SEEN:
+ New API must be flagged with @FlaggedApi: field android.app.usage.UsageEvents.Event.NOTIFICATION_SEEN
+UnflaggedApi: android.app.usage.UsageEvents.Event#SLICE_PINNED:
+ New API must be flagged with @FlaggedApi: field android.app.usage.UsageEvents.Event.SLICE_PINNED
+UnflaggedApi: android.app.usage.UsageEvents.Event#SLICE_PINNED_PRIV:
+ New API must be flagged with @FlaggedApi: field android.app.usage.UsageEvents.Event.SLICE_PINNED_PRIV
+UnflaggedApi: android.app.usage.UsageEvents.Event#SYSTEM_INTERACTION:
+ New API must be flagged with @FlaggedApi: field android.app.usage.UsageEvents.Event.SYSTEM_INTERACTION
+UnflaggedApi: android.app.usage.UsageEvents.Event#getInstanceId():
+ New API must be flagged with @FlaggedApi: method android.app.usage.UsageEvents.Event.getInstanceId()
+UnflaggedApi: android.app.usage.UsageEvents.Event#getNotificationChannelId():
+ New API must be flagged with @FlaggedApi: method android.app.usage.UsageEvents.Event.getNotificationChannelId()
+UnflaggedApi: android.app.usage.UsageEvents.Event#getTaskRootClassName():
+ New API must be flagged with @FlaggedApi: method android.app.usage.UsageEvents.Event.getTaskRootClassName()
+UnflaggedApi: android.app.usage.UsageEvents.Event#getTaskRootPackageName():
+ New API must be flagged with @FlaggedApi: method android.app.usage.UsageEvents.Event.getTaskRootPackageName()
+UnflaggedApi: android.app.usage.UsageEvents.Event#isInstantApp():
+ New API must be flagged with @FlaggedApi: method android.app.usage.UsageEvents.Event.isInstantApp()
+UnflaggedApi: android.app.wallpapereffectsgeneration.CinematicEffectRequest#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.app.wallpapereffectsgeneration.CinematicEffectRequest.equals(Object)
+UnflaggedApi: android.app.wallpapereffectsgeneration.CinematicEffectRequest#hashCode():
+ New API must be flagged with @FlaggedApi: method android.app.wallpapereffectsgeneration.CinematicEffectRequest.hashCode()
+UnflaggedApi: android.app.wallpapereffectsgeneration.CinematicEffectResponse#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.app.wallpapereffectsgeneration.CinematicEffectResponse.equals(Object)
+UnflaggedApi: android.app.wallpapereffectsgeneration.CinematicEffectResponse#hashCode():
+ New API must be flagged with @FlaggedApi: method android.app.wallpapereffectsgeneration.CinematicEffectResponse.hashCode()
+UnflaggedApi: android.companion.virtual.VirtualDeviceManager.VirtualDevice#getPersistentDeviceId():
+ New API must be flagged with @FlaggedApi: method android.companion.virtual.VirtualDeviceManager.VirtualDevice.getPersistentDeviceId()
+UnflaggedApi: android.companion.virtual.VirtualDeviceParams#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.companion.virtual.VirtualDeviceParams.equals(Object)
+UnflaggedApi: android.companion.virtual.VirtualDeviceParams#hashCode():
+ New API must be flagged with @FlaggedApi: method android.companion.virtual.VirtualDeviceParams.hashCode()
+UnflaggedApi: android.companion.virtual.VirtualDeviceParams#toString():
+ New API must be flagged with @FlaggedApi: method android.companion.virtual.VirtualDeviceParams.toString()
+UnflaggedApi: android.companion.virtual.sensor.VirtualSensorConfig#toString():
+ New API must be flagged with @FlaggedApi: method android.companion.virtual.sensor.VirtualSensorConfig.toString()
+UnflaggedApi: android.content.Intent#ACTION_UNARCHIVE_PACKAGE:
+ New API must be flagged with @FlaggedApi: field android.content.Intent.ACTION_UNARCHIVE_PACKAGE
+UnflaggedApi: android.content.integrity.Rule#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.content.integrity.Rule.equals(Object)
+UnflaggedApi: android.content.integrity.Rule#hashCode():
+ New API must be flagged with @FlaggedApi: method android.content.integrity.Rule.hashCode()
+UnflaggedApi: android.content.integrity.Rule#toString():
+ New API must be flagged with @FlaggedApi: method android.content.integrity.Rule.toString()
+UnflaggedApi: android.content.pm.PackageArchiver:
+ New API must be flagged with @FlaggedApi: class android.content.pm.PackageArchiver
+UnflaggedApi: android.content.pm.PackageArchiver#EXTRA_UNARCHIVE_ALL_USERS:
+ New API must be flagged with @FlaggedApi: field android.content.pm.PackageArchiver.EXTRA_UNARCHIVE_ALL_USERS
+UnflaggedApi: android.content.pm.PackageArchiver#EXTRA_UNARCHIVE_PACKAGE_NAME:
+ New API must be flagged with @FlaggedApi: field android.content.pm.PackageArchiver.EXTRA_UNARCHIVE_PACKAGE_NAME
+UnflaggedApi: android.content.pm.PackageArchiver#requestArchive(String, android.content.IntentSender):
+ New API must be flagged with @FlaggedApi: method android.content.pm.PackageArchiver.requestArchive(String,android.content.IntentSender)
+UnflaggedApi: android.content.pm.PackageArchiver#requestUnarchive(String):
+ New API must be flagged with @FlaggedApi: method android.content.pm.PackageArchiver.requestUnarchive(String)
+UnflaggedApi: android.content.pm.PackageInfo#isArchived:
+ New API must be flagged with @FlaggedApi: field android.content.pm.PackageInfo.isArchived
+UnflaggedApi: android.content.pm.PackageInstaller#readInstallInfo(android.os.ParcelFileDescriptor, String, int):
+ New API must be flagged with @FlaggedApi: method android.content.pm.PackageInstaller.readInstallInfo(android.os.ParcelFileDescriptor,String,int)
+UnflaggedApi: android.content.pm.PackageInstaller.InstallInfo#calculateInstalledSize(android.content.pm.PackageInstaller.SessionParams, android.os.ParcelFileDescriptor):
+ New API must be flagged with @FlaggedApi: method android.content.pm.PackageInstaller.InstallInfo.calculateInstalledSize(android.content.pm.PackageInstaller.SessionParams,android.os.ParcelFileDescriptor)
+UnflaggedApi: android.content.pm.PackageInstaller.SessionInfo#getResolvedBaseApkPath():
+ New API must be flagged with @FlaggedApi: method android.content.pm.PackageInstaller.SessionInfo.getResolvedBaseApkPath()
+UnflaggedApi: android.content.pm.PackageManager#EXTRA_REQUEST_PERMISSIONS_DEVICE_ID:
+ New API must be flagged with @FlaggedApi: field android.content.pm.PackageManager.EXTRA_REQUEST_PERMISSIONS_DEVICE_ID
+UnflaggedApi: android.content.pm.PackageManager#MATCH_ARCHIVED_PACKAGES:
+ New API must be flagged with @FlaggedApi: field android.content.pm.PackageManager.MATCH_ARCHIVED_PACKAGES
+UnflaggedApi: android.content.pm.PackageManager#getPackageArchiver():
+ New API must be flagged with @FlaggedApi: method android.content.pm.PackageManager.getPackageArchiver()
+UnflaggedApi: android.content.pm.SuspendDialogInfo#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.content.pm.SuspendDialogInfo.equals(Object)
+UnflaggedApi: android.content.pm.SuspendDialogInfo#hashCode():
+ New API must be flagged with @FlaggedApi: method android.content.pm.SuspendDialogInfo.hashCode()
+UnflaggedApi: android.content.pm.SuspendDialogInfo#toString():
+ New API must be flagged with @FlaggedApi: method android.content.pm.SuspendDialogInfo.toString()
+UnflaggedApi: android.content.pm.UserProperties#toString():
+ New API must be flagged with @FlaggedApi: method android.content.pm.UserProperties.toString()
+UnflaggedApi: android.content.pm.verify.domain.DomainOwner#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.content.pm.verify.domain.DomainOwner.equals(Object)
+UnflaggedApi: android.content.pm.verify.domain.DomainOwner#hashCode():
+ New API must be flagged with @FlaggedApi: method android.content.pm.verify.domain.DomainOwner.hashCode()
+UnflaggedApi: android.content.pm.verify.domain.DomainOwner#toString():
+ New API must be flagged with @FlaggedApi: method android.content.pm.verify.domain.DomainOwner.toString()
+UnflaggedApi: android.content.pm.verify.domain.DomainVerificationInfo#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.content.pm.verify.domain.DomainVerificationInfo.equals(Object)
+UnflaggedApi: android.content.pm.verify.domain.DomainVerificationInfo#hashCode():
+ New API must be flagged with @FlaggedApi: method android.content.pm.verify.domain.DomainVerificationInfo.hashCode()
+UnflaggedApi: android.content.pm.verify.domain.DomainVerificationInfo#toString():
+ New API must be flagged with @FlaggedApi: method android.content.pm.verify.domain.DomainVerificationInfo.toString()
+UnflaggedApi: android.content.pm.verify.domain.DomainVerificationRequest#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.content.pm.verify.domain.DomainVerificationRequest.equals(Object)
+UnflaggedApi: android.content.pm.verify.domain.DomainVerificationRequest#hashCode():
+ New API must be flagged with @FlaggedApi: method android.content.pm.verify.domain.DomainVerificationRequest.hashCode()
+UnflaggedApi: android.hardware.biometrics.BiometricManager.Authenticators#BIOMETRIC_CONVENIENCE:
+ New API must be flagged with @FlaggedApi: field android.hardware.biometrics.BiometricManager.Authenticators.BIOMETRIC_CONVENIENCE
+UnflaggedApi: android.hardware.biometrics.BiometricManager.Authenticators#EMPTY_SET:
+ New API must be flagged with @FlaggedApi: field android.hardware.biometrics.BiometricManager.Authenticators.EMPTY_SET
+UnflaggedApi: android.hardware.display.AmbientBrightnessDayStats#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.hardware.display.AmbientBrightnessDayStats.equals(Object)
+UnflaggedApi: android.hardware.display.AmbientBrightnessDayStats#hashCode():
+ New API must be flagged with @FlaggedApi: method android.hardware.display.AmbientBrightnessDayStats.hashCode()
+UnflaggedApi: android.hardware.display.AmbientBrightnessDayStats#toString():
+ New API must be flagged with @FlaggedApi: method android.hardware.display.AmbientBrightnessDayStats.toString()
+UnflaggedApi: android.hardware.display.BrightnessChangeEvent#toString():
+ New API must be flagged with @FlaggedApi: method android.hardware.display.BrightnessChangeEvent.toString()
+UnflaggedApi: android.hardware.display.BrightnessConfiguration#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.hardware.display.BrightnessConfiguration.equals(Object)
+UnflaggedApi: android.hardware.display.BrightnessConfiguration#hashCode():
+ New API must be flagged with @FlaggedApi: method android.hardware.display.BrightnessConfiguration.hashCode()
+UnflaggedApi: android.hardware.display.BrightnessConfiguration#toString():
+ New API must be flagged with @FlaggedApi: method android.hardware.display.BrightnessConfiguration.toString()
+UnflaggedApi: android.hardware.display.BrightnessCorrection#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.hardware.display.BrightnessCorrection.equals(Object)
+UnflaggedApi: android.hardware.display.BrightnessCorrection#hashCode():
+ New API must be flagged with @FlaggedApi: method android.hardware.display.BrightnessCorrection.hashCode()
+UnflaggedApi: android.hardware.display.BrightnessCorrection#toString():
+ New API must be flagged with @FlaggedApi: method android.hardware.display.BrightnessCorrection.toString()
+UnflaggedApi: android.hardware.hdmi.HdmiDeviceInfo#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.hardware.hdmi.HdmiDeviceInfo.equals(Object)
+UnflaggedApi: android.hardware.hdmi.HdmiDeviceInfo#hashCode():
+ New API must be flagged with @FlaggedApi: method android.hardware.hdmi.HdmiDeviceInfo.hashCode()
+UnflaggedApi: android.hardware.hdmi.HdmiDeviceInfo#toString():
+ New API must be flagged with @FlaggedApi: method android.hardware.hdmi.HdmiDeviceInfo.toString()
+UnflaggedApi: android.hardware.hdmi.HdmiPortInfo#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.hardware.hdmi.HdmiPortInfo.equals(Object)
+UnflaggedApi: android.hardware.hdmi.HdmiPortInfo#hashCode():
+ New API must be flagged with @FlaggedApi: method android.hardware.hdmi.HdmiPortInfo.hashCode()
+UnflaggedApi: android.hardware.hdmi.HdmiPortInfo#toString():
+ New API must be flagged with @FlaggedApi: method android.hardware.hdmi.HdmiPortInfo.toString()
+UnflaggedApi: android.hardware.location.ContextHubClient#finalize():
+ New API must be flagged with @FlaggedApi: method android.hardware.location.ContextHubClient.finalize()
+UnflaggedApi: android.hardware.location.ContextHubInfo#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.hardware.location.ContextHubInfo.equals(Object)
+UnflaggedApi: android.hardware.location.ContextHubInfo#toString():
+ New API must be flagged with @FlaggedApi: method android.hardware.location.ContextHubInfo.toString()
+UnflaggedApi: android.hardware.location.ContextHubIntentEvent#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.hardware.location.ContextHubIntentEvent.equals(Object)
+UnflaggedApi: android.hardware.location.ContextHubIntentEvent#toString():
+ New API must be flagged with @FlaggedApi: method android.hardware.location.ContextHubIntentEvent.toString()
+UnflaggedApi: android.hardware.location.ContextHubMessage#toString():
+ New API must be flagged with @FlaggedApi: method android.hardware.location.ContextHubMessage.toString()
+UnflaggedApi: android.hardware.location.GeofenceHardwareMonitorEvent#toString():
+ New API must be flagged with @FlaggedApi: method android.hardware.location.GeofenceHardwareMonitorEvent.toString()
+UnflaggedApi: android.hardware.location.MemoryRegion#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.hardware.location.MemoryRegion.equals(Object)
+UnflaggedApi: android.hardware.location.MemoryRegion#toString():
+ New API must be flagged with @FlaggedApi: method android.hardware.location.MemoryRegion.toString()
+UnflaggedApi: android.hardware.location.NanoApp#toString():
+ New API must be flagged with @FlaggedApi: method android.hardware.location.NanoApp.toString()
+UnflaggedApi: android.hardware.location.NanoAppFilter#toString():
+ New API must be flagged with @FlaggedApi: method android.hardware.location.NanoAppFilter.toString()
+UnflaggedApi: android.hardware.location.NanoAppInstanceInfo#toString():
+ New API must be flagged with @FlaggedApi: method android.hardware.location.NanoAppInstanceInfo.toString()
+UnflaggedApi: android.hardware.location.NanoAppMessage#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.hardware.location.NanoAppMessage.equals(Object)
+UnflaggedApi: android.hardware.location.NanoAppMessage#toString():
+ New API must be flagged with @FlaggedApi: method android.hardware.location.NanoAppMessage.toString()
+UnflaggedApi: android.hardware.location.NanoAppRpcService#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.hardware.location.NanoAppRpcService.equals(Object)
+UnflaggedApi: android.hardware.location.NanoAppRpcService#hashCode():
+ New API must be flagged with @FlaggedApi: method android.hardware.location.NanoAppRpcService.hashCode()
+UnflaggedApi: android.hardware.location.NanoAppRpcService#toString():
+ New API must be flagged with @FlaggedApi: method android.hardware.location.NanoAppRpcService.toString()
+UnflaggedApi: android.hardware.radio.ProgramList.Filter#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.hardware.radio.ProgramList.Filter.equals(Object)
+UnflaggedApi: android.hardware.radio.ProgramList.Filter#hashCode():
+ New API must be flagged with @FlaggedApi: method android.hardware.radio.ProgramList.Filter.hashCode()
+UnflaggedApi: android.hardware.radio.ProgramList.Filter#toString():
+ New API must be flagged with @FlaggedApi: method android.hardware.radio.ProgramList.Filter.toString()
+UnflaggedApi: android.hardware.radio.ProgramSelector#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.hardware.radio.ProgramSelector.equals(Object)
+UnflaggedApi: android.hardware.radio.ProgramSelector#hashCode():
+ New API must be flagged with @FlaggedApi: method android.hardware.radio.ProgramSelector.hashCode()
+UnflaggedApi: android.hardware.radio.ProgramSelector#toString():
+ New API must be flagged with @FlaggedApi: method android.hardware.radio.ProgramSelector.toString()
+UnflaggedApi: android.hardware.radio.ProgramSelector.Identifier#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.hardware.radio.ProgramSelector.Identifier.equals(Object)
+UnflaggedApi: android.hardware.radio.ProgramSelector.Identifier#hashCode():
+ New API must be flagged with @FlaggedApi: method android.hardware.radio.ProgramSelector.Identifier.hashCode()
+UnflaggedApi: android.hardware.radio.ProgramSelector.Identifier#toString():
+ New API must be flagged with @FlaggedApi: method android.hardware.radio.ProgramSelector.Identifier.toString()
+UnflaggedApi: android.hardware.radio.RadioManager.AmBandConfig#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.hardware.radio.RadioManager.AmBandConfig.equals(Object)
+UnflaggedApi: android.hardware.radio.RadioManager.AmBandConfig#hashCode():
+ New API must be flagged with @FlaggedApi: method android.hardware.radio.RadioManager.AmBandConfig.hashCode()
+UnflaggedApi: android.hardware.radio.RadioManager.AmBandConfig#toString():
+ New API must be flagged with @FlaggedApi: method android.hardware.radio.RadioManager.AmBandConfig.toString()
+UnflaggedApi: android.hardware.radio.RadioManager.AmBandDescriptor#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.hardware.radio.RadioManager.AmBandDescriptor.equals(Object)
+UnflaggedApi: android.hardware.radio.RadioManager.AmBandDescriptor#hashCode():
+ New API must be flagged with @FlaggedApi: method android.hardware.radio.RadioManager.AmBandDescriptor.hashCode()
+UnflaggedApi: android.hardware.radio.RadioManager.AmBandDescriptor#toString():
+ New API must be flagged with @FlaggedApi: method android.hardware.radio.RadioManager.AmBandDescriptor.toString()
+UnflaggedApi: android.hardware.radio.RadioManager.BandConfig#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.hardware.radio.RadioManager.BandConfig.equals(Object)
+UnflaggedApi: android.hardware.radio.RadioManager.BandConfig#hashCode():
+ New API must be flagged with @FlaggedApi: method android.hardware.radio.RadioManager.BandConfig.hashCode()
+UnflaggedApi: android.hardware.radio.RadioManager.BandConfig#toString():
+ New API must be flagged with @FlaggedApi: method android.hardware.radio.RadioManager.BandConfig.toString()
+UnflaggedApi: android.hardware.radio.RadioManager.BandDescriptor#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.hardware.radio.RadioManager.BandDescriptor.equals(Object)
+UnflaggedApi: android.hardware.radio.RadioManager.BandDescriptor#hashCode():
+ New API must be flagged with @FlaggedApi: method android.hardware.radio.RadioManager.BandDescriptor.hashCode()
+UnflaggedApi: android.hardware.radio.RadioManager.BandDescriptor#toString():
+ New API must be flagged with @FlaggedApi: method android.hardware.radio.RadioManager.BandDescriptor.toString()
+UnflaggedApi: android.hardware.radio.RadioManager.FmBandConfig#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.hardware.radio.RadioManager.FmBandConfig.equals(Object)
+UnflaggedApi: android.hardware.radio.RadioManager.FmBandConfig#hashCode():
+ New API must be flagged with @FlaggedApi: method android.hardware.radio.RadioManager.FmBandConfig.hashCode()
+UnflaggedApi: android.hardware.radio.RadioManager.FmBandConfig#toString():
+ New API must be flagged with @FlaggedApi: method android.hardware.radio.RadioManager.FmBandConfig.toString()
+UnflaggedApi: android.hardware.radio.RadioManager.FmBandDescriptor#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.hardware.radio.RadioManager.FmBandDescriptor.equals(Object)
+UnflaggedApi: android.hardware.radio.RadioManager.FmBandDescriptor#hashCode():
+ New API must be flagged with @FlaggedApi: method android.hardware.radio.RadioManager.FmBandDescriptor.hashCode()
+UnflaggedApi: android.hardware.radio.RadioManager.FmBandDescriptor#toString():
+ New API must be flagged with @FlaggedApi: method android.hardware.radio.RadioManager.FmBandDescriptor.toString()
+UnflaggedApi: android.hardware.radio.RadioManager.ModuleProperties#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.hardware.radio.RadioManager.ModuleProperties.equals(Object)
+UnflaggedApi: android.hardware.radio.RadioManager.ModuleProperties#hashCode():
+ New API must be flagged with @FlaggedApi: method android.hardware.radio.RadioManager.ModuleProperties.hashCode()
+UnflaggedApi: android.hardware.radio.RadioManager.ModuleProperties#toString():
+ New API must be flagged with @FlaggedApi: method android.hardware.radio.RadioManager.ModuleProperties.toString()
+UnflaggedApi: android.hardware.radio.RadioManager.ProgramInfo#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.hardware.radio.RadioManager.ProgramInfo.equals(Object)
+UnflaggedApi: android.hardware.radio.RadioManager.ProgramInfo#hashCode():
+ New API must be flagged with @FlaggedApi: method android.hardware.radio.RadioManager.ProgramInfo.hashCode()
+UnflaggedApi: android.hardware.radio.RadioManager.ProgramInfo#toString():
+ New API must be flagged with @FlaggedApi: method android.hardware.radio.RadioManager.ProgramInfo.toString()
+UnflaggedApi: android.hardware.radio.RadioMetadata#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.hardware.radio.RadioMetadata.equals(Object)
+UnflaggedApi: android.hardware.radio.RadioMetadata#hashCode():
+ New API must be flagged with @FlaggedApi: method android.hardware.radio.RadioMetadata.hashCode()
+UnflaggedApi: android.hardware.radio.RadioMetadata#toString():
+ New API must be flagged with @FlaggedApi: method android.hardware.radio.RadioMetadata.toString()
+UnflaggedApi: android.hardware.soundtrigger.SoundTrigger.Keyphrase#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.hardware.soundtrigger.SoundTrigger.Keyphrase.equals(Object)
+UnflaggedApi: android.hardware.soundtrigger.SoundTrigger.Keyphrase#hashCode():
+ New API must be flagged with @FlaggedApi: method android.hardware.soundtrigger.SoundTrigger.Keyphrase.hashCode()
+UnflaggedApi: android.hardware.soundtrigger.SoundTrigger.Keyphrase#toString():
+ New API must be flagged with @FlaggedApi: method android.hardware.soundtrigger.SoundTrigger.Keyphrase.toString()
+UnflaggedApi: android.hardware.soundtrigger.SoundTrigger.KeyphraseRecognitionExtra#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.hardware.soundtrigger.SoundTrigger.KeyphraseRecognitionExtra.equals(Object)
+UnflaggedApi: android.hardware.soundtrigger.SoundTrigger.KeyphraseRecognitionExtra#hashCode():
+ New API must be flagged with @FlaggedApi: method android.hardware.soundtrigger.SoundTrigger.KeyphraseRecognitionExtra.hashCode()
+UnflaggedApi: android.hardware.soundtrigger.SoundTrigger.KeyphraseRecognitionExtra#toString():
+ New API must be flagged with @FlaggedApi: method android.hardware.soundtrigger.SoundTrigger.KeyphraseRecognitionExtra.toString()
+UnflaggedApi: android.hardware.soundtrigger.SoundTrigger.KeyphraseSoundModel#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.hardware.soundtrigger.SoundTrigger.KeyphraseSoundModel.equals(Object)
+UnflaggedApi: android.hardware.soundtrigger.SoundTrigger.KeyphraseSoundModel#hashCode():
+ New API must be flagged with @FlaggedApi: method android.hardware.soundtrigger.SoundTrigger.KeyphraseSoundModel.hashCode()
+UnflaggedApi: android.hardware.soundtrigger.SoundTrigger.KeyphraseSoundModel#toString():
+ New API must be flagged with @FlaggedApi: method android.hardware.soundtrigger.SoundTrigger.KeyphraseSoundModel.toString()
+UnflaggedApi: android.hardware.soundtrigger.SoundTrigger.ModelParamRange#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.hardware.soundtrigger.SoundTrigger.ModelParamRange.equals(Object)
+UnflaggedApi: android.hardware.soundtrigger.SoundTrigger.ModelParamRange#toString():
+ New API must be flagged with @FlaggedApi: method android.hardware.soundtrigger.SoundTrigger.ModelParamRange.toString()
+UnflaggedApi: android.hardware.soundtrigger.SoundTrigger.ModuleProperties#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.hardware.soundtrigger.SoundTrigger.ModuleProperties.equals(Object)
+UnflaggedApi: android.hardware.soundtrigger.SoundTrigger.ModuleProperties#hashCode():
+ New API must be flagged with @FlaggedApi: method android.hardware.soundtrigger.SoundTrigger.ModuleProperties.hashCode()
+UnflaggedApi: android.hardware.soundtrigger.SoundTrigger.ModuleProperties#toString():
+ New API must be flagged with @FlaggedApi: method android.hardware.soundtrigger.SoundTrigger.ModuleProperties.toString()
+UnflaggedApi: android.hardware.soundtrigger.SoundTrigger.RecognitionEvent#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.hardware.soundtrigger.SoundTrigger.RecognitionEvent.equals(Object)
+UnflaggedApi: android.hardware.soundtrigger.SoundTrigger.RecognitionEvent#hashCode():
+ New API must be flagged with @FlaggedApi: method android.hardware.soundtrigger.SoundTrigger.RecognitionEvent.hashCode()
+UnflaggedApi: android.hardware.soundtrigger.SoundTrigger.RecognitionEvent#toString():
+ New API must be flagged with @FlaggedApi: method android.hardware.soundtrigger.SoundTrigger.RecognitionEvent.toString()
+UnflaggedApi: android.hardware.soundtrigger.SoundTrigger.SoundModel#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.hardware.soundtrigger.SoundTrigger.SoundModel.equals(Object)
+UnflaggedApi: android.hardware.soundtrigger.SoundTrigger.SoundModel#hashCode():
+ New API must be flagged with @FlaggedApi: method android.hardware.soundtrigger.SoundTrigger.SoundModel.hashCode()
+UnflaggedApi: android.hardware.usb.DisplayPortAltModeInfo#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.hardware.usb.DisplayPortAltModeInfo.equals(Object)
+UnflaggedApi: android.hardware.usb.DisplayPortAltModeInfo#hashCode():
+ New API must be flagged with @FlaggedApi: method android.hardware.usb.DisplayPortAltModeInfo.hashCode()
+UnflaggedApi: android.hardware.usb.DisplayPortAltModeInfo#toString():
+ New API must be flagged with @FlaggedApi: method android.hardware.usb.DisplayPortAltModeInfo.toString()
+UnflaggedApi: android.hardware.usb.UsbPort#toString():
+ New API must be flagged with @FlaggedApi: method android.hardware.usb.UsbPort.toString()
+UnflaggedApi: android.hardware.usb.UsbPortStatus#toString():
+ New API must be flagged with @FlaggedApi: method android.hardware.usb.UsbPortStatus.toString()
+UnflaggedApi: android.location.CorrelationVector#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.location.CorrelationVector.equals(Object)
+UnflaggedApi: android.location.CorrelationVector#hashCode():
+ New API must be flagged with @FlaggedApi: method android.location.CorrelationVector.hashCode()
+UnflaggedApi: android.location.CorrelationVector#toString():
+ New API must be flagged with @FlaggedApi: method android.location.CorrelationVector.toString()
+UnflaggedApi: android.location.Country#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.location.Country.equals(Object)
+UnflaggedApi: android.location.Country#hashCode():
+ New API must be flagged with @FlaggedApi: method android.location.Country.hashCode()
+UnflaggedApi: android.location.Country#toString():
+ New API must be flagged with @FlaggedApi: method android.location.Country.toString()
+UnflaggedApi: android.location.GnssExcessPathInfo#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.location.GnssExcessPathInfo.equals(Object)
+UnflaggedApi: android.location.GnssExcessPathInfo#hashCode():
+ New API must be flagged with @FlaggedApi: method android.location.GnssExcessPathInfo.hashCode()
+UnflaggedApi: android.location.GnssExcessPathInfo#toString():
+ New API must be flagged with @FlaggedApi: method android.location.GnssExcessPathInfo.toString()
+UnflaggedApi: android.location.GnssMeasurementCorrections#toString():
+ New API must be flagged with @FlaggedApi: method android.location.GnssMeasurementCorrections.toString()
+UnflaggedApi: android.location.GnssMeasurementRequest#getWorkSource():
+ New API must be flagged with @FlaggedApi: method android.location.GnssMeasurementRequest.getWorkSource()
+UnflaggedApi: android.location.GnssMeasurementRequest.Builder#setWorkSource(android.os.WorkSource):
+ New API must be flagged with @FlaggedApi: method android.location.GnssMeasurementRequest.Builder.setWorkSource(android.os.WorkSource)
+UnflaggedApi: android.location.GnssReflectingPlane#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.location.GnssReflectingPlane.equals(Object)
+UnflaggedApi: android.location.GnssReflectingPlane#hashCode():
+ New API must be flagged with @FlaggedApi: method android.location.GnssReflectingPlane.hashCode()
+UnflaggedApi: android.location.GnssReflectingPlane#toString():
+ New API must be flagged with @FlaggedApi: method android.location.GnssReflectingPlane.toString()
+UnflaggedApi: android.location.GnssRequest#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.location.GnssRequest.equals(Object)
+UnflaggedApi: android.location.GnssRequest#hashCode():
+ New API must be flagged with @FlaggedApi: method android.location.GnssRequest.hashCode()
+UnflaggedApi: android.location.GnssRequest#toString():
+ New API must be flagged with @FlaggedApi: method android.location.GnssRequest.toString()
+UnflaggedApi: android.location.GnssSingleSatCorrection#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.location.GnssSingleSatCorrection.equals(Object)
+UnflaggedApi: android.location.GnssSingleSatCorrection#hashCode():
+ New API must be flagged with @FlaggedApi: method android.location.GnssSingleSatCorrection.hashCode()
+UnflaggedApi: android.location.GnssSingleSatCorrection#toString():
+ New API must be flagged with @FlaggedApi: method android.location.GnssSingleSatCorrection.toString()
+UnflaggedApi: android.location.GpsClock#toString():
+ New API must be flagged with @FlaggedApi: method android.location.GpsClock.toString()
+UnflaggedApi: android.location.GpsMeasurement#toString():
+ New API must be flagged with @FlaggedApi: method android.location.GpsMeasurement.toString()
+UnflaggedApi: android.location.GpsMeasurementsEvent#toString():
+ New API must be flagged with @FlaggedApi: method android.location.GpsMeasurementsEvent.toString()
+UnflaggedApi: android.location.GpsNavigationMessage#toString():
+ New API must be flagged with @FlaggedApi: method android.location.GpsNavigationMessage.toString()
+UnflaggedApi: android.location.GpsNavigationMessageEvent#toString():
+ New API must be flagged with @FlaggedApi: method android.location.GpsNavigationMessageEvent.toString()
+UnflaggedApi: android.location.LastLocationRequest#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.location.LastLocationRequest.equals(Object)
+UnflaggedApi: android.location.LastLocationRequest#hashCode():
+ New API must be flagged with @FlaggedApi: method android.location.LastLocationRequest.hashCode()
+UnflaggedApi: android.location.LastLocationRequest#toString():
+ New API must be flagged with @FlaggedApi: method android.location.LastLocationRequest.toString()
+UnflaggedApi: android.location.SatellitePvt#toString():
+ New API must be flagged with @FlaggedApi: method android.location.SatellitePvt.toString()
+UnflaggedApi: android.location.SatellitePvt.ClockInfo#toString():
+ New API must be flagged with @FlaggedApi: method android.location.SatellitePvt.ClockInfo.toString()
+UnflaggedApi: android.location.SatellitePvt.PositionEcef#toString():
+ New API must be flagged with @FlaggedApi: method android.location.SatellitePvt.PositionEcef.toString()
+UnflaggedApi: android.location.SatellitePvt.VelocityEcef#toString():
+ New API must be flagged with @FlaggedApi: method android.location.SatellitePvt.VelocityEcef.toString()
+UnflaggedApi: android.location.provider.ProviderRequest#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.location.provider.ProviderRequest.equals(Object)
+UnflaggedApi: android.location.provider.ProviderRequest#hashCode():
+ New API must be flagged with @FlaggedApi: method android.location.provider.ProviderRequest.hashCode()
+UnflaggedApi: android.location.provider.ProviderRequest#toString():
+ New API must be flagged with @FlaggedApi: method android.location.provider.ProviderRequest.toString()
+UnflaggedApi: android.media.AudioDeviceAttributes#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.media.AudioDeviceAttributes.equals(Object)
+UnflaggedApi: android.media.AudioDeviceAttributes#hashCode():
+ New API must be flagged with @FlaggedApi: method android.media.AudioDeviceAttributes.hashCode()
+UnflaggedApi: android.media.AudioDeviceAttributes#toString():
+ New API must be flagged with @FlaggedApi: method android.media.AudioDeviceAttributes.toString()
+UnflaggedApi: android.media.AudioFocusInfo#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.media.AudioFocusInfo.equals(Object)
+UnflaggedApi: android.media.AudioFocusInfo#hashCode():
+ New API must be flagged with @FlaggedApi: method android.media.AudioFocusInfo.hashCode()
+UnflaggedApi: android.media.MediaRecorder.AudioSource#ECHO_REFERENCE:
+ New API must be flagged with @FlaggedApi: field android.media.MediaRecorder.AudioSource.ECHO_REFERENCE
+UnflaggedApi: android.media.MediaRecorder.AudioSource#HOTWORD:
+ New API must be flagged with @FlaggedApi: field android.media.MediaRecorder.AudioSource.HOTWORD
+UnflaggedApi: android.media.MediaRecorder.AudioSource#RADIO_TUNER:
+ New API must be flagged with @FlaggedApi: field android.media.MediaRecorder.AudioSource.RADIO_TUNER
+UnflaggedApi: android.media.MediaRecorder.AudioSource#ULTRASOUND:
+ New API must be flagged with @FlaggedApi: field android.media.MediaRecorder.AudioSource.ULTRASOUND
+UnflaggedApi: android.media.NearbyDevice#toString():
+ New API must be flagged with @FlaggedApi: method android.media.NearbyDevice.toString()
+UnflaggedApi: android.media.VolumeInfo#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.media.VolumeInfo.equals(Object)
+UnflaggedApi: android.media.VolumeInfo#hashCode():
+ New API must be flagged with @FlaggedApi: method android.media.VolumeInfo.hashCode()
+UnflaggedApi: android.media.VolumeInfo#toString():
+ New API must be flagged with @FlaggedApi: method android.media.VolumeInfo.toString()
+UnflaggedApi: android.media.audiopolicy.AudioMix#CREATOR:
+ New API must be flagged with @FlaggedApi: field android.media.audiopolicy.AudioMix.CREATOR
+UnflaggedApi: android.media.audiopolicy.AudioMix#describeContents():
+ New API must be flagged with @FlaggedApi: method android.media.audiopolicy.AudioMix.describeContents()
+UnflaggedApi: android.media.audiopolicy.AudioMix#writeToParcel(android.os.Parcel, int):
+ New API must be flagged with @FlaggedApi: method android.media.audiopolicy.AudioMix.writeToParcel(android.os.Parcel,int)
+UnflaggedApi: android.media.audiopolicy.AudioMixingRule#CREATOR:
+ New API must be flagged with @FlaggedApi: field android.media.audiopolicy.AudioMixingRule.CREATOR
+UnflaggedApi: android.media.audiopolicy.AudioMixingRule#describeContents():
+ New API must be flagged with @FlaggedApi: method android.media.audiopolicy.AudioMixingRule.describeContents()
+UnflaggedApi: android.media.audiopolicy.AudioMixingRule#hashCode():
+ New API must be flagged with @FlaggedApi: method android.media.audiopolicy.AudioMixingRule.hashCode()
+UnflaggedApi: android.media.audiopolicy.AudioMixingRule#writeToParcel(android.os.Parcel, int):
+ New API must be flagged with @FlaggedApi: method android.media.audiopolicy.AudioMixingRule.writeToParcel(android.os.Parcel,int)
+UnflaggedApi: android.media.audiopolicy.AudioPolicy#updateMixingRules(java.util.List<android.util.Pair<android.media.audiopolicy.AudioMix,android.media.audiopolicy.AudioMixingRule>>):
+ New API must be flagged with @FlaggedApi: method android.media.audiopolicy.AudioPolicy.updateMixingRules(java.util.List<android.util.Pair<android.media.audiopolicy.AudioMix,android.media.audiopolicy.AudioMixingRule>>)
+UnflaggedApi: android.media.audiopolicy.AudioProductStrategy#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.media.audiopolicy.AudioProductStrategy.equals(Object)
+UnflaggedApi: android.media.audiopolicy.AudioProductStrategy#hashCode():
+ New API must be flagged with @FlaggedApi: method android.media.audiopolicy.AudioProductStrategy.hashCode()
+UnflaggedApi: android.media.audiopolicy.AudioProductStrategy#toString():
+ New API must be flagged with @FlaggedApi: method android.media.audiopolicy.AudioProductStrategy.toString()
+UnflaggedApi: android.media.audiopolicy.AudioVolumeGroup#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.media.audiopolicy.AudioVolumeGroup.equals(Object)
+UnflaggedApi: android.media.audiopolicy.AudioVolumeGroup#toString():
+ New API must be flagged with @FlaggedApi: method android.media.audiopolicy.AudioVolumeGroup.toString()
+UnflaggedApi: android.media.musicrecognition.MusicRecognitionService#onCreate():
+ New API must be flagged with @FlaggedApi: method android.media.musicrecognition.MusicRecognitionService.onCreate()
+UnflaggedApi: android.media.soundtrigger.SoundTriggerDetectionService#onUnbind(android.content.Intent):
+ New API must be flagged with @FlaggedApi: method android.media.soundtrigger.SoundTriggerDetectionService.onUnbind(android.content.Intent)
+UnflaggedApi: android.media.tv.TunedInfo#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.media.tv.TunedInfo.equals(Object)
+UnflaggedApi: android.media.tv.TunedInfo#hashCode():
+ New API must be flagged with @FlaggedApi: method android.media.tv.TunedInfo.hashCode()
+UnflaggedApi: android.media.tv.TunedInfo#toString():
+ New API must be flagged with @FlaggedApi: method android.media.tv.TunedInfo.toString()
+UnflaggedApi: android.media.tv.TvInputHardwareInfo#toString():
+ New API must be flagged with @FlaggedApi: method android.media.tv.TvInputHardwareInfo.toString()
+UnflaggedApi: android.media.tv.TvRecordingClient.RecordingCallback#onEvent(String, String, android.os.Bundle):
+ New API must be flagged with @FlaggedApi: method android.media.tv.TvRecordingClient.RecordingCallback.onEvent(String,String,android.os.Bundle)
+UnflaggedApi: android.media.tv.TvStreamConfig#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.media.tv.TvStreamConfig.equals(Object)
+UnflaggedApi: android.media.tv.TvStreamConfig#toString():
+ New API must be flagged with @FlaggedApi: method android.media.tv.TvStreamConfig.toString()
+UnflaggedApi: android.net.MatchAllNetworkSpecifier#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.net.MatchAllNetworkSpecifier.equals(Object)
+UnflaggedApi: android.net.MatchAllNetworkSpecifier#hashCode():
+ New API must be flagged with @FlaggedApi: method android.net.MatchAllNetworkSpecifier.hashCode()
+UnflaggedApi: android.net.NetworkKey#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.net.NetworkKey.equals(Object)
+UnflaggedApi: android.net.NetworkKey#hashCode():
+ New API must be flagged with @FlaggedApi: method android.net.NetworkKey.hashCode()
+UnflaggedApi: android.net.NetworkKey#toString():
+ New API must be flagged with @FlaggedApi: method android.net.NetworkKey.toString()
+UnflaggedApi: android.net.RssiCurve#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.net.RssiCurve.equals(Object)
+UnflaggedApi: android.net.RssiCurve#hashCode():
+ New API must be flagged with @FlaggedApi: method android.net.RssiCurve.hashCode()
+UnflaggedApi: android.net.RssiCurve#toString():
+ New API must be flagged with @FlaggedApi: method android.net.RssiCurve.toString()
+UnflaggedApi: android.net.ScoredNetwork#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.net.ScoredNetwork.equals(Object)
+UnflaggedApi: android.net.ScoredNetwork#hashCode():
+ New API must be flagged with @FlaggedApi: method android.net.ScoredNetwork.hashCode()
+UnflaggedApi: android.net.ScoredNetwork#toString():
+ New API must be flagged with @FlaggedApi: method android.net.ScoredNetwork.toString()
+UnflaggedApi: android.net.WebAddress#toString():
+ New API must be flagged with @FlaggedApi: method android.net.WebAddress.toString()
+UnflaggedApi: android.net.WifiKey#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.net.WifiKey.equals(Object)
+UnflaggedApi: android.net.WifiKey#hashCode():
+ New API must be flagged with @FlaggedApi: method android.net.WifiKey.hashCode()
+UnflaggedApi: android.net.WifiKey#toString():
+ New API must be flagged with @FlaggedApi: method android.net.WifiKey.toString()
+UnflaggedApi: android.net.metrics.ApfProgramEvent#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.net.metrics.ApfProgramEvent.equals(Object)
+UnflaggedApi: android.net.metrics.ApfProgramEvent#toString():
+ New API must be flagged with @FlaggedApi: method android.net.metrics.ApfProgramEvent.toString()
+UnflaggedApi: android.net.metrics.ApfStats#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.net.metrics.ApfStats.equals(Object)
+UnflaggedApi: android.net.metrics.ApfStats#toString():
+ New API must be flagged with @FlaggedApi: method android.net.metrics.ApfStats.toString()
+UnflaggedApi: android.net.metrics.DhcpClientEvent#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.net.metrics.DhcpClientEvent.equals(Object)
+UnflaggedApi: android.net.metrics.DhcpClientEvent#toString():
+ New API must be flagged with @FlaggedApi: method android.net.metrics.DhcpClientEvent.toString()
+UnflaggedApi: android.net.metrics.DhcpErrorEvent#toString():
+ New API must be flagged with @FlaggedApi: method android.net.metrics.DhcpErrorEvent.toString()
+UnflaggedApi: android.net.metrics.IpManagerEvent#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.net.metrics.IpManagerEvent.equals(Object)
+UnflaggedApi: android.net.metrics.IpManagerEvent#toString():
+ New API must be flagged with @FlaggedApi: method android.net.metrics.IpManagerEvent.toString()
+UnflaggedApi: android.net.metrics.IpReachabilityEvent#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.net.metrics.IpReachabilityEvent.equals(Object)
+UnflaggedApi: android.net.metrics.IpReachabilityEvent#toString():
+ New API must be flagged with @FlaggedApi: method android.net.metrics.IpReachabilityEvent.toString()
+UnflaggedApi: android.net.metrics.NetworkEvent#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.net.metrics.NetworkEvent.equals(Object)
+UnflaggedApi: android.net.metrics.NetworkEvent#toString():
+ New API must be flagged with @FlaggedApi: method android.net.metrics.NetworkEvent.toString()
+UnflaggedApi: android.net.metrics.RaEvent#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.net.metrics.RaEvent.equals(Object)
+UnflaggedApi: android.net.metrics.RaEvent#toString():
+ New API must be flagged with @FlaggedApi: method android.net.metrics.RaEvent.toString()
+UnflaggedApi: android.net.metrics.ValidationProbeEvent#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.net.metrics.ValidationProbeEvent.equals(Object)
+UnflaggedApi: android.net.metrics.ValidationProbeEvent#toString():
+ New API must be flagged with @FlaggedApi: method android.net.metrics.ValidationProbeEvent.toString()
+UnflaggedApi: android.net.vcn.VcnNetworkPolicyResult#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.net.vcn.VcnNetworkPolicyResult.equals(Object)
+UnflaggedApi: android.net.vcn.VcnNetworkPolicyResult#hashCode():
+ New API must be flagged with @FlaggedApi: method android.net.vcn.VcnNetworkPolicyResult.hashCode()
+UnflaggedApi: android.net.vcn.VcnNetworkPolicyResult#toString():
+ New API must be flagged with @FlaggedApi: method android.net.vcn.VcnNetworkPolicyResult.toString()
+UnflaggedApi: android.net.wifi.nl80211.DeviceWiphyCapabilities#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.net.wifi.nl80211.DeviceWiphyCapabilities.equals(Object)
+UnflaggedApi: android.net.wifi.nl80211.DeviceWiphyCapabilities#hashCode():
+ New API must be flagged with @FlaggedApi: method android.net.wifi.nl80211.DeviceWiphyCapabilities.hashCode()
+UnflaggedApi: android.net.wifi.nl80211.DeviceWiphyCapabilities#toString():
+ New API must be flagged with @FlaggedApi: method android.net.wifi.nl80211.DeviceWiphyCapabilities.toString()
+UnflaggedApi: android.net.wifi.nl80211.NativeWifiClient#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.net.wifi.nl80211.NativeWifiClient.equals(Object)
+UnflaggedApi: android.net.wifi.nl80211.NativeWifiClient#hashCode():
+ New API must be flagged with @FlaggedApi: method android.net.wifi.nl80211.NativeWifiClient.hashCode()
+UnflaggedApi: android.net.wifi.nl80211.PnoNetwork#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.net.wifi.nl80211.PnoNetwork.equals(Object)
+UnflaggedApi: android.net.wifi.nl80211.PnoNetwork#hashCode():
+ New API must be flagged with @FlaggedApi: method android.net.wifi.nl80211.PnoNetwork.hashCode()
+UnflaggedApi: android.net.wifi.nl80211.PnoSettings#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.net.wifi.nl80211.PnoSettings.equals(Object)
+UnflaggedApi: android.net.wifi.nl80211.PnoSettings#hashCode():
+ New API must be flagged with @FlaggedApi: method android.net.wifi.nl80211.PnoSettings.hashCode()
+UnflaggedApi: android.net.wifi.nl80211.RadioChainInfo#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.net.wifi.nl80211.RadioChainInfo.equals(Object)
+UnflaggedApi: android.net.wifi.nl80211.RadioChainInfo#hashCode():
+ New API must be flagged with @FlaggedApi: method android.net.wifi.nl80211.RadioChainInfo.hashCode()
+UnflaggedApi: android.net.wifi.sharedconnectivity.app.HotspotNetwork#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.net.wifi.sharedconnectivity.app.HotspotNetwork.equals(Object)
+UnflaggedApi: android.net.wifi.sharedconnectivity.app.HotspotNetwork#hashCode():
+ New API must be flagged with @FlaggedApi: method android.net.wifi.sharedconnectivity.app.HotspotNetwork.hashCode()
+UnflaggedApi: android.net.wifi.sharedconnectivity.app.HotspotNetwork#toString():
+ New API must be flagged with @FlaggedApi: method android.net.wifi.sharedconnectivity.app.HotspotNetwork.toString()
+UnflaggedApi: android.net.wifi.sharedconnectivity.app.HotspotNetworkConnectionStatus#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.net.wifi.sharedconnectivity.app.HotspotNetworkConnectionStatus.equals(Object)
+UnflaggedApi: android.net.wifi.sharedconnectivity.app.HotspotNetworkConnectionStatus#hashCode():
+ New API must be flagged with @FlaggedApi: method android.net.wifi.sharedconnectivity.app.HotspotNetworkConnectionStatus.hashCode()
+UnflaggedApi: android.net.wifi.sharedconnectivity.app.HotspotNetworkConnectionStatus#toString():
+ New API must be flagged with @FlaggedApi: method android.net.wifi.sharedconnectivity.app.HotspotNetworkConnectionStatus.toString()
+UnflaggedApi: android.net.wifi.sharedconnectivity.app.KnownNetwork#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.net.wifi.sharedconnectivity.app.KnownNetwork.equals(Object)
+UnflaggedApi: android.net.wifi.sharedconnectivity.app.KnownNetwork#hashCode():
+ New API must be flagged with @FlaggedApi: method android.net.wifi.sharedconnectivity.app.KnownNetwork.hashCode()
+UnflaggedApi: android.net.wifi.sharedconnectivity.app.KnownNetwork#toString():
+ New API must be flagged with @FlaggedApi: method android.net.wifi.sharedconnectivity.app.KnownNetwork.toString()
+UnflaggedApi: android.net.wifi.sharedconnectivity.app.KnownNetworkConnectionStatus#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.net.wifi.sharedconnectivity.app.KnownNetworkConnectionStatus.equals(Object)
+UnflaggedApi: android.net.wifi.sharedconnectivity.app.KnownNetworkConnectionStatus#hashCode():
+ New API must be flagged with @FlaggedApi: method android.net.wifi.sharedconnectivity.app.KnownNetworkConnectionStatus.hashCode()
+UnflaggedApi: android.net.wifi.sharedconnectivity.app.KnownNetworkConnectionStatus#toString():
+ New API must be flagged with @FlaggedApi: method android.net.wifi.sharedconnectivity.app.KnownNetworkConnectionStatus.toString()
+UnflaggedApi: android.net.wifi.sharedconnectivity.app.NetworkProviderInfo#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.net.wifi.sharedconnectivity.app.NetworkProviderInfo.equals(Object)
+UnflaggedApi: android.net.wifi.sharedconnectivity.app.NetworkProviderInfo#hashCode():
+ New API must be flagged with @FlaggedApi: method android.net.wifi.sharedconnectivity.app.NetworkProviderInfo.hashCode()
+UnflaggedApi: android.net.wifi.sharedconnectivity.app.NetworkProviderInfo#isBatteryCharging():
+ New API must be flagged with @FlaggedApi: method android.net.wifi.sharedconnectivity.app.NetworkProviderInfo.isBatteryCharging()
+UnflaggedApi: android.net.wifi.sharedconnectivity.app.NetworkProviderInfo#toString():
+ New API must be flagged with @FlaggedApi: method android.net.wifi.sharedconnectivity.app.NetworkProviderInfo.toString()
+UnflaggedApi: android.net.wifi.sharedconnectivity.app.NetworkProviderInfo.Builder#setBatteryCharging(boolean):
+ New API must be flagged with @FlaggedApi: method android.net.wifi.sharedconnectivity.app.NetworkProviderInfo.Builder.setBatteryCharging(boolean)
+UnflaggedApi: android.net.wifi.sharedconnectivity.app.SharedConnectivitySettingsState#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.net.wifi.sharedconnectivity.app.SharedConnectivitySettingsState.equals(Object)
+UnflaggedApi: android.net.wifi.sharedconnectivity.app.SharedConnectivitySettingsState#hashCode():
+ New API must be flagged with @FlaggedApi: method android.net.wifi.sharedconnectivity.app.SharedConnectivitySettingsState.hashCode()
+UnflaggedApi: android.net.wifi.sharedconnectivity.app.SharedConnectivitySettingsState#toString():
+ New API must be flagged with @FlaggedApi: method android.net.wifi.sharedconnectivity.app.SharedConnectivitySettingsState.toString()
+UnflaggedApi: android.os.BatterySaverPolicyConfig#toString():
+ New API must be flagged with @FlaggedApi: method android.os.BatterySaverPolicyConfig.toString()
+UnflaggedApi: android.os.BugreportParams#BUGREPORT_MODE_ONBOARDING:
+ New API must be flagged with @FlaggedApi: field android.os.BugreportParams.BUGREPORT_MODE_ONBOARDING
+UnflaggedApi: android.os.Build.VERSION#KNOWN_CODENAMES:
+ New API must be flagged with @FlaggedApi: field android.os.Build.VERSION.KNOWN_CODENAMES
+UnflaggedApi: android.os.Build.VERSION#PREVIEW_SDK_FINGERPRINT:
+ New API must be flagged with @FlaggedApi: field android.os.Build.VERSION.PREVIEW_SDK_FINGERPRINT
+UnflaggedApi: android.os.IncidentManager.PendingReport#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.os.IncidentManager.PendingReport.equals(Object)
+UnflaggedApi: android.os.IncidentManager.PendingReport#toString():
+ New API must be flagged with @FlaggedApi: method android.os.IncidentManager.PendingReport.toString()
+UnflaggedApi: android.os.IncidentReportArgs#toString():
+ New API must be flagged with @FlaggedApi: method android.os.IncidentReportArgs.toString()
+UnflaggedApi: android.os.NewUserRequest#toString():
+ New API must be flagged with @FlaggedApi: method android.os.NewUserRequest.toString()
+UnflaggedApi: android.os.NewUserResponse#toString():
+ New API must be flagged with @FlaggedApi: method android.os.NewUserResponse.toString()
+UnflaggedApi: android.os.PowerManager.LowPowerStandbyPolicy#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.os.PowerManager.LowPowerStandbyPolicy.equals(Object)
+UnflaggedApi: android.os.PowerManager.LowPowerStandbyPolicy#hashCode():
+ New API must be flagged with @FlaggedApi: method android.os.PowerManager.LowPowerStandbyPolicy.hashCode()
+UnflaggedApi: android.os.PowerManager.LowPowerStandbyPolicy#toString():
+ New API must be flagged with @FlaggedApi: method android.os.PowerManager.LowPowerStandbyPolicy.toString()
+UnflaggedApi: android.os.PowerManager.LowPowerStandbyPortDescription#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.os.PowerManager.LowPowerStandbyPortDescription.equals(Object)
+UnflaggedApi: android.os.PowerManager.LowPowerStandbyPortDescription#hashCode():
+ New API must be flagged with @FlaggedApi: method android.os.PowerManager.LowPowerStandbyPortDescription.hashCode()
+UnflaggedApi: android.os.PowerManager.LowPowerStandbyPortDescription#toString():
+ New API must be flagged with @FlaggedApi: method android.os.PowerManager.LowPowerStandbyPortDescription.toString()
+UnflaggedApi: android.os.ServiceSpecificException#toString():
+ New API must be flagged with @FlaggedApi: method android.os.ServiceSpecificException.toString()
+UnflaggedApi: android.os.WorkSource.WorkChain#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.os.WorkSource.WorkChain.equals(Object)
+UnflaggedApi: android.os.WorkSource.WorkChain#hashCode():
+ New API must be flagged with @FlaggedApi: method android.os.WorkSource.WorkChain.hashCode()
+UnflaggedApi: android.os.WorkSource.WorkChain#toString():
+ New API must be flagged with @FlaggedApi: method android.os.WorkSource.WorkChain.toString()
+UnflaggedApi: android.os.connectivity.CellularBatteryStats#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.os.connectivity.CellularBatteryStats.equals(Object)
+UnflaggedApi: android.os.connectivity.CellularBatteryStats#hashCode():
+ New API must be flagged with @FlaggedApi: method android.os.connectivity.CellularBatteryStats.hashCode()
+UnflaggedApi: android.os.connectivity.WifiActivityEnergyInfo#toString():
+ New API must be flagged with @FlaggedApi: method android.os.connectivity.WifiActivityEnergyInfo.toString()
+UnflaggedApi: android.os.connectivity.WifiBatteryStats#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.os.connectivity.WifiBatteryStats.equals(Object)
+UnflaggedApi: android.os.connectivity.WifiBatteryStats#hashCode():
+ New API must be flagged with @FlaggedApi: method android.os.connectivity.WifiBatteryStats.hashCode()
+UnflaggedApi: android.permission.AdminPermissionControlParams#toString():
+ New API must be flagged with @FlaggedApi: method android.permission.AdminPermissionControlParams.toString()
+UnflaggedApi: android.permission.PermissionGroupUsage#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.permission.PermissionGroupUsage.equals(Object)
+UnflaggedApi: android.permission.PermissionGroupUsage#hashCode():
+ New API must be flagged with @FlaggedApi: method android.permission.PermissionGroupUsage.hashCode()
+UnflaggedApi: android.permission.PermissionGroupUsage#toString():
+ New API must be flagged with @FlaggedApi: method android.permission.PermissionGroupUsage.toString()
+UnflaggedApi: android.permission.PermissionManager.SplitPermissionInfo#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.permission.PermissionManager.SplitPermissionInfo.equals(Object)
+UnflaggedApi: android.permission.PermissionManager.SplitPermissionInfo#hashCode():
+ New API must be flagged with @FlaggedApi: method android.permission.PermissionManager.SplitPermissionInfo.hashCode()
+UnflaggedApi: android.printservice.PrintServiceInfo#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.printservice.PrintServiceInfo.equals(Object)
+UnflaggedApi: android.printservice.PrintServiceInfo#hashCode():
+ New API must be flagged with @FlaggedApi: method android.printservice.PrintServiceInfo.hashCode()
+UnflaggedApi: android.printservice.PrintServiceInfo#toString():
+ New API must be flagged with @FlaggedApi: method android.printservice.PrintServiceInfo.toString()
+UnflaggedApi: android.printservice.recommendation.RecommendationService#attachBaseContext(android.content.Context):
+ New API must be flagged with @FlaggedApi: method android.printservice.recommendation.RecommendationService.attachBaseContext(android.content.Context)
+UnflaggedApi: android.provider.CallLog.CallComposerLoggingException#toString():
+ New API must be flagged with @FlaggedApi: method android.provider.CallLog.CallComposerLoggingException.toString()
+UnflaggedApi: android.provider.ContactsContract.MetadataSync#CONTENT_ITEM_TYPE:
+ New API must be flagged with @FlaggedApi: field android.provider.ContactsContract.MetadataSync.CONTENT_ITEM_TYPE
+UnflaggedApi: android.provider.ContactsContract.MetadataSync#CONTENT_TYPE:
+ New API must be flagged with @FlaggedApi: field android.provider.ContactsContract.MetadataSync.CONTENT_TYPE
+UnflaggedApi: android.provider.ContactsContract.MetadataSync#CONTENT_URI:
+ New API must be flagged with @FlaggedApi: field android.provider.ContactsContract.MetadataSync.CONTENT_URI
+UnflaggedApi: android.provider.ContactsContract.MetadataSync#METADATA_AUTHORITY:
+ New API must be flagged with @FlaggedApi: field android.provider.ContactsContract.MetadataSync.METADATA_AUTHORITY
+UnflaggedApi: android.provider.ContactsContract.MetadataSync#METADATA_AUTHORITY_URI:
+ New API must be flagged with @FlaggedApi: field android.provider.ContactsContract.MetadataSync.METADATA_AUTHORITY_URI
+UnflaggedApi: android.provider.ContactsContract.MetadataSync#_COUNT:
+ New API must be flagged with @FlaggedApi: field android.provider.ContactsContract.MetadataSync._COUNT
+UnflaggedApi: android.provider.ContactsContract.MetadataSync#_ID:
+ New API must be flagged with @FlaggedApi: field android.provider.ContactsContract.MetadataSync._ID
+UnflaggedApi: android.provider.ContactsContract.MetadataSyncColumns#ACCOUNT_NAME:
+ New API must be flagged with @FlaggedApi: field android.provider.ContactsContract.MetadataSyncColumns.ACCOUNT_NAME
+UnflaggedApi: android.provider.ContactsContract.MetadataSyncColumns#ACCOUNT_TYPE:
+ New API must be flagged with @FlaggedApi: field android.provider.ContactsContract.MetadataSyncColumns.ACCOUNT_TYPE
+UnflaggedApi: android.provider.ContactsContract.MetadataSyncColumns#DATA:
+ New API must be flagged with @FlaggedApi: field android.provider.ContactsContract.MetadataSyncColumns.DATA
+UnflaggedApi: android.provider.ContactsContract.MetadataSyncColumns#DATA_SET:
+ New API must be flagged with @FlaggedApi: field android.provider.ContactsContract.MetadataSyncColumns.DATA_SET
+UnflaggedApi: android.provider.ContactsContract.MetadataSyncColumns#DELETED:
+ New API must be flagged with @FlaggedApi: field android.provider.ContactsContract.MetadataSyncColumns.DELETED
+UnflaggedApi: android.provider.ContactsContract.MetadataSyncColumns#RAW_CONTACT_BACKUP_ID:
+ New API must be flagged with @FlaggedApi: field android.provider.ContactsContract.MetadataSyncColumns.RAW_CONTACT_BACKUP_ID
+UnflaggedApi: android.provider.ContactsContract.MetadataSyncState#CONTENT_ITEM_TYPE:
+ New API must be flagged with @FlaggedApi: field android.provider.ContactsContract.MetadataSyncState.CONTENT_ITEM_TYPE
+UnflaggedApi: android.provider.ContactsContract.MetadataSyncState#CONTENT_TYPE:
+ New API must be flagged with @FlaggedApi: field android.provider.ContactsContract.MetadataSyncState.CONTENT_TYPE
+UnflaggedApi: android.provider.ContactsContract.MetadataSyncState#CONTENT_URI:
+ New API must be flagged with @FlaggedApi: field android.provider.ContactsContract.MetadataSyncState.CONTENT_URI
+UnflaggedApi: android.provider.ContactsContract.MetadataSyncState#_COUNT:
+ New API must be flagged with @FlaggedApi: field android.provider.ContactsContract.MetadataSyncState._COUNT
+UnflaggedApi: android.provider.ContactsContract.MetadataSyncState#_ID:
+ New API must be flagged with @FlaggedApi: field android.provider.ContactsContract.MetadataSyncState._ID
+UnflaggedApi: android.provider.ContactsContract.MetadataSyncStateColumns#ACCOUNT_NAME:
+ New API must be flagged with @FlaggedApi: field android.provider.ContactsContract.MetadataSyncStateColumns.ACCOUNT_NAME
+UnflaggedApi: android.provider.ContactsContract.MetadataSyncStateColumns#ACCOUNT_TYPE:
+ New API must be flagged with @FlaggedApi: field android.provider.ContactsContract.MetadataSyncStateColumns.ACCOUNT_TYPE
+UnflaggedApi: android.provider.ContactsContract.MetadataSyncStateColumns#DATA_SET:
+ New API must be flagged with @FlaggedApi: field android.provider.ContactsContract.MetadataSyncStateColumns.DATA_SET
+UnflaggedApi: android.provider.ContactsContract.MetadataSyncStateColumns#STATE:
+ New API must be flagged with @FlaggedApi: field android.provider.ContactsContract.MetadataSyncStateColumns.STATE
+UnflaggedApi: android.provider.ContactsContract.Settings#setDefaultAccount(android.content.ContentResolver, android.accounts.Account):
+ New API must be flagged with @FlaggedApi: method android.provider.ContactsContract.Settings.setDefaultAccount(android.content.ContentResolver,android.accounts.Account)
+UnflaggedApi: android.provider.ContactsContract.SimContacts#addSimAccount(android.content.ContentResolver, String, String, int, int):
+ New API must be flagged with @FlaggedApi: method android.provider.ContactsContract.SimContacts.addSimAccount(android.content.ContentResolver,String,String,int,int)
+UnflaggedApi: android.provider.ContactsContract.SimContacts#removeSimAccounts(android.content.ContentResolver, int):
+ New API must be flagged with @FlaggedApi: method android.provider.ContactsContract.SimContacts.removeSimAccounts(android.content.ContentResolver,int)
+UnflaggedApi: android.provider.SearchIndexableData#toString():
+ New API must be flagged with @FlaggedApi: method android.provider.SearchIndexableData.toString()
+UnflaggedApi: android.provider.SearchIndexableResource#toString():
+ New API must be flagged with @FlaggedApi: method android.provider.SearchIndexableResource.toString()
+UnflaggedApi: android.provider.SearchIndexablesProvider#attachInfo(android.content.Context, android.content.pm.ProviderInfo):
+ New API must be flagged with @FlaggedApi: method android.provider.SearchIndexablesProvider.attachInfo(android.content.Context,android.content.pm.ProviderInfo)
+UnflaggedApi: android.provider.Settings#ACTION_APP_PERMISSIONS_SETTINGS:
+ New API must be flagged with @FlaggedApi: field android.provider.Settings.ACTION_APP_PERMISSIONS_SETTINGS
+UnflaggedApi: android.provider.Settings.System#putString(android.content.ContentResolver, String, String, boolean, boolean):
+ New API must be flagged with @FlaggedApi: method android.provider.Settings.System.putString(android.content.ContentResolver,String,String,boolean,boolean)
+UnflaggedApi: android.provider.Settings.System#resetToDefaults(android.content.ContentResolver, String):
+ New API must be flagged with @FlaggedApi: method android.provider.Settings.System.resetToDefaults(android.content.ContentResolver,String)
+UnflaggedApi: android.provider.SimPhonebookContract.SimRecords#QUERY_ARG_PIN2:
+ New API must be flagged with @FlaggedApi: field android.provider.SimPhonebookContract.SimRecords.QUERY_ARG_PIN2
+UnflaggedApi: android.provider.Telephony.Carriers#APN_SET_ID:
+ New API must be flagged with @FlaggedApi: field android.provider.Telephony.Carriers.APN_SET_ID
+UnflaggedApi: android.provider.Telephony.Carriers#CARRIER_EDITED:
+ New API must be flagged with @FlaggedApi: field android.provider.Telephony.Carriers.CARRIER_EDITED
+UnflaggedApi: android.provider.Telephony.Carriers#EDITED_STATUS:
+ New API must be flagged with @FlaggedApi: field android.provider.Telephony.Carriers.EDITED_STATUS
+UnflaggedApi: android.provider.Telephony.Carriers#MATCH_ALL_APN_SET_ID:
+ New API must be flagged with @FlaggedApi: field android.provider.Telephony.Carriers.MATCH_ALL_APN_SET_ID
+UnflaggedApi: android.provider.Telephony.Carriers#MAX_CONNECTIONS:
+ New API must be flagged with @FlaggedApi: field android.provider.Telephony.Carriers.MAX_CONNECTIONS
+UnflaggedApi: android.provider.Telephony.Carriers#MODEM_PERSIST:
+ New API must be flagged with @FlaggedApi: field android.provider.Telephony.Carriers.MODEM_PERSIST
+UnflaggedApi: android.provider.Telephony.Carriers#MTU_V4:
+ New API must be flagged with @FlaggedApi: field android.provider.Telephony.Carriers.MTU_V4
+UnflaggedApi: android.provider.Telephony.Carriers#MTU_V6:
+ New API must be flagged with @FlaggedApi: field android.provider.Telephony.Carriers.MTU_V6
+UnflaggedApi: android.provider.Telephony.Carriers#NO_APN_SET_ID:
+ New API must be flagged with @FlaggedApi: field android.provider.Telephony.Carriers.NO_APN_SET_ID
+UnflaggedApi: android.provider.Telephony.Carriers#TIME_LIMIT_FOR_MAX_CONNECTIONS:
+ New API must be flagged with @FlaggedApi: field android.provider.Telephony.Carriers.TIME_LIMIT_FOR_MAX_CONNECTIONS
+UnflaggedApi: android.provider.Telephony.Carriers#UNEDITED:
+ New API must be flagged with @FlaggedApi: field android.provider.Telephony.Carriers.UNEDITED
+UnflaggedApi: android.provider.Telephony.Carriers#USER_DELETED:
+ New API must be flagged with @FlaggedApi: field android.provider.Telephony.Carriers.USER_DELETED
+UnflaggedApi: android.provider.Telephony.Carriers#USER_EDITABLE:
+ New API must be flagged with @FlaggedApi: field android.provider.Telephony.Carriers.USER_EDITABLE
+UnflaggedApi: android.provider.Telephony.Carriers#USER_EDITED:
+ New API must be flagged with @FlaggedApi: field android.provider.Telephony.Carriers.USER_EDITED
+UnflaggedApi: android.provider.Telephony.Carriers#USER_VISIBLE:
+ New API must be flagged with @FlaggedApi: field android.provider.Telephony.Carriers.USER_VISIBLE
+UnflaggedApi: android.provider.Telephony.Carriers#WAIT_TIME_RETRY:
+ New API must be flagged with @FlaggedApi: field android.provider.Telephony.Carriers.WAIT_TIME_RETRY
+UnflaggedApi: android.provider.Telephony.CellBroadcasts:
+ New API must be flagged with @FlaggedApi: class android.provider.Telephony.CellBroadcasts
+UnflaggedApi: android.provider.Telephony.CellBroadcasts#AUTHORITY_LEGACY:
+ New API must be flagged with @FlaggedApi: field android.provider.Telephony.CellBroadcasts.AUTHORITY_LEGACY
+UnflaggedApi: android.provider.Telephony.CellBroadcasts#AUTHORITY_LEGACY_URI:
+ New API must be flagged with @FlaggedApi: field android.provider.Telephony.CellBroadcasts.AUTHORITY_LEGACY_URI
+UnflaggedApi: android.provider.Telephony.CellBroadcasts#CALL_METHOD_GET_PREFERENCE:
+ New API must be flagged with @FlaggedApi: field android.provider.Telephony.CellBroadcasts.CALL_METHOD_GET_PREFERENCE
+UnflaggedApi: android.provider.Telephony.CellBroadcasts#CID:
+ New API must be flagged with @FlaggedApi: field android.provider.Telephony.CellBroadcasts.CID
+UnflaggedApi: android.provider.Telephony.CellBroadcasts#CMAS_CATEGORY:
+ New API must be flagged with @FlaggedApi: field android.provider.Telephony.CellBroadcasts.CMAS_CATEGORY
+UnflaggedApi: android.provider.Telephony.CellBroadcasts#CMAS_CERTAINTY:
+ New API must be flagged with @FlaggedApi: field android.provider.Telephony.CellBroadcasts.CMAS_CERTAINTY
+UnflaggedApi: android.provider.Telephony.CellBroadcasts#CMAS_MESSAGE_CLASS:
+ New API must be flagged with @FlaggedApi: field android.provider.Telephony.CellBroadcasts.CMAS_MESSAGE_CLASS
+UnflaggedApi: android.provider.Telephony.CellBroadcasts#CMAS_RESPONSE_TYPE:
+ New API must be flagged with @FlaggedApi: field android.provider.Telephony.CellBroadcasts.CMAS_RESPONSE_TYPE
+UnflaggedApi: android.provider.Telephony.CellBroadcasts#CMAS_SEVERITY:
+ New API must be flagged with @FlaggedApi: field android.provider.Telephony.CellBroadcasts.CMAS_SEVERITY
+UnflaggedApi: android.provider.Telephony.CellBroadcasts#CMAS_URGENCY:
+ New API must be flagged with @FlaggedApi: field android.provider.Telephony.CellBroadcasts.CMAS_URGENCY
+UnflaggedApi: android.provider.Telephony.CellBroadcasts#CONTENT_URI:
+ New API must be flagged with @FlaggedApi: field android.provider.Telephony.CellBroadcasts.CONTENT_URI
+UnflaggedApi: android.provider.Telephony.CellBroadcasts#DATA_CODING_SCHEME:
+ New API must be flagged with @FlaggedApi: field android.provider.Telephony.CellBroadcasts.DATA_CODING_SCHEME
+UnflaggedApi: android.provider.Telephony.CellBroadcasts#DEFAULT_SORT_ORDER:
+ New API must be flagged with @FlaggedApi: field android.provider.Telephony.CellBroadcasts.DEFAULT_SORT_ORDER
+UnflaggedApi: android.provider.Telephony.CellBroadcasts#DELIVERY_TIME:
+ New API must be flagged with @FlaggedApi: field android.provider.Telephony.CellBroadcasts.DELIVERY_TIME
+UnflaggedApi: android.provider.Telephony.CellBroadcasts#ETWS_IS_PRIMARY:
+ New API must be flagged with @FlaggedApi: field android.provider.Telephony.CellBroadcasts.ETWS_IS_PRIMARY
+UnflaggedApi: android.provider.Telephony.CellBroadcasts#ETWS_WARNING_TYPE:
+ New API must be flagged with @FlaggedApi: field android.provider.Telephony.CellBroadcasts.ETWS_WARNING_TYPE
+UnflaggedApi: android.provider.Telephony.CellBroadcasts#GEOGRAPHICAL_SCOPE:
+ New API must be flagged with @FlaggedApi: field android.provider.Telephony.CellBroadcasts.GEOGRAPHICAL_SCOPE
+UnflaggedApi: android.provider.Telephony.CellBroadcasts#GEOMETRIES:
+ New API must be flagged with @FlaggedApi: field android.provider.Telephony.CellBroadcasts.GEOMETRIES
+UnflaggedApi: android.provider.Telephony.CellBroadcasts#LAC:
+ New API must be flagged with @FlaggedApi: field android.provider.Telephony.CellBroadcasts.LAC
+UnflaggedApi: android.provider.Telephony.CellBroadcasts#LANGUAGE_CODE:
+ New API must be flagged with @FlaggedApi: field android.provider.Telephony.CellBroadcasts.LANGUAGE_CODE
+UnflaggedApi: android.provider.Telephony.CellBroadcasts#LOCATION_CHECK_TIME:
+ New API must be flagged with @FlaggedApi: field android.provider.Telephony.CellBroadcasts.LOCATION_CHECK_TIME
+UnflaggedApi: android.provider.Telephony.CellBroadcasts#MAXIMUM_WAIT_TIME:
+ New API must be flagged with @FlaggedApi: field android.provider.Telephony.CellBroadcasts.MAXIMUM_WAIT_TIME
+UnflaggedApi: android.provider.Telephony.CellBroadcasts#MESSAGE_BODY:
+ New API must be flagged with @FlaggedApi: field android.provider.Telephony.CellBroadcasts.MESSAGE_BODY
+UnflaggedApi: android.provider.Telephony.CellBroadcasts#MESSAGE_BROADCASTED:
+ New API must be flagged with @FlaggedApi: field android.provider.Telephony.CellBroadcasts.MESSAGE_BROADCASTED
+UnflaggedApi: android.provider.Telephony.CellBroadcasts#MESSAGE_DISPLAYED:
+ New API must be flagged with @FlaggedApi: field android.provider.Telephony.CellBroadcasts.MESSAGE_DISPLAYED
+UnflaggedApi: android.provider.Telephony.CellBroadcasts#MESSAGE_FORMAT:
+ New API must be flagged with @FlaggedApi: field android.provider.Telephony.CellBroadcasts.MESSAGE_FORMAT
+UnflaggedApi: android.provider.Telephony.CellBroadcasts#MESSAGE_HISTORY_URI:
+ New API must be flagged with @FlaggedApi: field android.provider.Telephony.CellBroadcasts.MESSAGE_HISTORY_URI
+UnflaggedApi: android.provider.Telephony.CellBroadcasts#MESSAGE_PRIORITY:
+ New API must be flagged with @FlaggedApi: field android.provider.Telephony.CellBroadcasts.MESSAGE_PRIORITY
+UnflaggedApi: android.provider.Telephony.CellBroadcasts#MESSAGE_READ:
+ New API must be flagged with @FlaggedApi: field android.provider.Telephony.CellBroadcasts.MESSAGE_READ
+UnflaggedApi: android.provider.Telephony.CellBroadcasts#PLMN:
+ New API must be flagged with @FlaggedApi: field android.provider.Telephony.CellBroadcasts.PLMN
+UnflaggedApi: android.provider.Telephony.CellBroadcasts#RECEIVED_TIME:
+ New API must be flagged with @FlaggedApi: field android.provider.Telephony.CellBroadcasts.RECEIVED_TIME
+UnflaggedApi: android.provider.Telephony.CellBroadcasts#SERIAL_NUMBER:
+ New API must be flagged with @FlaggedApi: field android.provider.Telephony.CellBroadcasts.SERIAL_NUMBER
+UnflaggedApi: android.provider.Telephony.CellBroadcasts#SERVICE_CATEGORY:
+ New API must be flagged with @FlaggedApi: field android.provider.Telephony.CellBroadcasts.SERVICE_CATEGORY
+UnflaggedApi: android.provider.Telephony.CellBroadcasts#SLOT_INDEX:
+ New API must be flagged with @FlaggedApi: field android.provider.Telephony.CellBroadcasts.SLOT_INDEX
+UnflaggedApi: android.provider.Telephony.CellBroadcasts#SUBSCRIPTION_ID:
+ New API must be flagged with @FlaggedApi: field android.provider.Telephony.CellBroadcasts.SUBSCRIPTION_ID
+UnflaggedApi: android.provider.Telephony.CellBroadcasts#_COUNT:
+ New API must be flagged with @FlaggedApi: field android.provider.Telephony.CellBroadcasts._COUNT
+UnflaggedApi: android.provider.Telephony.CellBroadcasts#_ID:
+ New API must be flagged with @FlaggedApi: field android.provider.Telephony.CellBroadcasts._ID
+UnflaggedApi: android.provider.Telephony.CellBroadcasts.Preference:
+ New API must be flagged with @FlaggedApi: class android.provider.Telephony.CellBroadcasts.Preference
+UnflaggedApi: android.provider.Telephony.CellBroadcasts.Preference#ENABLE_ALERT_VIBRATION_PREF:
+ New API must be flagged with @FlaggedApi: field android.provider.Telephony.CellBroadcasts.Preference.ENABLE_ALERT_VIBRATION_PREF
+UnflaggedApi: android.provider.Telephony.CellBroadcasts.Preference#ENABLE_AREA_UPDATE_INFO_PREF:
+ New API must be flagged with @FlaggedApi: field android.provider.Telephony.CellBroadcasts.Preference.ENABLE_AREA_UPDATE_INFO_PREF
+UnflaggedApi: android.provider.Telephony.CellBroadcasts.Preference#ENABLE_CMAS_AMBER_PREF:
+ New API must be flagged with @FlaggedApi: field android.provider.Telephony.CellBroadcasts.Preference.ENABLE_CMAS_AMBER_PREF
+UnflaggedApi: android.provider.Telephony.CellBroadcasts.Preference#ENABLE_CMAS_EXTREME_THREAT_PREF:
+ New API must be flagged with @FlaggedApi: field android.provider.Telephony.CellBroadcasts.Preference.ENABLE_CMAS_EXTREME_THREAT_PREF
+UnflaggedApi: android.provider.Telephony.CellBroadcasts.Preference#ENABLE_CMAS_IN_SECOND_LANGUAGE_PREF:
+ New API must be flagged with @FlaggedApi: field android.provider.Telephony.CellBroadcasts.Preference.ENABLE_CMAS_IN_SECOND_LANGUAGE_PREF
+UnflaggedApi: android.provider.Telephony.CellBroadcasts.Preference#ENABLE_CMAS_PRESIDENTIAL_PREF:
+ New API must be flagged with @FlaggedApi: field android.provider.Telephony.CellBroadcasts.Preference.ENABLE_CMAS_PRESIDENTIAL_PREF
+UnflaggedApi: android.provider.Telephony.CellBroadcasts.Preference#ENABLE_CMAS_SEVERE_THREAT_PREF:
+ New API must be flagged with @FlaggedApi: field android.provider.Telephony.CellBroadcasts.Preference.ENABLE_CMAS_SEVERE_THREAT_PREF
+UnflaggedApi: android.provider.Telephony.CellBroadcasts.Preference#ENABLE_EMERGENCY_PERF:
+ New API must be flagged with @FlaggedApi: field android.provider.Telephony.CellBroadcasts.Preference.ENABLE_EMERGENCY_PERF
+UnflaggedApi: android.provider.Telephony.CellBroadcasts.Preference#ENABLE_PUBLIC_SAFETY_PREF:
+ New API must be flagged with @FlaggedApi: field android.provider.Telephony.CellBroadcasts.Preference.ENABLE_PUBLIC_SAFETY_PREF
+UnflaggedApi: android.provider.Telephony.CellBroadcasts.Preference#ENABLE_STATE_LOCAL_TEST_PREF:
+ New API must be flagged with @FlaggedApi: field android.provider.Telephony.CellBroadcasts.Preference.ENABLE_STATE_LOCAL_TEST_PREF
+UnflaggedApi: android.provider.Telephony.CellBroadcasts.Preference#ENABLE_TEST_ALERT_PREF:
+ New API must be flagged with @FlaggedApi: field android.provider.Telephony.CellBroadcasts.Preference.ENABLE_TEST_ALERT_PREF
+UnflaggedApi: android.provider.Telephony.Sms.Intents#ACTION_SMS_EMERGENCY_CB_RECEIVED:
+ New API must be flagged with @FlaggedApi: field android.provider.Telephony.Sms.Intents.ACTION_SMS_EMERGENCY_CB_RECEIVED
+UnflaggedApi: android.service.ambientcontext.AmbientContextDetectionResult#toString():
+ New API must be flagged with @FlaggedApi: method android.service.ambientcontext.AmbientContextDetectionResult.toString()
+UnflaggedApi: android.service.ambientcontext.AmbientContextDetectionServiceStatus#toString():
+ New API must be flagged with @FlaggedApi: method android.service.ambientcontext.AmbientContextDetectionServiceStatus.toString()
+UnflaggedApi: android.service.appprediction.AppPredictionService#onCreate():
+ New API must be flagged with @FlaggedApi: method android.service.appprediction.AppPredictionService.onCreate()
+UnflaggedApi: android.service.assist.classification.FieldClassificationRequest#toString():
+ New API must be flagged with @FlaggedApi: method android.service.assist.classification.FieldClassificationRequest.toString()
+UnflaggedApi: android.service.assist.classification.FieldClassificationResponse#toString():
+ New API must be flagged with @FlaggedApi: method android.service.assist.classification.FieldClassificationResponse.toString()
+UnflaggedApi: android.service.assist.classification.FieldClassificationService#onCreate():
+ New API must be flagged with @FlaggedApi: method android.service.assist.classification.FieldClassificationService.onCreate()
+UnflaggedApi: android.service.autofill.AutofillFieldClassificationService#onCreate():
+ New API must be flagged with @FlaggedApi: method android.service.autofill.AutofillFieldClassificationService.onCreate()
+UnflaggedApi: android.service.autofill.Dataset.Builder#setContent(android.view.autofill.AutofillId, android.content.ClipData):
+ New API must be flagged with @FlaggedApi: method android.service.autofill.Dataset.Builder.setContent(android.view.autofill.AutofillId,android.content.ClipData)
+UnflaggedApi: android.service.autofill.augmented.AugmentedAutofillService#onCreate():
+ New API must be flagged with @FlaggedApi: method android.service.autofill.augmented.AugmentedAutofillService.onCreate()
+UnflaggedApi: android.service.autofill.augmented.AugmentedAutofillService#onUnbind(android.content.Intent):
+ New API must be flagged with @FlaggedApi: method android.service.autofill.augmented.AugmentedAutofillService.onUnbind(android.content.Intent)
+UnflaggedApi: android.service.autofill.augmented.FillRequest#toString():
+ New API must be flagged with @FlaggedApi: method android.service.autofill.augmented.FillRequest.toString()
+UnflaggedApi: android.service.autofill.augmented.FillWindow#finalize():
+ New API must be flagged with @FlaggedApi: method android.service.autofill.augmented.FillWindow.finalize()
+UnflaggedApi: android.service.autofill.augmented.PresentationParams.Area#toString():
+ New API must be flagged with @FlaggedApi: method android.service.autofill.augmented.PresentationParams.Area.toString()
+UnflaggedApi: android.service.cloudsearch.CloudSearchService#onCreate():
+ New API must be flagged with @FlaggedApi: method android.service.cloudsearch.CloudSearchService.onCreate()
+UnflaggedApi: android.service.contentcapture.ActivityEvent#toString():
+ New API must be flagged with @FlaggedApi: method android.service.contentcapture.ActivityEvent.toString()
+UnflaggedApi: android.service.contentcapture.ContentCaptureService#dump(java.io.FileDescriptor, java.io.PrintWriter, String[]):
+ New API must be flagged with @FlaggedApi: method android.service.contentcapture.ContentCaptureService.dump(java.io.FileDescriptor,java.io.PrintWriter,String[])
+UnflaggedApi: android.service.contentcapture.ContentCaptureService#onCreate():
+ New API must be flagged with @FlaggedApi: method android.service.contentcapture.ContentCaptureService.onCreate()
+UnflaggedApi: android.service.contentsuggestions.ContentSuggestionsService#onCreate():
+ New API must be flagged with @FlaggedApi: method android.service.contentsuggestions.ContentSuggestionsService.onCreate()
+UnflaggedApi: android.service.displayhash.DisplayHashParams#toString():
+ New API must be flagged with @FlaggedApi: method android.service.displayhash.DisplayHashParams.toString()
+UnflaggedApi: android.service.displayhash.DisplayHashingService#onCreate():
+ New API must be flagged with @FlaggedApi: method android.service.displayhash.DisplayHashingService.onCreate()
+UnflaggedApi: android.service.euicc.EuiccProfileInfo#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.service.euicc.EuiccProfileInfo.equals(Object)
+UnflaggedApi: android.service.euicc.EuiccProfileInfo#hashCode():
+ New API must be flagged with @FlaggedApi: method android.service.euicc.EuiccProfileInfo.hashCode()
+UnflaggedApi: android.service.euicc.EuiccProfileInfo#toString():
+ New API must be flagged with @FlaggedApi: method android.service.euicc.EuiccProfileInfo.toString()
+UnflaggedApi: android.service.euicc.EuiccService#onCreate():
+ New API must be flagged with @FlaggedApi: method android.service.euicc.EuiccService.onCreate()
+UnflaggedApi: android.service.euicc.EuiccService#onDestroy():
+ New API must be flagged with @FlaggedApi: method android.service.euicc.EuiccService.onDestroy()
+UnflaggedApi: android.service.games.CreateGameSessionRequest#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.service.games.CreateGameSessionRequest.equals(Object)
+UnflaggedApi: android.service.games.CreateGameSessionRequest#hashCode():
+ New API must be flagged with @FlaggedApi: method android.service.games.CreateGameSessionRequest.hashCode()
+UnflaggedApi: android.service.games.CreateGameSessionRequest#toString():
+ New API must be flagged with @FlaggedApi: method android.service.games.CreateGameSessionRequest.toString()
+UnflaggedApi: android.service.games.GameSessionService#onCreate():
+ New API must be flagged with @FlaggedApi: method android.service.games.GameSessionService.onCreate()
+UnflaggedApi: android.service.games.GameStartedEvent#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.service.games.GameStartedEvent.equals(Object)
+UnflaggedApi: android.service.games.GameStartedEvent#hashCode():
+ New API must be flagged with @FlaggedApi: method android.service.games.GameStartedEvent.hashCode()
+UnflaggedApi: android.service.games.GameStartedEvent#toString():
+ New API must be flagged with @FlaggedApi: method android.service.games.GameStartedEvent.toString()
+UnflaggedApi: android.service.notification.Adjustment#toString():
+ New API must be flagged with @FlaggedApi: method android.service.notification.Adjustment.toString()
+UnflaggedApi: android.service.notification.NotificationAssistantService#attachBaseContext(android.content.Context):
+ New API must be flagged with @FlaggedApi: method android.service.notification.NotificationAssistantService.attachBaseContext(android.content.Context)
+UnflaggedApi: android.service.notification.NotificationStats#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.service.notification.NotificationStats.equals(Object)
+UnflaggedApi: android.service.notification.NotificationStats#hashCode():
+ New API must be flagged with @FlaggedApi: method android.service.notification.NotificationStats.hashCode()
+UnflaggedApi: android.service.notification.NotificationStats#toString():
+ New API must be flagged with @FlaggedApi: method android.service.notification.NotificationStats.toString()
+UnflaggedApi: android.service.notification.SnoozeCriterion#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.service.notification.SnoozeCriterion.equals(Object)
+UnflaggedApi: android.service.notification.SnoozeCriterion#hashCode():
+ New API must be flagged with @FlaggedApi: method android.service.notification.SnoozeCriterion.hashCode()
+UnflaggedApi: android.service.resolver.ResolverRankerService#onDestroy():
+ New API must be flagged with @FlaggedApi: method android.service.resolver.ResolverRankerService.onDestroy()
+UnflaggedApi: android.service.resolver.ResolverTarget#toString():
+ New API must be flagged with @FlaggedApi: method android.service.resolver.ResolverTarget.toString()
+UnflaggedApi: android.service.rotationresolver.RotationResolutionRequest#toString():
+ New API must be flagged with @FlaggedApi: method android.service.rotationresolver.RotationResolutionRequest.toString()
+UnflaggedApi: android.service.search.SearchUiService#onCreate():
+ New API must be flagged with @FlaggedApi: method android.service.search.SearchUiService.onCreate()
+UnflaggedApi: android.service.smartspace.SmartspaceService#onCreate():
+ New API must be flagged with @FlaggedApi: method android.service.smartspace.SmartspaceService.onCreate()
+UnflaggedApi: android.service.textclassifier.TextClassifierService#onUnbind(android.content.Intent):
+ New API must be flagged with @FlaggedApi: method android.service.textclassifier.TextClassifierService.onUnbind(android.content.Intent)
+UnflaggedApi: android.service.timezone.TimeZoneProviderStatus#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.service.timezone.TimeZoneProviderStatus.equals(Object)
+UnflaggedApi: android.service.timezone.TimeZoneProviderStatus#hashCode():
+ New API must be flagged with @FlaggedApi: method android.service.timezone.TimeZoneProviderStatus.hashCode()
+UnflaggedApi: android.service.timezone.TimeZoneProviderStatus#toString():
+ New API must be flagged with @FlaggedApi: method android.service.timezone.TimeZoneProviderStatus.toString()
+UnflaggedApi: android.service.timezone.TimeZoneProviderSuggestion#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.service.timezone.TimeZoneProviderSuggestion.equals(Object)
+UnflaggedApi: android.service.timezone.TimeZoneProviderSuggestion#hashCode():
+ New API must be flagged with @FlaggedApi: method android.service.timezone.TimeZoneProviderSuggestion.hashCode()
+UnflaggedApi: android.service.timezone.TimeZoneProviderSuggestion#toString():
+ New API must be flagged with @FlaggedApi: method android.service.timezone.TimeZoneProviderSuggestion.toString()
+UnflaggedApi: android.service.translation.TranslationService#onCreate():
+ New API must be flagged with @FlaggedApi: method android.service.translation.TranslationService.onCreate()
+UnflaggedApi: android.service.trust.TrustAgentService#onCreate():
+ New API must be flagged with @FlaggedApi: method android.service.trust.TrustAgentService.onCreate()
+UnflaggedApi: android.service.voice.AlwaysOnHotwordDetector#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.service.voice.AlwaysOnHotwordDetector.equals(Object)
+UnflaggedApi: android.service.voice.AlwaysOnHotwordDetector#hashCode():
+ New API must be flagged with @FlaggedApi: method android.service.voice.AlwaysOnHotwordDetector.hashCode()
+UnflaggedApi: android.service.voice.AlwaysOnHotwordDetector.ModelParamRange#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.service.voice.AlwaysOnHotwordDetector.ModelParamRange.equals(Object)
+UnflaggedApi: android.service.voice.AlwaysOnHotwordDetector.ModelParamRange#hashCode():
+ New API must be flagged with @FlaggedApi: method android.service.voice.AlwaysOnHotwordDetector.ModelParamRange.hashCode()
+UnflaggedApi: android.service.voice.AlwaysOnHotwordDetector.ModelParamRange#toString():
+ New API must be flagged with @FlaggedApi: method android.service.voice.AlwaysOnHotwordDetector.ModelParamRange.toString()
+UnflaggedApi: android.service.voice.HotwordAudioStream#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.service.voice.HotwordAudioStream.equals(Object)
+UnflaggedApi: android.service.voice.HotwordAudioStream#hashCode():
+ New API must be flagged with @FlaggedApi: method android.service.voice.HotwordAudioStream.hashCode()
+UnflaggedApi: android.service.voice.HotwordAudioStream#toString():
+ New API must be flagged with @FlaggedApi: method android.service.voice.HotwordAudioStream.toString()
+UnflaggedApi: android.service.voice.HotwordDetectedResult#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.service.voice.HotwordDetectedResult.equals(Object)
+UnflaggedApi: android.service.voice.HotwordDetectedResult#hashCode():
+ New API must be flagged with @FlaggedApi: method android.service.voice.HotwordDetectedResult.hashCode()
+UnflaggedApi: android.service.voice.HotwordDetectedResult#toString():
+ New API must be flagged with @FlaggedApi: method android.service.voice.HotwordDetectedResult.toString()
+UnflaggedApi: android.service.voice.HotwordDetectionService#getSystemService(String):
+ New API must be flagged with @FlaggedApi: method android.service.voice.HotwordDetectionService.getSystemService(String)
+UnflaggedApi: android.service.voice.HotwordDetectionServiceFailure#toString():
+ New API must be flagged with @FlaggedApi: method android.service.voice.HotwordDetectionServiceFailure.toString()
+UnflaggedApi: android.service.voice.HotwordRejectedResult#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.service.voice.HotwordRejectedResult.equals(Object)
+UnflaggedApi: android.service.voice.HotwordRejectedResult#hashCode():
+ New API must be flagged with @FlaggedApi: method android.service.voice.HotwordRejectedResult.hashCode()
+UnflaggedApi: android.service.voice.HotwordRejectedResult#toString():
+ New API must be flagged with @FlaggedApi: method android.service.voice.HotwordRejectedResult.toString()
+UnflaggedApi: android.service.voice.HotwordTrainingAudio:
+ New API must be flagged with @FlaggedApi: class android.service.voice.HotwordTrainingAudio
+UnflaggedApi: android.service.voice.HotwordTrainingAudio#CONTENTS_FILE_DESCRIPTOR:
+ New API must be flagged with @FlaggedApi: field android.service.voice.HotwordTrainingAudio.CONTENTS_FILE_DESCRIPTOR
+UnflaggedApi: android.service.voice.HotwordTrainingAudio#CREATOR:
+ New API must be flagged with @FlaggedApi: field android.service.voice.HotwordTrainingAudio.CREATOR
+UnflaggedApi: android.service.voice.HotwordTrainingAudio#HOTWORD_OFFSET_UNSET:
+ New API must be flagged with @FlaggedApi: field android.service.voice.HotwordTrainingAudio.HOTWORD_OFFSET_UNSET
+UnflaggedApi: android.service.voice.HotwordTrainingAudio#PARCELABLE_WRITE_RETURN_VALUE:
+ New API must be flagged with @FlaggedApi: field android.service.voice.HotwordTrainingAudio.PARCELABLE_WRITE_RETURN_VALUE
+UnflaggedApi: android.service.voice.HotwordTrainingAudio#describeContents():
+ New API must be flagged with @FlaggedApi: method android.service.voice.HotwordTrainingAudio.describeContents()
+UnflaggedApi: android.service.voice.HotwordTrainingAudio#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.service.voice.HotwordTrainingAudio.equals(Object)
+UnflaggedApi: android.service.voice.HotwordTrainingAudio#getAudioFormat():
+ New API must be flagged with @FlaggedApi: method android.service.voice.HotwordTrainingAudio.getAudioFormat()
+UnflaggedApi: android.service.voice.HotwordTrainingAudio#getAudioType():
+ New API must be flagged with @FlaggedApi: method android.service.voice.HotwordTrainingAudio.getAudioType()
+UnflaggedApi: android.service.voice.HotwordTrainingAudio#getHotwordAudio():
+ New API must be flagged with @FlaggedApi: method android.service.voice.HotwordTrainingAudio.getHotwordAudio()
+UnflaggedApi: android.service.voice.HotwordTrainingAudio#getHotwordOffsetMillis():
+ New API must be flagged with @FlaggedApi: method android.service.voice.HotwordTrainingAudio.getHotwordOffsetMillis()
+UnflaggedApi: android.service.voice.HotwordTrainingAudio#hashCode():
+ New API must be flagged with @FlaggedApi: method android.service.voice.HotwordTrainingAudio.hashCode()
+UnflaggedApi: android.service.voice.HotwordTrainingAudio#toString():
+ New API must be flagged with @FlaggedApi: method android.service.voice.HotwordTrainingAudio.toString()
+UnflaggedApi: android.service.voice.HotwordTrainingAudio#writeToParcel(android.os.Parcel, int):
+ New API must be flagged with @FlaggedApi: method android.service.voice.HotwordTrainingAudio.writeToParcel(android.os.Parcel,int)
+UnflaggedApi: android.service.voice.HotwordTrainingAudio.Builder:
+ New API must be flagged with @FlaggedApi: class android.service.voice.HotwordTrainingAudio.Builder
+UnflaggedApi: android.service.voice.HotwordTrainingAudio.Builder#Builder(byte[], android.media.AudioFormat):
+ New API must be flagged with @FlaggedApi: constructor android.service.voice.HotwordTrainingAudio.Builder(byte[],android.media.AudioFormat)
+UnflaggedApi: android.service.voice.HotwordTrainingAudio.Builder#build():
+ New API must be flagged with @FlaggedApi: method android.service.voice.HotwordTrainingAudio.Builder.build()
+UnflaggedApi: android.service.voice.HotwordTrainingAudio.Builder#setAudioFormat(android.media.AudioFormat):
+ New API must be flagged with @FlaggedApi: method android.service.voice.HotwordTrainingAudio.Builder.setAudioFormat(android.media.AudioFormat)
+UnflaggedApi: android.service.voice.HotwordTrainingAudio.Builder#setAudioType(int):
+ New API must be flagged with @FlaggedApi: method android.service.voice.HotwordTrainingAudio.Builder.setAudioType(int)
+UnflaggedApi: android.service.voice.HotwordTrainingAudio.Builder#setHotwordAudio(byte...):
+ New API must be flagged with @FlaggedApi: method android.service.voice.HotwordTrainingAudio.Builder.setHotwordAudio(byte...)
+UnflaggedApi: android.service.voice.HotwordTrainingAudio.Builder#setHotwordOffsetMillis(int):
+ New API must be flagged with @FlaggedApi: method android.service.voice.HotwordTrainingAudio.Builder.setHotwordOffsetMillis(int)
+UnflaggedApi: android.service.voice.HotwordTrainingData:
+ New API must be flagged with @FlaggedApi: class android.service.voice.HotwordTrainingData
+UnflaggedApi: android.service.voice.HotwordTrainingData#CONTENTS_FILE_DESCRIPTOR:
+ New API must be flagged with @FlaggedApi: field android.service.voice.HotwordTrainingData.CONTENTS_FILE_DESCRIPTOR
+UnflaggedApi: android.service.voice.HotwordTrainingData#CREATOR:
+ New API must be flagged with @FlaggedApi: field android.service.voice.HotwordTrainingData.CREATOR
+UnflaggedApi: android.service.voice.HotwordTrainingData#PARCELABLE_WRITE_RETURN_VALUE:
+ New API must be flagged with @FlaggedApi: field android.service.voice.HotwordTrainingData.PARCELABLE_WRITE_RETURN_VALUE
+UnflaggedApi: android.service.voice.HotwordTrainingData#TIMEOUT_STAGE_EARLY:
+ New API must be flagged with @FlaggedApi: field android.service.voice.HotwordTrainingData.TIMEOUT_STAGE_EARLY
+UnflaggedApi: android.service.voice.HotwordTrainingData#TIMEOUT_STAGE_LATE:
+ New API must be flagged with @FlaggedApi: field android.service.voice.HotwordTrainingData.TIMEOUT_STAGE_LATE
+UnflaggedApi: android.service.voice.HotwordTrainingData#TIMEOUT_STAGE_MIDDLE:
+ New API must be flagged with @FlaggedApi: field android.service.voice.HotwordTrainingData.TIMEOUT_STAGE_MIDDLE
+UnflaggedApi: android.service.voice.HotwordTrainingData#TIMEOUT_STAGE_UNKNOWN:
+ New API must be flagged with @FlaggedApi: field android.service.voice.HotwordTrainingData.TIMEOUT_STAGE_UNKNOWN
+UnflaggedApi: android.service.voice.HotwordTrainingData#TIMEOUT_STAGE_VERY_EARLY:
+ New API must be flagged with @FlaggedApi: field android.service.voice.HotwordTrainingData.TIMEOUT_STAGE_VERY_EARLY
+UnflaggedApi: android.service.voice.HotwordTrainingData#describeContents():
+ New API must be flagged with @FlaggedApi: method android.service.voice.HotwordTrainingData.describeContents()
+UnflaggedApi: android.service.voice.HotwordTrainingData#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.service.voice.HotwordTrainingData.equals(Object)
+UnflaggedApi: android.service.voice.HotwordTrainingData#getMaxTrainingDataSize():
+ New API must be flagged with @FlaggedApi: method android.service.voice.HotwordTrainingData.getMaxTrainingDataSize()
+UnflaggedApi: android.service.voice.HotwordTrainingData#getTimeoutStage():
+ New API must be flagged with @FlaggedApi: method android.service.voice.HotwordTrainingData.getTimeoutStage()
+UnflaggedApi: android.service.voice.HotwordTrainingData#getTrainingAudios():
+ New API must be flagged with @FlaggedApi: method android.service.voice.HotwordTrainingData.getTrainingAudios()
+UnflaggedApi: android.service.voice.HotwordTrainingData#hashCode():
+ New API must be flagged with @FlaggedApi: method android.service.voice.HotwordTrainingData.hashCode()
+UnflaggedApi: android.service.voice.HotwordTrainingData#toString():
+ New API must be flagged with @FlaggedApi: method android.service.voice.HotwordTrainingData.toString()
+UnflaggedApi: android.service.voice.HotwordTrainingData#writeToParcel(android.os.Parcel, int):
+ New API must be flagged with @FlaggedApi: method android.service.voice.HotwordTrainingData.writeToParcel(android.os.Parcel,int)
+UnflaggedApi: android.service.voice.HotwordTrainingData.Builder:
+ New API must be flagged with @FlaggedApi: class android.service.voice.HotwordTrainingData.Builder
+UnflaggedApi: android.service.voice.HotwordTrainingData.Builder#Builder():
+ New API must be flagged with @FlaggedApi: constructor android.service.voice.HotwordTrainingData.Builder()
+UnflaggedApi: android.service.voice.HotwordTrainingData.Builder#addTrainingAudio(android.service.voice.HotwordTrainingAudio):
+ New API must be flagged with @FlaggedApi: method android.service.voice.HotwordTrainingData.Builder.addTrainingAudio(android.service.voice.HotwordTrainingAudio)
+UnflaggedApi: android.service.voice.HotwordTrainingData.Builder#build():
+ New API must be flagged with @FlaggedApi: method android.service.voice.HotwordTrainingData.Builder.build()
+UnflaggedApi: android.service.voice.HotwordTrainingData.Builder#setTimeoutStage(int):
+ New API must be flagged with @FlaggedApi: method android.service.voice.HotwordTrainingData.Builder.setTimeoutStage(int)
+UnflaggedApi: android.service.voice.HotwordTrainingData.Builder#setTrainingAudios(java.util.List<android.service.voice.HotwordTrainingAudio>):
+ New API must be flagged with @FlaggedApi: method android.service.voice.HotwordTrainingData.Builder.setTrainingAudios(java.util.List<android.service.voice.HotwordTrainingAudio>)
+UnflaggedApi: android.service.voice.SoundTriggerFailure#toString():
+ New API must be flagged with @FlaggedApi: method android.service.voice.SoundTriggerFailure.toString()
+UnflaggedApi: android.service.voice.VisualQueryDetectionService#getSystemService(String):
+ New API must be flagged with @FlaggedApi: method android.service.voice.VisualQueryDetectionService.getSystemService(String)
+UnflaggedApi: android.service.voice.VisualQueryDetectionService#openFileInput(String):
+ New API must be flagged with @FlaggedApi: method android.service.voice.VisualQueryDetectionService.openFileInput(String)
+UnflaggedApi: android.service.voice.VisualQueryDetectionServiceFailure#toString():
+ New API must be flagged with @FlaggedApi: method android.service.voice.VisualQueryDetectionServiceFailure.toString()
+UnflaggedApi: android.service.wallpaper.WallpaperService.Engine#isInAmbientMode():
+ New API must be flagged with @FlaggedApi: method android.service.wallpaper.WallpaperService.Engine.isInAmbientMode()
+UnflaggedApi: android.service.wallpaper.WallpaperService.Engine#onAmbientModeChanged(boolean, long):
+ New API must be flagged with @FlaggedApi: method android.service.wallpaper.WallpaperService.Engine.onAmbientModeChanged(boolean,long)
+UnflaggedApi: android.service.wallpapereffectsgeneration.WallpaperEffectsGenerationService#onCreate():
+ New API must be flagged with @FlaggedApi: method android.service.wallpapereffectsgeneration.WallpaperEffectsGenerationService.onCreate()
+UnflaggedApi: android.service.watchdog.ExplicitHealthCheckService.PackageConfig#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.service.watchdog.ExplicitHealthCheckService.PackageConfig.equals(Object)
+UnflaggedApi: android.service.watchdog.ExplicitHealthCheckService.PackageConfig#hashCode():
+ New API must be flagged with @FlaggedApi: method android.service.watchdog.ExplicitHealthCheckService.PackageConfig.hashCode()
+UnflaggedApi: android.service.watchdog.ExplicitHealthCheckService.PackageConfig#toString():
+ New API must be flagged with @FlaggedApi: method android.service.watchdog.ExplicitHealthCheckService.PackageConfig.toString()
+UnflaggedApi: android.telecom.AudioState#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.telecom.AudioState.equals(Object)
+UnflaggedApi: android.telecom.AudioState#toString():
+ New API must be flagged with @FlaggedApi: method android.telecom.AudioState.toString()
+UnflaggedApi: android.telecom.BluetoothCallQualityReport#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.telecom.BluetoothCallQualityReport.equals(Object)
+UnflaggedApi: android.telecom.BluetoothCallQualityReport#hashCode():
+ New API must be flagged with @FlaggedApi: method android.telecom.BluetoothCallQualityReport.hashCode()
+UnflaggedApi: android.telecom.CallScreeningService.CallResponse.Builder#setShouldScreenCallViaAudioProcessing(boolean):
+ New API must be flagged with @FlaggedApi: method android.telecom.CallScreeningService.CallResponse.Builder.setShouldScreenCallViaAudioProcessing(boolean)
+UnflaggedApi: android.telecom.Connection.CallFilteringCompletionInfo#toString():
+ New API must be flagged with @FlaggedApi: method android.telecom.Connection.CallFilteringCompletionInfo.toString()
+UnflaggedApi: android.telecom.StreamingCall#EXTRA_CALL_ID:
+ New API must be flagged with @FlaggedApi: field android.telecom.StreamingCall.EXTRA_CALL_ID
+UnflaggedApi: android.telephony.CallAttributes#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.telephony.CallAttributes.equals(Object)
+UnflaggedApi: android.telephony.CallAttributes#hashCode():
+ New API must be flagged with @FlaggedApi: method android.telephony.CallAttributes.hashCode()
+UnflaggedApi: android.telephony.CallAttributes#toString():
+ New API must be flagged with @FlaggedApi: method android.telephony.CallAttributes.toString()
+UnflaggedApi: android.telephony.CallQuality#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.telephony.CallQuality.equals(Object)
+UnflaggedApi: android.telephony.CallQuality#hashCode():
+ New API must be flagged with @FlaggedApi: method android.telephony.CallQuality.hashCode()
+UnflaggedApi: android.telephony.CallQuality#toString():
+ New API must be flagged with @FlaggedApi: method android.telephony.CallQuality.toString()
+UnflaggedApi: android.telephony.CallState#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.telephony.CallState.equals(Object)
+UnflaggedApi: android.telephony.CallState#hashCode():
+ New API must be flagged with @FlaggedApi: method android.telephony.CallState.hashCode()
+UnflaggedApi: android.telephony.CallState#toString():
+ New API must be flagged with @FlaggedApi: method android.telephony.CallState.toString()
+UnflaggedApi: android.telephony.CarrierRestrictionRules#toString():
+ New API must be flagged with @FlaggedApi: method android.telephony.CarrierRestrictionRules.toString()
+UnflaggedApi: android.telephony.CbGeoUtils.Circle#toString():
+ New API must be flagged with @FlaggedApi: method android.telephony.CbGeoUtils.Circle.toString()
+UnflaggedApi: android.telephony.CbGeoUtils.LatLng#toString():
+ New API must be flagged with @FlaggedApi: method android.telephony.CbGeoUtils.LatLng.toString()
+UnflaggedApi: android.telephony.CbGeoUtils.Polygon#toString():
+ New API must be flagged with @FlaggedApi: method android.telephony.CbGeoUtils.Polygon.toString()
+UnflaggedApi: android.telephony.CellBroadcastIdRange#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.telephony.CellBroadcastIdRange.equals(Object)
+UnflaggedApi: android.telephony.CellBroadcastIdRange#hashCode():
+ New API must be flagged with @FlaggedApi: method android.telephony.CellBroadcastIdRange.hashCode()
+UnflaggedApi: android.telephony.CellBroadcastIdRange#toString():
+ New API must be flagged with @FlaggedApi: method android.telephony.CellBroadcastIdRange.toString()
+UnflaggedApi: android.telephony.DataSpecificRegistrationInfo#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.telephony.DataSpecificRegistrationInfo.equals(Object)
+UnflaggedApi: android.telephony.DataSpecificRegistrationInfo#hashCode():
+ New API must be flagged with @FlaggedApi: method android.telephony.DataSpecificRegistrationInfo.hashCode()
+UnflaggedApi: android.telephony.DataSpecificRegistrationInfo#toString():
+ New API must be flagged with @FlaggedApi: method android.telephony.DataSpecificRegistrationInfo.toString()
+UnflaggedApi: android.telephony.DataThrottlingRequest#toString():
+ New API must be flagged with @FlaggedApi: method android.telephony.DataThrottlingRequest.toString()
+UnflaggedApi: android.telephony.ImsiEncryptionInfo#toString():
+ New API must be flagged with @FlaggedApi: method android.telephony.ImsiEncryptionInfo.toString()
+UnflaggedApi: android.telephony.LinkCapacityEstimate#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.telephony.LinkCapacityEstimate.equals(Object)
+UnflaggedApi: android.telephony.LinkCapacityEstimate#hashCode():
+ New API must be flagged with @FlaggedApi: method android.telephony.LinkCapacityEstimate.hashCode()
+UnflaggedApi: android.telephony.LinkCapacityEstimate#toString():
+ New API must be flagged with @FlaggedApi: method android.telephony.LinkCapacityEstimate.toString()
+UnflaggedApi: android.telephony.LteVopsSupportInfo#toString():
+ New API must be flagged with @FlaggedApi: method android.telephony.LteVopsSupportInfo.toString()
+UnflaggedApi: android.telephony.ModemActivityInfo#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.telephony.ModemActivityInfo.equals(Object)
+UnflaggedApi: android.telephony.ModemActivityInfo#hashCode():
+ New API must be flagged with @FlaggedApi: method android.telephony.ModemActivityInfo.hashCode()
+UnflaggedApi: android.telephony.ModemActivityInfo#toString():
+ New API must be flagged with @FlaggedApi: method android.telephony.ModemActivityInfo.toString()
+UnflaggedApi: android.telephony.NetworkRegistrationInfo.Builder#setIsNonTerrestrialNetwork(boolean):
+ New API must be flagged with @FlaggedApi: method android.telephony.NetworkRegistrationInfo.Builder.setIsNonTerrestrialNetwork(boolean)
+UnflaggedApi: android.telephony.NetworkService#onUnbind(android.content.Intent):
+ New API must be flagged with @FlaggedApi: method android.telephony.NetworkService.onUnbind(android.content.Intent)
+UnflaggedApi: android.telephony.NrVopsSupportInfo#toString():
+ New API must be flagged with @FlaggedApi: method android.telephony.NrVopsSupportInfo.toString()
+UnflaggedApi: android.telephony.PhoneCapability#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.telephony.PhoneCapability.equals(Object)
+UnflaggedApi: android.telephony.PhoneCapability#hashCode():
+ New API must be flagged with @FlaggedApi: method android.telephony.PhoneCapability.hashCode()
+UnflaggedApi: android.telephony.PhoneCapability#toString():
+ New API must be flagged with @FlaggedApi: method android.telephony.PhoneCapability.toString()
+UnflaggedApi: android.telephony.PhoneNumberRange#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.telephony.PhoneNumberRange.equals(Object)
+UnflaggedApi: android.telephony.PhoneNumberRange#hashCode():
+ New API must be flagged with @FlaggedApi: method android.telephony.PhoneNumberRange.hashCode()
+UnflaggedApi: android.telephony.PhoneNumberRange#toString():
+ New API must be flagged with @FlaggedApi: method android.telephony.PhoneNumberRange.toString()
+UnflaggedApi: android.telephony.PinResult#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.telephony.PinResult.equals(Object)
+UnflaggedApi: android.telephony.PinResult#hashCode():
+ New API must be flagged with @FlaggedApi: method android.telephony.PinResult.hashCode()
+UnflaggedApi: android.telephony.PinResult#toString():
+ New API must be flagged with @FlaggedApi: method android.telephony.PinResult.toString()
+UnflaggedApi: android.telephony.PreciseCallState#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.telephony.PreciseCallState.equals(Object)
+UnflaggedApi: android.telephony.PreciseCallState#hashCode():
+ New API must be flagged with @FlaggedApi: method android.telephony.PreciseCallState.hashCode()
+UnflaggedApi: android.telephony.PreciseCallState#toString():
+ New API must be flagged with @FlaggedApi: method android.telephony.PreciseCallState.toString()
+UnflaggedApi: android.telephony.SmsCbCmasInfo#toString():
+ New API must be flagged with @FlaggedApi: method android.telephony.SmsCbCmasInfo.toString()
+UnflaggedApi: android.telephony.SmsCbEtwsInfo#toString():
+ New API must be flagged with @FlaggedApi: method android.telephony.SmsCbEtwsInfo.toString()
+UnflaggedApi: android.telephony.SmsCbLocation#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.telephony.SmsCbLocation.equals(Object)
+UnflaggedApi: android.telephony.SmsCbLocation#hashCode():
+ New API must be flagged with @FlaggedApi: method android.telephony.SmsCbLocation.hashCode()
+UnflaggedApi: android.telephony.SmsCbLocation#toString():
+ New API must be flagged with @FlaggedApi: method android.telephony.SmsCbLocation.toString()
+UnflaggedApi: android.telephony.SmsCbMessage#toString():
+ New API must be flagged with @FlaggedApi: method android.telephony.SmsCbMessage.toString()
+UnflaggedApi: android.telephony.TelephonyHistogram#toString():
+ New API must be flagged with @FlaggedApi: method android.telephony.TelephonyHistogram.toString()
+UnflaggedApi: android.telephony.TelephonyManager.ModemActivityInfoException#toString():
+ New API must be flagged with @FlaggedApi: method android.telephony.TelephonyManager.ModemActivityInfoException.toString()
+UnflaggedApi: android.telephony.ThermalMitigationRequest#toString():
+ New API must be flagged with @FlaggedApi: method android.telephony.ThermalMitigationRequest.toString()
+UnflaggedApi: android.telephony.UiccAccessRule#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.telephony.UiccAccessRule.equals(Object)
+UnflaggedApi: android.telephony.UiccAccessRule#hashCode():
+ New API must be flagged with @FlaggedApi: method android.telephony.UiccAccessRule.hashCode()
+UnflaggedApi: android.telephony.UiccAccessRule#toString():
+ New API must be flagged with @FlaggedApi: method android.telephony.UiccAccessRule.toString()
+UnflaggedApi: android.telephony.UiccSlotInfo#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.telephony.UiccSlotInfo.equals(Object)
+UnflaggedApi: android.telephony.UiccSlotInfo#hashCode():
+ New API must be flagged with @FlaggedApi: method android.telephony.UiccSlotInfo.hashCode()
+UnflaggedApi: android.telephony.UiccSlotInfo#toString():
+ New API must be flagged with @FlaggedApi: method android.telephony.UiccSlotInfo.toString()
+UnflaggedApi: android.telephony.UiccSlotMapping#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.telephony.UiccSlotMapping.equals(Object)
+UnflaggedApi: android.telephony.UiccSlotMapping#hashCode():
+ New API must be flagged with @FlaggedApi: method android.telephony.UiccSlotMapping.hashCode()
+UnflaggedApi: android.telephony.UiccSlotMapping#toString():
+ New API must be flagged with @FlaggedApi: method android.telephony.UiccSlotMapping.toString()
+UnflaggedApi: android.telephony.VopsSupportInfo#writeToParcel(android.os.Parcel, int):
+ New API must be flagged with @FlaggedApi: method android.telephony.VopsSupportInfo.writeToParcel(android.os.Parcel,int)
+UnflaggedApi: android.telephony.cdma.CdmaSmsCbProgramData#toString():
+ New API must be flagged with @FlaggedApi: method android.telephony.cdma.CdmaSmsCbProgramData.toString()
+UnflaggedApi: android.telephony.data.DataCallResponse#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.telephony.data.DataCallResponse.equals(Object)
+UnflaggedApi: android.telephony.data.DataCallResponse#hashCode():
+ New API must be flagged with @FlaggedApi: method android.telephony.data.DataCallResponse.hashCode()
+UnflaggedApi: android.telephony.data.DataCallResponse#toString():
+ New API must be flagged with @FlaggedApi: method android.telephony.data.DataCallResponse.toString()
+UnflaggedApi: android.telephony.data.DataProfile#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.telephony.data.DataProfile.equals(Object)
+UnflaggedApi: android.telephony.data.DataProfile#hashCode():
+ New API must be flagged with @FlaggedApi: method android.telephony.data.DataProfile.hashCode()
+UnflaggedApi: android.telephony.data.DataProfile#toString():
+ New API must be flagged with @FlaggedApi: method android.telephony.data.DataProfile.toString()
+UnflaggedApi: android.telephony.data.DataService#onDestroy():
+ New API must be flagged with @FlaggedApi: method android.telephony.data.DataService.onDestroy()
+UnflaggedApi: android.telephony.data.DataService#onUnbind(android.content.Intent):
+ New API must be flagged with @FlaggedApi: method android.telephony.data.DataService.onUnbind(android.content.Intent)
+UnflaggedApi: android.telephony.data.EpsBearerQosSessionAttributes#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.telephony.data.EpsBearerQosSessionAttributes.equals(Object)
+UnflaggedApi: android.telephony.data.EpsBearerQosSessionAttributes#hashCode():
+ New API must be flagged with @FlaggedApi: method android.telephony.data.EpsBearerQosSessionAttributes.hashCode()
+UnflaggedApi: android.telephony.data.NrQosSessionAttributes#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.telephony.data.NrQosSessionAttributes.equals(Object)
+UnflaggedApi: android.telephony.data.NrQosSessionAttributes#hashCode():
+ New API must be flagged with @FlaggedApi: method android.telephony.data.NrQosSessionAttributes.hashCode()
+UnflaggedApi: android.telephony.data.ThrottleStatus#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.telephony.data.ThrottleStatus.equals(Object)
+UnflaggedApi: android.telephony.data.ThrottleStatus#hashCode():
+ New API must be flagged with @FlaggedApi: method android.telephony.data.ThrottleStatus.hashCode()
+UnflaggedApi: android.telephony.data.ThrottleStatus#toString():
+ New API must be flagged with @FlaggedApi: method android.telephony.data.ThrottleStatus.toString()
+UnflaggedApi: android.telephony.euicc.EuiccNotification#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.telephony.euicc.EuiccNotification.equals(Object)
+UnflaggedApi: android.telephony.euicc.EuiccNotification#hashCode():
+ New API must be flagged with @FlaggedApi: method android.telephony.euicc.EuiccNotification.hashCode()
+UnflaggedApi: android.telephony.euicc.EuiccNotification#toString():
+ New API must be flagged with @FlaggedApi: method android.telephony.euicc.EuiccNotification.toString()
+UnflaggedApi: android.telephony.euicc.EuiccRulesAuthTable#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.telephony.euicc.EuiccRulesAuthTable.equals(Object)
+UnflaggedApi: android.telephony.gba.UaSecurityProtocolIdentifier#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.telephony.gba.UaSecurityProtocolIdentifier.equals(Object)
+UnflaggedApi: android.telephony.gba.UaSecurityProtocolIdentifier#hashCode():
+ New API must be flagged with @FlaggedApi: method android.telephony.gba.UaSecurityProtocolIdentifier.hashCode()
+UnflaggedApi: android.telephony.gba.UaSecurityProtocolIdentifier#toString():
+ New API must be flagged with @FlaggedApi: method android.telephony.gba.UaSecurityProtocolIdentifier.toString()
+UnflaggedApi: android.telephony.ims.AudioCodecAttributes#toString():
+ New API must be flagged with @FlaggedApi: method android.telephony.ims.AudioCodecAttributes.toString()
+UnflaggedApi: android.telephony.ims.DelegateRegistrationState#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.telephony.ims.DelegateRegistrationState.equals(Object)
+UnflaggedApi: android.telephony.ims.DelegateRegistrationState#hashCode():
+ New API must be flagged with @FlaggedApi: method android.telephony.ims.DelegateRegistrationState.hashCode()
+UnflaggedApi: android.telephony.ims.DelegateRegistrationState#toString():
+ New API must be flagged with @FlaggedApi: method android.telephony.ims.DelegateRegistrationState.toString()
+UnflaggedApi: android.telephony.ims.DelegateRequest#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.telephony.ims.DelegateRequest.equals(Object)
+UnflaggedApi: android.telephony.ims.DelegateRequest#hashCode():
+ New API must be flagged with @FlaggedApi: method android.telephony.ims.DelegateRequest.hashCode()
+UnflaggedApi: android.telephony.ims.DelegateRequest#toString():
+ New API must be flagged with @FlaggedApi: method android.telephony.ims.DelegateRequest.toString()
+UnflaggedApi: android.telephony.ims.FeatureTagState#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.telephony.ims.FeatureTagState.equals(Object)
+UnflaggedApi: android.telephony.ims.FeatureTagState#hashCode():
+ New API must be flagged with @FlaggedApi: method android.telephony.ims.FeatureTagState.hashCode()
+UnflaggedApi: android.telephony.ims.FeatureTagState#toString():
+ New API must be flagged with @FlaggedApi: method android.telephony.ims.FeatureTagState.toString()
+UnflaggedApi: android.telephony.ims.ImsCallForwardInfo#toString():
+ New API must be flagged with @FlaggedApi: method android.telephony.ims.ImsCallForwardInfo.toString()
+UnflaggedApi: android.telephony.ims.ImsCallProfile#toString():
+ New API must be flagged with @FlaggedApi: method android.telephony.ims.ImsCallProfile.toString()
+UnflaggedApi: android.telephony.ims.ImsConferenceState#toString():
+ New API must be flagged with @FlaggedApi: method android.telephony.ims.ImsConferenceState.toString()
+UnflaggedApi: android.telephony.ims.ImsExternalCallState#toString():
+ New API must be flagged with @FlaggedApi: method android.telephony.ims.ImsExternalCallState.toString()
+UnflaggedApi: android.telephony.ims.ImsMmTelManager.RegistrationCallback#onTechnologyChangeFailed(int, android.telephony.ims.ImsReasonInfo):
+ New API must be flagged with @FlaggedApi: method android.telephony.ims.ImsMmTelManager.RegistrationCallback.onTechnologyChangeFailed(int,android.telephony.ims.ImsReasonInfo)
+UnflaggedApi: android.telephony.ims.ImsMmTelManager.RegistrationCallback#onUnregistered(android.telephony.ims.ImsReasonInfo):
+ New API must be flagged with @FlaggedApi: method android.telephony.ims.ImsMmTelManager.RegistrationCallback.onUnregistered(android.telephony.ims.ImsReasonInfo)
+UnflaggedApi: android.telephony.ims.ImsSsData#toString():
+ New API must be flagged with @FlaggedApi: method android.telephony.ims.ImsSsData.toString()
+UnflaggedApi: android.telephony.ims.ImsSsInfo#toString():
+ New API must be flagged with @FlaggedApi: method android.telephony.ims.ImsSsInfo.toString()
+UnflaggedApi: android.telephony.ims.ImsStreamMediaProfile#toString():
+ New API must be flagged with @FlaggedApi: method android.telephony.ims.ImsStreamMediaProfile.toString()
+UnflaggedApi: android.telephony.ims.ImsSuppServiceNotification#toString():
+ New API must be flagged with @FlaggedApi: method android.telephony.ims.ImsSuppServiceNotification.toString()
+UnflaggedApi: android.telephony.ims.MediaQualityStatus#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.telephony.ims.MediaQualityStatus.equals(Object)
+UnflaggedApi: android.telephony.ims.MediaQualityStatus#hashCode():
+ New API must be flagged with @FlaggedApi: method android.telephony.ims.MediaQualityStatus.hashCode()
+UnflaggedApi: android.telephony.ims.MediaQualityStatus#toString():
+ New API must be flagged with @FlaggedApi: method android.telephony.ims.MediaQualityStatus.toString()
+UnflaggedApi: android.telephony.ims.MediaThreshold#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.telephony.ims.MediaThreshold.equals(Object)
+UnflaggedApi: android.telephony.ims.MediaThreshold#hashCode():
+ New API must be flagged with @FlaggedApi: method android.telephony.ims.MediaThreshold.hashCode()
+UnflaggedApi: android.telephony.ims.MediaThreshold#toString():
+ New API must be flagged with @FlaggedApi: method android.telephony.ims.MediaThreshold.toString()
+UnflaggedApi: android.telephony.ims.PublishAttributes#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.telephony.ims.PublishAttributes.equals(Object)
+UnflaggedApi: android.telephony.ims.PublishAttributes#hashCode():
+ New API must be flagged with @FlaggedApi: method android.telephony.ims.PublishAttributes.hashCode()
+UnflaggedApi: android.telephony.ims.PublishAttributes#toString():
+ New API must be flagged with @FlaggedApi: method android.telephony.ims.PublishAttributes.toString()
+UnflaggedApi: android.telephony.ims.RcsClientConfiguration#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.telephony.ims.RcsClientConfiguration.equals(Object)
+UnflaggedApi: android.telephony.ims.RcsClientConfiguration#hashCode():
+ New API must be flagged with @FlaggedApi: method android.telephony.ims.RcsClientConfiguration.hashCode()
+UnflaggedApi: android.telephony.ims.RcsContactPresenceTuple#toString():
+ New API must be flagged with @FlaggedApi: method android.telephony.ims.RcsContactPresenceTuple.toString()
+UnflaggedApi: android.telephony.ims.RcsContactPresenceTuple.ServiceCapabilities#toString():
+ New API must be flagged with @FlaggedApi: method android.telephony.ims.RcsContactPresenceTuple.ServiceCapabilities.toString()
+UnflaggedApi: android.telephony.ims.RcsContactUceCapability#toString():
+ New API must be flagged with @FlaggedApi: method android.telephony.ims.RcsContactUceCapability.toString()
+UnflaggedApi: android.telephony.ims.RtpHeaderExtension#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.telephony.ims.RtpHeaderExtension.equals(Object)
+UnflaggedApi: android.telephony.ims.RtpHeaderExtension#hashCode():
+ New API must be flagged with @FlaggedApi: method android.telephony.ims.RtpHeaderExtension.hashCode()
+UnflaggedApi: android.telephony.ims.RtpHeaderExtension#toString():
+ New API must be flagged with @FlaggedApi: method android.telephony.ims.RtpHeaderExtension.toString()
+UnflaggedApi: android.telephony.ims.RtpHeaderExtensionType#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.telephony.ims.RtpHeaderExtensionType.equals(Object)
+UnflaggedApi: android.telephony.ims.RtpHeaderExtensionType#hashCode():
+ New API must be flagged with @FlaggedApi: method android.telephony.ims.RtpHeaderExtensionType.hashCode()
+UnflaggedApi: android.telephony.ims.RtpHeaderExtensionType#toString():
+ New API must be flagged with @FlaggedApi: method android.telephony.ims.RtpHeaderExtensionType.toString()
+UnflaggedApi: android.telephony.ims.SipDelegateConfiguration#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.telephony.ims.SipDelegateConfiguration.equals(Object)
+UnflaggedApi: android.telephony.ims.SipDelegateConfiguration#hashCode():
+ New API must be flagged with @FlaggedApi: method android.telephony.ims.SipDelegateConfiguration.hashCode()
+UnflaggedApi: android.telephony.ims.SipDelegateConfiguration#toString():
+ New API must be flagged with @FlaggedApi: method android.telephony.ims.SipDelegateConfiguration.toString()
+UnflaggedApi: android.telephony.ims.SipDelegateConfiguration.IpSecConfiguration#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.telephony.ims.SipDelegateConfiguration.IpSecConfiguration.equals(Object)
+UnflaggedApi: android.telephony.ims.SipDelegateConfiguration.IpSecConfiguration#hashCode():
+ New API must be flagged with @FlaggedApi: method android.telephony.ims.SipDelegateConfiguration.IpSecConfiguration.hashCode()
+UnflaggedApi: android.telephony.ims.SipDelegateConfiguration.IpSecConfiguration#toString():
+ New API must be flagged with @FlaggedApi: method android.telephony.ims.SipDelegateConfiguration.IpSecConfiguration.toString()
+UnflaggedApi: android.telephony.ims.SipDialogState#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.telephony.ims.SipDialogState.equals(Object)
+UnflaggedApi: android.telephony.ims.SipDialogState#hashCode():
+ New API must be flagged with @FlaggedApi: method android.telephony.ims.SipDialogState.hashCode()
+UnflaggedApi: android.telephony.ims.SipMessage#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.telephony.ims.SipMessage.equals(Object)
+UnflaggedApi: android.telephony.ims.SipMessage#hashCode():
+ New API must be flagged with @FlaggedApi: method android.telephony.ims.SipMessage.hashCode()
+UnflaggedApi: android.telephony.ims.SipMessage#toString():
+ New API must be flagged with @FlaggedApi: method android.telephony.ims.SipMessage.toString()
+UnflaggedApi: android.telephony.ims.SrvccCall#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.telephony.ims.SrvccCall.equals(Object)
+UnflaggedApi: android.telephony.ims.SrvccCall#hashCode():
+ New API must be flagged with @FlaggedApi: method android.telephony.ims.SrvccCall.hashCode()
+UnflaggedApi: android.telephony.ims.SrvccCall#toString():
+ New API must be flagged with @FlaggedApi: method android.telephony.ims.SrvccCall.toString()
+UnflaggedApi: android.telephony.ims.feature.CapabilityChangeRequest#toString():
+ New API must be flagged with @FlaggedApi: method android.telephony.ims.feature.CapabilityChangeRequest.toString()
+UnflaggedApi: android.telephony.ims.feature.CapabilityChangeRequest.CapabilityPair#toString():
+ New API must be flagged with @FlaggedApi: method android.telephony.ims.feature.CapabilityChangeRequest.CapabilityPair.toString()
+UnflaggedApi: android.telephony.ims.stub.ImsFeatureConfiguration.FeatureSlotPair#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.telephony.ims.stub.ImsFeatureConfiguration.FeatureSlotPair.equals(Object)
+UnflaggedApi: android.telephony.ims.stub.ImsFeatureConfiguration.FeatureSlotPair#hashCode():
+ New API must be flagged with @FlaggedApi: method android.telephony.ims.stub.ImsFeatureConfiguration.FeatureSlotPair.hashCode()
+UnflaggedApi: android.telephony.ims.stub.ImsFeatureConfiguration.FeatureSlotPair#toString():
+ New API must be flagged with @FlaggedApi: method android.telephony.ims.stub.ImsFeatureConfiguration.FeatureSlotPair.toString()
+UnflaggedApi: android.telephony.mbms.DownloadRequest.Builder#setServiceId(String):
+ New API must be flagged with @FlaggedApi: method android.telephony.mbms.DownloadRequest.Builder.setServiceId(String)
+UnflaggedApi: android.telephony.mbms.vendor.MbmsDownloadServiceBase#DESCRIPTOR:
+ New API must be flagged with @FlaggedApi: field android.telephony.mbms.vendor.MbmsDownloadServiceBase.DESCRIPTOR
+UnflaggedApi: android.telephony.mbms.vendor.MbmsStreamingServiceBase#DESCRIPTOR:
+ New API must be flagged with @FlaggedApi: field android.telephony.mbms.vendor.MbmsStreamingServiceBase.DESCRIPTOR
+UnflaggedApi: android.telephony.satellite.AntennaDirection:
+ New API must be flagged with @FlaggedApi: class android.telephony.satellite.AntennaDirection
+UnflaggedApi: android.telephony.satellite.AntennaDirection#CONTENTS_FILE_DESCRIPTOR:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.AntennaDirection.CONTENTS_FILE_DESCRIPTOR
+UnflaggedApi: android.telephony.satellite.AntennaDirection#CREATOR:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.AntennaDirection.CREATOR
+UnflaggedApi: android.telephony.satellite.AntennaDirection#PARCELABLE_WRITE_RETURN_VALUE:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.AntennaDirection.PARCELABLE_WRITE_RETURN_VALUE
+UnflaggedApi: android.telephony.satellite.AntennaDirection#describeContents():
+ New API must be flagged with @FlaggedApi: method android.telephony.satellite.AntennaDirection.describeContents()
+UnflaggedApi: android.telephony.satellite.AntennaDirection#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.telephony.satellite.AntennaDirection.equals(Object)
+UnflaggedApi: android.telephony.satellite.AntennaDirection#getX():
+ New API must be flagged with @FlaggedApi: method android.telephony.satellite.AntennaDirection.getX()
+UnflaggedApi: android.telephony.satellite.AntennaDirection#getY():
+ New API must be flagged with @FlaggedApi: method android.telephony.satellite.AntennaDirection.getY()
+UnflaggedApi: android.telephony.satellite.AntennaDirection#getZ():
+ New API must be flagged with @FlaggedApi: method android.telephony.satellite.AntennaDirection.getZ()
+UnflaggedApi: android.telephony.satellite.AntennaDirection#hashCode():
+ New API must be flagged with @FlaggedApi: method android.telephony.satellite.AntennaDirection.hashCode()
+UnflaggedApi: android.telephony.satellite.AntennaDirection#toString():
+ New API must be flagged with @FlaggedApi: method android.telephony.satellite.AntennaDirection.toString()
+UnflaggedApi: android.telephony.satellite.AntennaDirection#writeToParcel(android.os.Parcel, int):
+ New API must be flagged with @FlaggedApi: method android.telephony.satellite.AntennaDirection.writeToParcel(android.os.Parcel,int)
+UnflaggedApi: android.telephony.satellite.AntennaPosition:
+ New API must be flagged with @FlaggedApi: class android.telephony.satellite.AntennaPosition
+UnflaggedApi: android.telephony.satellite.AntennaPosition#CONTENTS_FILE_DESCRIPTOR:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.AntennaPosition.CONTENTS_FILE_DESCRIPTOR
+UnflaggedApi: android.telephony.satellite.AntennaPosition#CREATOR:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.AntennaPosition.CREATOR
+UnflaggedApi: android.telephony.satellite.AntennaPosition#PARCELABLE_WRITE_RETURN_VALUE:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.AntennaPosition.PARCELABLE_WRITE_RETURN_VALUE
+UnflaggedApi: android.telephony.satellite.AntennaPosition#describeContents():
+ New API must be flagged with @FlaggedApi: method android.telephony.satellite.AntennaPosition.describeContents()
+UnflaggedApi: android.telephony.satellite.AntennaPosition#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.telephony.satellite.AntennaPosition.equals(Object)
+UnflaggedApi: android.telephony.satellite.AntennaPosition#getAntennaDirection():
+ New API must be flagged with @FlaggedApi: method android.telephony.satellite.AntennaPosition.getAntennaDirection()
+UnflaggedApi: android.telephony.satellite.AntennaPosition#getSuggestedHoldPosition():
+ New API must be flagged with @FlaggedApi: method android.telephony.satellite.AntennaPosition.getSuggestedHoldPosition()
+UnflaggedApi: android.telephony.satellite.AntennaPosition#hashCode():
+ New API must be flagged with @FlaggedApi: method android.telephony.satellite.AntennaPosition.hashCode()
+UnflaggedApi: android.telephony.satellite.AntennaPosition#toString():
+ New API must be flagged with @FlaggedApi: method android.telephony.satellite.AntennaPosition.toString()
+UnflaggedApi: android.telephony.satellite.AntennaPosition#writeToParcel(android.os.Parcel, int):
+ New API must be flagged with @FlaggedApi: method android.telephony.satellite.AntennaPosition.writeToParcel(android.os.Parcel,int)
+UnflaggedApi: android.telephony.satellite.PointingInfo:
+ New API must be flagged with @FlaggedApi: class android.telephony.satellite.PointingInfo
+UnflaggedApi: android.telephony.satellite.PointingInfo#CONTENTS_FILE_DESCRIPTOR:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.PointingInfo.CONTENTS_FILE_DESCRIPTOR
+UnflaggedApi: android.telephony.satellite.PointingInfo#CREATOR:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.PointingInfo.CREATOR
+UnflaggedApi: android.telephony.satellite.PointingInfo#PARCELABLE_WRITE_RETURN_VALUE:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.PointingInfo.PARCELABLE_WRITE_RETURN_VALUE
+UnflaggedApi: android.telephony.satellite.PointingInfo#describeContents():
+ New API must be flagged with @FlaggedApi: method android.telephony.satellite.PointingInfo.describeContents()
+UnflaggedApi: android.telephony.satellite.PointingInfo#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.telephony.satellite.PointingInfo.equals(Object)
+UnflaggedApi: android.telephony.satellite.PointingInfo#getSatelliteAzimuthDegrees():
+ New API must be flagged with @FlaggedApi: method android.telephony.satellite.PointingInfo.getSatelliteAzimuthDegrees()
+UnflaggedApi: android.telephony.satellite.PointingInfo#getSatelliteElevationDegrees():
+ New API must be flagged with @FlaggedApi: method android.telephony.satellite.PointingInfo.getSatelliteElevationDegrees()
+UnflaggedApi: android.telephony.satellite.PointingInfo#hashCode():
+ New API must be flagged with @FlaggedApi: method android.telephony.satellite.PointingInfo.hashCode()
+UnflaggedApi: android.telephony.satellite.PointingInfo#toString():
+ New API must be flagged with @FlaggedApi: method android.telephony.satellite.PointingInfo.toString()
+UnflaggedApi: android.telephony.satellite.PointingInfo#writeToParcel(android.os.Parcel, int):
+ New API must be flagged with @FlaggedApi: method android.telephony.satellite.PointingInfo.writeToParcel(android.os.Parcel,int)
+UnflaggedApi: android.telephony.satellite.SatelliteCapabilities:
+ New API must be flagged with @FlaggedApi: class android.telephony.satellite.SatelliteCapabilities
+UnflaggedApi: android.telephony.satellite.SatelliteCapabilities#CONTENTS_FILE_DESCRIPTOR:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteCapabilities.CONTENTS_FILE_DESCRIPTOR
+UnflaggedApi: android.telephony.satellite.SatelliteCapabilities#CREATOR:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteCapabilities.CREATOR
+UnflaggedApi: android.telephony.satellite.SatelliteCapabilities#PARCELABLE_WRITE_RETURN_VALUE:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteCapabilities.PARCELABLE_WRITE_RETURN_VALUE
+UnflaggedApi: android.telephony.satellite.SatelliteCapabilities#describeContents():
+ New API must be flagged with @FlaggedApi: method android.telephony.satellite.SatelliteCapabilities.describeContents()
+UnflaggedApi: android.telephony.satellite.SatelliteCapabilities#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.telephony.satellite.SatelliteCapabilities.equals(Object)
+UnflaggedApi: android.telephony.satellite.SatelliteCapabilities#getAntennaPositionMap():
+ New API must be flagged with @FlaggedApi: method android.telephony.satellite.SatelliteCapabilities.getAntennaPositionMap()
+UnflaggedApi: android.telephony.satellite.SatelliteCapabilities#getMaxBytesPerOutgoingDatagram():
+ New API must be flagged with @FlaggedApi: method android.telephony.satellite.SatelliteCapabilities.getMaxBytesPerOutgoingDatagram()
+UnflaggedApi: android.telephony.satellite.SatelliteCapabilities#getSupportedRadioTechnologies():
+ New API must be flagged with @FlaggedApi: method android.telephony.satellite.SatelliteCapabilities.getSupportedRadioTechnologies()
+UnflaggedApi: android.telephony.satellite.SatelliteCapabilities#hashCode():
+ New API must be flagged with @FlaggedApi: method android.telephony.satellite.SatelliteCapabilities.hashCode()
+UnflaggedApi: android.telephony.satellite.SatelliteCapabilities#isPointingRequired():
+ New API must be flagged with @FlaggedApi: method android.telephony.satellite.SatelliteCapabilities.isPointingRequired()
+UnflaggedApi: android.telephony.satellite.SatelliteCapabilities#toString():
+ New API must be flagged with @FlaggedApi: method android.telephony.satellite.SatelliteCapabilities.toString()
+UnflaggedApi: android.telephony.satellite.SatelliteCapabilities#writeToParcel(android.os.Parcel, int):
+ New API must be flagged with @FlaggedApi: method android.telephony.satellite.SatelliteCapabilities.writeToParcel(android.os.Parcel,int)
+UnflaggedApi: android.telephony.satellite.SatelliteDatagram:
+ New API must be flagged with @FlaggedApi: class android.telephony.satellite.SatelliteDatagram
+UnflaggedApi: android.telephony.satellite.SatelliteDatagram#CONTENTS_FILE_DESCRIPTOR:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteDatagram.CONTENTS_FILE_DESCRIPTOR
+UnflaggedApi: android.telephony.satellite.SatelliteDatagram#CREATOR:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteDatagram.CREATOR
+UnflaggedApi: android.telephony.satellite.SatelliteDatagram#PARCELABLE_WRITE_RETURN_VALUE:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteDatagram.PARCELABLE_WRITE_RETURN_VALUE
+UnflaggedApi: android.telephony.satellite.SatelliteDatagram#describeContents():
+ New API must be flagged with @FlaggedApi: method android.telephony.satellite.SatelliteDatagram.describeContents()
+UnflaggedApi: android.telephony.satellite.SatelliteDatagram#getSatelliteDatagram():
+ New API must be flagged with @FlaggedApi: method android.telephony.satellite.SatelliteDatagram.getSatelliteDatagram()
+UnflaggedApi: android.telephony.satellite.SatelliteDatagram#writeToParcel(android.os.Parcel, int):
+ New API must be flagged with @FlaggedApi: method android.telephony.satellite.SatelliteDatagram.writeToParcel(android.os.Parcel,int)
+UnflaggedApi: android.telephony.satellite.SatelliteDatagramCallback:
+ New API must be flagged with @FlaggedApi: class android.telephony.satellite.SatelliteDatagramCallback
+UnflaggedApi: android.telephony.satellite.SatelliteDatagramCallback#onSatelliteDatagramReceived(long, android.telephony.satellite.SatelliteDatagram, int, java.util.function.Consumer<java.lang.Void>):
+ New API must be flagged with @FlaggedApi: method android.telephony.satellite.SatelliteDatagramCallback.onSatelliteDatagramReceived(long,android.telephony.satellite.SatelliteDatagram,int,java.util.function.Consumer<java.lang.Void>)
+UnflaggedApi: android.telephony.satellite.SatelliteManager:
+ New API must be flagged with @FlaggedApi: class android.telephony.satellite.SatelliteManager
+UnflaggedApi: android.telephony.satellite.SatelliteManager#DATAGRAM_TYPE_LOCATION_SHARING:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.DATAGRAM_TYPE_LOCATION_SHARING
+UnflaggedApi: android.telephony.satellite.SatelliteManager#DATAGRAM_TYPE_SOS_MESSAGE:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.DATAGRAM_TYPE_SOS_MESSAGE
+UnflaggedApi: android.telephony.satellite.SatelliteManager#DATAGRAM_TYPE_UNKNOWN:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.DATAGRAM_TYPE_UNKNOWN
+UnflaggedApi: android.telephony.satellite.SatelliteManager#DEVICE_HOLD_POSITION_LANDSCAPE_LEFT:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.DEVICE_HOLD_POSITION_LANDSCAPE_LEFT
+UnflaggedApi: android.telephony.satellite.SatelliteManager#DEVICE_HOLD_POSITION_LANDSCAPE_RIGHT:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.DEVICE_HOLD_POSITION_LANDSCAPE_RIGHT
+UnflaggedApi: android.telephony.satellite.SatelliteManager#DEVICE_HOLD_POSITION_PORTRAIT:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.DEVICE_HOLD_POSITION_PORTRAIT
+UnflaggedApi: android.telephony.satellite.SatelliteManager#DEVICE_HOLD_POSITION_UNKNOWN:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.DEVICE_HOLD_POSITION_UNKNOWN
+UnflaggedApi: android.telephony.satellite.SatelliteManager#DISPLAY_MODE_CLOSED:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.DISPLAY_MODE_CLOSED
+UnflaggedApi: android.telephony.satellite.SatelliteManager#DISPLAY_MODE_FIXED:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.DISPLAY_MODE_FIXED
+UnflaggedApi: android.telephony.satellite.SatelliteManager#DISPLAY_MODE_OPENED:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.DISPLAY_MODE_OPENED
+UnflaggedApi: android.telephony.satellite.SatelliteManager#DISPLAY_MODE_UNKNOWN:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.DISPLAY_MODE_UNKNOWN
+UnflaggedApi: android.telephony.satellite.SatelliteManager#NT_RADIO_TECHNOLOGY_EMTC_NTN:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.NT_RADIO_TECHNOLOGY_EMTC_NTN
+UnflaggedApi: android.telephony.satellite.SatelliteManager#NT_RADIO_TECHNOLOGY_NB_IOT_NTN:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.NT_RADIO_TECHNOLOGY_NB_IOT_NTN
+UnflaggedApi: android.telephony.satellite.SatelliteManager#NT_RADIO_TECHNOLOGY_NR_NTN:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.NT_RADIO_TECHNOLOGY_NR_NTN
+UnflaggedApi: android.telephony.satellite.SatelliteManager#NT_RADIO_TECHNOLOGY_PROPRIETARY:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.NT_RADIO_TECHNOLOGY_PROPRIETARY
+UnflaggedApi: android.telephony.satellite.SatelliteManager#NT_RADIO_TECHNOLOGY_UNKNOWN:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.NT_RADIO_TECHNOLOGY_UNKNOWN
+UnflaggedApi: android.telephony.satellite.SatelliteManager#SATELLITE_ACCESS_BARRED:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.SATELLITE_ACCESS_BARRED
+UnflaggedApi: android.telephony.satellite.SatelliteManager#SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE
+UnflaggedApi: android.telephony.satellite.SatelliteManager#SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_FAILED:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_FAILED
+UnflaggedApi: android.telephony.satellite.SatelliteManager#SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_NONE:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_NONE
+UnflaggedApi: android.telephony.satellite.SatelliteManager#SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_SUCCESS:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_SUCCESS
+UnflaggedApi: android.telephony.satellite.SatelliteManager#SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVING:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVING
+UnflaggedApi: android.telephony.satellite.SatelliteManager#SATELLITE_DATAGRAM_TRANSFER_STATE_SENDING:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_SENDING
+UnflaggedApi: android.telephony.satellite.SatelliteManager#SATELLITE_DATAGRAM_TRANSFER_STATE_SEND_FAILED:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_SEND_FAILED
+UnflaggedApi: android.telephony.satellite.SatelliteManager#SATELLITE_DATAGRAM_TRANSFER_STATE_SEND_SUCCESS:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_SEND_SUCCESS
+UnflaggedApi: android.telephony.satellite.SatelliteManager#SATELLITE_DATAGRAM_TRANSFER_STATE_UNKNOWN:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_UNKNOWN
+UnflaggedApi: android.telephony.satellite.SatelliteManager#SATELLITE_ERROR:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.SATELLITE_ERROR
+UnflaggedApi: android.telephony.satellite.SatelliteManager#SATELLITE_ERROR_NONE:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.SATELLITE_ERROR_NONE
+UnflaggedApi: android.telephony.satellite.SatelliteManager#SATELLITE_INVALID_ARGUMENTS:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.SATELLITE_INVALID_ARGUMENTS
+UnflaggedApi: android.telephony.satellite.SatelliteManager#SATELLITE_INVALID_MODEM_STATE:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.SATELLITE_INVALID_MODEM_STATE
+UnflaggedApi: android.telephony.satellite.SatelliteManager#SATELLITE_INVALID_TELEPHONY_STATE:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE
+UnflaggedApi: android.telephony.satellite.SatelliteManager#SATELLITE_MODEM_BUSY:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.SATELLITE_MODEM_BUSY
+UnflaggedApi: android.telephony.satellite.SatelliteManager#SATELLITE_MODEM_ERROR:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.SATELLITE_MODEM_ERROR
+UnflaggedApi: android.telephony.satellite.SatelliteManager#SATELLITE_MODEM_STATE_DATAGRAM_RETRYING:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.SATELLITE_MODEM_STATE_DATAGRAM_RETRYING
+UnflaggedApi: android.telephony.satellite.SatelliteManager#SATELLITE_MODEM_STATE_DATAGRAM_TRANSFERRING:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.SATELLITE_MODEM_STATE_DATAGRAM_TRANSFERRING
+UnflaggedApi: android.telephony.satellite.SatelliteManager#SATELLITE_MODEM_STATE_IDLE:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.SATELLITE_MODEM_STATE_IDLE
+UnflaggedApi: android.telephony.satellite.SatelliteManager#SATELLITE_MODEM_STATE_LISTENING:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.SATELLITE_MODEM_STATE_LISTENING
+UnflaggedApi: android.telephony.satellite.SatelliteManager#SATELLITE_MODEM_STATE_OFF:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.SATELLITE_MODEM_STATE_OFF
+UnflaggedApi: android.telephony.satellite.SatelliteManager#SATELLITE_MODEM_STATE_UNAVAILABLE:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.SATELLITE_MODEM_STATE_UNAVAILABLE
+UnflaggedApi: android.telephony.satellite.SatelliteManager#SATELLITE_MODEM_STATE_UNKNOWN:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.SATELLITE_MODEM_STATE_UNKNOWN
+UnflaggedApi: android.telephony.satellite.SatelliteManager#SATELLITE_NETWORK_ERROR:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.SATELLITE_NETWORK_ERROR
+UnflaggedApi: android.telephony.satellite.SatelliteManager#SATELLITE_NETWORK_TIMEOUT:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.SATELLITE_NETWORK_TIMEOUT
+UnflaggedApi: android.telephony.satellite.SatelliteManager#SATELLITE_NOT_AUTHORIZED:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.SATELLITE_NOT_AUTHORIZED
+UnflaggedApi: android.telephony.satellite.SatelliteManager#SATELLITE_NOT_REACHABLE:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.SATELLITE_NOT_REACHABLE
+UnflaggedApi: android.telephony.satellite.SatelliteManager#SATELLITE_NOT_SUPPORTED:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.SATELLITE_NOT_SUPPORTED
+UnflaggedApi: android.telephony.satellite.SatelliteManager#SATELLITE_NO_RESOURCES:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.SATELLITE_NO_RESOURCES
+UnflaggedApi: android.telephony.satellite.SatelliteManager#SATELLITE_RADIO_NOT_AVAILABLE:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.SATELLITE_RADIO_NOT_AVAILABLE
+UnflaggedApi: android.telephony.satellite.SatelliteManager#SATELLITE_REQUEST_ABORTED:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.SATELLITE_REQUEST_ABORTED
+UnflaggedApi: android.telephony.satellite.SatelliteManager#SATELLITE_REQUEST_FAILED:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.SATELLITE_REQUEST_FAILED
+UnflaggedApi: android.telephony.satellite.SatelliteManager#SATELLITE_REQUEST_IN_PROGRESS:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.SATELLITE_REQUEST_IN_PROGRESS
+UnflaggedApi: android.telephony.satellite.SatelliteManager#SATELLITE_REQUEST_NOT_SUPPORTED:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.SATELLITE_REQUEST_NOT_SUPPORTED
+UnflaggedApi: android.telephony.satellite.SatelliteManager#SATELLITE_RESULT_ACCESS_BARRED:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_ACCESS_BARRED
+UnflaggedApi: android.telephony.satellite.SatelliteManager#SATELLITE_RESULT_ERROR:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_ERROR
+UnflaggedApi: android.telephony.satellite.SatelliteManager#SATELLITE_RESULT_INVALID_ARGUMENTS:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_INVALID_ARGUMENTS
+UnflaggedApi: android.telephony.satellite.SatelliteManager#SATELLITE_RESULT_INVALID_MODEM_STATE:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_INVALID_MODEM_STATE
+UnflaggedApi: android.telephony.satellite.SatelliteManager#SATELLITE_RESULT_INVALID_TELEPHONY_STATE:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_INVALID_TELEPHONY_STATE
+UnflaggedApi: android.telephony.satellite.SatelliteManager#SATELLITE_RESULT_MODEM_BUSY:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_MODEM_BUSY
+UnflaggedApi: android.telephony.satellite.SatelliteManager#SATELLITE_RESULT_MODEM_ERROR:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_MODEM_ERROR
+UnflaggedApi: android.telephony.satellite.SatelliteManager#SATELLITE_RESULT_NETWORK_ERROR:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_NETWORK_ERROR
+UnflaggedApi: android.telephony.satellite.SatelliteManager#SATELLITE_RESULT_NETWORK_TIMEOUT:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_NETWORK_TIMEOUT
+UnflaggedApi: android.telephony.satellite.SatelliteManager#SATELLITE_RESULT_NOT_AUTHORIZED:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_NOT_AUTHORIZED
+UnflaggedApi: android.telephony.satellite.SatelliteManager#SATELLITE_RESULT_NOT_REACHABLE:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_NOT_REACHABLE
+UnflaggedApi: android.telephony.satellite.SatelliteManager#SATELLITE_RESULT_NOT_SUPPORTED:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_NOT_SUPPORTED
+UnflaggedApi: android.telephony.satellite.SatelliteManager#SATELLITE_RESULT_NO_RESOURCES:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_NO_RESOURCES
+UnflaggedApi: android.telephony.satellite.SatelliteManager#SATELLITE_RESULT_RADIO_NOT_AVAILABLE:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_RADIO_NOT_AVAILABLE
+UnflaggedApi: android.telephony.satellite.SatelliteManager#SATELLITE_RESULT_REQUEST_ABORTED:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_REQUEST_ABORTED
+UnflaggedApi: android.telephony.satellite.SatelliteManager#SATELLITE_RESULT_REQUEST_FAILED:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_REQUEST_FAILED
+UnflaggedApi: android.telephony.satellite.SatelliteManager#SATELLITE_RESULT_REQUEST_IN_PROGRESS:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_REQUEST_IN_PROGRESS
+UnflaggedApi: android.telephony.satellite.SatelliteManager#SATELLITE_RESULT_REQUEST_NOT_SUPPORTED:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED
+UnflaggedApi: android.telephony.satellite.SatelliteManager#SATELLITE_RESULT_SERVER_ERROR:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_SERVER_ERROR
+UnflaggedApi: android.telephony.satellite.SatelliteManager#SATELLITE_RESULT_SERVICE_ERROR:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_SERVICE_ERROR
+UnflaggedApi: android.telephony.satellite.SatelliteManager#SATELLITE_RESULT_SERVICE_NOT_PROVISIONED:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_SERVICE_NOT_PROVISIONED
+UnflaggedApi: android.telephony.satellite.SatelliteManager#SATELLITE_RESULT_SERVICE_PROVISION_IN_PROGRESS:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_SERVICE_PROVISION_IN_PROGRESS
+UnflaggedApi: android.telephony.satellite.SatelliteManager#SATELLITE_RESULT_SUCCESS:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_SUCCESS
+UnflaggedApi: android.telephony.satellite.SatelliteManager#SATELLITE_SERVER_ERROR:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.SATELLITE_SERVER_ERROR
+UnflaggedApi: android.telephony.satellite.SatelliteManager#SATELLITE_SERVICE_ERROR:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.SATELLITE_SERVICE_ERROR
+UnflaggedApi: android.telephony.satellite.SatelliteManager#SATELLITE_SERVICE_NOT_PROVISIONED:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.SATELLITE_SERVICE_NOT_PROVISIONED
+UnflaggedApi: android.telephony.satellite.SatelliteManager#SATELLITE_SERVICE_PROVISION_IN_PROGRESS:
+ New API must be flagged with @FlaggedApi: field android.telephony.satellite.SatelliteManager.SATELLITE_SERVICE_PROVISION_IN_PROGRESS
+UnflaggedApi: android.telephony.satellite.SatelliteManager#deprovisionSatelliteService(String, java.util.concurrent.Executor, java.util.function.Consumer<java.lang.Integer>):
+ New API must be flagged with @FlaggedApi: method android.telephony.satellite.SatelliteManager.deprovisionSatelliteService(String,java.util.concurrent.Executor,java.util.function.Consumer<java.lang.Integer>)
+UnflaggedApi: android.telephony.satellite.SatelliteManager#pollPendingSatelliteDatagrams(java.util.concurrent.Executor, java.util.function.Consumer<java.lang.Integer>):
+ New API must be flagged with @FlaggedApi: method android.telephony.satellite.SatelliteManager.pollPendingSatelliteDatagrams(java.util.concurrent.Executor,java.util.function.Consumer<java.lang.Integer>)
+UnflaggedApi: android.telephony.satellite.SatelliteManager#provisionSatelliteService(String, byte[], android.os.CancellationSignal, java.util.concurrent.Executor, java.util.function.Consumer<java.lang.Integer>):
+ New API must be flagged with @FlaggedApi: method android.telephony.satellite.SatelliteManager.provisionSatelliteService(String,byte[],android.os.CancellationSignal,java.util.concurrent.Executor,java.util.function.Consumer<java.lang.Integer>)
+UnflaggedApi: android.telephony.satellite.SatelliteManager#registerForSatelliteDatagram(java.util.concurrent.Executor, android.telephony.satellite.SatelliteDatagramCallback):
+ New API must be flagged with @FlaggedApi: method android.telephony.satellite.SatelliteManager.registerForSatelliteDatagram(java.util.concurrent.Executor,android.telephony.satellite.SatelliteDatagramCallback)
+UnflaggedApi: android.telephony.satellite.SatelliteManager#registerForSatelliteModemStateChanged(java.util.concurrent.Executor, android.telephony.satellite.SatelliteStateCallback):
+ New API must be flagged with @FlaggedApi: method android.telephony.satellite.SatelliteManager.registerForSatelliteModemStateChanged(java.util.concurrent.Executor,android.telephony.satellite.SatelliteStateCallback)
+UnflaggedApi: android.telephony.satellite.SatelliteManager#registerForSatelliteProvisionStateChanged(java.util.concurrent.Executor, android.telephony.satellite.SatelliteProvisionStateCallback):
+ New API must be flagged with @FlaggedApi: method android.telephony.satellite.SatelliteManager.registerForSatelliteProvisionStateChanged(java.util.concurrent.Executor,android.telephony.satellite.SatelliteProvisionStateCallback)
+UnflaggedApi: android.telephony.satellite.SatelliteManager#requestIsDemoModeEnabled(java.util.concurrent.Executor, android.os.OutcomeReceiver<java.lang.Boolean,android.telephony.satellite.SatelliteManager.SatelliteException>):
+ New API must be flagged with @FlaggedApi: method android.telephony.satellite.SatelliteManager.requestIsDemoModeEnabled(java.util.concurrent.Executor,android.os.OutcomeReceiver<java.lang.Boolean,android.telephony.satellite.SatelliteManager.SatelliteException>)
+UnflaggedApi: android.telephony.satellite.SatelliteManager#requestIsSatelliteCommunicationAllowedForCurrentLocation(java.util.concurrent.Executor, android.os.OutcomeReceiver<java.lang.Boolean,android.telephony.satellite.SatelliteManager.SatelliteException>):
+ New API must be flagged with @FlaggedApi: method android.telephony.satellite.SatelliteManager.requestIsSatelliteCommunicationAllowedForCurrentLocation(java.util.concurrent.Executor,android.os.OutcomeReceiver<java.lang.Boolean,android.telephony.satellite.SatelliteManager.SatelliteException>)
+UnflaggedApi: android.telephony.satellite.SatelliteManager#requestIsSatelliteEnabled(java.util.concurrent.Executor, android.os.OutcomeReceiver<java.lang.Boolean,android.telephony.satellite.SatelliteManager.SatelliteException>):
+ New API must be flagged with @FlaggedApi: method android.telephony.satellite.SatelliteManager.requestIsSatelliteEnabled(java.util.concurrent.Executor,android.os.OutcomeReceiver<java.lang.Boolean,android.telephony.satellite.SatelliteManager.SatelliteException>)
+UnflaggedApi: android.telephony.satellite.SatelliteManager#requestIsSatelliteProvisioned(java.util.concurrent.Executor, android.os.OutcomeReceiver<java.lang.Boolean,android.telephony.satellite.SatelliteManager.SatelliteException>):
+ New API must be flagged with @FlaggedApi: method android.telephony.satellite.SatelliteManager.requestIsSatelliteProvisioned(java.util.concurrent.Executor,android.os.OutcomeReceiver<java.lang.Boolean,android.telephony.satellite.SatelliteManager.SatelliteException>)
+UnflaggedApi: android.telephony.satellite.SatelliteManager#requestIsSatelliteSupported(java.util.concurrent.Executor, android.os.OutcomeReceiver<java.lang.Boolean,android.telephony.satellite.SatelliteManager.SatelliteException>):
+ New API must be flagged with @FlaggedApi: method android.telephony.satellite.SatelliteManager.requestIsSatelliteSupported(java.util.concurrent.Executor,android.os.OutcomeReceiver<java.lang.Boolean,android.telephony.satellite.SatelliteManager.SatelliteException>)
+UnflaggedApi: android.telephony.satellite.SatelliteManager#requestSatelliteCapabilities(java.util.concurrent.Executor, android.os.OutcomeReceiver<android.telephony.satellite.SatelliteCapabilities,android.telephony.satellite.SatelliteManager.SatelliteException>):
+ New API must be flagged with @FlaggedApi: method android.telephony.satellite.SatelliteManager.requestSatelliteCapabilities(java.util.concurrent.Executor,android.os.OutcomeReceiver<android.telephony.satellite.SatelliteCapabilities,android.telephony.satellite.SatelliteManager.SatelliteException>)
+UnflaggedApi: android.telephony.satellite.SatelliteManager#requestSatelliteEnabled(boolean, boolean, java.util.concurrent.Executor, java.util.function.Consumer<java.lang.Integer>):
+ New API must be flagged with @FlaggedApi: method android.telephony.satellite.SatelliteManager.requestSatelliteEnabled(boolean,boolean,java.util.concurrent.Executor,java.util.function.Consumer<java.lang.Integer>)
+UnflaggedApi: android.telephony.satellite.SatelliteManager#requestTimeForNextSatelliteVisibility(java.util.concurrent.Executor, android.os.OutcomeReceiver<java.time.Duration,android.telephony.satellite.SatelliteManager.SatelliteException>):
+ New API must be flagged with @FlaggedApi: method android.telephony.satellite.SatelliteManager.requestTimeForNextSatelliteVisibility(java.util.concurrent.Executor,android.os.OutcomeReceiver<java.time.Duration,android.telephony.satellite.SatelliteManager.SatelliteException>)
+UnflaggedApi: android.telephony.satellite.SatelliteManager#sendSatelliteDatagram(int, android.telephony.satellite.SatelliteDatagram, boolean, java.util.concurrent.Executor, java.util.function.Consumer<java.lang.Integer>):
+ New API must be flagged with @FlaggedApi: method android.telephony.satellite.SatelliteManager.sendSatelliteDatagram(int,android.telephony.satellite.SatelliteDatagram,boolean,java.util.concurrent.Executor,java.util.function.Consumer<java.lang.Integer>)
+UnflaggedApi: android.telephony.satellite.SatelliteManager#setDeviceAlignedWithSatellite(boolean):
+ New API must be flagged with @FlaggedApi: method android.telephony.satellite.SatelliteManager.setDeviceAlignedWithSatellite(boolean)
+UnflaggedApi: android.telephony.satellite.SatelliteManager#startSatelliteTransmissionUpdates(java.util.concurrent.Executor, java.util.function.Consumer<java.lang.Integer>, android.telephony.satellite.SatelliteTransmissionUpdateCallback):
+ New API must be flagged with @FlaggedApi: method android.telephony.satellite.SatelliteManager.startSatelliteTransmissionUpdates(java.util.concurrent.Executor,java.util.function.Consumer<java.lang.Integer>,android.telephony.satellite.SatelliteTransmissionUpdateCallback)
+UnflaggedApi: android.telephony.satellite.SatelliteManager#stopSatelliteTransmissionUpdates(android.telephony.satellite.SatelliteTransmissionUpdateCallback, java.util.concurrent.Executor, java.util.function.Consumer<java.lang.Integer>):
+ New API must be flagged with @FlaggedApi: method android.telephony.satellite.SatelliteManager.stopSatelliteTransmissionUpdates(android.telephony.satellite.SatelliteTransmissionUpdateCallback,java.util.concurrent.Executor,java.util.function.Consumer<java.lang.Integer>)
+UnflaggedApi: android.telephony.satellite.SatelliteManager#unregisterForSatelliteDatagram(android.telephony.satellite.SatelliteDatagramCallback):
+ New API must be flagged with @FlaggedApi: method android.telephony.satellite.SatelliteManager.unregisterForSatelliteDatagram(android.telephony.satellite.SatelliteDatagramCallback)
+UnflaggedApi: android.telephony.satellite.SatelliteManager#unregisterForSatelliteModemStateChanged(android.telephony.satellite.SatelliteStateCallback):
+ New API must be flagged with @FlaggedApi: method android.telephony.satellite.SatelliteManager.unregisterForSatelliteModemStateChanged(android.telephony.satellite.SatelliteStateCallback)
+UnflaggedApi: android.telephony.satellite.SatelliteManager#unregisterForSatelliteProvisionStateChanged(android.telephony.satellite.SatelliteProvisionStateCallback):
+ New API must be flagged with @FlaggedApi: method android.telephony.satellite.SatelliteManager.unregisterForSatelliteProvisionStateChanged(android.telephony.satellite.SatelliteProvisionStateCallback)
+UnflaggedApi: android.telephony.satellite.SatelliteManager.SatelliteException:
+ New API must be flagged with @FlaggedApi: class android.telephony.satellite.SatelliteManager.SatelliteException
+UnflaggedApi: android.telephony.satellite.SatelliteManager.SatelliteException#SatelliteException(int):
+ New API must be flagged with @FlaggedApi: constructor android.telephony.satellite.SatelliteManager.SatelliteException(int)
+UnflaggedApi: android.telephony.satellite.SatelliteManager.SatelliteException#getErrorCode():
+ New API must be flagged with @FlaggedApi: method android.telephony.satellite.SatelliteManager.SatelliteException.getErrorCode()
+UnflaggedApi: android.telephony.satellite.SatelliteProvisionStateCallback:
+ New API must be flagged with @FlaggedApi: class android.telephony.satellite.SatelliteProvisionStateCallback
+UnflaggedApi: android.telephony.satellite.SatelliteProvisionStateCallback#onSatelliteProvisionStateChanged(boolean):
+ New API must be flagged with @FlaggedApi: method android.telephony.satellite.SatelliteProvisionStateCallback.onSatelliteProvisionStateChanged(boolean)
+UnflaggedApi: android.telephony.satellite.SatelliteStateCallback:
+ New API must be flagged with @FlaggedApi: class android.telephony.satellite.SatelliteStateCallback
+UnflaggedApi: android.telephony.satellite.SatelliteStateCallback#onSatelliteModemStateChanged(int):
+ New API must be flagged with @FlaggedApi: method android.telephony.satellite.SatelliteStateCallback.onSatelliteModemStateChanged(int)
+UnflaggedApi: android.telephony.satellite.SatelliteTransmissionUpdateCallback:
+ New API must be flagged with @FlaggedApi: class android.telephony.satellite.SatelliteTransmissionUpdateCallback
+UnflaggedApi: android.telephony.satellite.SatelliteTransmissionUpdateCallback#onReceiveDatagramStateChanged(int, int, int):
+ New API must be flagged with @FlaggedApi: method android.telephony.satellite.SatelliteTransmissionUpdateCallback.onReceiveDatagramStateChanged(int,int,int)
+UnflaggedApi: android.telephony.satellite.SatelliteTransmissionUpdateCallback#onSatellitePositionChanged(android.telephony.satellite.PointingInfo):
+ New API must be flagged with @FlaggedApi: method android.telephony.satellite.SatelliteTransmissionUpdateCallback.onSatellitePositionChanged(android.telephony.satellite.PointingInfo)
+UnflaggedApi: android.telephony.satellite.SatelliteTransmissionUpdateCallback#onSendDatagramStateChanged(int, int, int):
+ New API must be flagged with @FlaggedApi: method android.telephony.satellite.SatelliteTransmissionUpdateCallback.onSendDatagramStateChanged(int,int,int)
+UnflaggedApi: android.text.FontConfig#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.text.FontConfig.equals(Object)
+UnflaggedApi: android.text.FontConfig#hashCode():
+ New API must be flagged with @FlaggedApi: method android.text.FontConfig.hashCode()
+UnflaggedApi: android.text.FontConfig#toString():
+ New API must be flagged with @FlaggedApi: method android.text.FontConfig.toString()
+UnflaggedApi: android.text.FontConfig.Alias#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.text.FontConfig.Alias.equals(Object)
+UnflaggedApi: android.text.FontConfig.Alias#hashCode():
+ New API must be flagged with @FlaggedApi: method android.text.FontConfig.Alias.hashCode()
+UnflaggedApi: android.text.FontConfig.Alias#toString():
+ New API must be flagged with @FlaggedApi: method android.text.FontConfig.Alias.toString()
+UnflaggedApi: android.text.FontConfig.Font#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.text.FontConfig.Font.equals(Object)
+UnflaggedApi: android.text.FontConfig.Font#hashCode():
+ New API must be flagged with @FlaggedApi: method android.text.FontConfig.Font.hashCode()
+UnflaggedApi: android.text.FontConfig.Font#toString():
+ New API must be flagged with @FlaggedApi: method android.text.FontConfig.Font.toString()
+UnflaggedApi: android.text.FontConfig.FontFamily#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.text.FontConfig.FontFamily.equals(Object)
+UnflaggedApi: android.text.FontConfig.FontFamily#hashCode():
+ New API must be flagged with @FlaggedApi: method android.text.FontConfig.FontFamily.hashCode()
+UnflaggedApi: android.text.FontConfig.FontFamily#toString():
+ New API must be flagged with @FlaggedApi: method android.text.FontConfig.FontFamily.toString()
+UnflaggedApi: android.text.FontConfig.NamedFamilyList#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.text.FontConfig.NamedFamilyList.equals(Object)
+UnflaggedApi: android.text.FontConfig.NamedFamilyList#hashCode():
+ New API must be flagged with @FlaggedApi: method android.text.FontConfig.NamedFamilyList.hashCode()
+UnflaggedApi: android.text.FontConfig.NamedFamilyList#toString():
+ New API must be flagged with @FlaggedApi: method android.text.FontConfig.NamedFamilyList.toString()
+UnflaggedApi: android.view.contentcapture.ContentCaptureEvent#toString():
+ New API must be flagged with @FlaggedApi: method android.view.contentcapture.ContentCaptureEvent.toString()
+UnflaggedApi: android.view.contentcapture.ViewNode#getAutofillHints():
+ New API must be flagged with @FlaggedApi: method android.view.contentcapture.ViewNode.getAutofillHints()
+UnflaggedApi: android.view.contentcapture.ViewNode#getAutofillId():
+ New API must be flagged with @FlaggedApi: method android.view.contentcapture.ViewNode.getAutofillId()
+UnflaggedApi: android.view.contentcapture.ViewNode#getAutofillOptions():
+ New API must be flagged with @FlaggedApi: method android.view.contentcapture.ViewNode.getAutofillOptions()
+UnflaggedApi: android.view.contentcapture.ViewNode#getAutofillType():
+ New API must be flagged with @FlaggedApi: method android.view.contentcapture.ViewNode.getAutofillType()
+UnflaggedApi: android.view.contentcapture.ViewNode#getAutofillValue():
+ New API must be flagged with @FlaggedApi: method android.view.contentcapture.ViewNode.getAutofillValue()
+UnflaggedApi: android.view.contentcapture.ViewNode#getClassName():
+ New API must be flagged with @FlaggedApi: method android.view.contentcapture.ViewNode.getClassName()
+UnflaggedApi: android.view.contentcapture.ViewNode#getContentDescription():
+ New API must be flagged with @FlaggedApi: method android.view.contentcapture.ViewNode.getContentDescription()
+UnflaggedApi: android.view.contentcapture.ViewNode#getExtras():
+ New API must be flagged with @FlaggedApi: method android.view.contentcapture.ViewNode.getExtras()
+UnflaggedApi: android.view.contentcapture.ViewNode#getHeight():
+ New API must be flagged with @FlaggedApi: method android.view.contentcapture.ViewNode.getHeight()
+UnflaggedApi: android.view.contentcapture.ViewNode#getHint():
+ New API must be flagged with @FlaggedApi: method android.view.contentcapture.ViewNode.getHint()
+UnflaggedApi: android.view.contentcapture.ViewNode#getHintIdEntry():
+ New API must be flagged with @FlaggedApi: method android.view.contentcapture.ViewNode.getHintIdEntry()
+UnflaggedApi: android.view.contentcapture.ViewNode#getId():
+ New API must be flagged with @FlaggedApi: method android.view.contentcapture.ViewNode.getId()
+UnflaggedApi: android.view.contentcapture.ViewNode#getIdEntry():
+ New API must be flagged with @FlaggedApi: method android.view.contentcapture.ViewNode.getIdEntry()
+UnflaggedApi: android.view.contentcapture.ViewNode#getIdPackage():
+ New API must be flagged with @FlaggedApi: method android.view.contentcapture.ViewNode.getIdPackage()
+UnflaggedApi: android.view.contentcapture.ViewNode#getIdType():
+ New API must be flagged with @FlaggedApi: method android.view.contentcapture.ViewNode.getIdType()
+UnflaggedApi: android.view.contentcapture.ViewNode#getInputType():
+ New API must be flagged with @FlaggedApi: method android.view.contentcapture.ViewNode.getInputType()
+UnflaggedApi: android.view.contentcapture.ViewNode#getLeft():
+ New API must be flagged with @FlaggedApi: method android.view.contentcapture.ViewNode.getLeft()
+UnflaggedApi: android.view.contentcapture.ViewNode#getLocaleList():
+ New API must be flagged with @FlaggedApi: method android.view.contentcapture.ViewNode.getLocaleList()
+UnflaggedApi: android.view.contentcapture.ViewNode#getMaxTextEms():
+ New API must be flagged with @FlaggedApi: method android.view.contentcapture.ViewNode.getMaxTextEms()
+UnflaggedApi: android.view.contentcapture.ViewNode#getMaxTextLength():
+ New API must be flagged with @FlaggedApi: method android.view.contentcapture.ViewNode.getMaxTextLength()
+UnflaggedApi: android.view.contentcapture.ViewNode#getMinTextEms():
+ New API must be flagged with @FlaggedApi: method android.view.contentcapture.ViewNode.getMinTextEms()
+UnflaggedApi: android.view.contentcapture.ViewNode#getReceiveContentMimeTypes():
+ New API must be flagged with @FlaggedApi: method android.view.contentcapture.ViewNode.getReceiveContentMimeTypes()
+UnflaggedApi: android.view.contentcapture.ViewNode#getScrollX():
+ New API must be flagged with @FlaggedApi: method android.view.contentcapture.ViewNode.getScrollX()
+UnflaggedApi: android.view.contentcapture.ViewNode#getScrollY():
+ New API must be flagged with @FlaggedApi: method android.view.contentcapture.ViewNode.getScrollY()
+UnflaggedApi: android.view.contentcapture.ViewNode#getText():
+ New API must be flagged with @FlaggedApi: method android.view.contentcapture.ViewNode.getText()
+UnflaggedApi: android.view.contentcapture.ViewNode#getTextBackgroundColor():
+ New API must be flagged with @FlaggedApi: method android.view.contentcapture.ViewNode.getTextBackgroundColor()
+UnflaggedApi: android.view.contentcapture.ViewNode#getTextColor():
+ New API must be flagged with @FlaggedApi: method android.view.contentcapture.ViewNode.getTextColor()
+UnflaggedApi: android.view.contentcapture.ViewNode#getTextIdEntry():
+ New API must be flagged with @FlaggedApi: method android.view.contentcapture.ViewNode.getTextIdEntry()
+UnflaggedApi: android.view.contentcapture.ViewNode#getTextLineBaselines():
+ New API must be flagged with @FlaggedApi: method android.view.contentcapture.ViewNode.getTextLineBaselines()
+UnflaggedApi: android.view.contentcapture.ViewNode#getTextLineCharOffsets():
+ New API must be flagged with @FlaggedApi: method android.view.contentcapture.ViewNode.getTextLineCharOffsets()
+UnflaggedApi: android.view.contentcapture.ViewNode#getTextSelectionEnd():
+ New API must be flagged with @FlaggedApi: method android.view.contentcapture.ViewNode.getTextSelectionEnd()
+UnflaggedApi: android.view.contentcapture.ViewNode#getTextSelectionStart():
+ New API must be flagged with @FlaggedApi: method android.view.contentcapture.ViewNode.getTextSelectionStart()
+UnflaggedApi: android.view.contentcapture.ViewNode#getTextSize():
+ New API must be flagged with @FlaggedApi: method android.view.contentcapture.ViewNode.getTextSize()
+UnflaggedApi: android.view.contentcapture.ViewNode#getTextStyle():
+ New API must be flagged with @FlaggedApi: method android.view.contentcapture.ViewNode.getTextStyle()
+UnflaggedApi: android.view.contentcapture.ViewNode#getTop():
+ New API must be flagged with @FlaggedApi: method android.view.contentcapture.ViewNode.getTop()
+UnflaggedApi: android.view.contentcapture.ViewNode#getVisibility():
+ New API must be flagged with @FlaggedApi: method android.view.contentcapture.ViewNode.getVisibility()
+UnflaggedApi: android.view.contentcapture.ViewNode#getWidth():
+ New API must be flagged with @FlaggedApi: method android.view.contentcapture.ViewNode.getWidth()
+UnflaggedApi: android.view.contentcapture.ViewNode#isAccessibilityFocused():
+ New API must be flagged with @FlaggedApi: method android.view.contentcapture.ViewNode.isAccessibilityFocused()
+UnflaggedApi: android.view.contentcapture.ViewNode#isActivated():
+ New API must be flagged with @FlaggedApi: method android.view.contentcapture.ViewNode.isActivated()
+UnflaggedApi: android.view.contentcapture.ViewNode#isAssistBlocked():
+ New API must be flagged with @FlaggedApi: method android.view.contentcapture.ViewNode.isAssistBlocked()
+UnflaggedApi: android.view.contentcapture.ViewNode#isCheckable():
+ New API must be flagged with @FlaggedApi: method android.view.contentcapture.ViewNode.isCheckable()
+UnflaggedApi: android.view.contentcapture.ViewNode#isChecked():
+ New API must be flagged with @FlaggedApi: method android.view.contentcapture.ViewNode.isChecked()
+UnflaggedApi: android.view.contentcapture.ViewNode#isClickable():
+ New API must be flagged with @FlaggedApi: method android.view.contentcapture.ViewNode.isClickable()
+UnflaggedApi: android.view.contentcapture.ViewNode#isContextClickable():
+ New API must be flagged with @FlaggedApi: method android.view.contentcapture.ViewNode.isContextClickable()
+UnflaggedApi: android.view.contentcapture.ViewNode#isEnabled():
+ New API must be flagged with @FlaggedApi: method android.view.contentcapture.ViewNode.isEnabled()
+UnflaggedApi: android.view.contentcapture.ViewNode#isFocusable():
+ New API must be flagged with @FlaggedApi: method android.view.contentcapture.ViewNode.isFocusable()
+UnflaggedApi: android.view.contentcapture.ViewNode#isFocused():
+ New API must be flagged with @FlaggedApi: method android.view.contentcapture.ViewNode.isFocused()
+UnflaggedApi: android.view.contentcapture.ViewNode#isLongClickable():
+ New API must be flagged with @FlaggedApi: method android.view.contentcapture.ViewNode.isLongClickable()
+UnflaggedApi: android.view.contentcapture.ViewNode#isOpaque():
+ New API must be flagged with @FlaggedApi: method android.view.contentcapture.ViewNode.isOpaque()
+UnflaggedApi: android.view.contentcapture.ViewNode#isSelected():
+ New API must be flagged with @FlaggedApi: method android.view.contentcapture.ViewNode.isSelected()
+UnflaggedApi: android.view.translation.UiTranslationSpec#equals(Object):
+ New API must be flagged with @FlaggedApi: method android.view.translation.UiTranslationSpec.equals(Object)
+UnflaggedApi: android.view.translation.UiTranslationSpec#hashCode():
+ New API must be flagged with @FlaggedApi: method android.view.translation.UiTranslationSpec.hashCode()
+UnflaggedApi: android.view.translation.UiTranslationSpec#toString():
+ New API must be flagged with @FlaggedApi: method android.view.translation.UiTranslationSpec.toString()
diff --git a/core/java/android/hardware/radio/ProgramList.java b/core/java/android/hardware/radio/ProgramList.java
index b2dfd8501772..4f07acf6961a 100644
--- a/core/java/android/hardware/radio/ProgramList.java
+++ b/core/java/android/hardware/radio/ProgramList.java
@@ -23,6 +23,7 @@ import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.ArrayMap;
+import android.util.ArraySet;
import com.android.internal.annotations.GuardedBy;
@@ -34,7 +35,6 @@ import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.Executor;
-import java.util.stream.Collectors;
/**
* @hide
@@ -45,8 +45,8 @@ public final class ProgramList implements AutoCloseable {
private final Object mLock = new Object();
@GuardedBy("mLock")
- private final Map<ProgramSelector.Identifier, RadioManager.ProgramInfo> mPrograms =
- new ArrayMap<>();
+ private final Map<ProgramSelector.Identifier, Map<UniqueProgramIdentifier,
+ RadioManager.ProgramInfo>> mPrograms = new ArrayMap<>();
@GuardedBy("mLock")
private final List<ListCallback> mListCallbacks = new ArrayList<>();
@@ -193,7 +193,7 @@ public final class ProgramList implements AutoCloseable {
void apply(Chunk chunk) {
List<ProgramSelector.Identifier> removedList = new ArrayList<>();
- List<ProgramSelector.Identifier> changedList = new ArrayList<>();
+ Set<ProgramSelector.Identifier> changedSet = new ArraySet<>();
List<ProgramList.ListCallback> listCallbacksCopied;
List<OnCompleteListener> onCompleteListenersCopied = new ArrayList<>();
synchronized (mLock) {
@@ -203,19 +203,27 @@ public final class ProgramList implements AutoCloseable {
listCallbacksCopied = new ArrayList<>(mListCallbacks);
if (chunk.isPurge()) {
- Iterator<Map.Entry<ProgramSelector.Identifier, RadioManager.ProgramInfo>>
- programsIterator = mPrograms.entrySet().iterator();
+ Iterator<Map.Entry<ProgramSelector.Identifier, Map<UniqueProgramIdentifier,
+ RadioManager.ProgramInfo>>> programsIterator =
+ mPrograms.entrySet().iterator();
while (programsIterator.hasNext()) {
- RadioManager.ProgramInfo removed = programsIterator.next().getValue();
- if (removed != null) {
- removedList.add(removed.getSelector().getPrimaryId());
+ Map.Entry<ProgramSelector.Identifier, Map<UniqueProgramIdentifier,
+ RadioManager.ProgramInfo>> removed = programsIterator.next();
+ if (removed.getValue() != null) {
+ removedList.add(removed.getKey());
}
programsIterator.remove();
}
}
- chunk.getRemoved().stream().forEach(id -> removeLocked(id, removedList));
- chunk.getModified().stream().forEach(info -> putLocked(info, changedList));
+ Iterator<UniqueProgramIdentifier> removedIterator = chunk.getRemoved().iterator();
+ while (removedIterator.hasNext()) {
+ removeLocked(removedIterator.next(), removedList);
+ }
+ Iterator<RadioManager.ProgramInfo> modifiedIterator = chunk.getModified().iterator();
+ while (modifiedIterator.hasNext()) {
+ putLocked(modifiedIterator.next(), changedSet);
+ }
if (chunk.isComplete()) {
mIsComplete = true;
@@ -228,9 +236,11 @@ public final class ProgramList implements AutoCloseable {
listCallbacksCopied.get(cbIndex).onItemRemoved(removedList.get(i));
}
}
- for (int i = 0; i < changedList.size(); i++) {
+ Iterator<ProgramSelector.Identifier> changedIterator = changedSet.iterator();
+ while (changedIterator.hasNext()) {
+ ProgramSelector.Identifier changedId = changedIterator.next();
for (int cbIndex = 0; cbIndex < listCallbacksCopied.size(); cbIndex++) {
- listCallbacksCopied.get(cbIndex).onItemChanged(changedList.get(i));
+ listCallbacksCopied.get(cbIndex).onItemChanged(changedId);
}
}
if (chunk.isComplete()) {
@@ -242,20 +252,31 @@ public final class ProgramList implements AutoCloseable {
@GuardedBy("mLock")
private void putLocked(RadioManager.ProgramInfo value,
- List<ProgramSelector.Identifier> changedIdentifierList) {
- ProgramSelector.Identifier key = value.getSelector().getPrimaryId();
- mPrograms.put(Objects.requireNonNull(key), value);
- ProgramSelector.Identifier sel = value.getSelector().getPrimaryId();
- changedIdentifierList.add(sel);
+ Set<ProgramSelector.Identifier> changedIdentifierSet) {
+ UniqueProgramIdentifier key = new UniqueProgramIdentifier(
+ value.getSelector());
+ ProgramSelector.Identifier primaryKey = Objects.requireNonNull(key.getPrimaryId());
+ if (!mPrograms.containsKey(primaryKey)) {
+ mPrograms.put(primaryKey, new ArrayMap<>());
+ }
+ mPrograms.get(primaryKey).put(key, value);
+ changedIdentifierSet.add(primaryKey);
}
@GuardedBy("mLock")
- private void removeLocked(ProgramSelector.Identifier key,
+ private void removeLocked(UniqueProgramIdentifier key,
List<ProgramSelector.Identifier> removedIdentifierList) {
- RadioManager.ProgramInfo removed = mPrograms.remove(Objects.requireNonNull(key));
+ ProgramSelector.Identifier primaryKey = Objects.requireNonNull(key.getPrimaryId());
+ if (!mPrograms.containsKey(primaryKey)) {
+ return;
+ }
+ Map<UniqueProgramIdentifier, RadioManager.ProgramInfo> entries = mPrograms
+ .get(primaryKey);
+ RadioManager.ProgramInfo removed = entries.remove(Objects.requireNonNull(key));
if (removed == null) return;
- ProgramSelector.Identifier sel = removed.getSelector().getPrimaryId();
- removedIdentifierList.add(sel);
+ if (entries.size() == 0) {
+ removedIdentifierList.add(primaryKey);
+ }
}
/**
@@ -264,9 +285,20 @@ public final class ProgramList implements AutoCloseable {
* @return the new List<> object; it won't receive any further updates
*/
public @NonNull List<RadioManager.ProgramInfo> toList() {
+ List<RadioManager.ProgramInfo> list = new ArrayList<>();
synchronized (mLock) {
- return mPrograms.values().stream().collect(Collectors.toList());
+ Iterator<Map.Entry<ProgramSelector.Identifier, Map<UniqueProgramIdentifier,
+ RadioManager.ProgramInfo>>> listIterator = mPrograms.entrySet().iterator();
+ while (listIterator.hasNext()) {
+ Iterator<Map.Entry<UniqueProgramIdentifier,
+ RadioManager.ProgramInfo>> prorgramsIterator = listIterator.next()
+ .getValue().entrySet().iterator();
+ while (prorgramsIterator.hasNext()) {
+ list.add(prorgramsIterator.next().getValue());
+ }
+ }
}
+ return list;
}
/**
@@ -276,9 +308,15 @@ public final class ProgramList implements AutoCloseable {
* @return the program info, or null if there is no such program on the list
*/
public @Nullable RadioManager.ProgramInfo get(@NonNull ProgramSelector.Identifier id) {
+ Map<UniqueProgramIdentifier, RadioManager.ProgramInfo> entries;
synchronized (mLock) {
- return mPrograms.get(Objects.requireNonNull(id));
+ entries = mPrograms.get(Objects.requireNonNull(id,
+ "Primary identifier can not be null"));
+ }
+ if (entries == null) {
+ return null;
}
+ return entries.entrySet().iterator().next().getValue();
}
/**
@@ -404,7 +442,7 @@ public final class ProgramList implements AutoCloseable {
* Checks, if non-tunable entries that define tree structure on the
* program list (i.e. DAB ensembles) should be included.
*
- * @see {@link ProgramSelector.Identifier#isCategory()}
+ * @see ProgramSelector.Identifier#isCategoryType()
*/
public boolean areCategoriesIncluded() {
return mIncludeCategories;
@@ -459,11 +497,11 @@ public final class ProgramList implements AutoCloseable {
private final boolean mPurge;
private final boolean mComplete;
private final @NonNull Set<RadioManager.ProgramInfo> mModified;
- private final @NonNull Set<ProgramSelector.Identifier> mRemoved;
+ private final @NonNull Set<UniqueProgramIdentifier> mRemoved;
public Chunk(boolean purge, boolean complete,
@Nullable Set<RadioManager.ProgramInfo> modified,
- @Nullable Set<ProgramSelector.Identifier> removed) {
+ @Nullable Set<UniqueProgramIdentifier> removed) {
mPurge = purge;
mComplete = complete;
mModified = (modified != null) ? modified : Collections.emptySet();
@@ -474,7 +512,7 @@ public final class ProgramList implements AutoCloseable {
mPurge = in.readByte() != 0;
mComplete = in.readByte() != 0;
mModified = Utils.createSet(in, RadioManager.ProgramInfo.CREATOR);
- mRemoved = Utils.createSet(in, ProgramSelector.Identifier.CREATOR);
+ mRemoved = Utils.createSet(in, UniqueProgramIdentifier.CREATOR);
}
@Override
@@ -512,7 +550,7 @@ public final class ProgramList implements AutoCloseable {
return mModified;
}
- public @NonNull Set<ProgramSelector.Identifier> getRemoved() {
+ public @NonNull Set<UniqueProgramIdentifier> getRemoved() {
return mRemoved;
}
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index c6cb604d4039..80b7d40c14c5 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -4663,26 +4663,6 @@ public class UserManager {
}
/**
- * Returns number of full users on the device.
- * @hide
- */
- @RequiresPermission(anyOf = {
- android.Manifest.permission.MANAGE_USERS,
- android.Manifest.permission.CREATE_USERS
- })
- public int getFullUserCount() {
- List<UserInfo> users = getUsers(/* excludePartial= */ true, /* excludeDying= */ true,
- /* excludePreCreated= */ true);
- int count = 0;
- for (UserInfo user : users) {
- if (user.isFull()) {
- count++;
- }
- }
- return count;
- }
-
- /**
* @deprecated use {@link #getAliveUsers()} for {@code getUsers(true)}, or
* {@link #getUsers()} for @code getUsers(false)}.
*
diff --git a/core/java/android/security/FileIntegrityManager.java b/core/java/android/security/FileIntegrityManager.java
index d6f3bf334456..132700d289b8 100644
--- a/core/java/android/security/FileIntegrityManager.java
+++ b/core/java/android/security/FileIntegrityManager.java
@@ -133,13 +133,11 @@ public final class FileIntegrityManager {
* also use this API to download the best signature on the running device.
*
* @return whether the certificate is trusted in the system
- * @deprecated The feature is no longer supported, and this API now always returns false.
*/
@RequiresPermission(anyOf = {
android.Manifest.permission.INSTALL_PACKAGES,
android.Manifest.permission.REQUEST_INSTALL_PACKAGES
})
- @Deprecated
public boolean isAppSourceCertificateTrusted(@NonNull X509Certificate certificate)
throws CertificateEncodingException {
try {
diff --git a/core/java/android/service/voice/HotwordTrainingAudio.java b/core/java/android/service/voice/HotwordTrainingAudio.java
index 895b0c0e2d55..91e34dcc4a64 100644
--- a/core/java/android/service/voice/HotwordTrainingAudio.java
+++ b/core/java/android/service/voice/HotwordTrainingAudio.java
@@ -18,6 +18,7 @@ package android.service.voice;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.media.AudioFormat;
import android.os.Parcel;
@@ -25,6 +26,8 @@ import android.os.Parcelable;
import com.android.internal.util.DataClass;
+import java.util.Objects;
+
/**
* Represents audio supporting hotword model training.
*
@@ -43,7 +46,10 @@ public final class HotwordTrainingAudio implements Parcelable {
/** Represents unset value for the hotword offset. */
public static final int HOTWORD_OFFSET_UNSET = -1;
- /** Buffer of hotword audio data for training models. */
+ /**
+ * Buffer of hotword audio data for training models. The data format is expected to match
+ * {@link #getAudioFormat()}.
+ */
@NonNull
private final byte[] mHotwordAudio;
@@ -74,6 +80,24 @@ public final class HotwordTrainingAudio implements Parcelable {
*/
private int mHotwordOffsetMillis = HOTWORD_OFFSET_UNSET;
+ @DataClass.Suppress("setHotwordAudio")
+ abstract static class BaseBuilder {
+
+ /**
+ * Buffer of hotword audio data for training models. The data format is expected to match
+ * {@link #getAudioFormat()}.
+ */
+ @SuppressLint("UnflaggedApi")
+ public @NonNull HotwordTrainingAudio.Builder setHotwordAudio(@NonNull byte[] value) {
+ Objects.requireNonNull(value, "value should not be null");
+ final HotwordTrainingAudio.Builder builder = (HotwordTrainingAudio.Builder) this;
+ // If the code gen flag in build() is changed, we must update the flag e.g. 0x1 here.
+ builder.mBuilderFieldsSet |= 0x1;
+ builder.mHotwordAudio = value;
+ return builder;
+ }
+ }
+
// Code below generated by codegen v1.0.23.
@@ -110,7 +134,8 @@ public final class HotwordTrainingAudio implements Parcelable {
}
/**
- * Buffer of hotword audio data for training models.
+ * Buffer of hotword audio data for training models. The data format is expected to match
+ * {@link #getAudioFormat()}.
*/
@DataClass.Generated.Member
public @NonNull byte[] getHotwordAudio() {
@@ -171,7 +196,7 @@ public final class HotwordTrainingAudio implements Parcelable {
//noinspection PointlessBooleanExpression
return true
&& java.util.Arrays.equals(mHotwordAudio, that.mHotwordAudio)
- && java.util.Objects.equals(mAudioFormat, that.mAudioFormat)
+ && Objects.equals(mAudioFormat, that.mAudioFormat)
&& mAudioType == that.mAudioType
&& mHotwordOffsetMillis == that.mHotwordOffsetMillis;
}
@@ -184,7 +209,7 @@ public final class HotwordTrainingAudio implements Parcelable {
int _hash = 1;
_hash = 31 * _hash + java.util.Arrays.hashCode(mHotwordAudio);
- _hash = 31 * _hash + java.util.Objects.hashCode(mAudioFormat);
+ _hash = 31 * _hash + Objects.hashCode(mAudioFormat);
_hash = 31 * _hash + mAudioType;
_hash = 31 * _hash + mHotwordOffsetMillis;
return _hash;
@@ -251,7 +276,7 @@ public final class HotwordTrainingAudio implements Parcelable {
*/
@SuppressWarnings("WeakerAccess")
@DataClass.Generated.Member
- public static final class Builder {
+ public static final class Builder extends BaseBuilder {
private @NonNull byte[] mHotwordAudio;
private @NonNull AudioFormat mAudioFormat;
@@ -264,7 +289,8 @@ public final class HotwordTrainingAudio implements Parcelable {
* Creates a new Builder.
*
* @param hotwordAudio
- * Buffer of hotword audio data for training models.
+ * Buffer of hotword audio data for training models. The data format is expected to match
+ * {@link #getAudioFormat()}.
* @param audioFormat
* The {@link AudioFormat} of the {@link HotwordTrainingAudio#mHotwordAudio}.
*/
@@ -280,17 +306,6 @@ public final class HotwordTrainingAudio implements Parcelable {
}
/**
- * Buffer of hotword audio data for training models.
- */
- @DataClass.Generated.Member
- public @NonNull Builder setHotwordAudio(@NonNull byte... value) {
- checkNotUsed();
- mBuilderFieldsSet |= 0x1;
- mHotwordAudio = value;
- return this;
- }
-
- /**
* The {@link AudioFormat} of the {@link HotwordTrainingAudio#mHotwordAudio}.
*/
@DataClass.Generated.Member
@@ -353,10 +368,10 @@ public final class HotwordTrainingAudio implements Parcelable {
}
@DataClass.Generated(
- time = 1692837160437L,
+ time = 1694193905346L,
codegenVersion = "1.0.23",
sourceFile = "frameworks/base/core/java/android/service/voice/HotwordTrainingAudio.java",
- inputSignatures = "public static final int HOTWORD_OFFSET_UNSET\nprivate final @android.annotation.NonNull byte[] mHotwordAudio\nprivate final @android.annotation.NonNull android.media.AudioFormat mAudioFormat\nprivate final @android.annotation.NonNull int mAudioType\nprivate int mHotwordOffsetMillis\nprivate java.lang.String hotwordAudioToString()\nprivate static int defaultAudioType()\nclass HotwordTrainingAudio extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genConstructor=false, genBuilder=true, genEqualsHashCode=true, genHiddenConstDefs=true, genParcelable=true, genToString=true)")
+ inputSignatures = "public static final int HOTWORD_OFFSET_UNSET\nprivate final @android.annotation.NonNull byte[] mHotwordAudio\nprivate final @android.annotation.NonNull android.media.AudioFormat mAudioFormat\nprivate final @android.annotation.NonNull int mAudioType\nprivate int mHotwordOffsetMillis\nprivate java.lang.String hotwordAudioToString()\nprivate static int defaultAudioType()\nclass HotwordTrainingAudio extends java.lang.Object implements [android.os.Parcelable]\npublic @android.annotation.SuppressLint @android.annotation.NonNull android.service.voice.HotwordTrainingAudio.Builder setHotwordAudio(byte[])\nclass BaseBuilder extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genBuilder=true, genEqualsHashCode=true, genHiddenConstDefs=true, genParcelable=true, genToString=true)\npublic @android.annotation.SuppressLint @android.annotation.NonNull android.service.voice.HotwordTrainingAudio.Builder setHotwordAudio(byte[])\nclass BaseBuilder extends java.lang.Object implements []")
@Deprecated
private void __metadata() {}
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index b8385c6ecba9..e64274ec3892 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -3139,15 +3139,6 @@ public interface WindowManager extends ViewManager {
public static final int PRIVATE_FLAG_DISABLE_WALLPAPER_TOUCH_EVENTS = 1 << 10;
/**
- * Flag to force the status bar window to be visible all the time. If the bar is hidden when
- * this flag is set it will be shown again.
- * This can only be set by {@link LayoutParams#TYPE_STATUS_BAR}.
- *
- * {@hide}
- */
- public static final int PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR = 1 << 11;
-
- /**
* Flag to indicate that the window frame should be the requested frame adding the display
* cutout frame. This will only be applied if a specific size smaller than the parent frame
* is given, and the window is covering the display cutout. The extended frame will not be
@@ -3238,15 +3229,6 @@ public interface WindowManager extends ViewManager {
public static final int PRIVATE_FLAG_NOT_MAGNIFIABLE = 1 << 22;
/**
- * Flag to indicate that the status bar window is in a state such that it forces showing
- * the navigation bar unless the navigation bar window is explicitly set to
- * {@link View#GONE}.
- * It only takes effects if this is set by {@link LayoutParams#TYPE_STATUS_BAR}.
- * @hide
- */
- public static final int PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION = 1 << 23;
-
- /**
* Flag to indicate that the window is color space agnostic, and the color can be
* interpreted to any color space.
* @hide
@@ -3334,7 +3316,6 @@ public interface WindowManager extends ViewManager {
PRIVATE_FLAG_SYSTEM_ERROR,
PRIVATE_FLAG_OPTIMIZE_MEASURE,
PRIVATE_FLAG_DISABLE_WALLPAPER_TOUCH_EVENTS,
- PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR,
PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT,
PRIVATE_FLAG_FORCE_DECOR_VIEW_VISIBILITY,
PRIVATE_FLAG_LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME,
@@ -3345,7 +3326,6 @@ public interface WindowManager extends ViewManager {
PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY,
PRIVATE_FLAG_EXCLUDE_FROM_SCREEN_MAGNIFICATION,
PRIVATE_FLAG_NOT_MAGNIFIABLE,
- PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION,
PRIVATE_FLAG_COLOR_SPACE_AGNOSTIC,
PRIVATE_FLAG_USE_BLAST,
PRIVATE_FLAG_APPEARANCE_CONTROLLED,
@@ -3401,10 +3381,6 @@ public interface WindowManager extends ViewManager {
equals = PRIVATE_FLAG_DISABLE_WALLPAPER_TOUCH_EVENTS,
name = "DISABLE_WALLPAPER_TOUCH_EVENTS"),
@ViewDebug.FlagToString(
- mask = PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR,
- equals = PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR,
- name = "FORCE_STATUS_BAR_VISIBLE"),
- @ViewDebug.FlagToString(
mask = PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT,
equals = PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT,
name = "LAYOUT_SIZE_EXTENDED_BY_CUTOUT"),
@@ -3445,10 +3421,6 @@ public interface WindowManager extends ViewManager {
equals = PRIVATE_FLAG_NOT_MAGNIFIABLE,
name = "NOT_MAGNIFIABLE"),
@ViewDebug.FlagToString(
- mask = PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION,
- equals = PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION,
- name = "STATUS_FORCE_SHOW_NAVIGATION"),
- @ViewDebug.FlagToString(
mask = PRIVATE_FLAG_COLOR_SPACE_AGNOSTIC,
equals = PRIVATE_FLAG_COLOR_SPACE_AGNOSTIC,
name = "COLOR_SPACE_AGNOSTIC"),
@@ -4412,6 +4384,16 @@ public interface WindowManager extends ViewManager {
public InsetsFrameProvider[] providedInsets;
/**
+ * Specifies which {@link InsetsType}s should be forcibly shown. The types shown by this
+ * method won't affect the app's layout. This field only takes effects if the caller has
+ * {@link android.Manifest.permission#STATUS_BAR_SERVICE} or the caller has the same uid as
+ * the recents component.
+ *
+ * @hide
+ */
+ public @InsetsType int forciblyShownTypes;
+
+ /**
* {@link LayoutParams} to be applied to the window when layout with a assigned rotation.
* This will make layout during rotation change smoothly.
*
@@ -4869,6 +4851,7 @@ public interface WindowManager extends ViewManager {
out.writeInt(mBlurBehindRadius);
out.writeBoolean(mWallpaperTouchEventsEnabled);
out.writeTypedArray(providedInsets, 0 /* parcelableFlags */);
+ out.writeInt(forciblyShownTypes);
checkNonRecursiveParams();
out.writeTypedArray(paramsForRotation, 0 /* parcelableFlags */);
out.writeInt(mDisplayFlags);
@@ -4940,6 +4923,7 @@ public interface WindowManager extends ViewManager {
mBlurBehindRadius = in.readInt();
mWallpaperTouchEventsEnabled = in.readBoolean();
providedInsets = in.createTypedArray(InsetsFrameProvider.CREATOR);
+ forciblyShownTypes = in.readInt();
paramsForRotation = in.createTypedArray(LayoutParams.CREATOR);
mDisplayFlags = in.readInt();
}
@@ -5245,6 +5229,11 @@ public interface WindowManager extends ViewManager {
changes |= LAYOUT_CHANGED;
}
+ if (forciblyShownTypes != o.forciblyShownTypes) {
+ forciblyShownTypes = o.forciblyShownTypes;
+ changes |= PRIVATE_FLAGS_CHANGED;
+ }
+
if (paramsForRotation != o.paramsForRotation) {
if ((changes & LAYOUT_CHANGED) == 0) {
if (paramsForRotation != null && o.paramsForRotation != null
@@ -5482,6 +5471,11 @@ public interface WindowManager extends ViewManager {
sb.append(prefix).append(" ").append(providedInsets[i]);
}
}
+ if (forciblyShownTypes != 0) {
+ sb.append(System.lineSeparator());
+ sb.append(prefix).append(" forciblyShownTypes=").append(
+ WindowInsets.Type.toString(forciblyShownTypes));
+ }
if (paramsForRotation != null && paramsForRotation.length != 0) {
sb.append(System.lineSeparator());
sb.append(prefix).append(" paramsForRotation:");
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 32fe4e3e4104..3180ffbef79d 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1466,10 +1466,9 @@
<!-- Allows an application to initiate a phone call without going through
the Dialer user interface for the user to confirm the call.
- <p>
- <em>Note: An app holding this permission can also call carrier MMI codes to change settings
- such as call forwarding or call waiting preferences.
- <p>Protection level: dangerous
+ <p class="note"><b>Note:</b> An app holding this permission can also call carrier MMI
+ codes to change settings such as call forwarding or call waiting preferences.</p>
+ <p>Protection level: dangerous</p>
-->
<permission android:name="android.permission.CALL_PHONE"
android:permissionGroup="android.permission-group.UNDEFINED"
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 7d2690eabc96..e7764d8b1fde 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -5717,13 +5717,13 @@
<!-- Blur radius for the Option 3 in R.integer.config_letterboxBackgroundType. Values < 0 are
ignored and 0 is used. -->
- <dimen name="config_letterboxBackgroundWallpaperBlurRadius">24dp</dimen>
+ <dimen name="config_letterboxBackgroundWallpaperBlurRadius">38dp</dimen>
<!-- Alpha of a black translucent scrim showed over wallpaper letterbox background when
the Option 3 is selected for R.integer.config_letterboxBackgroundType.
Values < 0 or >= 1 are ignored and 0.0 (transparent) is used instead. -->
<item name="config_letterboxBackgroundWallaperDarkScrimAlpha" format="float" type="dimen">
- 0.75
+ 0.54
</item>
<!-- Corners appearance of the letterbox background.
diff --git a/core/tests/BroadcastRadioTests/src/android/hardware/radio/ProgramListTest.java b/core/tests/BroadcastRadioTests/src/android/hardware/radio/ProgramListTest.java
index 7c3d2f2138a4..d638fedc5358 100644
--- a/core/tests/BroadcastRadioTests/src/android/hardware/radio/ProgramListTest.java
+++ b/core/tests/BroadcastRadioTests/src/android/hardware/radio/ProgramListTest.java
@@ -74,18 +74,45 @@ public final class ProgramListTest {
private static final ProgramSelector.Identifier DAB_ENSEMBLE_IDENTIFIER =
new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_DAB_ENSEMBLE,
/* value= */ 0x1013);
+ private static final ProgramSelector.Identifier DAB_FREQUENCY_IDENTIFIER_1 =
+ new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_DAB_FREQUENCY,
+ /* value= */ 222_064);
+ private static final ProgramSelector.Identifier DAB_FREQUENCY_IDENTIFIER_2 =
+ new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_DAB_FREQUENCY,
+ /* value= */ 220_352);
+
+ private static final ProgramSelector DAB_SELECTOR_1 = new ProgramSelector(
+ ProgramSelector.PROGRAM_TYPE_DAB, DAB_DMB_SID_EXT_IDENTIFIER,
+ new ProgramSelector.Identifier[]{DAB_ENSEMBLE_IDENTIFIER, DAB_FREQUENCY_IDENTIFIER_1},
+ /* vendorIds= */ null);
+ private static final ProgramSelector DAB_SELECTOR_2 = new ProgramSelector(
+ ProgramSelector.PROGRAM_TYPE_DAB, DAB_DMB_SID_EXT_IDENTIFIER,
+ new ProgramSelector.Identifier[]{DAB_ENSEMBLE_IDENTIFIER, DAB_FREQUENCY_IDENTIFIER_2},
+ /* vendorIds= */ null);
+
+ private static final UniqueProgramIdentifier RDS_UNIQUE_IDENTIFIER =
+ new UniqueProgramIdentifier(RDS_IDENTIFIER);
+ private static final UniqueProgramIdentifier DAB_UNIQUE_IDENTIFIER_1 =
+ new UniqueProgramIdentifier(DAB_SELECTOR_1);
+ private static final UniqueProgramIdentifier DAB_UNIQUE_IDENTIFIER_2 =
+ new UniqueProgramIdentifier(DAB_SELECTOR_2);
+
private static final RadioManager.ProgramInfo FM_PROGRAM_INFO = createFmProgramInfo(
createProgramSelector(ProgramSelector.PROGRAM_TYPE_FM, FM_IDENTIFIER));
- private static final RadioManager.ProgramInfo RDS_PROGRAM_INFO = createFmProgramInfo(
- createProgramSelector(ProgramSelector.PROGRAM_TYPE_FM, RDS_IDENTIFIER));
+ private static final RadioManager.ProgramInfo DAB_PROGRAM_INFO_1 = createDabProgramInfo(
+ DAB_SELECTOR_1);
+ private static final RadioManager.ProgramInfo DAB_PROGRAM_INFO_2 = createDabProgramInfo(
+ DAB_SELECTOR_2);
private static final Set<Integer> FILTER_IDENTIFIER_TYPES = Set.of(
- ProgramSelector.IDENTIFIER_TYPE_AMFM_FREQUENCY, ProgramSelector.IDENTIFIER_TYPE_RDS_PI);
- private static final Set<ProgramSelector.Identifier> FILTER_IDENTIFIERS = Set.of(FM_IDENTIFIER);
-
- private static final ProgramList.Chunk FM_RDS_ADD_CHUNK = new ProgramList.Chunk(IS_PURGE,
- IS_COMPLETE, Set.of(FM_PROGRAM_INFO, RDS_PROGRAM_INFO),
- Set.of(DAB_DMB_SID_EXT_IDENTIFIER, DAB_ENSEMBLE_IDENTIFIER));
+ ProgramSelector.IDENTIFIER_TYPE_AMFM_FREQUENCY,
+ ProgramSelector.IDENTIFIER_TYPE_DAB_DMB_SID_EXT);
+ private static final Set<ProgramSelector.Identifier> FILTER_IDENTIFIERS = Set.of(
+ FM_IDENTIFIER, DAB_DMB_SID_EXT_IDENTIFIER);
+
+ private static final ProgramList.Chunk FM_DAB_ADD_CHUNK = new ProgramList.Chunk(IS_PURGE,
+ IS_COMPLETE, Set.of(FM_PROGRAM_INFO, DAB_PROGRAM_INFO_1, DAB_PROGRAM_INFO_2),
+ Set.of(RDS_UNIQUE_IDENTIFIER));
private static final ProgramList.Chunk FM_ADD_INCOMPLETE_CHUNK = new ProgramList.Chunk(IS_PURGE,
/* complete= */ false, Set.of(FM_PROGRAM_INFO), new ArraySet<>());
private static final ProgramList.Filter TEST_FILTER = new ProgramList.Filter(
@@ -213,58 +240,44 @@ public final class ProgramListTest {
@Test
public void isPurge_forChunk() {
- ProgramList.Chunk chunk = new ProgramList.Chunk(IS_PURGE, IS_COMPLETE,
- Set.of(FM_PROGRAM_INFO, RDS_PROGRAM_INFO),
- Set.of(DAB_DMB_SID_EXT_IDENTIFIER, DAB_ENSEMBLE_IDENTIFIER));
-
- assertWithMessage("Puring chunk").that(chunk.isPurge()).isEqualTo(IS_PURGE);
+ assertWithMessage("Puring chunk").that(FM_DAB_ADD_CHUNK.isPurge()).isEqualTo(IS_PURGE);
}
@Test
public void isComplete_forChunk() {
- ProgramList.Chunk chunk = new ProgramList.Chunk(IS_PURGE, IS_COMPLETE,
- Set.of(FM_PROGRAM_INFO, RDS_PROGRAM_INFO),
- Set.of(DAB_DMB_SID_EXT_IDENTIFIER, DAB_ENSEMBLE_IDENTIFIER));
-
- assertWithMessage("Complete chunk").that(chunk.isComplete()).isEqualTo(IS_COMPLETE);
+ assertWithMessage("Complete chunk").that(FM_DAB_ADD_CHUNK.isComplete())
+ .isEqualTo(IS_COMPLETE);
}
@Test
public void getModified_forChunk() {
- ProgramList.Chunk chunk = new ProgramList.Chunk(IS_PURGE, IS_COMPLETE,
- Set.of(FM_PROGRAM_INFO, RDS_PROGRAM_INFO),
- Set.of(DAB_DMB_SID_EXT_IDENTIFIER, DAB_ENSEMBLE_IDENTIFIER));
-
assertWithMessage("Modified program info in chunk")
- .that(chunk.getModified()).containsExactly(FM_PROGRAM_INFO, RDS_PROGRAM_INFO);
+ .that(FM_DAB_ADD_CHUNK.getModified())
+ .containsExactly(FM_PROGRAM_INFO, DAB_PROGRAM_INFO_1, DAB_PROGRAM_INFO_2);
}
@Test
public void getRemoved_forChunk() {
- ProgramList.Chunk chunk = new ProgramList.Chunk(IS_PURGE, IS_COMPLETE,
- Set.of(FM_PROGRAM_INFO, RDS_PROGRAM_INFO),
- Set.of(DAB_DMB_SID_EXT_IDENTIFIER, DAB_ENSEMBLE_IDENTIFIER));
-
- assertWithMessage("Removed program identifiers in chunk").that(chunk.getRemoved())
- .containsExactly(DAB_DMB_SID_EXT_IDENTIFIER, DAB_ENSEMBLE_IDENTIFIER);
+ assertWithMessage("Removed program identifiers in chunk")
+ .that(FM_DAB_ADD_CHUNK.getRemoved()).containsExactly(RDS_UNIQUE_IDENTIFIER);
}
@Test
public void describeContents_forChunk() {
- assertWithMessage("Chunk contents").that(FM_RDS_ADD_CHUNK.describeContents()).isEqualTo(0);
+ assertWithMessage("Chunk contents").that(FM_DAB_ADD_CHUNK.describeContents()).isEqualTo(0);
}
@Test
public void writeToParcel_forChunk() {
Parcel parcel = Parcel.obtain();
- FM_RDS_ADD_CHUNK.writeToParcel(parcel, /* flags= */ 0);
+ FM_DAB_ADD_CHUNK.writeToParcel(parcel, /* flags= */ 0);
parcel.setDataPosition(0);
ProgramList.Chunk chunkFromParcel =
ProgramList.Chunk.CREATOR.createFromParcel(parcel);
assertWithMessage("Chunk created from parcel")
- .that(chunkFromParcel).isEqualTo(FM_RDS_ADD_CHUNK);
+ .that(chunkFromParcel).isEqualTo(FM_DAB_ADD_CHUNK);
}
@Test
@@ -336,37 +349,78 @@ public final class ProgramListTest {
}
@Test
- public void onProgramListUpdated_withNewIdsAdded_invokesMockedCallbacks() throws Exception {
+ public void onProgramListUpdated_withNewIdsAdded_invokesCallbacks() throws Exception {
createRadioTuner();
mProgramList = mRadioTuner.getDynamicProgramList(TEST_FILTER);
registerListCallbacks(/* numCallbacks= */ 1);
addOnCompleteListeners(/* numListeners= */ 1);
- mTunerCallback.onProgramListUpdated(FM_RDS_ADD_CHUNK);
+ mTunerCallback.onProgramListUpdated(FM_DAB_ADD_CHUNK);
verify(mListCallbackMocks[0], CALLBACK_TIMEOUT).onItemChanged(FM_IDENTIFIER);
- verify(mListCallbackMocks[0], CALLBACK_TIMEOUT).onItemChanged(RDS_IDENTIFIER);
+ verify(mListCallbackMocks[0], CALLBACK_TIMEOUT).onItemChanged(DAB_DMB_SID_EXT_IDENTIFIER);
verify(mOnCompleteListenerMocks[0], CALLBACK_TIMEOUT).onComplete();
- assertWithMessage("Program info in program list after adding FM and RDS info")
- .that(mProgramList.toList()).containsExactly(FM_PROGRAM_INFO, RDS_PROGRAM_INFO);
+ assertWithMessage("Program info in program list after adding FM and DAB info")
+ .that(mProgramList.toList()).containsExactly(FM_PROGRAM_INFO, DAB_PROGRAM_INFO_1,
+ DAB_PROGRAM_INFO_2);
}
@Test
- public void onProgramListUpdated_withIdsRemoved_invokesMockedCallbacks() throws Exception {
+ public void onProgramListUpdated_withFmIdsRemoved_invokesCallbacks() throws Exception {
+ UniqueProgramIdentifier fmUniqueId = new UniqueProgramIdentifier(FM_IDENTIFIER);
ProgramList.Chunk fmRemovedChunk = new ProgramList.Chunk(/* purge= */ false,
- /* complete= */ false, new ArraySet<>(), Set.of(FM_IDENTIFIER));
+ /* complete= */ false, new ArraySet<>(), Set.of(fmUniqueId));
createRadioTuner();
mProgramList = mRadioTuner.getDynamicProgramList(TEST_FILTER);
registerListCallbacks(/* numCallbacks= */ 1);
- mTunerCallback.onProgramListUpdated(FM_RDS_ADD_CHUNK);
+ mTunerCallback.onProgramListUpdated(FM_DAB_ADD_CHUNK);
mTunerCallback.onProgramListUpdated(fmRemovedChunk);
verify(mListCallbackMocks[0], CALLBACK_TIMEOUT).onItemRemoved(FM_IDENTIFIER);
assertWithMessage("Program info in program list after removing FM id")
- .that(mProgramList.toList()).containsExactly(RDS_PROGRAM_INFO);
- assertWithMessage("Program info FM identifier")
- .that(mProgramList.get(RDS_IDENTIFIER)).isEqualTo(RDS_PROGRAM_INFO);
+ .that(mProgramList.toList()).containsExactly(DAB_PROGRAM_INFO_1,
+ DAB_PROGRAM_INFO_2);
+ }
+
+ @Test
+ public void onProgramListUpdated_withPartOfDabIdsRemoved_doesNotInvokeCallbacks()
+ throws Exception {
+ ProgramList.Chunk dabRemovedChunk1 = new ProgramList.Chunk(/* purge= */ false,
+ /* complete= */ false, new ArraySet<>(), Set.of(DAB_UNIQUE_IDENTIFIER_1));
+ createRadioTuner();
+ mProgramList = mRadioTuner.getDynamicProgramList(TEST_FILTER);
+ registerListCallbacks(/* numCallbacks= */ 1);
+ mTunerCallback.onProgramListUpdated(FM_DAB_ADD_CHUNK);
+
+ mTunerCallback.onProgramListUpdated(dabRemovedChunk1);
+
+ verify(mListCallbackMocks[0], after(TIMEOUT_MS).never()).onItemRemoved(
+ DAB_DMB_SID_EXT_IDENTIFIER);
+ assertWithMessage("Program info in program list after removing part of DAB ids")
+ .that(mProgramList.toList()).containsExactly(FM_PROGRAM_INFO, DAB_PROGRAM_INFO_2);
+ }
+
+ @Test
+ public void onProgramListUpdated_withAllDabIdsRemoved_invokesCallbacks()
+ throws Exception {
+ ProgramList.Chunk dabRemovedChunk1 = new ProgramList.Chunk(/* purge= */ false,
+ /* complete= */ false, new ArraySet<>(), Set.of(DAB_UNIQUE_IDENTIFIER_1));
+ ProgramList.Chunk dabRemovedChunk2 = new ProgramList.Chunk(/* purge= */ false,
+ /* complete= */ false, new ArraySet<>(), Set.of(DAB_UNIQUE_IDENTIFIER_2));
+ createRadioTuner();
+ mProgramList = mRadioTuner.getDynamicProgramList(TEST_FILTER);
+ registerListCallbacks(/* numCallbacks= */ 1);
+ mTunerCallback.onProgramListUpdated(FM_DAB_ADD_CHUNK);
+ mTunerCallback.onProgramListUpdated(dabRemovedChunk1);
+ verify(mListCallbackMocks[0], after(TIMEOUT_MS).never()).onItemRemoved(
+ DAB_DMB_SID_EXT_IDENTIFIER);
+
+ mTunerCallback.onProgramListUpdated(dabRemovedChunk2);
+
+ verify(mListCallbackMocks[0], CALLBACK_TIMEOUT).onItemRemoved(DAB_DMB_SID_EXT_IDENTIFIER);
+ assertWithMessage("Program info in program list after removing all DAB ids")
+ .that(mProgramList.toList()).containsExactly(FM_PROGRAM_INFO);
}
@Test
@@ -388,18 +442,18 @@ public final class ProgramListTest {
createRadioTuner();
mProgramList = mRadioTuner.getDynamicProgramList(TEST_FILTER);
registerListCallbacks(/* numCallbacks= */ 1);
- mTunerCallback.onProgramListUpdated(FM_RDS_ADD_CHUNK);
+ mTunerCallback.onProgramListUpdated(FM_DAB_ADD_CHUNK);
mTunerCallback.onProgramListUpdated(purgeChunk);
verify(mListCallbackMocks[0], CALLBACK_TIMEOUT).onItemRemoved(FM_IDENTIFIER);
- verify(mListCallbackMocks[0], CALLBACK_TIMEOUT).onItemRemoved(RDS_IDENTIFIER);
+ verify(mListCallbackMocks[0], CALLBACK_TIMEOUT).onItemRemoved(DAB_DMB_SID_EXT_IDENTIFIER);
assertWithMessage("Program list after purge chunk applied")
.that(mProgramList.toList()).isEmpty();
}
@Test
- public void onProgramListUpdated_afterProgramListClosed_notInvokeMockedCallbacks()
+ public void onProgramListUpdated_afterProgramListClosed_notInvokeCallbacks()
throws Exception {
createRadioTuner();
mProgramList = mRadioTuner.getDynamicProgramList(TEST_FILTER);
@@ -407,7 +461,7 @@ public final class ProgramListTest {
addOnCompleteListeners(/* numListeners= */ 1);
mProgramList.close();
- mTunerCallback.onProgramListUpdated(FM_RDS_ADD_CHUNK);
+ mTunerCallback.onProgramListUpdated(FM_DAB_ADD_CHUNK);
verify(mListCallbackMocks[0], after(TIMEOUT_MS).never()).onItemChanged(any());
verify(mListCallbackMocks[0], never()).onItemChanged(any());
@@ -462,7 +516,7 @@ public final class ProgramListTest {
throws Exception {
createRadioTuner();
mProgramList = mRadioTuner.getDynamicProgramList(TEST_FILTER);
- mTunerCallback.onProgramListUpdated(FM_RDS_ADD_CHUNK);
+ mTunerCallback.onProgramListUpdated(FM_DAB_ADD_CHUNK);
mTunerCallback.onBackgroundScanComplete();
@@ -487,7 +541,7 @@ public final class ProgramListTest {
mProgramList = mRadioTuner.getDynamicProgramList(TEST_FILTER);
mTunerCallback.onBackgroundScanComplete();
- mTunerCallback.onProgramListUpdated(FM_RDS_ADD_CHUNK);
+ mTunerCallback.onProgramListUpdated(FM_DAB_ADD_CHUNK);
verify(mTunerCallbackMock, CALLBACK_TIMEOUT).onBackgroundScanComplete();
}
@@ -512,7 +566,7 @@ public final class ProgramListTest {
mock(ProgramList.OnCompleteListener.class);
mProgramList.addOnCompleteListener(mExecutor, onCompleteListenerMock);
- mTunerCallback.onProgramListUpdated(FM_RDS_ADD_CHUNK);
+ mTunerCallback.onProgramListUpdated(FM_DAB_ADD_CHUNK);
verify(onCompleteListenerMock, CALLBACK_TIMEOUT).onComplete();
}
@@ -524,7 +578,7 @@ public final class ProgramListTest {
mProgramList = mRadioTuner.getDynamicProgramList(TEST_FILTER);
addOnCompleteListeners(numListeners);
- mTunerCallback.onProgramListUpdated(FM_RDS_ADD_CHUNK);
+ mTunerCallback.onProgramListUpdated(FM_DAB_ADD_CHUNK);
for (int index = 0; index < numListeners; index++) {
verify(mOnCompleteListenerMocks[index], CALLBACK_TIMEOUT).onComplete();
@@ -538,7 +592,7 @@ public final class ProgramListTest {
addOnCompleteListeners(/* numListeners= */ 1);
mProgramList.removeOnCompleteListener(mOnCompleteListenerMocks[0]);
- mTunerCallback.onProgramListUpdated(FM_RDS_ADD_CHUNK);
+ mTunerCallback.onProgramListUpdated(FM_DAB_ADD_CHUNK);
verify(mOnCompleteListenerMocks[0], after(TIMEOUT_MS).never()).onComplete();
}
@@ -566,6 +620,13 @@ public final class ProgramListTest {
/* vendorInfo= */ null);
}
+ private static RadioManager.ProgramInfo createDabProgramInfo(ProgramSelector selector) {
+ return new RadioManager.ProgramInfo(selector, selector.getPrimaryId(),
+ DAB_ENSEMBLE_IDENTIFIER, /* relatedContents= */ null, /* infoFlags= */ 0,
+ /* signalQuality= */ 1, new RadioMetadata.Builder().build(),
+ /* vendorInfo= */ null);
+ }
+
private void createRadioTuner() throws Exception {
mApplicationInfo.targetSdkVersion = TEST_TARGET_SDK_VERSION;
when(mContextMock.getApplicationInfo()).thenReturn(mApplicationInfo);
diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/AidlTestUtils.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/AidlTestUtils.java
index 6c701920bd51..4f469bb957d4 100644
--- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/AidlTestUtils.java
+++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/AidlTestUtils.java
@@ -25,6 +25,7 @@ import android.hardware.radio.ProgramList;
import android.hardware.radio.ProgramSelector;
import android.hardware.radio.RadioManager;
import android.hardware.radio.RadioMetadata;
+import android.hardware.radio.UniqueProgramIdentifier;
import android.os.RemoteException;
import android.util.ArrayMap;
import android.util.ArraySet;
@@ -149,12 +150,12 @@ final class AidlTestUtils {
static ProgramList.Chunk makeChunk(boolean purge, boolean complete,
List<RadioManager.ProgramInfo> modified,
- List<ProgramSelector.Identifier> removed) throws RemoteException {
+ List<UniqueProgramIdentifier> removed) throws RemoteException {
ArraySet<RadioManager.ProgramInfo> modifiedSet = new ArraySet<>();
if (modified != null) {
modifiedSet.addAll(modified);
}
- ArraySet<ProgramSelector.Identifier> removedSet = new ArraySet<>();
+ ArraySet<UniqueProgramIdentifier> removedSet = new ArraySet<>();
if (removed != null) {
removedSet.addAll(removed);
}
diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/ConversionUtilsTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/ConversionUtilsTest.java
index 2ef923d1339a..89b91cf27b38 100644
--- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/ConversionUtilsTest.java
+++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/ConversionUtilsTest.java
@@ -25,7 +25,6 @@ import android.hardware.broadcastradio.DabTableEntry;
import android.hardware.broadcastradio.IdentifierType;
import android.hardware.broadcastradio.ProgramIdentifier;
import android.hardware.broadcastradio.ProgramInfo;
-import android.hardware.broadcastradio.ProgramListChunk;
import android.hardware.broadcastradio.Properties;
import android.hardware.broadcastradio.Result;
import android.hardware.broadcastradio.VendorKeyValue;
@@ -33,6 +32,7 @@ import android.hardware.radio.Announcement;
import android.hardware.radio.ProgramList;
import android.hardware.radio.ProgramSelector;
import android.hardware.radio.RadioManager;
+import android.hardware.radio.UniqueProgramIdentifier;
import android.os.ServiceSpecificException;
import com.android.dx.mockito.inline.extended.StaticMockitoSessionBuilder;
@@ -103,12 +103,6 @@ public final class ConversionUtilsTest extends ExtendedRadioMockitoTestCase {
private static final ProgramIdentifier TEST_HAL_DAB_FREQUENCY_ID =
AidlTestUtils.makeHalIdentifier(IdentifierType.DAB_FREQUENCY_KHZ,
TEST_DAB_FREQUENCY_VALUE);
- private static final ProgramIdentifier TEST_HAL_FM_FREQUENCY_ID =
- AidlTestUtils.makeHalIdentifier(IdentifierType.AMFM_FREQUENCY_KHZ,
- TEST_FM_FREQUENCY_VALUE);
- private static final ProgramIdentifier TEST_HAL_VENDOR_ID =
- AidlTestUtils.makeHalIdentifier(IdentifierType.VENDOR_START,
- TEST_VENDOR_ID_VALUE);
private static final ProgramSelector TEST_DAB_SELECTOR = new ProgramSelector(
ProgramSelector.PROGRAM_TYPE_DAB, TEST_DAB_SID_EXT_ID,
@@ -117,6 +111,12 @@ public final class ConversionUtilsTest extends ExtendedRadioMockitoTestCase {
private static final ProgramSelector TEST_FM_SELECTOR =
AidlTestUtils.makeFmSelector(TEST_FM_FREQUENCY_VALUE);
+ private static final UniqueProgramIdentifier TEST_DAB_UNIQUE_ID = new UniqueProgramIdentifier(
+ TEST_DAB_SELECTOR);
+
+ private static final UniqueProgramIdentifier TEST_VENDOR_UNIQUE_ID =
+ new UniqueProgramIdentifier(TEST_VENDOR_ID);
+
private static final int TEST_ENABLED_TYPE = Announcement.TYPE_EMERGENCY;
private static final int TEST_ANNOUNCEMENT_FREQUENCY = FM_LOWER_LIMIT + FM_SPACING;
@@ -326,57 +326,6 @@ public final class ConversionUtilsTest extends ExtendedRadioMockitoTestCase {
}
@Test
- public void chunkFromHalProgramListChunk_withValidChunk() {
- boolean purge = false;
- boolean complete = true;
- android.hardware.broadcastradio.ProgramSelector halDabSelector =
- AidlTestUtils.makeHalSelector(TEST_HAL_DAB_SID_EXT_ID, new ProgramIdentifier[]{
- TEST_HAL_DAB_ENSEMBLE_ID, TEST_HAL_DAB_FREQUENCY_ID});
- ProgramInfo halDabInfo = AidlTestUtils.makeHalProgramInfo(halDabSelector,
- TEST_HAL_DAB_SID_EXT_ID, TEST_HAL_DAB_FREQUENCY_ID, TEST_SIGNAL_QUALITY);
- RadioManager.ProgramInfo dabInfo =
- ConversionUtils.programInfoFromHalProgramInfo(halDabInfo);
- ProgramListChunk halChunk = AidlTestUtils.makeHalChunk(purge, complete,
- new ProgramInfo[]{halDabInfo},
- new ProgramIdentifier[]{TEST_HAL_VENDOR_ID, TEST_HAL_FM_FREQUENCY_ID});
-
- ProgramList.Chunk chunk = ConversionUtils.chunkFromHalProgramListChunk(halChunk);
-
- expect.withMessage("Purged state of the converted valid program list chunk")
- .that(chunk.isPurge()).isEqualTo(purge);
- expect.withMessage("Completion state of the converted valid program list chunk")
- .that(chunk.isComplete()).isEqualTo(complete);
- expect.withMessage("Modified program info in the converted valid program list chunk")
- .that(chunk.getModified()).containsExactly(dabInfo);
- expect.withMessage("Removed program ides in the converted valid program list chunk")
- .that(chunk.getRemoved()).containsExactly(TEST_VENDOR_ID, TEST_FM_FREQUENCY_ID);
- }
-
- @Test
- public void chunkFromHalProgramListChunk_withInvalidModifiedProgramInfo() {
- boolean purge = true;
- boolean complete = false;
- android.hardware.broadcastradio.ProgramSelector halDabSelector =
- AidlTestUtils.makeHalSelector(TEST_HAL_DAB_SID_EXT_ID, new ProgramIdentifier[]{
- TEST_HAL_DAB_ENSEMBLE_ID, TEST_HAL_DAB_FREQUENCY_ID});
- ProgramInfo halDabInfo = AidlTestUtils.makeHalProgramInfo(halDabSelector,
- TEST_HAL_DAB_SID_EXT_ID, TEST_HAL_DAB_ENSEMBLE_ID, TEST_SIGNAL_QUALITY);
- ProgramListChunk halChunk = AidlTestUtils.makeHalChunk(purge, complete,
- new ProgramInfo[]{halDabInfo}, new ProgramIdentifier[]{TEST_HAL_FM_FREQUENCY_ID});
-
- ProgramList.Chunk chunk = ConversionUtils.chunkFromHalProgramListChunk(halChunk);
-
- expect.withMessage("Purged state of the converted invalid program list chunk")
- .that(chunk.isPurge()).isEqualTo(purge);
- expect.withMessage("Completion state of the converted invalid program list chunk")
- .that(chunk.isComplete()).isEqualTo(complete);
- expect.withMessage("Modified program info in the converted invalid program list chunk")
- .that(chunk.getModified()).isEmpty();
- expect.withMessage("Removed program ids in the converted invalid program list chunk")
- .that(chunk.getRemoved()).containsExactly(TEST_FM_FREQUENCY_ID);
- }
-
- @Test
public void programSelectorMeetsSdkVersionRequirement_withLowerVersionId_returnsFalse() {
expect.withMessage("Selector %s without required SDK version", TEST_DAB_SELECTOR)
.that(ConversionUtils.programSelectorMeetsSdkVersionRequirement(TEST_DAB_SELECTOR,
@@ -418,7 +367,7 @@ public final class ConversionUtilsTest extends ExtendedRadioMockitoTestCase {
TEST_SIGNAL_QUALITY);
ProgramList.Chunk chunk = new ProgramList.Chunk(/* purge= */ true,
/* complete= */ true, Set.of(dabProgramInfo, fmProgramInfo),
- Set.of(TEST_DAB_SID_EXT_ID, TEST_DAB_ENSEMBLE_ID, TEST_VENDOR_ID));
+ Set.of(TEST_DAB_UNIQUE_ID, TEST_VENDOR_UNIQUE_ID));
ProgramList.Chunk convertedChunk = ConversionUtils.convertChunkToTargetSdkVersion(chunk,
T_APP_UID);
@@ -434,8 +383,7 @@ public final class ConversionUtilsTest extends ExtendedRadioMockitoTestCase {
.that(convertedChunk.getModified()).containsExactly(fmProgramInfo);
expect.withMessage(
"Removed program ids in the converted program list chunk with lower SDK version")
- .that(convertedChunk.getRemoved())
- .containsExactly(TEST_DAB_ENSEMBLE_ID, TEST_VENDOR_ID);
+ .that(convertedChunk.getRemoved()).containsExactly(TEST_VENDOR_UNIQUE_ID);
}
@Test
@@ -446,7 +394,7 @@ public final class ConversionUtilsTest extends ExtendedRadioMockitoTestCase {
TEST_SIGNAL_QUALITY);
ProgramList.Chunk chunk = new ProgramList.Chunk(/* purge= */ true,
/* complete= */ true, Set.of(dabProgramInfo, fmProgramInfo),
- Set.of(TEST_DAB_SID_EXT_ID, TEST_DAB_ENSEMBLE_ID, TEST_VENDOR_ID));
+ Set.of(TEST_DAB_UNIQUE_ID, TEST_VENDOR_UNIQUE_ID));
ProgramList.Chunk convertedChunk = ConversionUtils.convertChunkToTargetSdkVersion(chunk,
U_APP_UID);
diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/ProgramInfoCacheTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/ProgramInfoCacheTest.java
index d54397e07a63..ce27bc177769 100644
--- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/ProgramInfoCacheTest.java
+++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/ProgramInfoCacheTest.java
@@ -22,6 +22,7 @@ import android.hardware.broadcastradio.ProgramListChunk;
import android.hardware.radio.ProgramList;
import android.hardware.radio.ProgramSelector;
import android.hardware.radio.RadioManager;
+import android.hardware.radio.UniqueProgramIdentifier;
import android.os.RemoteException;
import android.util.ArraySet;
@@ -32,6 +33,7 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.junit.MockitoJUnitRunner;
+import java.util.ArrayList;
import java.util.List;
import java.util.Set;
@@ -43,6 +45,9 @@ public class ProgramInfoCacheTest {
private static final int TEST_SIGNAL_QUALITY = 90;
+ private static final int TEST_MAX_NUM_MODIFIED_PER_CHUNK = 2;
+ private static final int TEST_MAX_NUM_REMOVED_PER_CHUNK = 2;
+
private static final ProgramSelector.Identifier TEST_FM_FREQUENCY_ID =
new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_AMFM_FREQUENCY,
/* value= */ 88_500);
@@ -58,6 +63,8 @@ public class ProgramInfoCacheTest {
private static final ProgramSelector.Identifier TEST_AM_FREQUENCY_ID =
new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_AMFM_FREQUENCY,
/* value= */ 1_700);
+ private static final UniqueProgramIdentifier TEST_AM_UNIQUE_ID = new UniqueProgramIdentifier(
+ TEST_AM_FREQUENCY_ID);
private static final RadioManager.ProgramInfo TEST_AM_INFO = AidlTestUtils.makeProgramInfo(
AidlTestUtils.makeProgramSelector(ProgramSelector.PROGRAM_TYPE_FM,
TEST_AM_FREQUENCY_ID), TEST_AM_FREQUENCY_ID, TEST_AM_FREQUENCY_ID,
@@ -66,6 +73,8 @@ public class ProgramInfoCacheTest {
private static final ProgramSelector.Identifier TEST_RDS_PI_ID =
new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_RDS_PI,
/* value= */ 15_019);
+ private static final UniqueProgramIdentifier TEST_RDS_PI_UNIQUE_ID =
+ new UniqueProgramIdentifier(TEST_RDS_PI_ID);
private static final RadioManager.ProgramInfo TEST_RDS_INFO = AidlTestUtils.makeProgramInfo(
AidlTestUtils.makeProgramSelector(ProgramSelector.PROGRAM_TYPE_FM, TEST_RDS_PI_ID),
TEST_RDS_PI_ID, new ProgramSelector.Identifier(
@@ -81,11 +90,27 @@ public class ProgramInfoCacheTest {
private static final ProgramSelector.Identifier TEST_DAB_FREQUENCY_ID =
new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_DAB_FREQUENCY,
/* value= */ 220_352);
- private static final RadioManager.ProgramInfo TEST_DAB_INFO = AidlTestUtils.makeProgramInfo(
- new ProgramSelector(ProgramSelector.PROGRAM_TYPE_DAB, TEST_DAB_DMB_SID_EXT_ID,
- new ProgramSelector.Identifier[]{TEST_DAB_FREQUENCY_ID, TEST_DAB_ENSEMBLE_ID},
- /* vendorIds= */ null), TEST_DAB_DMB_SID_EXT_ID, TEST_DAB_FREQUENCY_ID,
- TEST_SIGNAL_QUALITY);
+ private static final ProgramSelector.Identifier TEST_DAB_FREQUENCY_ID_ALTERNATIVE =
+ new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_DAB_FREQUENCY,
+ /* value= */ 220_064);
+ private static final ProgramSelector TEST_DAB_SELECTOR = new ProgramSelector(
+ ProgramSelector.PROGRAM_TYPE_DAB, TEST_DAB_DMB_SID_EXT_ID,
+ new ProgramSelector.Identifier[]{TEST_DAB_FREQUENCY_ID, TEST_DAB_ENSEMBLE_ID},
+ /* vendorIds= */ null);
+ private static final ProgramSelector TEST_DAB_SELECTOR_ALTERNATIVE = new ProgramSelector(
+ ProgramSelector.PROGRAM_TYPE_DAB, TEST_DAB_DMB_SID_EXT_ID,
+ new ProgramSelector.Identifier[]{TEST_DAB_FREQUENCY_ID_ALTERNATIVE,
+ TEST_DAB_ENSEMBLE_ID}, /* vendorIds= */ null);
+ private static final UniqueProgramIdentifier TEST_DAB_UNIQUE_ID = new UniqueProgramIdentifier(
+ TEST_DAB_SELECTOR);
+ private static final UniqueProgramIdentifier TEST_DAB_UNIQUE_ID_ALTERNATIVE =
+ new UniqueProgramIdentifier(TEST_DAB_SELECTOR_ALTERNATIVE);
+ private static final RadioManager.ProgramInfo TEST_DAB_INFO =
+ AidlTestUtils.makeProgramInfo(TEST_DAB_SELECTOR, TEST_DAB_DMB_SID_EXT_ID,
+ TEST_DAB_FREQUENCY_ID, TEST_SIGNAL_QUALITY);
+ private static final RadioManager.ProgramInfo TEST_DAB_INFO_ALTERNATIVE =
+ AidlTestUtils.makeProgramInfo(TEST_DAB_SELECTOR_ALTERNATIVE, TEST_DAB_DMB_SID_EXT_ID,
+ TEST_DAB_FREQUENCY_ID_ALTERNATIVE, TEST_SIGNAL_QUALITY);
private static final ProgramSelector.Identifier TEST_VENDOR_ID =
new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_VENDOR_START,
@@ -95,8 +120,8 @@ public class ProgramInfoCacheTest {
TEST_VENDOR_ID), TEST_VENDOR_ID, TEST_VENDOR_ID, TEST_SIGNAL_QUALITY);
private static final ProgramInfoCache FULL_PROGRAM_INFO_CACHE = new ProgramInfoCache(
- /* filter= */ null, /* complete= */ true,
- TEST_FM_INFO, TEST_AM_INFO, TEST_RDS_INFO, TEST_DAB_INFO, TEST_VENDOR_INFO);
+ /* filter= */ null, /* complete= */ true, TEST_FM_INFO, TEST_AM_INFO, TEST_RDS_INFO,
+ TEST_DAB_INFO, TEST_DAB_INFO_ALTERNATIVE, TEST_VENDOR_INFO);
@Rule
public final Expect expect = Expect.create();
@@ -163,6 +188,22 @@ public class ProgramInfoCacheTest {
}
@Test
+ public void updateFromHalProgramListChunk_withInvalidChunk() {
+ RadioManager.ProgramInfo invalidDabInfo = AidlTestUtils.makeProgramInfo(TEST_DAB_SELECTOR,
+ TEST_DAB_DMB_SID_EXT_ID, TEST_DAB_ENSEMBLE_ID, TEST_SIGNAL_QUALITY);
+ ProgramInfoCache cache = new ProgramInfoCache(/* filter= */ null,
+ /* complete= */ false);
+ ProgramListChunk chunk = AidlTestUtils.makeHalChunk(/* purge= */ false,
+ /* complete= */ true, new ProgramInfo[]{AidlTestUtils.programInfoToHalProgramInfo(
+ invalidDabInfo)}, new ProgramIdentifier[]{});
+
+ cache.updateFromHalProgramListChunk(chunk);
+
+ expect.withMessage("Program cache updated with invalid chunk")
+ .that(cache.toProgramInfoList()).isEmpty();
+ }
+
+ @Test
public void filterAndUpdateFromInternal_withNullFilter() {
ProgramInfoCache cache = new ProgramInfoCache(/* filter= */ null,
/* complete= */ true);
@@ -172,7 +213,7 @@ public class ProgramInfoCacheTest {
expect.withMessage("Program cache filtered by null filter")
.that(cache.toProgramInfoList())
.containsExactly(TEST_FM_INFO, TEST_AM_INFO, TEST_RDS_INFO, TEST_DAB_INFO,
- TEST_VENDOR_INFO);
+ TEST_DAB_INFO_ALTERNATIVE, TEST_VENDOR_INFO);
}
@Test
@@ -186,21 +227,21 @@ public class ProgramInfoCacheTest {
expect.withMessage("Program cache filtered by empty filter")
.that(cache.toProgramInfoList())
.containsExactly(TEST_FM_INFO, TEST_AM_INFO, TEST_RDS_INFO, TEST_DAB_INFO,
- TEST_VENDOR_INFO);
+ TEST_DAB_INFO_ALTERNATIVE, TEST_VENDOR_INFO);
}
@Test
public void filterAndUpdateFromInternal_withFilterByIdentifierType() {
ProgramInfoCache cache = new ProgramInfoCache(
new ProgramList.Filter(Set.of(ProgramSelector.IDENTIFIER_TYPE_AMFM_FREQUENCY,
- ProgramSelector.IDENTIFIER_TYPE_RDS_PI), new ArraySet<>(),
+ ProgramSelector.IDENTIFIER_TYPE_DAB_DMB_SID_EXT), new ArraySet<>(),
/* includeCategories= */ true, /* excludeModifications= */ false));
cache.filterAndUpdateFromInternal(FULL_PROGRAM_INFO_CACHE, /* purge= */ false);
expect.withMessage("Program cache filtered by identifier type")
- .that(cache.toProgramInfoList())
- .containsExactly(TEST_FM_INFO, TEST_AM_INFO, TEST_RDS_INFO);
+ .that(cache.toProgramInfoList()).containsExactly(TEST_FM_INFO, TEST_AM_INFO,
+ TEST_DAB_INFO, TEST_DAB_INFO_ALTERNATIVE);
}
@Test
@@ -208,20 +249,60 @@ public class ProgramInfoCacheTest {
ProgramInfoCache cache = new ProgramInfoCache(new ProgramList.Filter(
new ArraySet<>(), Set.of(TEST_FM_FREQUENCY_ID, TEST_DAB_DMB_SID_EXT_ID),
/* includeCategories= */ true, /* excludeModifications= */ false));
- int maxNumModifiedPerChunk = 2;
- int maxNumRemovedPerChunk = 2;
List<ProgramList.Chunk> programListChunks = cache.filterAndUpdateFromInternal(
- FULL_PROGRAM_INFO_CACHE, /* purge= */ true, maxNumModifiedPerChunk,
- maxNumRemovedPerChunk);
+ FULL_PROGRAM_INFO_CACHE, /* purge= */ false, TEST_MAX_NUM_MODIFIED_PER_CHUNK,
+ TEST_MAX_NUM_REMOVED_PER_CHUNK);
expect.withMessage("Program cache filtered by identifier")
- .that(cache.toProgramInfoList()).containsExactly(TEST_FM_INFO, TEST_DAB_INFO);
+ .that(cache.toProgramInfoList()).containsExactly(TEST_FM_INFO, TEST_DAB_INFO,
+ TEST_DAB_INFO_ALTERNATIVE);
+ verifyChunkListPurge(programListChunks, /* purge= */ true);
+ verifyChunkListComplete(programListChunks, cache.isComplete());
+ verifyChunkListModified(programListChunks, TEST_MAX_NUM_MODIFIED_PER_CHUNK, TEST_FM_INFO,
+ TEST_DAB_INFO, TEST_DAB_INFO_ALTERNATIVE);
+ verifyChunkListRemoved(programListChunks, TEST_MAX_NUM_REMOVED_PER_CHUNK);
+ }
+
+ @Test
+ public void filterAndUpdateFromInternal_withPurging() {
+ ProgramInfoCache cache = new ProgramInfoCache(new ProgramList.Filter(new ArraySet<>(),
+ new ArraySet<>(), /* includeCategories= */ true, /* excludeModifications= */ false),
+ /* complete= */ true, TEST_RDS_INFO, TEST_DAB_INFO);
+ ProgramInfoCache otherCache = new ProgramInfoCache(/* filter= */ null, /* complete= */ true,
+ TEST_FM_INFO, TEST_RDS_INFO, TEST_DAB_INFO_ALTERNATIVE);
+
+ List<ProgramList.Chunk> programListChunks = cache.filterAndUpdateFromInternal(otherCache,
+ /* purge= */ true, TEST_MAX_NUM_MODIFIED_PER_CHUNK, TEST_MAX_NUM_REMOVED_PER_CHUNK);
+
+ expect.withMessage("Program cache filtered with purging").that(cache.toProgramInfoList())
+ .containsExactly(TEST_FM_INFO, TEST_RDS_INFO, TEST_DAB_INFO_ALTERNATIVE);
verifyChunkListPurge(programListChunks, /* purge= */ true);
- verifyChunkListComplete(programListChunks, FULL_PROGRAM_INFO_CACHE.isComplete());
+ verifyChunkListModified(programListChunks, TEST_MAX_NUM_MODIFIED_PER_CHUNK, TEST_FM_INFO,
+ TEST_RDS_INFO, TEST_DAB_INFO_ALTERNATIVE);
+ verifyChunkListRemoved(programListChunks, TEST_MAX_NUM_REMOVED_PER_CHUNK);
+ }
+
+ @Test
+ public void filterAndUpdateFromInternal_withoutPurging() {
+ ProgramInfoCache cache = new ProgramInfoCache(new ProgramList.Filter(new ArraySet<>(),
+ new ArraySet<>(), /* includeCategories= */ true, /* excludeModifications= */ false),
+ /* complete= */ true, TEST_RDS_INFO, TEST_DAB_INFO);
+ ProgramInfoCache otherCache = new ProgramInfoCache(/* filter= */ null, /* complete= */ true,
+ TEST_FM_INFO, TEST_RDS_INFO, TEST_DAB_INFO_ALTERNATIVE);
+ int maxNumModifiedPerChunk = 1;
+
+ List<ProgramList.Chunk> programListChunks = cache.filterAndUpdateFromInternal(otherCache,
+ /* purge= */ false, maxNumModifiedPerChunk, TEST_MAX_NUM_REMOVED_PER_CHUNK);
+
+ expect.withMessage("Program cache filtered without puring").that(cache.toProgramInfoList())
+ .containsExactly(TEST_FM_INFO, TEST_RDS_INFO, TEST_DAB_INFO_ALTERNATIVE);
+ verifyChunkListPurge(programListChunks, /* purge= */ false);
+ verifyChunkListComplete(programListChunks, cache.isComplete());
verifyChunkListModified(programListChunks, maxNumModifiedPerChunk, TEST_FM_INFO,
- TEST_DAB_INFO);
- verifyChunkListRemoved(programListChunks, maxNumRemovedPerChunk);
+ TEST_DAB_INFO_ALTERNATIVE);
+ verifyChunkListRemoved(programListChunks, TEST_MAX_NUM_REMOVED_PER_CHUNK,
+ TEST_DAB_UNIQUE_ID);
}
@Test
@@ -230,20 +311,19 @@ public class ProgramInfoCacheTest {
new ArraySet<>(), /* includeCategories= */ false,
/* excludeModifications= */ false));
int maxNumModifiedPerChunk = 3;
- int maxNumRemovedPerChunk = 2;
List<ProgramList.Chunk> programListChunks = cache.filterAndUpdateFromInternal(
FULL_PROGRAM_INFO_CACHE, /* purge= */ false, maxNumModifiedPerChunk,
- maxNumRemovedPerChunk);
+ TEST_MAX_NUM_REMOVED_PER_CHUNK);
expect.withMessage("Program cache filtered by excluding categories")
- .that(cache.toProgramInfoList())
- .containsExactly(TEST_FM_INFO, TEST_AM_INFO, TEST_RDS_INFO, TEST_DAB_INFO);
+ .that(cache.toProgramInfoList()).containsExactly(TEST_FM_INFO, TEST_AM_INFO,
+ TEST_RDS_INFO, TEST_DAB_INFO, TEST_DAB_INFO_ALTERNATIVE);
verifyChunkListPurge(programListChunks, /* purge= */ true);
- verifyChunkListComplete(programListChunks, FULL_PROGRAM_INFO_CACHE.isComplete());
+ verifyChunkListComplete(programListChunks, cache.isComplete());
verifyChunkListModified(programListChunks, maxNumModifiedPerChunk, TEST_FM_INFO,
- TEST_AM_INFO, TEST_RDS_INFO, TEST_DAB_INFO);
- verifyChunkListRemoved(programListChunks, maxNumRemovedPerChunk);
+ TEST_AM_INFO, TEST_RDS_INFO, TEST_DAB_INFO, TEST_DAB_INFO_ALTERNATIVE);
+ verifyChunkListRemoved(programListChunks, TEST_MAX_NUM_REMOVED_PER_CHUNK);
}
@Test
@@ -254,21 +334,21 @@ public class ProgramInfoCacheTest {
ProgramInfoCache cache = new ProgramInfoCache(filterExcludingModifications,
/* complete= */ true, TEST_FM_INFO, TEST_RDS_INFO, TEST_AM_INFO, TEST_DAB_INFO);
ProgramInfoCache halCache = new ProgramInfoCache(/* filter= */ null, /* complete= */ false,
- TEST_FM_INFO_MODIFIED, TEST_VENDOR_INFO);
- int maxNumModifiedPerChunk = 2;
- int maxNumRemovedPerChunk = 2;
+ TEST_FM_INFO_MODIFIED, TEST_DAB_INFO_ALTERNATIVE, TEST_VENDOR_INFO);
List<ProgramList.Chunk> programListChunks = cache.filterAndUpdateFromInternal(halCache,
- /* purge= */ false, maxNumModifiedPerChunk, maxNumRemovedPerChunk);
+ /* purge= */ false, TEST_MAX_NUM_MODIFIED_PER_CHUNK,
+ TEST_MAX_NUM_REMOVED_PER_CHUNK);
expect.withMessage("Program cache filtered by excluding modifications")
.that(cache.toProgramInfoList())
- .containsExactly(TEST_FM_INFO, TEST_VENDOR_INFO);
+ .containsExactly(TEST_FM_INFO, TEST_DAB_INFO_ALTERNATIVE, TEST_VENDOR_INFO);
verifyChunkListPurge(programListChunks, /* purge= */ false);
verifyChunkListComplete(programListChunks, halCache.isComplete());
- verifyChunkListModified(programListChunks, maxNumModifiedPerChunk, TEST_VENDOR_INFO);
- verifyChunkListRemoved(programListChunks, maxNumRemovedPerChunk, TEST_RDS_PI_ID,
- TEST_AM_FREQUENCY_ID, TEST_DAB_DMB_SID_EXT_ID);
+ verifyChunkListModified(programListChunks, TEST_MAX_NUM_MODIFIED_PER_CHUNK,
+ TEST_VENDOR_INFO, TEST_DAB_INFO_ALTERNATIVE);
+ verifyChunkListRemoved(programListChunks, TEST_MAX_NUM_REMOVED_PER_CHUNK,
+ TEST_RDS_PI_UNIQUE_ID, TEST_AM_UNIQUE_ID, TEST_DAB_UNIQUE_ID);
}
@Test
@@ -276,69 +356,88 @@ public class ProgramInfoCacheTest {
ProgramInfoCache cache = new ProgramInfoCache(new ProgramList.Filter(new ArraySet<>(),
new ArraySet<>(), /* includeCategories= */ true,
/* excludeModifications= */ false),
- /* complete= */ true, TEST_FM_INFO, TEST_RDS_INFO);
+ /* complete= */ true, TEST_FM_INFO, TEST_RDS_INFO, TEST_DAB_INFO);
ProgramInfoCache halCache = new ProgramInfoCache(/* filter= */ null, /* complete= */ false,
- TEST_FM_INFO_MODIFIED, TEST_DAB_INFO, TEST_VENDOR_INFO);
- int maxNumModifiedPerChunk = 2;
- int maxNumRemovedPerChunk = 2;
+ TEST_FM_INFO_MODIFIED, TEST_DAB_INFO_ALTERNATIVE, TEST_VENDOR_INFO);
List<ProgramList.Chunk> programListChunks = cache.filterAndUpdateFromInternal(halCache,
- /* purge= */ true, maxNumModifiedPerChunk, maxNumRemovedPerChunk);
+ /* purge= */ true, TEST_MAX_NUM_MODIFIED_PER_CHUNK, TEST_MAX_NUM_REMOVED_PER_CHUNK);
expect.withMessage("Purged program cache").that(cache.toProgramInfoList())
- .containsExactly(TEST_FM_INFO_MODIFIED, TEST_DAB_INFO, TEST_VENDOR_INFO);
+ .containsExactly(TEST_FM_INFO_MODIFIED, TEST_DAB_INFO_ALTERNATIVE,
+ TEST_VENDOR_INFO);
verifyChunkListPurge(programListChunks, /* purge= */ true);
verifyChunkListComplete(programListChunks, halCache.isComplete());
- verifyChunkListModified(programListChunks, maxNumModifiedPerChunk, TEST_FM_INFO_MODIFIED,
- TEST_DAB_INFO, TEST_VENDOR_INFO);
- verifyChunkListRemoved(programListChunks, maxNumRemovedPerChunk);
+ verifyChunkListModified(programListChunks, TEST_MAX_NUM_MODIFIED_PER_CHUNK,
+ TEST_FM_INFO_MODIFIED, TEST_DAB_INFO_ALTERNATIVE, TEST_VENDOR_INFO);
+ verifyChunkListRemoved(programListChunks, TEST_MAX_NUM_REMOVED_PER_CHUNK);
}
@Test
- public void filterAndApplyChunkInternal_withPurgingIncompleteChunk() throws RemoteException {
+ public void filterAndApplyChunkInternal_withPurgingAndIncompleteChunk() throws RemoteException {
ProgramInfoCache cache = new ProgramInfoCache(/* filter= */ null,
- /* complete= */ false, TEST_FM_INFO, TEST_DAB_INFO);
- ProgramList.Chunk chunk = AidlTestUtils.makeChunk(/* purge= */ true, /* complete= */ false,
- List.of(TEST_FM_INFO_MODIFIED, TEST_RDS_INFO, TEST_VENDOR_INFO),
- List.of(TEST_DAB_DMB_SID_EXT_ID));
- int maxNumModifiedPerChunk = 2;
- int maxNumRemovedPerChunk = 2;
+ /* complete= */ false, TEST_FM_INFO, TEST_RDS_INFO, TEST_DAB_INFO);
+ ProgramListChunk halChunk = AidlTestUtils.makeHalChunk(/* purge= */ true,
+ /* complete= */ false, List.of(TEST_FM_INFO_MODIFIED,
+ TEST_DAB_INFO_ALTERNATIVE, TEST_VENDOR_INFO), new ArrayList<>());
- List<ProgramList.Chunk> programListChunks = cache.filterAndApplyChunkInternal(chunk,
- maxNumModifiedPerChunk, maxNumRemovedPerChunk);
+ List<ProgramList.Chunk> programListChunks = cache.filterAndApplyChunkInternal(halChunk,
+ TEST_MAX_NUM_MODIFIED_PER_CHUNK, TEST_MAX_NUM_REMOVED_PER_CHUNK);
- expect.withMessage("Program cache applied with non-purging and complete chunk")
- .that(cache.toProgramInfoList())
- .containsExactly(TEST_FM_INFO_MODIFIED, TEST_RDS_INFO, TEST_VENDOR_INFO);
+ expect.withMessage("Program cache applied with purge-enabled and complete chunk")
+ .that(cache.toProgramInfoList()).containsExactly(TEST_FM_INFO_MODIFIED,
+ TEST_DAB_INFO_ALTERNATIVE, TEST_VENDOR_INFO);
verifyChunkListPurge(programListChunks, /* purge= */ true);
verifyChunkListComplete(programListChunks, /* complete= */ false);
- verifyChunkListModified(programListChunks, maxNumModifiedPerChunk, TEST_FM_INFO_MODIFIED,
- TEST_RDS_INFO, TEST_VENDOR_INFO);
- verifyChunkListRemoved(programListChunks, maxNumRemovedPerChunk);
+ verifyChunkListModified(programListChunks, TEST_MAX_NUM_MODIFIED_PER_CHUNK,
+ TEST_FM_INFO_MODIFIED, TEST_DAB_INFO_ALTERNATIVE, TEST_VENDOR_INFO);
+ verifyChunkListRemoved(programListChunks, TEST_MAX_NUM_REMOVED_PER_CHUNK);
}
@Test
- public void filterAndApplyChunk_withNonPurgingCompleteChunk() throws RemoteException {
- ProgramInfoCache cache = new ProgramInfoCache(/* filter= */ null,
- /* complete= */ false, TEST_FM_INFO, TEST_RDS_INFO, TEST_AM_INFO, TEST_DAB_INFO);
- ProgramList.Chunk chunk = AidlTestUtils.makeChunk(/* purge= */ false, /* complete= */ true,
- List.of(TEST_FM_INFO_MODIFIED, TEST_VENDOR_INFO),
+ public void filterAndApplyChunk_withNonPurgingAndIncompleteChunk() throws RemoteException {
+ ProgramInfoCache cache = new ProgramInfoCache(/* filter= */ null, /* complete= */ false,
+ TEST_FM_INFO, TEST_RDS_INFO, TEST_AM_INFO, TEST_DAB_INFO);
+ ProgramListChunk halChunk = AidlTestUtils.makeHalChunk(/* purge= */ false,
+ /* complete= */ false, List.of(TEST_FM_INFO_MODIFIED, TEST_DAB_INFO_ALTERNATIVE,
+ TEST_VENDOR_INFO), List.of(TEST_RDS_PI_ID, TEST_AM_FREQUENCY_ID));
+
+ List<ProgramList.Chunk> programListChunks = cache.filterAndApplyChunkInternal(halChunk,
+ TEST_MAX_NUM_MODIFIED_PER_CHUNK, TEST_MAX_NUM_REMOVED_PER_CHUNK);
+
+ expect.withMessage("Program cache applied with non-purging and incomplete chunk")
+ .that(cache.toProgramInfoList()).containsExactly(TEST_DAB_INFO,
+ TEST_DAB_INFO_ALTERNATIVE, TEST_FM_INFO_MODIFIED, TEST_VENDOR_INFO);
+ verifyChunkListPurge(programListChunks, /* purge= */ false);
+ verifyChunkListComplete(programListChunks, /* complete= */ false);
+ verifyChunkListModified(programListChunks, TEST_MAX_NUM_MODIFIED_PER_CHUNK,
+ TEST_FM_INFO_MODIFIED, TEST_DAB_INFO_ALTERNATIVE, TEST_VENDOR_INFO);
+ verifyChunkListRemoved(programListChunks, TEST_MAX_NUM_REMOVED_PER_CHUNK,
+ TEST_RDS_PI_UNIQUE_ID, TEST_AM_UNIQUE_ID);
+ }
+
+ @Test
+ public void filterAndApplyChunk_withNonPurgingAndCompleteChunk() throws RemoteException {
+ ProgramInfoCache cache = new ProgramInfoCache(/* filter= */ null, /* complete= */ false,
+ TEST_FM_INFO, TEST_RDS_INFO, TEST_AM_INFO, TEST_DAB_INFO,
+ TEST_DAB_INFO_ALTERNATIVE);
+ ProgramListChunk halChunk = AidlTestUtils.makeHalChunk(/* purge= */ false,
+ /* complete= */ true, List.of(TEST_FM_INFO_MODIFIED, TEST_VENDOR_INFO),
List.of(TEST_RDS_PI_ID, TEST_AM_FREQUENCY_ID, TEST_DAB_DMB_SID_EXT_ID));
- int maxNumModifiedPerChunk = 2;
- int maxNumRemovedPerChunk = 2;
- List<ProgramList.Chunk> programListChunks = cache.filterAndApplyChunkInternal(chunk,
- maxNumModifiedPerChunk, maxNumRemovedPerChunk);
+ List<ProgramList.Chunk> programListChunks = cache.filterAndApplyChunkInternal(halChunk,
+ TEST_MAX_NUM_MODIFIED_PER_CHUNK, TEST_MAX_NUM_REMOVED_PER_CHUNK);
- expect.withMessage("Program cache applied with purge-enabled complete chunk")
+ expect.withMessage("Program cache applied with non-purging and complete chunk")
.that(cache.toProgramInfoList())
.containsExactly(TEST_FM_INFO_MODIFIED, TEST_VENDOR_INFO);
verifyChunkListPurge(programListChunks, /* purge= */ false);
verifyChunkListComplete(programListChunks, /* complete= */ true);
- verifyChunkListModified(programListChunks, maxNumModifiedPerChunk, TEST_FM_INFO_MODIFIED,
- TEST_VENDOR_INFO);
- verifyChunkListRemoved(programListChunks, maxNumRemovedPerChunk, TEST_RDS_PI_ID,
- TEST_AM_FREQUENCY_ID, TEST_DAB_DMB_SID_EXT_ID);
+ verifyChunkListModified(programListChunks, TEST_MAX_NUM_MODIFIED_PER_CHUNK,
+ TEST_FM_INFO_MODIFIED, TEST_VENDOR_INFO);
+ verifyChunkListRemoved(programListChunks, TEST_MAX_NUM_REMOVED_PER_CHUNK,
+ TEST_RDS_PI_UNIQUE_ID, TEST_AM_UNIQUE_ID, TEST_DAB_UNIQUE_ID,
+ TEST_DAB_UNIQUE_ID_ALTERNATIVE);
}
private void verifyChunkListPurge(List<ProgramList.Chunk> chunks, boolean purge) {
@@ -387,17 +486,17 @@ public class ProgramInfoCacheTest {
.that(actualSet).containsExactlyElementsIn(expectedProgramInfos);
}
- private void verifyChunkListRemoved(List<ProgramList.Chunk> chunks,
- int maxRemovedPerChunk, ProgramSelector.Identifier... expectedIdentifiers) {
+ private void verifyChunkListRemoved(List<ProgramList.Chunk> chunks, int maxRemovedPerChunk,
+ UniqueProgramIdentifier... expectedIdentifiers) {
if (chunks.isEmpty()) {
expect.withMessage("Empty program info list")
.that(expectedIdentifiers.length).isEqualTo(0);
return;
}
- ArraySet<ProgramSelector.Identifier> actualSet = new ArraySet<>();
+ ArraySet<UniqueProgramIdentifier> actualSet = new ArraySet<>();
for (int i = 0; i < chunks.size(); i++) {
- Set<ProgramSelector.Identifier> chunkRemoved = chunks.get(i).getRemoved();
+ Set<UniqueProgramIdentifier> chunkRemoved = chunks.get(i).getRemoved();
actualSet.addAll(chunkRemoved);
expect.withMessage("Chunk %s removed identifier array size ", i)
diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/TunerSessionTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/TunerSessionTest.java
index 84aa86472e81..a1952282dd0b 100644
--- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/TunerSessionTest.java
+++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/TunerSessionTest.java
@@ -18,8 +18,6 @@ package com.android.server.broadcastradio.aidl;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
-import static com.google.common.truth.Truth.assertWithMessage;
-
import static org.junit.Assert.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
@@ -47,6 +45,7 @@ import android.hardware.radio.ProgramList;
import android.hardware.radio.ProgramSelector;
import android.hardware.radio.RadioManager;
import android.hardware.radio.RadioTuner;
+import android.hardware.radio.UniqueProgramIdentifier;
import android.os.Binder;
import android.os.ParcelableException;
import android.os.RemoteException;
@@ -59,13 +58,18 @@ import com.android.dx.mockito.inline.extended.StaticMockitoSessionBuilder;
import com.android.server.broadcastradio.ExtendedRadioMockitoTestCase;
import com.android.server.broadcastradio.RadioServiceUserController;
+import com.google.common.truth.Expect;
+
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
+import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.verification.VerificationWithTimeout;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -94,10 +98,6 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
private static final ProgramSelector.Identifier TEST_FM_FREQUENCY_ID =
new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_AMFM_FREQUENCY,
/* value= */ 88_500);
- private static final ProgramSelector.Identifier TEST_RDS_PI_ID =
- new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_RDS_PI,
- /* value= */ 15_019);
-
private static final RadioManager.ProgramInfo TEST_FM_INFO = AidlTestUtils.makeProgramInfo(
AidlTestUtils.makeProgramSelector(ProgramSelector.PROGRAM_TYPE_FM,
TEST_FM_FREQUENCY_ID), TEST_FM_FREQUENCY_ID, TEST_FM_FREQUENCY_ID,
@@ -106,11 +106,37 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
AidlTestUtils.makeProgramInfo(AidlTestUtils.makeProgramSelector(
ProgramSelector.PROGRAM_TYPE_FM, TEST_FM_FREQUENCY_ID), TEST_FM_FREQUENCY_ID,
TEST_FM_FREQUENCY_ID, /* signalQuality= */ 100);
- private static final RadioManager.ProgramInfo TEST_RDS_INFO = AidlTestUtils.makeProgramInfo(
- AidlTestUtils.makeProgramSelector(ProgramSelector.PROGRAM_TYPE_FM, TEST_RDS_PI_ID),
- TEST_RDS_PI_ID, new ProgramSelector.Identifier(
- ProgramSelector.IDENTIFIER_TYPE_AMFM_FREQUENCY, /* value= */ 89_500),
- SIGNAL_QUALITY);
+
+ private static final ProgramSelector.Identifier TEST_DAB_FREQUENCY_ID =
+ new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_DAB_FREQUENCY,
+ /* value= */ 220_352);
+ private static final ProgramSelector.Identifier TEST_DAB_FREQUENCY_ID_ALT =
+ new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_DAB_FREQUENCY,
+ /* value= */ 220_064);
+ private static final ProgramSelector.Identifier TEST_DAB_SID_EXT_ID =
+ new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_DAB_DMB_SID_EXT,
+ /* value= */ 0xA000000111L);
+ private static final ProgramSelector.Identifier TEST_DAB_ENSEMBLE_ID =
+ new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_DAB_ENSEMBLE,
+ /* value= */ 0x1001);
+ private static final ProgramSelector TEST_DAB_SELECTOR = new ProgramSelector(
+ ProgramSelector.PROGRAM_TYPE_DAB, TEST_DAB_SID_EXT_ID,
+ new ProgramSelector.Identifier[]{TEST_DAB_FREQUENCY_ID, TEST_DAB_ENSEMBLE_ID},
+ /* vendorIds= */ null);
+ private static final ProgramSelector TEST_DAB_SELECTOR_ALT = new ProgramSelector(
+ ProgramSelector.PROGRAM_TYPE_DAB, TEST_DAB_SID_EXT_ID,
+ new ProgramSelector.Identifier[]{TEST_DAB_FREQUENCY_ID_ALT, TEST_DAB_ENSEMBLE_ID},
+ /* vendorIds= */ null);
+ private static final UniqueProgramIdentifier TEST_DAB_UNIQUE_ID = new UniqueProgramIdentifier(
+ TEST_DAB_SELECTOR);
+ private static final UniqueProgramIdentifier TEST_DAB_UNIQUE_ID_ALT =
+ new UniqueProgramIdentifier(TEST_DAB_SELECTOR_ALT);
+ private static final RadioManager.ProgramInfo TEST_DAB_INFO =
+ AidlTestUtils.makeProgramInfo(TEST_DAB_SELECTOR, TEST_DAB_SID_EXT_ID,
+ TEST_DAB_FREQUENCY_ID, SIGNAL_QUALITY);
+ private static final RadioManager.ProgramInfo TEST_DAB_INFO_ALT =
+ AidlTestUtils.makeProgramInfo(TEST_DAB_SELECTOR_ALT, TEST_DAB_SID_EXT_ID,
+ TEST_DAB_FREQUENCY_ID_ALT, SIGNAL_QUALITY);
// Mocks
@Mock
@@ -129,6 +155,9 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
private TunerSession[] mTunerSessions;
+ @Rule
+ public final Expect expect = Expect.create();
+
@Override
protected void initializeSession(StaticMockitoSessionBuilder builder) {
builder.spyStatic(RadioServiceUserController.class).spyStatic(CompatChanges.class)
@@ -225,7 +254,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
openAidlClients(numSessions);
for (int index = 0; index < numSessions; index++) {
- assertWithMessage("Session of index %s close state", index)
+ expect.withMessage("Session of index %s close state", index)
.that(mTunerSessions[index].isClosed()).isFalse();
}
}
@@ -257,7 +286,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
RadioManager.BandConfig config = mTunerSessions[0].getConfiguration();
- assertWithMessage("Session configuration").that(config)
+ expect.withMessage("Session configuration").that(config)
.isEqualTo(FM_BAND_CONFIG);
}
@@ -267,7 +296,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
mTunerSessions[0].setMuted(/* mute= */ false);
- assertWithMessage("Session mute state after setting unmuted")
+ expect.withMessage("Session mute state after setting unmuted")
.that(mTunerSessions[0].isMuted()).isFalse();
}
@@ -277,7 +306,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
mTunerSessions[0].setMuted(/* mute= */ true);
- assertWithMessage("Session mute state after setting muted")
+ expect.withMessage("Session mute state after setting muted")
.that(mTunerSessions[0].isMuted()).isTrue();
}
@@ -287,7 +316,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
mTunerSessions[0].close();
- assertWithMessage("Close state of broadcast radio service session")
+ expect.withMessage("Close state of broadcast radio service session")
.that(mTunerSessions[0].isClosed()).isTrue();
}
@@ -301,11 +330,11 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
for (int index = 0; index < numSessions; index++) {
if (index == closeIdx) {
- assertWithMessage(
+ expect.withMessage(
"Close state of broadcast radio service session of index %s", index)
.that(mTunerSessions[index].isClosed()).isTrue();
} else {
- assertWithMessage(
+ expect.withMessage(
"Close state of broadcast radio service session of index %s", index)
.that(mTunerSessions[index].isClosed()).isFalse();
}
@@ -320,7 +349,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
mTunerSessions[0].close(errorCode);
verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onError(errorCode);
- assertWithMessage("Close state of broadcast radio service session")
+ expect.withMessage("Close state of broadcast radio service session")
.that(mTunerSessions[0].isClosed()).isTrue();
}
@@ -334,7 +363,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
for (int index = 0; index < numSessions; index++) {
verify(mAidlTunerCallbackMocks[index], CALLBACK_TIMEOUT).onError(errorCode);
- assertWithMessage("Close state of broadcast radio service session of index %s", index)
+ expect.withMessage("Close state of broadcast radio service session of index %s", index)
.that(mTunerSessions[index].isClosed()).isTrue();
}
}
@@ -383,22 +412,12 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
@Test
public void tune_withUnsupportedSelector_throwsException() throws Exception {
- ProgramSelector.Identifier dabPrimaryId =
- new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_DAB_DMB_SID_EXT,
- /* value= */ 0xA000000111L);
- ProgramSelector.Identifier[] dabSecondaryIds = new ProgramSelector.Identifier[]{
- new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_DAB_ENSEMBLE,
- /* value= */ 1337),
- new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_DAB_FREQUENCY,
- /* value= */ 225648)};
- ProgramSelector unsupportedSelector = new ProgramSelector(ProgramSelector.PROGRAM_TYPE_DAB,
- dabPrimaryId, dabSecondaryIds, /* vendorIds= */ null);
openAidlClients(/* numClients= */ 1);
UnsupportedOperationException thrown = assertThrows(UnsupportedOperationException.class,
- () -> mTunerSessions[0].tune(unsupportedSelector));
+ () -> mTunerSessions[0].tune(TEST_DAB_SELECTOR));
- assertWithMessage("Exception for tuning on unsupported program selector")
+ expect.withMessage("Exception for tuning on unsupported program selector")
.that(thrown).hasMessageThat().contains("tune: NOT_SUPPORTED");
}
@@ -413,7 +432,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class,
() -> mTunerSessions[0].tune(invalidSel));
- assertWithMessage("Exception for tuning on DAB selector without DAB_SID_EXT primary id")
+ expect.withMessage("Exception for tuning on DAB selector without DAB_SID_EXT primary id")
.that(thrown).hasMessageThat().contains("tune: INVALID_ARGUMENTS");
}
@@ -457,7 +476,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
mTunerSessions[0].tune(sel);
});
- assertWithMessage("Unknown error HAL exception when tuning")
+ expect.withMessage("Unknown error HAL exception when tuning")
.that(thrown).hasMessageThat().contains("UNKNOWN_ERROR");
}
@@ -520,7 +539,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
mTunerSessions[0].step(/* directionDown= */ true, /* skipSubChannel= */ false);
});
- assertWithMessage("Exception for stepping when HAL is in invalid state")
+ expect.withMessage("Exception for stepping when HAL is in invalid state")
.that(thrown).hasMessageThat().contains("INVALID_STATE");
}
@@ -599,7 +618,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
mTunerSessions[0].seek(/* directionDown= */ true, /* skipSubChannel= */ false);
});
- assertWithMessage("Internal error HAL exception when seeking")
+ expect.withMessage("Internal error HAL exception when seeking")
.that(thrown).hasMessageThat().contains("INTERNAL_ERROR");
}
@@ -636,7 +655,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
mTunerSessions[0].cancel();
});
- assertWithMessage("Exception for canceling when HAL throws remote exception")
+ expect.withMessage("Exception for canceling when HAL throws remote exception")
.that(thrown).hasMessageThat().contains(exceptionMessage);
}
@@ -649,7 +668,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
mTunerSessions[0].getImage(imageId);
});
- assertWithMessage("Get image exception")
+ expect.withMessage("Get image exception")
.that(thrown).hasMessageThat().contains("Image ID is missing");
}
@@ -660,7 +679,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
Bitmap imageTest = mTunerSessions[0].getImage(imageId);
- assertWithMessage("Null image").that(imageTest).isEqualTo(null);
+ expect.withMessage("Null image").that(imageTest).isEqualTo(null);
}
@Test
@@ -674,7 +693,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
mTunerSessions[0].getImage(/* id= */ 1);
});
- assertWithMessage("Exception for getting image when HAL throws remote exception")
+ expect.withMessage("Exception for getting image when HAL throws remote exception")
.that(thrown).hasMessageThat().contains(exceptionMessage);
}
@@ -702,18 +721,19 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
openAidlClients(/* numClients= */ 1);
ProgramList.Filter filter = new ProgramList.Filter(new ArraySet<>(), new ArraySet<>(),
/* includeCategories= */ true, /* excludeModifications= */ false);
- ProgramFilter halFilter = ConversionUtils.filterToHalProgramFilter(filter);
- List<RadioManager.ProgramInfo> modified = List.of(TEST_FM_INFO, TEST_RDS_INFO);
- List<ProgramSelector.Identifier> removed = new ArrayList<>();
+ List<RadioManager.ProgramInfo> modified = List.of(TEST_FM_INFO, TEST_DAB_INFO,
+ TEST_DAB_INFO_ALT);
+ List<ProgramSelector.Identifier> halRemoved = new ArrayList<>();
+ List<UniqueProgramIdentifier> removed = new ArrayList<>();
ProgramListChunk halProgramList = AidlTestUtils.makeHalChunk(/* purge= */ true,
- /* complete= */ true, modified, removed);
+ /* complete= */ true, modified, halRemoved);
ProgramList.Chunk expectedProgramList =
AidlTestUtils.makeChunk(/* purge= */ true, /* complete= */ true, modified, removed);
mTunerSessions[0].startProgramListUpdates(filter);
mHalTunerCallback.onProgramListUpdated(halProgramList);
- verify(mBroadcastRadioMock).startProgramListUpdates(halFilter);
+ verifyHalProgramListUpdatesInvocation(filter);
verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT)
.onProgramListUpdated(expectedProgramList);
}
@@ -723,19 +743,23 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
openAidlClients(/* numClients= */ 1);
ProgramList.Filter filter = new ProgramList.Filter(new ArraySet<>(), new ArraySet<>(),
/* includeCategories= */ true, /* excludeModifications= */ false);
+ List<RadioManager.ProgramInfo> modifiedInfo = List.of(TEST_FM_INFO, TEST_DAB_INFO,
+ TEST_DAB_INFO_ALT);
mTunerSessions[0].startProgramListUpdates(filter);
mHalTunerCallback.onProgramListUpdated(AidlTestUtils.makeHalChunk(/* purge= */ true,
- /* complete= */ true, List.of(TEST_FM_INFO, TEST_RDS_INFO), new ArrayList<>()));
+ /* complete= */ true, modifiedInfo, new ArrayList<>()));
verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onProgramListUpdated(
- AidlTestUtils.makeChunk(/* purge= */ true, /* complete= */ true,
- List.of(TEST_FM_INFO, TEST_RDS_INFO), new ArrayList<>()));
+ AidlTestUtils.makeChunk(/* purge= */ true, /* complete= */ true, modifiedInfo,
+ new ArrayList<>()));
mHalTunerCallback.onProgramListUpdated(AidlTestUtils.makeHalChunk(/* purge= */ false,
- /* complete= */ true, List.of(TEST_FM_INFO_MODIFIED), List.of(TEST_RDS_PI_ID)));
+ /* complete= */ true, List.of(TEST_FM_INFO_MODIFIED),
+ List.of(TEST_DAB_SID_EXT_ID)));
verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onProgramListUpdated(
AidlTestUtils.makeChunk(/* purge= */ false, /* complete= */ true,
- List.of(TEST_FM_INFO_MODIFIED), List.of(TEST_RDS_PI_ID)));
+ List.of(TEST_FM_INFO_MODIFIED),
+ List.of(TEST_DAB_UNIQUE_ID, TEST_DAB_UNIQUE_ID_ALT)));
}
@Test
@@ -743,17 +767,21 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
openAidlClients(/* numClients= */ 1);
ProgramList.Filter filter = new ProgramList.Filter(new ArraySet<>(), new ArraySet<>(),
/* includeCategories= */ true, /* excludeModifications= */ false);
+ List<RadioManager.ProgramInfo> modifiedInfo = List.of(TEST_FM_INFO, TEST_DAB_INFO,
+ TEST_DAB_INFO_ALT);
mTunerSessions[0].startProgramListUpdates(filter);
mHalTunerCallback.onProgramListUpdated(AidlTestUtils.makeHalChunk(/* purge= */ true,
- /* complete= */ true, List.of(TEST_FM_INFO, TEST_RDS_INFO), new ArrayList<>()));
+ /* complete= */ true, modifiedInfo, new ArrayList<>()));
verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onProgramListUpdated(
- AidlTestUtils.makeChunk(/* purge= */ true, /* complete= */ true,
- List.of(TEST_FM_INFO, TEST_RDS_INFO), new ArrayList<>()));
+ AidlTestUtils.makeChunk(/* purge= */ true, /* complete= */ true, modifiedInfo,
+ new ArrayList<>()));
mHalTunerCallback.onProgramListUpdated(AidlTestUtils.makeHalChunk(/* purge= */ false,
- /* complete= */ true, List.of(TEST_FM_INFO_MODIFIED), List.of(TEST_RDS_PI_ID)));
+ /* complete= */ true, List.of(TEST_FM_INFO_MODIFIED),
+ List.of(TEST_DAB_SID_EXT_ID)));
verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onProgramListUpdated(
AidlTestUtils.makeChunk(/* purge= */ false, /* complete= */ true,
- List.of(TEST_FM_INFO_MODIFIED), List.of(TEST_RDS_PI_ID)));
+ List.of(TEST_FM_INFO_MODIFIED),
+ List.of(TEST_DAB_UNIQUE_ID, TEST_DAB_UNIQUE_ID_ALT)));
mTunerSessions[0].startProgramListUpdates(filter);
@@ -766,40 +794,44 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
@Test
public void startProgramListUpdates_withNullFilter() throws Exception {
openAidlClients(/* numClients= */ 1);
+ List<RadioManager.ProgramInfo> modifiedInfo = List.of(TEST_FM_INFO, TEST_DAB_INFO,
+ TEST_DAB_INFO_ALT);
mTunerSessions[0].startProgramListUpdates(/* filter= */ null);
mHalTunerCallback.onProgramListUpdated(AidlTestUtils.makeHalChunk(/* purge= */ true,
- /* complete= */ true, List.of(TEST_FM_INFO, TEST_RDS_INFO), new ArrayList<>()));
+ /* complete= */ true, modifiedInfo, new ArrayList<>()));
verify(mBroadcastRadioMock).startProgramListUpdates(any());
verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onProgramListUpdated(
- AidlTestUtils.makeChunk(/* purge= */ true, /* complete= */ true,
- List.of(TEST_FM_INFO, TEST_RDS_INFO), new ArrayList<>()));
+ AidlTestUtils.makeChunk(/* purge= */ true, /* complete= */ true, modifiedInfo,
+ new ArrayList<>()));
mHalTunerCallback.onProgramListUpdated(AidlTestUtils.makeHalChunk(/* purge= */ false,
- /* complete= */ true, List.of(TEST_FM_INFO_MODIFIED), List.of(TEST_RDS_PI_ID)));
+ /* complete= */ true, List.of(TEST_FM_INFO_MODIFIED),
+ List.of(TEST_DAB_SID_EXT_ID)));
verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onProgramListUpdated(
AidlTestUtils.makeChunk(/* purge= */ false, /* complete= */ true,
- List.of(TEST_FM_INFO_MODIFIED), List.of(TEST_RDS_PI_ID)));
+ List.of(TEST_FM_INFO_MODIFIED),
+ List.of(TEST_DAB_UNIQUE_ID, TEST_DAB_UNIQUE_ID_ALT)));
}
@Test
public void startProgramListUpdates_withIdFilter() throws Exception {
openAidlClients(/* numClients= */ 1);
ProgramList.Filter idFilter = new ProgramList.Filter(new ArraySet<>(),
- Set.of(TEST_RDS_PI_ID), /* includeCategories= */ true,
+ Set.of(TEST_DAB_SID_EXT_ID), /* includeCategories= */ true,
/* excludeModifications= */ true);
- ProgramFilter halFilter = ConversionUtils.filterToHalProgramFilter(idFilter);
mTunerSessions[0].startProgramListUpdates(idFilter);
mHalTunerCallback.onProgramListUpdated(AidlTestUtils.makeHalChunk(/* purge= */ false,
- /* complete= */ true, List.of(TEST_RDS_INFO), new ArrayList<>()));
+ /* complete= */ true, List.of(TEST_DAB_INFO, TEST_DAB_INFO_ALT),
+ new ArrayList<>()));
- verify(mBroadcastRadioMock).startProgramListUpdates(halFilter);
+ verifyHalProgramListUpdatesInvocation(idFilter);
verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onProgramListUpdated(
AidlTestUtils.makeChunk(/* purge= */ false, /* complete= */ true,
- List.of(TEST_RDS_INFO), new ArrayList<>()));
+ List.of(TEST_DAB_INFO, TEST_DAB_INFO_ALT), new ArrayList<>()));
mHalTunerCallback.onProgramListUpdated(AidlTestUtils.makeHalChunk(/* purge= */ false,
/* complete= */ true, List.of(TEST_FM_INFO), new ArrayList<>()));
@@ -811,50 +843,52 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
public void startProgramListUpdates_withFilterExcludingModifications() throws Exception {
openAidlClients(/* numClients= */ 1);
ProgramList.Filter filterExcludingModifications = new ProgramList.Filter(
- Set.of(ProgramSelector.IDENTIFIER_TYPE_AMFM_FREQUENCY), new ArraySet<>(),
+ Set.of(ProgramSelector.IDENTIFIER_TYPE_DAB_DMB_SID_EXT,
+ ProgramSelector.IDENTIFIER_TYPE_AMFM_FREQUENCY), new ArraySet<>(),
/* includeCategories= */ true, /* excludeModifications= */ true);
- ProgramFilter halFilter =
- ConversionUtils.filterToHalProgramFilter(filterExcludingModifications);
mTunerSessions[0].startProgramListUpdates(filterExcludingModifications);
mHalTunerCallback.onProgramListUpdated(AidlTestUtils.makeHalChunk(/* purge= */ false,
- /* complete= */ true, List.of(TEST_FM_INFO), new ArrayList<>()));
+ /* complete= */ true, List.of(TEST_FM_INFO, TEST_DAB_INFO), new ArrayList<>()));
- verify(mBroadcastRadioMock).startProgramListUpdates(halFilter);
+ verifyHalProgramListUpdatesInvocation(filterExcludingModifications);
verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onProgramListUpdated(
AidlTestUtils.makeChunk(/* purge= */ false, /* complete= */ true,
- List.of(TEST_FM_INFO), new ArrayList<>()));
+ List.of(TEST_FM_INFO, TEST_DAB_INFO), new ArrayList<>()));
mHalTunerCallback.onProgramListUpdated(AidlTestUtils.makeHalChunk(/* purge= */ false,
- /* complete= */ true, List.of(TEST_FM_INFO_MODIFIED), new ArrayList<>()));
+ /* complete= */ true, List.of(TEST_FM_INFO_MODIFIED, TEST_DAB_INFO_ALT),
+ new ArrayList<>()));
- verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onProgramListUpdated(any());
+ verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onProgramListUpdated(
+ AidlTestUtils.makeChunk(/* purge= */ false, /* complete= */ true,
+ List.of(TEST_DAB_INFO_ALT), new ArrayList<>()));
}
@Test
public void startProgramListUpdates_withFilterIncludingModifications() throws Exception {
openAidlClients(/* numClients= */ 1);
ProgramList.Filter filterIncludingModifications = new ProgramList.Filter(
- Set.of(ProgramSelector.IDENTIFIER_TYPE_AMFM_FREQUENCY), new ArraySet<>(),
+ Set.of(ProgramSelector.IDENTIFIER_TYPE_DAB_DMB_SID_EXT,
+ ProgramSelector.IDENTIFIER_TYPE_AMFM_FREQUENCY), new ArraySet<>(),
/* includeCategories= */ true, /* excludeModifications= */ false);
- ProgramFilter halFilter =
- ConversionUtils.filterToHalProgramFilter(filterIncludingModifications);
mTunerSessions[0].startProgramListUpdates(filterIncludingModifications);
mHalTunerCallback.onProgramListUpdated(AidlTestUtils.makeHalChunk(/* purge= */ false,
- /* complete= */ true, List.of(TEST_FM_INFO), new ArrayList<>()));
+ /* complete= */ true, List.of(TEST_FM_INFO, TEST_DAB_INFO), new ArrayList<>()));
- verify(mBroadcastRadioMock).startProgramListUpdates(halFilter);
+ verifyHalProgramListUpdatesInvocation(filterIncludingModifications);
verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onProgramListUpdated(
AidlTestUtils.makeChunk(/* purge= */ false, /* complete= */ true,
- List.of(TEST_FM_INFO), new ArrayList<>()));
+ List.of(TEST_FM_INFO, TEST_DAB_INFO), new ArrayList<>()));
mHalTunerCallback.onProgramListUpdated(AidlTestUtils.makeHalChunk(/* purge= */ false,
- /* complete= */ true, List.of(TEST_FM_INFO_MODIFIED), new ArrayList<>()));
+ /* complete= */ true, List.of(TEST_FM_INFO_MODIFIED, TEST_DAB_INFO_ALT),
+ new ArrayList<>()));
verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onProgramListUpdated(
AidlTestUtils.makeChunk(/* purge= */ false, /* complete= */ true,
- List.of(TEST_FM_INFO_MODIFIED), new ArrayList<>()));
+ List.of(TEST_FM_INFO_MODIFIED, TEST_DAB_INFO_ALT), new ArrayList<>()));
}
@Test
@@ -910,7 +944,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
int numSessions = 3;
openAidlClients(numSessions);
List<ProgramList.Filter> filters = List.of(new ProgramList.Filter(
- Set.of(ProgramSelector.IDENTIFIER_TYPE_RDS_PI), new ArraySet<>(),
+ Set.of(ProgramSelector.IDENTIFIER_TYPE_DAB_DMB_SID_EXT), new ArraySet<>(),
/* includeCategories= */ true, /* excludeModifications= */ false),
new ProgramList.Filter(new ArraySet<>(), Set.of(TEST_FM_FREQUENCY_ID),
/* includeCategories= */ false, /* excludeModifications= */ true),
@@ -922,18 +956,20 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
}
mHalTunerCallback.onProgramListUpdated(AidlTestUtils.makeHalChunk(/* purge= */ false,
- /* complete= */ true, List.of(TEST_FM_INFO, TEST_RDS_INFO), new ArrayList<>()));
+ /* complete= */ true, List.of(TEST_FM_INFO, TEST_DAB_INFO, TEST_DAB_INFO_ALT),
+ new ArrayList<>()));
verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT)
.onProgramListUpdated(AidlTestUtils.makeChunk(/* purge= */ false,
- /* complete= */ true, List.of(TEST_RDS_INFO), new ArrayList<>()));
+ /* complete= */ true, List.of(TEST_DAB_INFO, TEST_DAB_INFO_ALT),
+ new ArrayList<>()));
verify(mAidlTunerCallbackMocks[1], CALLBACK_TIMEOUT)
.onProgramListUpdated(AidlTestUtils.makeChunk(/* purge= */ false,
/* complete= */ true, List.of(TEST_FM_INFO), new ArrayList<>()));
verify(mAidlTunerCallbackMocks[2], CALLBACK_TIMEOUT)
.onProgramListUpdated(AidlTestUtils.makeChunk(/* purge= */ false,
- /* complete= */ true, List.of(TEST_RDS_INFO, TEST_FM_INFO),
- new ArrayList<>()));
+ /* complete= */ true, List.of(TEST_DAB_INFO, TEST_DAB_INFO_ALT,
+ TEST_FM_INFO), new ArrayList<>()));
}
@Test
@@ -958,7 +994,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
mTunerSessions[0].startProgramListUpdates(/* filter= */ null);
});
- assertWithMessage("Unknown error HAL exception when updating program list")
+ expect.withMessage("Unknown error HAL exception when updating program list")
.that(thrown).hasMessageThat().contains("UNKNOWN_ERROR");
}
@@ -995,7 +1031,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
boolean isSupported = mTunerSessions[0].isConfigFlagSupported(flag);
verify(mBroadcastRadioMock).isConfigFlagSet(flag);
- assertWithMessage("Config flag %s is supported", flag).that(isSupported).isFalse();
+ expect.withMessage("Config flag %s is supported", flag).that(isSupported).isFalse();
}
@Test
@@ -1006,7 +1042,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
boolean isSupported = mTunerSessions[0].isConfigFlagSupported(flag);
verify(mBroadcastRadioMock).isConfigFlagSet(flag);
- assertWithMessage("Config flag %s is supported", flag).that(isSupported).isTrue();
+ expect.withMessage("Config flag %s is supported", flag).that(isSupported).isTrue();
}
@Test
@@ -1018,7 +1054,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
mTunerSessions[0].setConfigFlag(flag, /* value= */ true);
});
- assertWithMessage("Exception for setting unsupported flag %s", flag)
+ expect.withMessage("Exception for setting unsupported flag %s", flag)
.that(thrown).hasMessageThat().contains("setConfigFlag: NOT_SUPPORTED");
}
@@ -1063,7 +1099,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
mTunerSessions[0].isConfigFlagSet(flag);
});
- assertWithMessage("Exception for checking if unsupported flag %s is set", flag)
+ expect.withMessage("Exception for checking if unsupported flag %s is set", flag)
.that(thrown).hasMessageThat().contains("isConfigFlagSet: NOT_SUPPORTED");
}
@@ -1076,7 +1112,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
boolean isSet = mTunerSessions[0].isConfigFlagSet(flag);
- assertWithMessage("Config flag %s is set", flag)
+ expect.withMessage("Config flag %s is set", flag)
.that(isSet).isEqualTo(expectedConfigFlagValue);
}
@@ -1090,7 +1126,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
mTunerSessions[0].isConfigFlagSet(flag);
});
- assertWithMessage("Exception for checking config flag when HAL throws remote exception")
+ expect.withMessage("Exception for checking config flag when HAL throws remote exception")
.that(thrown).hasMessageThat().contains("Failed to check flag");
}
@@ -1131,7 +1167,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
mTunerSessions[0].setParameters(parametersSet);
});
- assertWithMessage("Exception for setting parameters when HAL throws remote exception")
+ expect.withMessage("Exception for setting parameters when HAL throws remote exception")
.that(thrown).hasMessageThat().contains(exceptionMessage);
}
@@ -1157,7 +1193,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
mTunerSessions[0].getParameters(parameterKeys);
});
- assertWithMessage("Exception for getting parameters when HAL throws remote exception")
+ expect.withMessage("Exception for getting parameters when HAL throws remote exception")
.that(thrown).hasMessageThat().contains(exceptionMessage);
}
@@ -1264,4 +1300,24 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
}
return seekFrequency;
}
+
+ private void verifyHalProgramListUpdatesInvocation(ProgramList.Filter filter) throws Exception {
+ ProgramFilter halFilterExpected = ConversionUtils.filterToHalProgramFilter(filter);
+ ArgumentCaptor<ProgramFilter> halFilterCaptor = ArgumentCaptor.forClass(
+ ProgramFilter.class);
+ verify(mBroadcastRadioMock).startProgramListUpdates(halFilterCaptor.capture());
+ ProgramFilter halFilterInvoked = halFilterCaptor.getValue();
+ expect.withMessage("Filtered identifier types").that(
+ halFilterInvoked.identifierTypes).asList().containsExactlyElementsIn(Arrays.stream(
+ halFilterExpected.identifierTypes).boxed().toArray(Integer[]::new));
+ expect.withMessage("Filtered identifiers").that(
+ halFilterInvoked.identifiers).asList()
+ .containsExactlyElementsIn(halFilterExpected.identifiers);
+ expect.withMessage("Categories-included filter")
+ .that(halFilterInvoked.includeCategories)
+ .isEqualTo(halFilterExpected.includeCategories);
+ expect.withMessage("Modifications-excluded filter")
+ .that(halFilterInvoked.excludeModifications)
+ .isEqualTo(halFilterExpected.excludeModifications);
+ }
}
diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/ProgramInfoCacheTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/ProgramInfoCacheTest.java
index ec55ddbe1a4a..fbb446b5bc23 100644
--- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/ProgramInfoCacheTest.java
+++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/ProgramInfoCacheTest.java
@@ -21,12 +21,16 @@ import android.hardware.broadcastradio.V2_0.ProgramListChunk;
import android.hardware.radio.ProgramList;
import android.hardware.radio.ProgramSelector;
import android.hardware.radio.RadioManager;
+import android.hardware.radio.UniqueProgramIdentifier;
import android.test.suitebuilder.annotation.MediumTest;
import androidx.test.runner.AndroidJUnit4;
import com.android.server.broadcastradio.ExtendedRadioMockitoTestCase;
+import com.google.common.truth.Expect;
+
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -40,188 +44,221 @@ import java.util.Set;
@RunWith(AndroidJUnit4.class)
@MediumTest
public class ProgramInfoCacheTest extends ExtendedRadioMockitoTestCase {
- private static final String TAG = "BroadcastRadioTests.ProgramInfoCache";
+ private static final int TEST_QUALITY = 1;
+
+ private static final ProgramSelector.Identifier TEST_AM_FM_ID = new ProgramSelector.Identifier(
+ ProgramSelector.IDENTIFIER_TYPE_AMFM_FREQUENCY, /* value= */ 88500);
+ private static final ProgramSelector TEST_AM_FM_SELECTOR = TestUtils.makeProgramSelector(
+ ProgramSelector.PROGRAM_TYPE_FM, TEST_AM_FM_ID);
+ private static final RadioManager.ProgramInfo TEST_AM_FM_INFO = TestUtils.makeProgramInfo(
+ TEST_AM_FM_SELECTOR, TEST_QUALITY);
- private final ProgramSelector.Identifier mAmFmIdentifier =
- new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_AMFM_FREQUENCY, 88500);
- private final RadioManager.ProgramInfo mAmFmInfo = TestUtils.makeProgramInfo(
- ProgramSelector.PROGRAM_TYPE_FM, mAmFmIdentifier, 0);
+ private static final ProgramSelector.Identifier TEST_RDS_ID = new ProgramSelector.Identifier(
+ ProgramSelector.IDENTIFIER_TYPE_RDS_PI, /* value= */ 15019);
+ private static final ProgramSelector TEST_RDS_SELECTOR = TestUtils.makeProgramSelector(
+ ProgramSelector.PROGRAM_TYPE_FM, TEST_RDS_ID);
+ private static final RadioManager.ProgramInfo TEST_RDS_INFO = TestUtils.makeProgramInfo(
+ TEST_RDS_SELECTOR, TEST_QUALITY);
- private final ProgramSelector.Identifier mRdsIdentifier =
- new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_RDS_PI, 15019);
- private final RadioManager.ProgramInfo mRdsInfo = TestUtils.makeProgramInfo(
- ProgramSelector.PROGRAM_TYPE_FM, mRdsIdentifier, 0);
+ private static final ProgramSelector TEST_HD_SELECTOR = TestUtils.makeProgramSelector(
+ ProgramSelector.PROGRAM_TYPE_FM_HD, new ProgramSelector.Identifier(
+ ProgramSelector.IDENTIFIER_TYPE_HD_STATION_ID_EXT,
+ /* value= */ 0x17C14100000001L));
- private final ProgramSelector.Identifier mDabEnsembleIdentifier =
- new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_DAB_ENSEMBLE, 1337);
- private final RadioManager.ProgramInfo mDabEnsembleInfo = TestUtils.makeProgramInfo(
- ProgramSelector.PROGRAM_TYPE_DAB, mDabEnsembleIdentifier, 0);
+ private static final ProgramSelector.Identifier TEST_DAB_SID_ID =
+ new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_DAB_SID_EXT,
+ /* value= */ 0xA000000111L);
+ private static final ProgramSelector.Identifier TEST_DAB_ENSEMBLE_ID =
+ new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_DAB_ENSEMBLE,
+ /* value= */ 0x1001);
+ private static final ProgramSelector.Identifier TEST_DAB_FREQUENCY_ID =
+ new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_DAB_FREQUENCY,
+ /* value= */ 220_352);
+ private static final ProgramSelector TEST_DAB_SELECTOR = TestUtils.makeProgramSelector(
+ ProgramSelector.PROGRAM_TYPE_DAB, TEST_DAB_SID_ID,
+ new ProgramSelector.Identifier[]{TEST_DAB_FREQUENCY_ID, TEST_DAB_ENSEMBLE_ID});
+ private static final UniqueProgramIdentifier TEST_DAB_UNIQUE_ID =
+ new UniqueProgramIdentifier(TEST_DAB_SELECTOR);
+ private static final RadioManager.ProgramInfo TEST_DAB_INFO = TestUtils.makeProgramInfo(
+ TEST_DAB_SELECTOR, TEST_QUALITY);
+ private static final ProgramSelector.Identifier TEST_VENDOR_ID = new ProgramSelector.Identifier(
+ ProgramSelector.IDENTIFIER_TYPE_VENDOR_START, /* value= */ 9001);
+ private static final ProgramSelector TEST_VENDOR_SELECTOR = TestUtils.makeProgramSelector(
+ ProgramSelector.PROGRAM_TYPE_VENDOR_START, TEST_VENDOR_ID);
+ private static final UniqueProgramIdentifier TEST_VENDOR_UNIQUE_ID =
+ new UniqueProgramIdentifier(TEST_VENDOR_SELECTOR);
+ private static final RadioManager.ProgramInfo TEST_VENDOR_INFO = TestUtils.makeProgramInfo(
+ TEST_VENDOR_SELECTOR, TEST_QUALITY);
- private final ProgramSelector.Identifier mVendorCustomIdentifier =
- new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_VENDOR_START, 9001);
- private final RadioManager.ProgramInfo mVendorCustomInfo = TestUtils.makeProgramInfo(
- ProgramSelector.PROGRAM_TYPE_VENDOR_START, mVendorCustomIdentifier, 0);
+ private static final ProgramInfoCache FULL_PROGRAM_INFO_CACHE = new ProgramInfoCache(
+ /* filter= */ null, /* complete= */ true, TEST_AM_FM_INFO, TEST_RDS_INFO, TEST_DAB_INFO,
+ TEST_VENDOR_INFO);
- // HAL-side ProgramInfoCache containing all of the above ProgramInfos.
- private final ProgramInfoCache mAllProgramInfos = new ProgramInfoCache(null, true, mAmFmInfo,
- mRdsInfo, mDabEnsembleInfo, mVendorCustomInfo);
+ @Rule
+ public final Expect expect = Expect.create();
@Test
public void testUpdateFromHal() {
// First test updating an incomplete cache with a purging, complete chunk.
- ProgramInfoCache cache = new ProgramInfoCache(null, false, mAmFmInfo);
+ ProgramInfoCache cache = new ProgramInfoCache(null, false, TEST_AM_FM_INFO);
ProgramListChunk chunk = new ProgramListChunk();
chunk.purge = true;
chunk.complete = true;
- chunk.modified.add(TestUtils.programInfoToHal(mRdsInfo));
- chunk.modified.add(TestUtils.programInfoToHal(mDabEnsembleInfo));
+ chunk.modified.add(TestUtils.programInfoToHal(TEST_RDS_INFO));
+ chunk.modified.add(TestUtils.programInfoToHal(TEST_DAB_INFO));
cache.updateFromHalProgramListChunk(chunk);
- assertTrue(cache.programInfosAreExactly(mRdsInfo, mDabEnsembleInfo));
+ expect.withMessage("Program info cache updated with a purging complete chunk")
+ .that(cache.toProgramInfoList()).containsExactly(TEST_RDS_INFO, TEST_DAB_INFO);
assertTrue(cache.isComplete());
// Then test a non-purging, incomplete chunk.
chunk.purge = false;
chunk.complete = false;
chunk.modified.clear();
- RadioManager.ProgramInfo updatedRdsInfo = TestUtils.makeProgramInfo(
- ProgramSelector.PROGRAM_TYPE_FM, mRdsIdentifier, 1);
+ RadioManager.ProgramInfo updatedRdsInfo = TestUtils.makeProgramInfo(TEST_RDS_SELECTOR, 1);
chunk.modified.add(TestUtils.programInfoToHal(updatedRdsInfo));
- chunk.modified.add(TestUtils.programInfoToHal(mVendorCustomInfo));
- chunk.removed.add(Convert.programIdentifierToHal(mDabEnsembleIdentifier));
+ chunk.modified.add(TestUtils.programInfoToHal(TEST_VENDOR_INFO));
+ chunk.removed.add(Convert.programIdentifierToHal(TEST_DAB_SID_ID));
cache.updateFromHalProgramListChunk(chunk);
- assertTrue(cache.programInfosAreExactly(updatedRdsInfo, mVendorCustomInfo));
+ expect.withMessage("Program info cache updated with non-puring incomplete chunk")
+ .that(cache.toProgramInfoList()).containsExactly(updatedRdsInfo, TEST_VENDOR_INFO);
assertFalse(cache.isComplete());
}
@Test
public void testNullFilter() {
ProgramInfoCache cache = new ProgramInfoCache(null, true);
- cache.filterAndUpdateFrom(mAllProgramInfos, false);
- assertTrue(cache.programInfosAreExactly(mAmFmInfo, mRdsInfo, mDabEnsembleInfo,
- mVendorCustomInfo));
+ cache.filterAndUpdateFrom(FULL_PROGRAM_INFO_CACHE, false);
+ expect.withMessage("Program info cache with null filter")
+ .that(cache.toProgramInfoList()).containsExactly(TEST_AM_FM_INFO, TEST_RDS_INFO,
+ TEST_DAB_INFO, TEST_VENDOR_INFO);
}
@Test
public void testEmptyFilter() {
ProgramInfoCache cache = new ProgramInfoCache(new ProgramList.Filter(new HashSet<Integer>(),
new HashSet<ProgramSelector.Identifier>(), true, false));
- cache.filterAndUpdateFrom(mAllProgramInfos, false);
- assertTrue(cache.programInfosAreExactly(mAmFmInfo, mRdsInfo, mDabEnsembleInfo,
- mVendorCustomInfo));
+ cache.filterAndUpdateFrom(FULL_PROGRAM_INFO_CACHE, false);
+ expect.withMessage("Program info cache with empty filter")
+ .that(cache.toProgramInfoList()).containsExactly(TEST_AM_FM_INFO, TEST_RDS_INFO,
+ TEST_DAB_INFO, TEST_VENDOR_INFO);
}
@Test
public void testFilterByType() {
HashSet<Integer> filterTypes = new HashSet<>();
filterTypes.add(ProgramSelector.IDENTIFIER_TYPE_AMFM_FREQUENCY);
- filterTypes.add(ProgramSelector.IDENTIFIER_TYPE_DAB_ENSEMBLE);
+ filterTypes.add(ProgramSelector.IDENTIFIER_TYPE_DAB_SID_EXT);
ProgramInfoCache cache = new ProgramInfoCache(new ProgramList.Filter(filterTypes,
new HashSet<ProgramSelector.Identifier>(), true, false));
- cache.filterAndUpdateFrom(mAllProgramInfos, false);
- assertTrue(cache.programInfosAreExactly(mAmFmInfo, mDabEnsembleInfo));
+ cache.filterAndUpdateFrom(FULL_PROGRAM_INFO_CACHE, false);
+ expect.withMessage("Program info cache with type filter")
+ .that(cache.toProgramInfoList()).containsExactly(TEST_AM_FM_INFO, TEST_DAB_INFO);
}
@Test
public void testFilterByIdentifier() {
HashSet<ProgramSelector.Identifier> filterIds = new HashSet<>();
- filterIds.add(mRdsIdentifier);
- filterIds.add(mVendorCustomIdentifier);
+ filterIds.add(TEST_RDS_ID);
+ filterIds.add(TEST_VENDOR_ID);
ProgramInfoCache cache = new ProgramInfoCache(new ProgramList.Filter(new HashSet<Integer>(),
filterIds, true, false));
- cache.filterAndUpdateFrom(mAllProgramInfos, false);
- assertTrue(cache.programInfosAreExactly(mRdsInfo, mVendorCustomInfo));
+ cache.filterAndUpdateFrom(FULL_PROGRAM_INFO_CACHE, false);
+ expect.withMessage("Program info cache with identifier filter")
+ .that(cache.toProgramInfoList()).containsExactly(TEST_RDS_INFO, TEST_VENDOR_INFO);
}
@Test
public void testFilterExcludeCategories() {
ProgramInfoCache cache = new ProgramInfoCache(new ProgramList.Filter(new HashSet<Integer>(),
new HashSet<ProgramSelector.Identifier>(), false, false));
- cache.filterAndUpdateFrom(mAllProgramInfos, false);
- assertTrue(cache.programInfosAreExactly(mAmFmInfo, mRdsInfo));
+ cache.filterAndUpdateFrom(FULL_PROGRAM_INFO_CACHE, false);
+ expect.withMessage("Program info cache with filter excluding categories")
+ .that(cache.toProgramInfoList()).containsExactly(TEST_AM_FM_INFO, TEST_RDS_INFO,
+ TEST_DAB_INFO);
}
@Test
public void testPurgeUpdateChunks() {
- ProgramInfoCache cache = new ProgramInfoCache(null, false, mAmFmInfo);
+ ProgramInfoCache cache = new ProgramInfoCache(null, false, TEST_AM_FM_INFO);
List<ProgramList.Chunk> chunks =
- cache.filterAndUpdateFromInternal(mAllProgramInfos, true, 3, 3);
+ cache.filterAndUpdateFromInternal(FULL_PROGRAM_INFO_CACHE, true, 3, 3);
assertEquals(2, chunks.size());
verifyChunkListFlags(chunks, true, true);
- verifyChunkListModified(chunks, 3, mAmFmInfo, mRdsInfo, mDabEnsembleInfo,
- mVendorCustomInfo);
+ verifyChunkListModified(chunks, 3, TEST_AM_FM_INFO, TEST_RDS_INFO, TEST_DAB_INFO,
+ TEST_VENDOR_INFO);
verifyChunkListRemoved(chunks, 0);
}
@Test
public void testDeltaUpdateChunksModificationsIncluded() {
// Create a cache with a filter that allows modifications, and set its contents to
- // mAmFmInfo, mRdsInfo, mDabEnsembleInfo, and mVendorCustomInfo.
- ProgramInfoCache cache = new ProgramInfoCache(null, true, mAmFmInfo, mRdsInfo,
- mDabEnsembleInfo, mVendorCustomInfo);
+ // TEST_AM_FM_INFO, TEST_RDS_INFO, TEST_DAB_INFO, and TEST_VENDOR_INFO.
+ ProgramInfoCache cache = new ProgramInfoCache(null, true, TEST_AM_FM_INFO, TEST_RDS_INFO,
+ TEST_DAB_INFO, TEST_VENDOR_INFO);
// Create a HAL cache that:
// - Is complete.
- // - Retains mAmFmInfo.
- // - Replaces mRdsInfo with updatedRdsInfo.
- // - Drops mDabEnsembleInfo and mVendorCustomInfo.
- // - Introduces a new SXM info.
- RadioManager.ProgramInfo updatedRdsInfo = TestUtils.makeProgramInfo(
- ProgramSelector.PROGRAM_TYPE_FM, mRdsIdentifier, 1);
- RadioManager.ProgramInfo newSxmInfo = TestUtils.makeProgramInfo(
- ProgramSelector.PROGRAM_TYPE_SXM,
- new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_SXM_CHANNEL, 12345),
- 0);
- ProgramInfoCache halCache = new ProgramInfoCache(null, true, mAmFmInfo, updatedRdsInfo,
- newSxmInfo);
+ // - Retains TEST_AM_FM_INFO.
+ // - Replaces TEST_RDS_INFO with updatedRdsInfo.
+ // - Drops TEST_DAB_INFO and TEST_VENDOR_INFO.
+ // - Introduces a new HD info.
+ RadioManager.ProgramInfo updatedRdsInfo = TestUtils.makeProgramInfo(TEST_RDS_SELECTOR,
+ TEST_QUALITY + 1);
+ RadioManager.ProgramInfo newHdInfo = TestUtils.makeProgramInfo(TEST_HD_SELECTOR,
+ TEST_QUALITY);
+ ProgramInfoCache halCache = new ProgramInfoCache(null, true, TEST_AM_FM_INFO,
+ updatedRdsInfo, newHdInfo);
// Update the cache and verify:
// - The final chunk's complete flag is set.
- // - mAmFmInfo is retained and not reported in the chunks.
- // - updatedRdsInfo should appear as an update to mRdsInfo.
- // - newSxmInfo should appear as a new entry.
- // - mDabEnsembleInfo and mVendorCustomInfo should be reported as removed.
+ // - TEST_AM_FM_INFO is retained and not reported in the chunks.
+ // - updatedRdsInfo should appear as an update to TEST_RDS_INFO.
+ // - newHdInfo should appear as a new entry.
+ // - TEST_DAB_INFO and TEST_VENDOR_INFO should be reported as removed.
List<ProgramList.Chunk> chunks = cache.filterAndUpdateFromInternal(halCache, false, 5, 1);
- assertTrue(cache.programInfosAreExactly(mAmFmInfo, updatedRdsInfo, newSxmInfo));
+ expect.withMessage("Program info cache with modification included")
+ .that(cache.toProgramInfoList()).containsExactly(TEST_AM_FM_INFO, updatedRdsInfo,
+ newHdInfo);
assertEquals(2, chunks.size());
verifyChunkListFlags(chunks, false, true);
- verifyChunkListModified(chunks, 5, updatedRdsInfo, newSxmInfo);
- verifyChunkListRemoved(chunks, 1, mDabEnsembleIdentifier, mVendorCustomIdentifier);
+ verifyChunkListModified(chunks, 5, updatedRdsInfo, newHdInfo);
+ verifyChunkListRemoved(chunks, 1, TEST_DAB_UNIQUE_ID, TEST_VENDOR_UNIQUE_ID);
}
@Test
public void testDeltaUpdateChunksModificationsExcluded() {
// Create a cache with a filter that excludes modifications, and set its contents to
- // mAmFmInfo, mRdsInfo, mDabEnsembleInfo, and mVendorCustomInfo.
+ // TEST_AM_FM_INFO, TEST_RDS_INFO, TEST_DAB_INFO, and TEST_VENDOR_INFO.
ProgramInfoCache cache = new ProgramInfoCache(new ProgramList.Filter(new HashSet<Integer>(),
- new HashSet<ProgramSelector.Identifier>(), true, true), true, mAmFmInfo, mRdsInfo,
- mDabEnsembleInfo, mVendorCustomInfo);
+ new HashSet<ProgramSelector.Identifier>(), true, true), true,
+ TEST_AM_FM_INFO, TEST_RDS_INFO, TEST_DAB_INFO, TEST_VENDOR_INFO);
// Create a HAL cache that:
// - Is incomplete.
- // - Retains mAmFmInfo.
- // - Replaces mRdsInfo with updatedRdsInfo.
- // - Drops mDabEnsembleInfo and mVendorCustomInfo.
- // - Introduces a new SXM info.
- RadioManager.ProgramInfo updatedRdsInfo = TestUtils.makeProgramInfo(
- ProgramSelector.PROGRAM_TYPE_FM, mRdsIdentifier, 1);
- RadioManager.ProgramInfo newSxmInfo = TestUtils.makeProgramInfo(
- ProgramSelector.PROGRAM_TYPE_SXM,
- new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_SXM_CHANNEL, 12345),
- 0);
- ProgramInfoCache halCache = new ProgramInfoCache(null, false, mAmFmInfo, updatedRdsInfo,
- newSxmInfo);
+ // - Retains TEST_AM_FM_INFO.
+ // - Replaces TEST_RDS_INFO with updatedRdsInfo.
+ // - Drops TEST_DAB_INFO and TEST_VENDOR_INFO.
+ // - Introduces a new HD info.
+ RadioManager.ProgramInfo updatedRdsInfo = TestUtils.makeProgramInfo(TEST_RDS_SELECTOR, 1);
+ RadioManager.ProgramInfo newHdInfo = TestUtils.makeProgramInfo(TEST_HD_SELECTOR,
+ TEST_QUALITY);
+ ProgramInfoCache halCache = new ProgramInfoCache(null, false, TEST_AM_FM_INFO,
+ updatedRdsInfo, newHdInfo);
// Update the cache and verify:
// - All complete flags are false.
- // - mAmFmInfo and mRdsInfo are retained and not reported in the chunks.
- // - newSxmInfo should appear as a new entry.
- // - mDabEnsembleInfo and mVendorCustomInfo should be reported as removed.
+ // - TEST_AM_FM_INFO and TEST_RDS_INFO are retained and not reported in the chunks.
+ // - newHdInfo should appear as a new entry.
+ // - TEST_DAB_INFO and TEST_VENDOR_INFO should be reported as removed.
List<ProgramList.Chunk> chunks = cache.filterAndUpdateFromInternal(halCache, false, 5, 1);
- assertTrue(cache.programInfosAreExactly(mAmFmInfo, mRdsInfo, newSxmInfo));
+ expect.withMessage("Program info cache with modification excluded")
+ .that(cache.toProgramInfoList()).containsExactly(TEST_AM_FM_INFO, TEST_RDS_INFO,
+ newHdInfo);
assertEquals(2, chunks.size());
verifyChunkListFlags(chunks, false, false);
- verifyChunkListModified(chunks, 5, newSxmInfo);
- verifyChunkListRemoved(chunks, 1, mDabEnsembleIdentifier, mVendorCustomIdentifier);
+ verifyChunkListModified(chunks, 5, newHdInfo);
+ verifyChunkListRemoved(chunks, 1, TEST_DAB_UNIQUE_ID, TEST_VENDOR_UNIQUE_ID);
}
// Verifies that:
@@ -271,20 +308,21 @@ public class ProgramInfoCacheTest extends ExtendedRadioMockitoTestCase {
// - Each chunk's removed array has a similar number of elements.
// - Each element of expectedIdentifiers appears in a chunk.
private static void verifyChunkListRemoved(List<ProgramList.Chunk> chunks,
- int maxRemovedPerChunk, ProgramSelector.Identifier... expectedIdentifiers) {
+ int maxRemovedPerChunk,
+ UniqueProgramIdentifier... expectedIdentifiers) {
if (chunks.isEmpty()) {
assertEquals(0, expectedIdentifiers.length);
return;
}
- HashSet<ProgramSelector.Identifier> expectedSet = new HashSet<>();
- for (ProgramSelector.Identifier identifier : expectedIdentifiers) {
+ HashSet<UniqueProgramIdentifier> expectedSet = new HashSet<>();
+ for (UniqueProgramIdentifier identifier : expectedIdentifiers) {
expectedSet.add(identifier);
}
- HashSet<ProgramSelector.Identifier> actualSet = new HashSet<>();
+ HashSet<UniqueProgramIdentifier> actualSet = new HashSet<>();
int chunk0NumRemoved = chunks.get(0).getRemoved().size();
for (ProgramList.Chunk chunk : chunks) {
- Set<ProgramSelector.Identifier> chunkRemoved = chunk.getRemoved();
+ Set<UniqueProgramIdentifier> chunkRemoved = chunk.getRemoved();
assertTrue(chunkRemoved.size() <= maxRemovedPerChunk);
assertTrue(Math.abs(chunkRemoved.size() - chunk0NumRemoved) <= 1);
actualSet.addAll(chunkRemoved);
diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/StartProgramListUpdatesFanoutTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/StartProgramListUpdatesFanoutTest.java
index 7d604d497984..8c16d79133ce 100644
--- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/StartProgramListUpdatesFanoutTest.java
+++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/StartProgramListUpdatesFanoutTest.java
@@ -35,6 +35,7 @@ import android.hardware.broadcastradio.V2_0.Result;
import android.hardware.radio.ProgramList;
import android.hardware.radio.ProgramSelector;
import android.hardware.radio.RadioManager;
+import android.hardware.radio.UniqueProgramIdentifier;
import android.os.RemoteException;
import com.android.dx.mockito.inline.extended.StaticMockitoSessionBuilder;
@@ -72,22 +73,42 @@ public class StartProgramListUpdatesFanoutTest extends ExtendedRadioMockitoTestC
private TunerSession[] mTunerSessions;
// Data objects used during tests
- private final ProgramSelector.Identifier mAmFmIdentifier =
- new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_AMFM_FREQUENCY, 88500);
- private final RadioManager.ProgramInfo mAmFmInfo = TestUtils.makeProgramInfo(
- ProgramSelector.PROGRAM_TYPE_FM, mAmFmIdentifier, 0);
- private final RadioManager.ProgramInfo mModifiedAmFmInfo = TestUtils.makeProgramInfo(
- ProgramSelector.PROGRAM_TYPE_FM, mAmFmIdentifier, 1);
-
- private final ProgramSelector.Identifier mRdsIdentifier =
- new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_RDS_PI, 15019);
- private final RadioManager.ProgramInfo mRdsInfo = TestUtils.makeProgramInfo(
- ProgramSelector.PROGRAM_TYPE_FM, mRdsIdentifier, 0);
-
- private final ProgramSelector.Identifier mDabEnsembleIdentifier =
- new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_DAB_ENSEMBLE, 1337);
- private final RadioManager.ProgramInfo mDabEnsembleInfo = TestUtils.makeProgramInfo(
- ProgramSelector.PROGRAM_TYPE_DAB, mDabEnsembleIdentifier, 0);
+ private static final int TEST_QUALITY = 0;
+ private static final ProgramSelector.Identifier TEST_AM_FM_ID =
+ new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_AMFM_FREQUENCY,
+ /* value= */ 88_500);
+ private static final ProgramSelector TEST_AM_FM_SELECTOR = TestUtils.makeProgramSelector(
+ ProgramSelector.PROGRAM_TYPE_FM, TEST_AM_FM_ID);
+ private static final RadioManager.ProgramInfo TEST_AM_FM_INFO = TestUtils.makeProgramInfo(
+ TEST_AM_FM_SELECTOR, TEST_QUALITY);
+ private static final RadioManager.ProgramInfo TEST_AM_FM_MODIFIED_INFO =
+ TestUtils.makeProgramInfo(TEST_AM_FM_SELECTOR, TEST_QUALITY + 1);
+
+ private static final ProgramSelector.Identifier TEST_RDS_ID =
+ new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_RDS_PI,
+ /* value= */ 15_019);
+ private static final ProgramSelector TEST_RDS_SELECTOR = TestUtils.makeProgramSelector(
+ ProgramSelector.PROGRAM_TYPE_FM, TEST_RDS_ID);
+
+ private static final UniqueProgramIdentifier TEST_RDS_UNIQUE_ID = new UniqueProgramIdentifier(
+ TEST_RDS_ID);
+ private static final RadioManager.ProgramInfo TEST_RDS_INFO = TestUtils.makeProgramInfo(
+ TEST_RDS_SELECTOR, TEST_QUALITY);
+
+ private static final ProgramSelector.Identifier TEST_DAB_SID_ID =
+ new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_DAB_SID_EXT,
+ /* value= */ 0xA000000111L);
+ private static final ProgramSelector.Identifier TEST_DAB_ENSEMBLE_ID =
+ new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_DAB_ENSEMBLE,
+ /* value= */ 0x1001);
+ private static final ProgramSelector.Identifier TEST_DAB_FREQUENCY_ID =
+ new ProgramSelector.Identifier(ProgramSelector.IDENTIFIER_TYPE_DAB_FREQUENCY,
+ /* value= */ 220_352);
+ private static final ProgramSelector TEST_DAB_SELECTOR = TestUtils.makeProgramSelector(
+ ProgramSelector.PROGRAM_TYPE_DAB, TEST_DAB_SID_ID,
+ new ProgramSelector.Identifier[]{TEST_DAB_FREQUENCY_ID, TEST_DAB_ENSEMBLE_ID});
+ private static final RadioManager.ProgramInfo TEST_DAB_INFO = TestUtils.makeProgramInfo(
+ TEST_DAB_SELECTOR, TEST_QUALITY);
@Override
protected void initializeSession(StaticMockitoSessionBuilder builder) {
@@ -126,18 +147,18 @@ public class StartProgramListUpdatesFanoutTest extends ExtendedRadioMockitoTestC
// Initiate a program list update from the HAL side and verify both connected AIDL clients
// receive the update.
- updateHalProgramInfo(true, Arrays.asList(mAmFmInfo, mRdsInfo), null);
+ updateHalProgramInfo(true, Arrays.asList(TEST_AM_FM_INFO, TEST_RDS_INFO), null);
for (int i = 0; i < 2; i++) {
verifyAidlClientReceivedChunk(mAidlTunerCallbackMocks[i], true, Arrays.asList(
- mAmFmInfo, mRdsInfo), null);
+ TEST_AM_FM_INFO, TEST_RDS_INFO), null);
}
// Repeat with a non-purging update.
- updateHalProgramInfo(false, Arrays.asList(mModifiedAmFmInfo),
- Arrays.asList(mRdsIdentifier));
+ updateHalProgramInfo(false, Arrays.asList(TEST_AM_FM_MODIFIED_INFO),
+ Arrays.asList(TEST_RDS_ID));
for (int i = 0; i < 2; i++) {
verifyAidlClientReceivedChunk(mAidlTunerCallbackMocks[i], false,
- Arrays.asList(mModifiedAmFmInfo), Arrays.asList(mRdsIdentifier));
+ Arrays.asList(TEST_AM_FM_MODIFIED_INFO), Arrays.asList(TEST_RDS_UNIQUE_ID));
}
// Now start updates on the 3rd client. Verify the HAL function has not been called again
@@ -145,19 +166,19 @@ public class StartProgramListUpdatesFanoutTest extends ExtendedRadioMockitoTestC
mTunerSessions[2].startProgramListUpdates(aidlFilter);
verify(mHalTunerSessionMock, times(1)).startProgramListUpdates(any());
verifyAidlClientReceivedChunk(mAidlTunerCallbackMocks[2], true,
- Arrays.asList(mModifiedAmFmInfo), null);
+ Arrays.asList(TEST_AM_FM_MODIFIED_INFO), null);
}
@Test
public void testFiltering() throws RemoteException {
// Open 4 clients that will use the following filters:
- // [0]: ID mRdsIdentifier, modifications excluded
+ // [0]: ID TEST_RDS_ID, modifications excluded
// [1]: No categories, modifications excluded
// [2]: Type IDENTIFIER_TYPE_AMFM_FREQUENCY, modifications excluded
// [3]: Type IDENTIFIER_TYPE_AMFM_FREQUENCY, modifications included
openAidlClients(4);
ProgramList.Filter idFilter = new ProgramList.Filter(new HashSet<Integer>(),
- new HashSet<ProgramSelector.Identifier>(Arrays.asList(mRdsIdentifier)), true, true);
+ new HashSet<ProgramSelector.Identifier>(Arrays.asList(TEST_RDS_ID)), true, true);
ProgramList.Filter categoryFilter = new ProgramList.Filter(new HashSet<Integer>(),
new HashSet<ProgramSelector.Identifier>(), false, true);
ProgramList.Filter typeFilterWithoutModifications = new ProgramList.Filter(
@@ -188,41 +209,40 @@ public class StartProgramListUpdatesFanoutTest extends ExtendedRadioMockitoTestC
halFilter.excludeModifications = false;
verify(mHalTunerSessionMock, times(1)).startProgramListUpdates(halFilter);
- // Adding mRdsInfo should update clients [0] and [1].
- updateHalProgramInfo(false, Arrays.asList(mRdsInfo), null);
- verifyAidlClientReceivedChunk(mAidlTunerCallbackMocks[0], false, Arrays.asList(mRdsInfo),
- null);
- verifyAidlClientReceivedChunk(mAidlTunerCallbackMocks[1], false, Arrays.asList(mRdsInfo),
- null);
-
- // Adding mAmFmInfo should update clients [1], [2], and [3].
- updateHalProgramInfo(false, Arrays.asList(mAmFmInfo), null);
- verifyAidlClientReceivedChunk(mAidlTunerCallbackMocks[1], false, Arrays.asList(mAmFmInfo),
- null);
- verifyAidlClientReceivedChunk(mAidlTunerCallbackMocks[2], false, Arrays.asList(mAmFmInfo),
- null);
- verifyAidlClientReceivedChunk(mAidlTunerCallbackMocks[3], false, Arrays.asList(mAmFmInfo),
- null);
+ // Adding TEST_RDS_INFO should update clients [0] and [1].
+ updateHalProgramInfo(false, Arrays.asList(TEST_RDS_INFO), null);
+ verifyAidlClientReceivedChunk(mAidlTunerCallbackMocks[0], false,
+ Arrays.asList(TEST_RDS_INFO), null);
+ verifyAidlClientReceivedChunk(mAidlTunerCallbackMocks[1], false,
+ Arrays.asList(TEST_RDS_INFO), null);
+
+ // Adding TEST_AM_FM_INFO should update clients [1], [2], and [3].
+ updateHalProgramInfo(false, Arrays.asList(TEST_AM_FM_INFO), null);
+ verifyAidlClientReceivedChunk(mAidlTunerCallbackMocks[1], false,
+ Arrays.asList(TEST_AM_FM_INFO), null);
+ verifyAidlClientReceivedChunk(mAidlTunerCallbackMocks[2], false,
+ Arrays.asList(TEST_AM_FM_INFO), null);
+ verifyAidlClientReceivedChunk(mAidlTunerCallbackMocks[3], false,
+ Arrays.asList(TEST_AM_FM_INFO), null);
- // Modifying mAmFmInfo to mModifiedAmFmInfo should update only [3].
- updateHalProgramInfo(false, Arrays.asList(mModifiedAmFmInfo), null);
+ // Modifying TEST_AM_FM_INFO to TEST_AM_FM_MODIFIED_INFO should update only [3].
+ updateHalProgramInfo(false, Arrays.asList(TEST_AM_FM_MODIFIED_INFO), null);
verifyAidlClientReceivedChunk(mAidlTunerCallbackMocks[3], false,
- Arrays.asList(mModifiedAmFmInfo), null);
+ Arrays.asList(TEST_AM_FM_MODIFIED_INFO), null);
- // Adding mDabEnsembleInfo should not update any client.
- updateHalProgramInfo(false, Arrays.asList(mDabEnsembleInfo), null);
+ updateHalProgramInfo(false, Arrays.asList(TEST_DAB_INFO), null);
verify(mAidlTunerCallbackMocks[0], CB_TIMEOUT.times(1)).onProgramListUpdated(any());
- verify(mAidlTunerCallbackMocks[1], CB_TIMEOUT.times(2)).onProgramListUpdated(any());
+ verify(mAidlTunerCallbackMocks[1], CB_TIMEOUT.times(3)).onProgramListUpdated(any());
verify(mAidlTunerCallbackMocks[2], CB_TIMEOUT.times(2)).onProgramListUpdated(any());
verify(mAidlTunerCallbackMocks[3], CB_TIMEOUT.times(2)).onProgramListUpdated(any());
}
@Test
public void testClientClosing() throws RemoteException {
- // Open 2 clients that use different filters that are both sensitive to mAmFmIdentifier.
+ // Open 2 clients that use different filters that are both sensitive to TEST_AM_FM_ID.
openAidlClients(2);
ProgramList.Filter idFilter = new ProgramList.Filter(new HashSet<Integer>(),
- new HashSet<ProgramSelector.Identifier>(Arrays.asList(mAmFmIdentifier)), true,
+ new HashSet<ProgramSelector.Identifier>(Arrays.asList(TEST_AM_FM_ID)), true,
false);
ProgramList.Filter typeFilter = new ProgramList.Filter(
new HashSet<Integer>(Arrays.asList(ProgramSelector.IDENTIFIER_TYPE_AMFM_FREQUENCY)),
@@ -237,23 +257,24 @@ public class StartProgramListUpdatesFanoutTest extends ExtendedRadioMockitoTestC
halFilter.identifiers.clear();
verify(mHalTunerSessionMock, times(1)).startProgramListUpdates(halFilter);
- // Update the HAL with mAmFmInfo, and verify both clients are updated.
- updateHalProgramInfo(true, Arrays.asList(mAmFmInfo), null);
- verifyAidlClientReceivedChunk(mAidlTunerCallbackMocks[0], true, Arrays.asList(mAmFmInfo),
- null);
- verifyAidlClientReceivedChunk(mAidlTunerCallbackMocks[1], true, Arrays.asList(mAmFmInfo),
- null);
+ // Update the HAL with TEST_AM_FM_INFO, and verify both clients are updated.
+ updateHalProgramInfo(true, Arrays.asList(TEST_AM_FM_INFO), null);
+ verifyAidlClientReceivedChunk(mAidlTunerCallbackMocks[0], true,
+ Arrays.asList(TEST_AM_FM_INFO), null);
+ verifyAidlClientReceivedChunk(mAidlTunerCallbackMocks[1], true,
+ Arrays.asList(TEST_AM_FM_INFO), null);
// Stop updates on the first client and verify the HAL filter is updated.
mTunerSessions[0].stopProgramListUpdates();
verify(mHalTunerSessionMock, times(1)).startProgramListUpdates(Convert.programFilterToHal(
typeFilter));
- // Update the HAL with mModifiedAmFmInfo, and verify only the remaining client is updated.
- updateHalProgramInfo(true, Arrays.asList(mModifiedAmFmInfo), null);
+ // Update the HAL with TEST_AM_FM_MODIFIED_INFO, and verify only the remaining client is
+ // updated.
+ updateHalProgramInfo(true, Arrays.asList(TEST_AM_FM_MODIFIED_INFO), null);
verify(mAidlTunerCallbackMocks[0], CB_TIMEOUT.times(1)).onProgramListUpdated(any());
verifyAidlClientReceivedChunk(mAidlTunerCallbackMocks[1], true,
- Arrays.asList(mModifiedAmFmInfo), null);
+ Arrays.asList(TEST_AM_FM_MODIFIED_INFO), null);
// Close the other client without explicitly stopping updates, and verify HAL updates are
// stopped as well.
@@ -269,15 +290,15 @@ public class StartProgramListUpdatesFanoutTest extends ExtendedRadioMockitoTestC
// Verify the AIDL client receives all types of updates (e.g. a new program, an update to
// that program, and a category).
- updateHalProgramInfo(true, Arrays.asList(mAmFmInfo, mRdsInfo), null);
+ updateHalProgramInfo(true, Arrays.asList(TEST_AM_FM_INFO, TEST_RDS_INFO), null);
verifyAidlClientReceivedChunk(mAidlTunerCallbackMocks[0], true, Arrays.asList(
- mAmFmInfo, mRdsInfo), null);
- updateHalProgramInfo(false, Arrays.asList(mModifiedAmFmInfo), null);
+ TEST_AM_FM_INFO, TEST_RDS_INFO), null);
+ updateHalProgramInfo(false, Arrays.asList(TEST_AM_FM_MODIFIED_INFO), null);
verifyAidlClientReceivedChunk(mAidlTunerCallbackMocks[0], false,
- Arrays.asList(mModifiedAmFmInfo), null);
- updateHalProgramInfo(false, Arrays.asList(mDabEnsembleInfo), null);
+ Arrays.asList(TEST_AM_FM_MODIFIED_INFO), null);
+ updateHalProgramInfo(false, Arrays.asList(TEST_DAB_INFO), null);
verifyAidlClientReceivedChunk(mAidlTunerCallbackMocks[0], false,
- Arrays.asList(mDabEnsembleInfo), null);
+ Arrays.asList(TEST_DAB_INFO), null);
// Verify closing the AIDL session also stops HAL updates.
mTunerSessions[0].close();
@@ -313,12 +334,12 @@ public class StartProgramListUpdatesFanoutTest extends ExtendedRadioMockitoTestC
private void verifyAidlClientReceivedChunk(android.hardware.radio.ITunerCallback clientMock,
boolean purge, List<RadioManager.ProgramInfo> modified,
- List<ProgramSelector.Identifier> removed) throws RemoteException {
+ List<UniqueProgramIdentifier> removed) throws RemoteException {
HashSet<RadioManager.ProgramInfo> modifiedSet = new HashSet<>();
if (modified != null) {
modifiedSet.addAll(modified);
}
- HashSet<ProgramSelector.Identifier> removedSet = new HashSet<>();
+ HashSet<UniqueProgramIdentifier> removedSet = new HashSet<>();
if (removed != null) {
removedSet.addAll(removed);
}
diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/TestUtils.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/TestUtils.java
index d4ca8d4c96d3..0b1614114869 100644
--- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/TestUtils.java
+++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/TestUtils.java
@@ -45,6 +45,23 @@ final class TestUtils {
static RadioManager.ProgramInfo makeProgramInfo(ProgramSelector selector,
ProgramSelector.Identifier logicallyTunedTo,
ProgramSelector.Identifier physicallyTunedTo, int signalQuality) {
+ if (logicallyTunedTo == null) {
+ logicallyTunedTo = selector.getPrimaryId();
+ }
+ if (physicallyTunedTo == null) {
+ if (selector.getPrimaryId().getType()
+ == ProgramSelector.IDENTIFIER_TYPE_DAB_SID_EXT) {
+ for (int i = 0; i < selector.getSecondaryIds().length; i++) {
+ if (selector.getSecondaryIds()[i].getType()
+ == ProgramSelector.IDENTIFIER_TYPE_DAB_FREQUENCY) {
+ physicallyTunedTo = selector.getSecondaryIds()[i];
+ break;
+ }
+ }
+ } else {
+ physicallyTunedTo = selector.getPrimaryId();
+ }
+ }
return new RadioManager.ProgramInfo(selector,
logicallyTunedTo, physicallyTunedTo, /* relatedContents= */ null,
/* infoFlags= */ 0, signalQuality,
@@ -52,14 +69,8 @@ final class TestUtils {
}
static RadioManager.ProgramInfo makeProgramInfo(ProgramSelector selector, int signalQuality) {
- return makeProgramInfo(selector, selector.getPrimaryId(), selector.getPrimaryId(),
- signalQuality);
- }
-
- static RadioManager.ProgramInfo makeProgramInfo(int programType,
- ProgramSelector.Identifier identifier, int signalQuality) {
- return makeProgramInfo(makeProgramSelector(programType, identifier),
- /* logicallyTunedTo= */ null, /* physicallyTunedTo= */ null, signalQuality);
+ return makeProgramInfo(selector, /* logicallyTunedTo= */ null,
+ /* physicallyTunedTo= */ null, signalQuality);
}
static ProgramSelector makeFmSelector(long freq) {
@@ -70,8 +81,12 @@ final class TestUtils {
static ProgramSelector makeProgramSelector(int programType,
ProgramSelector.Identifier identifier) {
- return new ProgramSelector(programType, identifier, /* secondaryIds= */ null,
- /* vendorIds= */ null);
+ return makeProgramSelector(programType, identifier, /* secondaryIds= */ null);
+ }
+
+ static ProgramSelector makeProgramSelector(int programType,
+ ProgramSelector.Identifier primaryId, ProgramSelector.Identifier[] secondaryIds) {
+ return new ProgramSelector(programType, primaryId, secondaryIds, /* vendorIds= */ null);
}
static ProgramInfo programInfoToHal(RadioManager.ProgramInfo info) {
@@ -79,6 +94,21 @@ final class TestUtils {
// function only copies fields that are set by makeProgramInfo().
ProgramInfo hwInfo = new ProgramInfo();
hwInfo.selector = Convert.programSelectorToHal(info.getSelector());
+ hwInfo.logicallyTunedTo = hwInfo.selector.primaryId;
+ if (info.getSelector().getPrimaryId().getType()
+ == ProgramSelector.IDENTIFIER_TYPE_DAB_SID_EXT) {
+ for (int i = 0; i < info.getSelector().getSecondaryIds().length; i++) {
+ if (info.getSelector().getSecondaryIds()[i].getType()
+ == ProgramSelector.IDENTIFIER_TYPE_DAB_FREQUENCY) {
+ hwInfo.physicallyTunedTo = Convert.programIdentifierToHal(info.getSelector()
+ .getSecondaryIds()[i]);
+ break;
+ }
+ }
+ } else {
+ hwInfo.physicallyTunedTo = Convert.programIdentifierToHal(info.getSelector()
+ .getPrimaryId());
+ }
hwInfo.signalQuality = info.getSignalStrength();
return hwInfo;
}
diff --git a/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java b/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java
index 0778311e98bd..819178f40451 100644
--- a/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java
+++ b/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java
@@ -99,7 +99,7 @@ public class ActivityThreadTest {
// The first sequence number to try with. Use a large number to avoid conflicts with the first a
// few sequence numbers the framework used to launch the test activity.
- private static final int BASE_SEQ = 10000;
+ private static final int BASE_SEQ = 10000000;
@Rule
public final ActivityTestRule<TestActivity> mActivityTestRule =
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index 6057852a7e4b..721a2db9d6d3 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -3067,6 +3067,12 @@
"group": "WM_DEBUG_REMOTE_ANIMATIONS",
"at": "com\/android\/server\/wm\/RemoteAnimationController.java"
},
+ "643263584": {
+ "message": "Content Recording: Apply transformations of shift %d x %d, scale %f, crop %d x %d for display %d",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_CONTENT_RECORDING",
+ "at": "com\/android\/server\/wm\/ContentRecorder.java"
+ },
"644675193": {
"message": "Real start recents",
"level": "DEBUG",
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index a4c655c8ce55..1ff5a3d46f8e 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -1779,7 +1779,7 @@ public final class Bitmap implements Parcelable {
* If the bitmap's internal config is in one of the public formats, return
* that config, otherwise return null.
*/
- @NonNull
+ @Nullable
public final Config getConfig() {
if (mRecycled) {
Log.w(TAG, "Called getConfig() on a recycle()'d bitmap! This is undefined behavior!");
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java
index 9b8006362c79..4640106b5f1c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java
@@ -245,8 +245,8 @@ class ActivityEmbeddingAnimationSpec {
private boolean shouldShowBackdrop(@NonNull TransitionInfo info,
@NonNull TransitionInfo.Change change) {
- final Animation a = loadAttributeAnimation(info.getType(), info, change,
- WALLPAPER_TRANSITION_NONE, mTransitionAnimation, false);
+ final Animation a = loadAttributeAnimation(info, change, WALLPAPER_TRANSITION_NONE,
+ mTransitionAnimation, false);
return a != null && a.getShowBackdrop();
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
index 093ecb1e3ade..d10de833ab89 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
@@ -131,6 +131,7 @@ public class BubbleStackView extends FrameLayout
private static final int EXPANDED_VIEW_ALPHA_ANIMATION_DURATION = 150;
+ /** Should be kept in sync with value in TaskbarScrimViewController. */
private static final float SCRIM_ALPHA = 0.32f;
/** Minimum alpha value for scrim when alpha is being changed via drag */
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
index f90ee586e696..991b699161ea 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
@@ -43,6 +43,7 @@ import android.app.ActivityOptions;
import android.app.ActivityTaskManager;
import android.app.PendingIntent;
import android.app.TaskInfo;
+import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ShortcutInfo;
@@ -814,21 +815,22 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
final String packageName1 = SplitScreenUtils.getPackageName(intent);
final String packageName2 = getPackageName(reverseSplitPosition(position));
final int userId2 = getUserId(reverseSplitPosition(position));
+ final ComponentName component = intent.getIntent().getComponent();
+
+ // To prevent accumulating large number of instances in the background, reuse task
+ // in the background. If we don't explicitly reuse, new may be created even if the app
+ // isn't multi-instance because WM won't automatically remove/reuse the previous instance
+ final ActivityManager.RecentTaskInfo taskInfo = mRecentTasksOptional
+ .map(recentTasks -> recentTasks.findTaskInBackground(component, userId1))
+ .orElse(null);
+ if (taskInfo != null) {
+ startTask(taskInfo.taskId, position, options);
+ ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN,
+ "Start task in background");
+ return;
+ }
if (samePackage(packageName1, packageName2, userId1, userId2)) {
if (supportMultiInstancesSplit(packageName1)) {
- // To prevent accumulating large number of instances in the background, reuse task
- // in the background with priority.
- final ActivityManager.RecentTaskInfo taskInfo = mRecentTasksOptional
- .map(recentTasks -> recentTasks.findTaskInBackground(
- intent.getIntent().getComponent(), userId1))
- .orElse(null);
- if (taskInfo != null) {
- startTask(taskInfo.taskId, position, options);
- ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN,
- "Start task in background");
- return;
- }
-
// Flag with MULTIPLE_TASK if this is launching the same activity into both sides of
// the split and there is no reusable background task.
fillInIntent.addFlags(FLAG_ACTIVITY_MULTIPLE_TASK);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java
index d310ae32993c..7df658e6c9db 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java
@@ -37,12 +37,8 @@ import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_ROTATE;
import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS;
import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_UNSPECIFIED;
import static android.view.WindowManager.TRANSIT_CHANGE;
-import static android.view.WindowManager.TRANSIT_CLOSE;
import static android.view.WindowManager.TRANSIT_KEYGUARD_UNOCCLUDE;
-import static android.view.WindowManager.TRANSIT_OPEN;
import static android.view.WindowManager.TRANSIT_RELAUNCH;
-import static android.view.WindowManager.TRANSIT_TO_FRONT;
-import static android.window.TransitionInfo.FLAGS_IS_NON_APP_WINDOW;
import static android.window.TransitionInfo.FLAG_BACK_GESTURE_ANIMATED;
import static android.window.TransitionInfo.FLAG_CROSS_PROFILE_OWNER_THUMBNAIL;
import static android.window.TransitionInfo.FLAG_CROSS_PROFILE_WORK_THUMBNAIL;
@@ -338,10 +334,6 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
boolean isDisplayRotationAnimationStarted = false;
final boolean isDreamTransition = isDreamTransition(info);
final boolean isOnlyTranslucent = isOnlyTranslucent(info);
- final boolean isActivityReplace = checkActivityReplacement(info, startTransaction);
- // Some patterns (eg. activity "replacement") require us to re-interpret the type
- @WindowManager.TransitionType final int transitType =
- isActivityReplace ? TRANSIT_OPEN : info.getType();
for (int i = info.getChanges().size() - 1; i >= 0; --i) {
final TransitionInfo.Change change = info.getChanges().get(i);
@@ -438,8 +430,7 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
// Don't animate anything that isn't independent.
if (!TransitionInfo.isIndependent(change, info)) continue;
- Animation a = loadAnimation(transitType, info, change, wallpaperTransit,
- isDreamTransition);
+ Animation a = loadAnimation(info, change, wallpaperTransit, isDreamTransition);
if (a != null) {
if (isTask) {
final boolean isTranslucent = (change.getFlags() & FLAG_TRANSLUCENT) != 0;
@@ -613,53 +604,6 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
return (translucentOpen + translucentClose) > 0;
}
- /**
- * Checks for an edge-case where an activity calls finish() followed immediately by
- * startActivity() to "replace" itself. If in this case, it will swap the layer of the
- * close/open activities and return `true`. This way, we pretend like we are just "opening"
- * the new activity.
- */
- private static boolean checkActivityReplacement(@NonNull TransitionInfo info,
- SurfaceControl.Transaction t) {
- if (info.getType() != TRANSIT_CLOSE) {
- return false;
- }
- int closing = -1;
- int opening = -1;
- for (int i = info.getChanges().size() - 1; i >= 0; --i) {
- final TransitionInfo.Change change = info.getChanges().get(i);
- if ((change.getTaskInfo() != null || change.hasFlags(FLAG_IS_DISPLAY))
- && !TransitionUtil.isOrderOnly(change)) {
- // This isn't an activity-level transition.
- return false;
- }
- if (change.getTaskInfo() != null
- && change.hasFlags(FLAG_IS_DISPLAY | FLAGS_IS_NON_APP_WINDOW)) {
- // Ignore non-activity containers.
- continue;
- }
- if (TransitionUtil.isClosingType(change.getMode())) {
- closing = i;
- } else if (change.getMode() == TRANSIT_OPEN) {
- // OPEN implies that it is a new launch. If going "back" the opening app will be
- // TO_FRONT
- opening = i;
- } else if (change.getMode() == TRANSIT_TO_FRONT) {
- // Normal "going back", so not a replacement.
- return false;
- }
- }
- if (closing < 0 || opening < 0) {
- return false;
- }
- // Swap the opening and closing z-orders since we're swapping the transit type.
- final int numChanges = info.getChanges().size();
- final int zSplitLine = numChanges + 1;
- t.setLayer(info.getChanges().get(opening).getLeash(), zSplitLine + numChanges - opening);
- t.setLayer(info.getChanges().get(closing).getLeash(), zSplitLine - closing);
- return true;
- }
-
@Override
public void mergeAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
@NonNull SurfaceControl.Transaction t, @NonNull IBinder mergeTarget,
@@ -712,11 +656,12 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
}
@Nullable
- private Animation loadAnimation(int type, @NonNull TransitionInfo info,
+ private Animation loadAnimation(@NonNull TransitionInfo info,
@NonNull TransitionInfo.Change change, int wallpaperTransit,
boolean isDreamTransition) {
Animation a;
+ final int type = info.getType();
final int flags = info.getFlags();
final int changeMode = change.getMode();
final int changeFlags = change.getFlags();
@@ -771,8 +716,8 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
// If there's a scene-transition, then jump-cut.
return null;
} else {
- a = loadAttributeAnimation(type, info, change, wallpaperTransit, mTransitionAnimation,
- isDreamTransition);
+ a = loadAttributeAnimation(
+ info, change, wallpaperTransit, mTransitionAnimation, isDreamTransition);
}
if (a != null) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/TransitionAnimationHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/TransitionAnimationHelper.java
index c99911de5291..d07d2b7b6db9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/TransitionAnimationHelper.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/TransitionAnimationHelper.java
@@ -45,7 +45,6 @@ import android.graphics.Rect;
import android.graphics.Shader;
import android.view.Surface;
import android.view.SurfaceControl;
-import android.view.WindowManager;
import android.view.animation.Animation;
import android.view.animation.Transformation;
import android.window.ScreenCapture;
@@ -62,10 +61,10 @@ public class TransitionAnimationHelper {
/** Loads the animation that is defined through attribute id for the given transition. */
@Nullable
- public static Animation loadAttributeAnimation(@WindowManager.TransitionType int type,
- @NonNull TransitionInfo info, @NonNull TransitionInfo.Change change,
- int wallpaperTransit, @NonNull TransitionAnimation transitionAnimation,
- boolean isDreamTransition) {
+ public static Animation loadAttributeAnimation(@NonNull TransitionInfo info,
+ @NonNull TransitionInfo.Change change, int wallpaperTransit,
+ @NonNull TransitionAnimation transitionAnimation, boolean isDreamTransition) {
+ final int type = info.getType();
final int changeMode = change.getMode();
final int changeFlags = change.getFlags();
final boolean enter = TransitionUtil.isOpeningType(changeMode);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java
index 568db919818c..99cd4f391153 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitScreenControllerTests.java
@@ -36,6 +36,7 @@ import static org.mockito.ArgumentMatchers.isA;
import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -218,8 +219,7 @@ public class SplitScreenControllerTests extends ShellTestCase {
}
@Test
- public void startIntent_multiInstancesSupported_startTaskInBackgroundBeforeSplitActivated() {
- doReturn(true).when(mSplitScreenController).supportMultiInstancesSplit(any());
+ public void startIntent_multiInstancesNotSupported_startTaskInBackgroundBeforeSplitActivated() {
doNothing().when(mSplitScreenController).startTask(anyInt(), anyInt(), any());
Intent startIntent = createStartIntent("startActivity");
PendingIntent pendingIntent =
@@ -237,6 +237,8 @@ public class SplitScreenControllerTests extends ShellTestCase {
verify(mSplitScreenController).startTask(anyInt(), eq(SPLIT_POSITION_TOP_OR_LEFT),
isNull());
+ verify(mSplitScreenController, never()).supportMultiInstancesSplit(any());
+ verify(mStageCoordinator, never()).switchSplitPosition(any());
}
@Test
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index 1ee5aa36740c..8e9c07996f83 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -931,8 +931,7 @@ public class MediaPlayer extends PlayerBase
* @return a MediaPlayer object, or null if creation failed
*/
public static MediaPlayer create(Context context, Uri uri, SurfaceHolder holder) {
- int s = AudioSystem.newAudioSessionId();
- return create(context, uri, holder, null, s > 0 ? s : 0);
+ return create(context, uri, holder, null, AudioSystem.AUDIO_SESSION_ALLOCATE);
}
/**
@@ -994,8 +993,7 @@ public class MediaPlayer extends PlayerBase
* @return a MediaPlayer object, or null if creation failed
*/
public static MediaPlayer create(Context context, int resid) {
- int s = AudioSystem.newAudioSessionId();
- return create(context, resid, null, s > 0 ? s : 0);
+ return create(context, resid, null, AudioSystem.AUDIO_SESSION_ALLOCATE);
}
/**
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerUnitTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerUnitTest.java
index f812d5fa1c20..f27a5687ee36 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerUnitTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerUnitTest.java
@@ -30,6 +30,7 @@ import static org.mockito.Mockito.when;
import android.companion.virtual.VirtualDeviceManager;
import android.content.Context;
+import android.media.AudioAttributes;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.test.mock.MockContext;
@@ -37,6 +38,8 @@ import android.test.mock.MockContext;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.platform.app.InstrumentationRegistry;
+import com.android.mediaframeworktest.R;
+
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -45,6 +48,8 @@ import org.junit.runner.RunWith;
public class MediaPlayerUnitTest {
private static final int TEST_VIRTUAL_DEVICE_ID = 42;
+ private static final AudioAttributes AUDIO_ATTRIBUTES_MEDIA =
+ new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_MEDIA).build();
@Test
public void testConstructionWithContext_virtualDeviceDefaultAudioPolicy() {
@@ -89,6 +94,49 @@ public class MediaPlayerUnitTest {
assertEquals(anotherSessionId, mediaPlayer.getAudioSessionId());
}
+ @Test
+ public void testCreateFromResource_virtualDeviceDefaultAudioPolicy() {
+ int vdmPlaybackSessionId = getContext().getSystemService(
+ AudioManager.class).generateAudioSessionId();
+ VirtualDeviceManager mockVdm = getMockVirtualDeviceManager(TEST_VIRTUAL_DEVICE_ID,
+ vdmPlaybackSessionId, DEVICE_POLICY_DEFAULT);
+ Context virtualDeviceContext = getVirtualDeviceMockContext(TEST_VIRTUAL_DEVICE_ID, mockVdm);
+
+ MediaPlayer mediaPlayer = MediaPlayer.create(virtualDeviceContext, R.raw.testmp3);
+
+ assertNotEquals(vdmPlaybackSessionId, mediaPlayer.getAudioSessionId());
+ assertTrue(mediaPlayer.getAudioSessionId() > 0);
+ }
+
+ @Test
+ public void testCreateFromResource_virtualDeviceCustomAudioPolicy() {
+ int vdmPlaybackSessionId = getContext().getSystemService(
+ AudioManager.class).generateAudioSessionId();
+ VirtualDeviceManager mockVdm = getMockVirtualDeviceManager(TEST_VIRTUAL_DEVICE_ID,
+ vdmPlaybackSessionId, DEVICE_POLICY_CUSTOM);
+ Context virtualDeviceContext = getVirtualDeviceMockContext(TEST_VIRTUAL_DEVICE_ID, mockVdm);
+
+ MediaPlayer mediaPlayer = MediaPlayer.create(virtualDeviceContext, R.raw.testmp3);
+
+ assertEquals(vdmPlaybackSessionId, mediaPlayer.getAudioSessionId());
+ }
+
+ @Test
+ public void testCreateFromResource_explicitSessionIdOverridesContext() {
+ int vdmPlaybackSessionId = getContext().getSystemService(
+ AudioManager.class).generateAudioSessionId();
+ int anotherSessionId = getContext().getSystemService(
+ AudioManager.class).generateAudioSessionId();
+ VirtualDeviceManager mockVdm = getMockVirtualDeviceManager(TEST_VIRTUAL_DEVICE_ID,
+ vdmPlaybackSessionId, DEVICE_POLICY_CUSTOM);
+ Context virtualDeviceContext = getVirtualDeviceMockContext(TEST_VIRTUAL_DEVICE_ID, mockVdm);
+
+ MediaPlayer mediaPlayer = MediaPlayer.create(virtualDeviceContext, R.raw.testmp3,
+ AUDIO_ATTRIBUTES_MEDIA, anotherSessionId);
+
+ assertEquals(anotherSessionId, mediaPlayer.getAudioSessionId());
+ }
+
private Context getContext() {
return InstrumentationRegistry.getInstrumentation().getContext();
}
@@ -98,6 +146,7 @@ public class MediaPlayerUnitTest {
when(mockContext.getDeviceId()).thenReturn(deviceId);
when(mockContext.getSystemService(VirtualDeviceManager.class)).thenReturn(vdm);
when(mockContext.getAttributionSource()).thenReturn(getContext().getAttributionSource());
+ when(mockContext.getResources()).thenReturn(getContext().getResources());
return mockContext;
}
diff --git a/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/TileUtils.java b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/TileUtils.java
index e46db75f633e..33907ece5a7c 100644
--- a/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/TileUtils.java
+++ b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/TileUtils.java
@@ -344,7 +344,9 @@ public class TileUtils {
continue;
}
final ProviderInfo providerInfo = resolved.providerInfo;
- final List<Bundle> entryData = getEntryDataFromProvider(context,
+ final List<Bundle> entryData = getEntryDataFromProvider(
+ // Build new context so the entry data is retrieved for the queried user.
+ context.createContextAsUser(user, 0 /* flags */),
providerInfo.authority);
if (entryData == null || entryData.isEmpty()) {
continue;
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java
index 20864664e512..a8063e84cfca 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java
@@ -35,6 +35,7 @@ import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -52,6 +53,7 @@ import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ProviderInfo;
import android.content.pm.ResolveInfo;
import android.content.res.Resources;
+import android.net.Uri;
import android.os.Bundle;
import android.os.UserHandle;
import android.os.UserManager;
@@ -69,6 +71,8 @@ import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
+import org.robolectric.shadow.api.Shadow;
+import org.robolectric.util.ReflectionHelpers;
import java.util.ArrayList;
import java.util.Arrays;
@@ -88,6 +92,10 @@ public class TileUtilsTest {
private UserManager mUserManager;
@Mock
private ContentResolver mContentResolver;
+ @Mock
+ private Context mUserContext;
+ @Mock
+ private ContentResolver mUserContentResolver;
private static final String URI_GET_SUMMARY = "content://authority/text/summary";
private static final String URI_GET_ICON = "content://authority/icon/my_icon";
@@ -104,6 +112,8 @@ public class TileUtilsTest {
mContentResolver = spy(application.getContentResolver());
when(mContext.getContentResolver()).thenReturn(mContentResolver);
when(mContext.getPackageName()).thenReturn("com.android.settings");
+ when(mUserContext.getContentResolver()).thenReturn(mUserContentResolver);
+ ShadowTileUtils.sCallRealEntryDataFromProvider = false;
}
@Test
@@ -375,6 +385,30 @@ public class TileUtilsTest {
}
@Test
+ public void loadTilesForAction_forUserProvider_getEntryDataFromProvider_inContextOfGivenUser() {
+ ShadowTileUtils.sCallRealEntryDataFromProvider = true;
+ UserHandle userHandle = new UserHandle(10);
+
+ doReturn(mUserContext).when(mContext).createContextAsUser(eq(userHandle), anyInt());
+
+ Map<Pair<String, String>, Tile> addedCache = new ArrayMap<>();
+ List<Tile> outTiles = new ArrayList<>();
+ List<ResolveInfo> info = new ArrayList<>();
+ ResolveInfo resolveInfo = newInfo(true, null /* category */, null, URI_GET_ICON,
+ URI_GET_SUMMARY, null, 123, PROFILE_ALL);
+ info.add(resolveInfo);
+
+ when(mPackageManager.queryIntentContentProvidersAsUser(any(Intent.class), anyInt(),
+ anyInt())).thenReturn(info);
+
+ TileUtils.loadTilesForAction(mContext, userHandle, IA_SETTINGS_ACTION,
+ addedCache, null /* defaultCategory */, outTiles, false /* requiresSettings */);
+
+ verify(mUserContentResolver, atLeastOnce())
+ .acquireUnstableProvider(any(Uri.class));
+ }
+
+ @Test
public void loadTilesForAction_withPendingIntent_updatesPendingIntentMap() {
Map<Pair<String, String>, Tile> addedCache = new ArrayMap<>();
List<Tile> outTiles = new ArrayList<>();
@@ -472,8 +506,17 @@ public class TileUtilsTest {
private static Bundle sMetaData;
+ private static boolean sCallRealEntryDataFromProvider;
+
@Implementation
protected static List<Bundle> getEntryDataFromProvider(Context context, String authority) {
+ if (sCallRealEntryDataFromProvider) {
+ return Shadow.directlyOn(
+ TileUtils.class,
+ "getEntryDataFromProvider",
+ ReflectionHelpers.ClassParameter.from(Context.class, context),
+ ReflectionHelpers.ClassParameter.from(String.class, authority));
+ }
return Arrays.asList(sMetaData);
}
diff --git a/packages/SystemUI/OWNERS b/packages/SystemUI/OWNERS
index a8922694e7a2..78da5a699759 100644
--- a/packages/SystemUI/OWNERS
+++ b/packages/SystemUI/OWNERS
@@ -6,6 +6,7 @@ dsandler@android.com
aaliomer@google.com
aaronjli@google.com
+achalke@google.com
acul@google.com
adamcohen@google.com
aioana@google.com
@@ -72,6 +73,7 @@ omarmt@google.com
patmanning@google.com
peanutbutter@google.com
peskal@google.com
+petrcermak@google.com
pinyaoting@google.com
pixel@google.com
pomini@google.com
@@ -82,13 +84,17 @@ santie@google.com
shanh@google.com
snoeberger@google.com
steell@google.com
+stevenckng@google.com
stwu@google.com
syeonlee@google.com
sunnygoyal@google.com
thiruram@google.com
+tkachenkoi@google.com
tracyzhou@google.com
tsuji@google.com
twickham@google.com
+vadimt@google.com
+vanjan@google.com
victortulias@google.com
winsonc@google.com
wleshner@google.com
diff --git a/packages/SystemUI/TEST_MAPPING b/packages/SystemUI/TEST_MAPPING
index 969c14821350..cb9e9ee903c5 100644
--- a/packages/SystemUI/TEST_MAPPING
+++ b/packages/SystemUI/TEST_MAPPING
@@ -1,47 +1,23 @@
{
- // Curious where your @Scenario tests will run?
+ // Curious where your @Scenario tests are running?
//
// @Ignore: Will not run in any configuration
//
- // @FlakyTest: Tests that don't block pre/postsubmit but are staged to run known failures
+ // @FlakyTest: Tests that don't block pre/postsubmit but are staged to run known failures.
+ // Tests will run in postsubmit on sysui-e2e-staged suite.
//
- // @Postsubmit: Runs in platinum suite and blocks droidfood in postsubmit
//
- // @PlatinumTest: As of May, 2023, running in postsubmit. Set to run in presubmit as part of
- // v2/android-platinum/suite-test-mapping-platinum-sysui
- // Please DO NOT annotate new or old tests with @PlatinumTest annotation without discussing
- // with mdb:android-platinum
+ // @PlatinumTest: Marking your test with this annotation will put your tests in presubmit.
+ // Please DO NOT annotate new or old tests with @PlatinumTest annotation
+ // without discussing with mdb:android-platinum
//
- // As of May, 2023, If you don't use @Postsubmit, your new test will immediately
- // block presubmit, which is probably NOT what you want. This will change effectively once
- // we move to @PlatinumTest annotation.
+ // @Postsubmit: Do not use this annotation for e2e tests. This won't have any affect.
+
+ // For all other e2e tests which are not platinum, they run in sysui-silver suite,that
+ // primarily runs in postsubmit with an exception to e2e test related changes.
+ // If you want to see one shot place to monitor all e2e tests, look for
+ // sysui-e2e-staged suite.
- // v2/sysui/test-mapping-presubmit-sysui_cloud-tf
- "presubmit-sysui": [
- {
- "name": "PlatformScenarioTests",
- "options": [
- {
- "include-filter": "android.platform.test.scenario.sysui"
- },
- {
- "include-annotation": "android.platform.test.scenario.annotation.Scenario"
- },
- {
- "exclude-annotation": "org.junit.Ignore"
- },
- {
- "exclude-annotation": "android.platform.test.annotations.Postsubmit"
- },
- {
- "exclude-annotation": "android.platform.test.annotations.FlakyTest"
- },
- {
- "exclude-annotation": "androidx.test.filters.FlakyTest"
- }
- ]
- }
- ],
// v2/android-virtual-infra/test_mapping/presubmit-avd
"presubmit": [
{
@@ -138,31 +114,6 @@
]
}
],
- "silver-sysui": [
- {
- "name": "PlatformScenarioTests",
- "options": [
- {
- "include-filter": "android.platform.test.scenario.sysui"
- },
- {
- "include-annotation": "android.platform.test.scenario.annotation.Scenario"
- },
- {
- "exclude-annotation": "org.junit.Ignore"
- },
- {
- "exclude-annotation": "android.platform.test.annotations.PlatinumTest"
- },
- {
- "exclude-annotation": "android.platform.test.annotations.FlakyTest"
- },
- {
- "exclude-annotation": "androidx.test.filters.FlakyTest"
- }
- ]
- }
- ],
"postsubmit": [
{
"name": "SystemUIGoogleScreenshotTests",
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/ribbon/ui/composable/Ribbon.kt b/packages/SystemUI/compose/features/src/com/android/systemui/ribbon/ui/composable/Ribbon.kt
new file mode 100644
index 000000000000..daa15929b9ce
--- /dev/null
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/ribbon/ui/composable/Ribbon.kt
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.ribbon.ui.composable
+
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Box
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.graphicsLayer
+import androidx.compose.ui.layout.layout
+import com.android.compose.modifiers.thenIf
+import kotlin.math.PI
+import kotlin.math.cos
+import kotlin.math.roundToInt
+import kotlin.math.sin
+import kotlin.math.tan
+
+/**
+ * Renders a "ribbon" at the bottom right corner of its container.
+ *
+ * The [content] is rendered leaning at an angle of [degrees] degrees (between `1` and `89`,
+ * inclusive), with an alpha of [alpha] (between `0f` and `1f`, inclusive).
+ *
+ * The background color of the strip can be modified by passing a value to the [backgroundColor] or
+ * `null` to remove the strip background.
+ *
+ * Note: this function assumes that it's been placed at the bottom right of its parent by its
+ * caller. It's the caller's responsibility to meet that assumption by actually placing this
+ * composable element at the bottom right.
+ */
+@Composable
+fun BottomRightCornerRibbon(
+ content: @Composable () -> Unit,
+ modifier: Modifier = Modifier,
+ degrees: Int = 45,
+ alpha: Float = 0.6f,
+ backgroundColor: Color? = Color.Red,
+) {
+ check(degrees in 1..89)
+ check(alpha in 0f..1f)
+
+ val radians = degrees * (PI / 180)
+
+ Box(
+ content = { content() },
+ modifier =
+ modifier
+ .graphicsLayer {
+ this.alpha = alpha
+
+ val w = size.width
+ val h = size.height
+
+ val sine = sin(radians).toFloat()
+ val cosine = cos(radians).toFloat()
+
+ translationX = (w - w * cosine + h * sine) / 2f
+ translationY = (h - w * sine + h * cosine) / 2f
+ rotationZ = 360f - degrees
+ }
+ .thenIf(backgroundColor != null) { Modifier.background(backgroundColor!!) }
+ .layout { measurable, constraints ->
+ val placeable = measurable.measure(constraints)
+
+ val tangent = tan(radians)
+ val leftPadding = (placeable.measuredHeight / tangent).roundToInt()
+ val rightPadding = (placeable.measuredHeight * tangent).roundToInt()
+
+ layout(
+ width = placeable.measuredWidth + leftPadding + rightPadding,
+ height = placeable.measuredHeight,
+ ) {
+ placeable.place(leftPadding, 0)
+ }
+ }
+ )
+}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt
index 019287d8d500..6a5a368b3599 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt
@@ -18,14 +18,19 @@
package com.android.systemui.scene.ui.composable
+import android.os.SystemProperties
+import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
+import androidx.compose.ui.Alignment
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.pointer.PointerEventPass
import androidx.compose.ui.input.pointer.motionEventSpy
import androidx.compose.ui.input.pointer.pointerInput
@@ -37,6 +42,7 @@ import com.android.compose.animation.scene.SceneTransitionLayoutState
import com.android.compose.animation.scene.Swipe
import com.android.compose.animation.scene.UserAction as SceneTransitionUserAction
import com.android.compose.animation.scene.observableTransitionState
+import com.android.systemui.ribbon.ui.composable.BottomRightCornerRibbon
import com.android.systemui.scene.shared.model.Direction
import com.android.systemui.scene.shared.model.ObservableTransitionState
import com.android.systemui.scene.shared.model.SceneKey
@@ -75,53 +81,70 @@ fun SceneContainer(
val currentDestinations: Map<UserAction, SceneModel> by
currentScene.destinationScenes().collectAsState()
val state = remember { SceneTransitionLayoutState(currentSceneKey.toTransitionSceneKey()) }
+ val isRibbonEnabled = remember { SystemProperties.getBoolean("flexi.ribbon", false) }
DisposableEffect(viewModel, state) {
viewModel.setTransitionState(state.observableTransitionState().map { it.toModel() })
onDispose { viewModel.setTransitionState(null) }
}
- SceneTransitionLayout(
- currentScene = currentSceneKey.toTransitionSceneKey(),
- onChangeScene = viewModel::onSceneChanged,
- transitions = SceneContainerTransitions,
- state = state,
- modifier =
- modifier
- .fillMaxSize()
- .motionEventSpy { event -> viewModel.onMotionEvent(event) }
- .pointerInput(Unit) {
- awaitPointerEventScope {
- while (true) {
- awaitPointerEvent(PointerEventPass.Final)
- viewModel.onMotionEventComplete()
- }
- }
- }
+ Box(
+ modifier = Modifier.fillMaxSize(),
) {
- sceneByKey.forEach { (sceneKey, composableScene) ->
- scene(
- key = sceneKey.toTransitionSceneKey(),
- userActions =
- if (sceneKey == currentSceneKey) {
- currentDestinations
- } else {
- composableScene.destinationScenes().value
+ SceneTransitionLayout(
+ currentScene = currentSceneKey.toTransitionSceneKey(),
+ onChangeScene = viewModel::onSceneChanged,
+ transitions = SceneContainerTransitions,
+ state = state,
+ modifier =
+ modifier
+ .fillMaxSize()
+ .motionEventSpy { event -> viewModel.onMotionEvent(event) }
+ .pointerInput(Unit) {
+ awaitPointerEventScope {
+ while (true) {
+ awaitPointerEvent(PointerEventPass.Final)
+ viewModel.onMotionEventComplete()
+ }
}
- .map { (userAction, destinationSceneModel) ->
- toTransitionModels(userAction, destinationSceneModel)
- }
- .toMap(),
- ) {
- with(composableScene) {
- this@scene.Content(
- modifier =
- Modifier.element(sceneKey.toTransitionSceneKey().rootElementKey)
- .fillMaxSize(),
- )
+ }
+ ) {
+ sceneByKey.forEach { (sceneKey, composableScene) ->
+ scene(
+ key = sceneKey.toTransitionSceneKey(),
+ userActions =
+ if (sceneKey == currentSceneKey) {
+ currentDestinations
+ } else {
+ composableScene.destinationScenes().value
+ }
+ .map { (userAction, destinationSceneModel) ->
+ toTransitionModels(userAction, destinationSceneModel)
+ }
+ .toMap(),
+ ) {
+ with(composableScene) {
+ this@scene.Content(
+ modifier =
+ Modifier.element(sceneKey.toTransitionSceneKey().rootElementKey)
+ .fillMaxSize(),
+ )
+ }
}
}
}
+
+ if (isRibbonEnabled) {
+ BottomRightCornerRibbon(
+ content = {
+ Text(
+ text = "flexi\uD83E\uDD43",
+ color = Color.White,
+ )
+ },
+ modifier = Modifier.align(Alignment.BottomEnd),
+ )
+ }
}
}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/statusbar/phone/SystemUIDialogFactoryExt.kt b/packages/SystemUI/compose/features/src/com/android/systemui/statusbar/phone/SystemUIDialogFactoryExt.kt
index 5d6dd3b6bd01..23d3089d7be3 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/statusbar/phone/SystemUIDialogFactoryExt.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/statusbar/phone/SystemUIDialogFactoryExt.kt
@@ -48,10 +48,11 @@ import com.android.compose.theme.PlatformTheme
*/
fun SystemUIDialogFactory.create(
context: Context = this.applicationContext,
+ theme: Int = SystemUIDialog.DEFAULT_THEME,
dismissOnDeviceLock: Boolean = SystemUIDialog.DEFAULT_DISMISS_ON_DEVICE_LOCK,
content: @Composable (SystemUIDialog) -> Unit,
): ComponentSystemUIDialog {
- val dialog = create(context, dismissOnDeviceLock)
+ val dialog = create(context, theme, dismissOnDeviceLock)
// Create the dialog so that it is properly constructed before we set the Compose content.
// Otherwise, the ComposeView won't render properly.
diff --git a/packages/SystemUI/res/layout/media_projection_app_selector.xml b/packages/SystemUI/res/layout/media_projection_app_selector.xml
index e4749381243a..b77f78dfc644 100644
--- a/packages/SystemUI/res/layout/media_projection_app_selector.xml
+++ b/packages/SystemUI/res/layout/media_projection_app_selector.xml
@@ -20,10 +20,11 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
- androidprv:maxCollapsedHeight="0dp"
+ androidprv:maxCollapsedHeight="10000dp"
androidprv:maxCollapsedHeightSmall="56dp"
androidprv:maxWidth="@*android:dimen/chooser_width"
android:id="@*android:id/contentPanel">
+ <!-- maxCollapsedHeight above is huge, to make sure the layout is always expanded. -->
<LinearLayout
android:id="@*android:id/chooser_header"
diff --git a/packages/SystemUI/res/values/ids.xml b/packages/SystemUI/res/values/ids.xml
index d8c808054fff..e48901ee0bb5 100644
--- a/packages/SystemUI/res/values/ids.xml
+++ b/packages/SystemUI/res/values/ids.xml
@@ -207,13 +207,14 @@
<!-- keyboard backlight indicator-->
<item type="id" name="backlight_icon" />
+ <!-- IDs for use in the keyguard/lockscreen scene -->
<item type="id" name="keyguard_root_view" />
<item type="id" name="keyguard_indication_area" />
<item type="id" name="keyguard_indication_text" />
<item type="id" name="keyguard_indication_text_bottom" />
<item type="id" name="nssl_guideline" />
- <item type="id" name="nssl_top_barrier" />
- <item type="id" name="nssl_bottom_barrier" />
+ <item type="id" name="nssl_placeholder" />
+ <item type="id" name="aod_notification_icon_container" />
<item type="id" name="split_shade_guideline" />
<item type="id" name="lock_icon" />
<item type="id" name="lock_icon_bg" />
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
index d89796005e25..11f95895338a 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
@@ -18,7 +18,6 @@ package com.android.keyguard;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
-
import static com.android.keyguard.KeyguardClockSwitch.LARGE;
import static com.android.keyguard.KeyguardClockSwitch.SMALL;
import static com.android.systemui.flags.Flags.LOCKSCREEN_WALLPAPER_DREAM_ENABLED;
@@ -42,6 +41,7 @@ import com.android.systemui.R;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.flags.FeatureFlags;
+import com.android.systemui.flags.Flags;
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor;
import com.android.systemui.log.LogBuffer;
@@ -240,7 +240,9 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
View nic = mView.findViewById(
R.id.left_aligned_notification_icon_container);
- nic.setVisibility(View.GONE);
+ if (nic != null) {
+ nic.setVisibility(View.GONE);
+ }
}
@Override
@@ -307,7 +309,11 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
}
int getNotificationIconAreaHeight() {
- return mNotificationIconAreaController.getHeight();
+ if (mFeatureFlags.isEnabled(Flags.MIGRATE_KEYGUARD_STATUS_VIEW)) {
+ return 0;
+ } else {
+ return mNotificationIconAreaController.getHeight();
+ }
}
@Override
@@ -518,10 +524,12 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
}
private void updateAodIcons() {
- NotificationIconContainer nic = (NotificationIconContainer)
- mView.findViewById(
- com.android.systemui.R.id.left_aligned_notification_icon_container);
- mNotificationIconAreaController.setupAodIcons(nic);
+ if (!mFeatureFlags.isEnabled(Flags.MIGRATE_KEYGUARD_STATUS_VIEW)) {
+ NotificationIconContainer nic = (NotificationIconContainer)
+ mView.findViewById(
+ com.android.systemui.R.id.left_aligned_notification_icon_container);
+ mNotificationIconAreaController.setupAodIcons(nic);
+ }
}
private void setClock(ClockController clock) {
diff --git a/packages/SystemUI/src/com/android/systemui/display/ui/view/MirroringConfirmationDialog.kt b/packages/SystemUI/src/com/android/systemui/display/ui/view/MirroringConfirmationDialog.kt
index ecc9d0ef7810..f730935e1b73 100644
--- a/packages/SystemUI/src/com/android/systemui/display/ui/view/MirroringConfirmationDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/display/ui/view/MirroringConfirmationDialog.kt
@@ -34,7 +34,8 @@ class MirroringConfirmationDialog(
context: Context,
private val onStartMirroringClickListener: View.OnClickListener,
private val onCancelMirroring: View.OnClickListener,
-) : Dialog(context, R.style.Theme_SystemUI_Dialog) {
+ theme: Int = R.style.Theme_SystemUI_Dialog,
+) : Dialog(context, theme) {
private lateinit var mirrorButton: TextView
private lateinit var dismissButton: TextView
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
index 1e5fcbe17557..2cc07fd74b95 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
@@ -802,4 +802,8 @@ object Flags {
/** Enable haptic slider component in the brightness slider */
@JvmField
val HAPTIC_BRIGHTNESS_SLIDER = unreleasedFlag("haptic_brightness_slider")
+
+ // TODO(b/287205379): Tracking bug
+ @JvmField
+ val QS_CONTAINER_GRAPH_OPTIMIZER = unreleasedFlag( "qs_container_graph_optimizer")
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/backlight/ui/view/KeyboardBacklightDialog.kt b/packages/SystemUI/src/com/android/systemui/keyboard/backlight/ui/view/KeyboardBacklightDialog.kt
index b5b56b2b2108..6f25f7c1921a 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/backlight/ui/view/KeyboardBacklightDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/backlight/ui/view/KeyboardBacklightDialog.kt
@@ -44,7 +44,8 @@ class KeyboardBacklightDialog(
context: Context,
initialCurrentLevel: Int,
initialMaxLevel: Int,
-) : Dialog(context, R.style.Theme_SystemUI_Dialog) {
+ theme: Int = R.style.Theme_SystemUI_Dialog,
+) : Dialog(context, theme) {
private data class RootProperties(
val cornerRadius: Float,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt
index 8b0b0ae543a7..9503f2c75052 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt
@@ -177,14 +177,13 @@ object KeyguardRootViewBinder {
oldRight: Int,
oldBottom: Int
) {
- val ksv = v.findViewById(R.id.keyguard_status_view) as View?
- val lockIcon = v.findViewById(R.id.lock_icon_view) as View?
+ val nsslPlaceholder = v.findViewById(R.id.nssl_placeholder) as View?
- if (ksv != null && lockIcon != null) {
+ if (nsslPlaceholder != null) {
// After layout, ensure the notifications are positioned correctly
viewModel.onSharedNotificationContainerPositionChanged(
- ksv!!.top.toFloat() + ksv!!.height,
- lockIcon!!.y
+ nsslPlaceholder.top.toFloat(),
+ nsslPlaceholder.bottom.toFloat(),
)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/DefaultKeyguardBlueprint.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/DefaultKeyguardBlueprint.kt
index b0c969f54b82..15bb90915d94 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/DefaultKeyguardBlueprint.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/DefaultKeyguardBlueprint.kt
@@ -22,6 +22,7 @@ import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags
import com.android.systemui.keyguard.shared.model.KeyguardBlueprint
+import com.android.systemui.keyguard.ui.view.layout.sections.AodNotificationIconsSection
import com.android.systemui.keyguard.ui.view.layout.sections.DefaultAmbientIndicationAreaSection
import com.android.systemui.keyguard.ui.view.layout.sections.DefaultIndicationAreaSection
import com.android.systemui.keyguard.ui.view.layout.sections.DefaultLockIconSection
@@ -50,6 +51,7 @@ constructor(
defaultStatusViewSection: DefaultStatusViewSection,
defaultNotificationStackScrollLayoutSection: DefaultNotificationStackScrollLayoutSection,
splitShadeGuidelines: SplitShadeGuidelines,
+ aodNotificationIconsSection: AodNotificationIconsSection,
private val featureFlags: FeatureFlags,
) : KeyguardBlueprint {
override val id: String = DEFAULT
@@ -64,6 +66,7 @@ constructor(
defaultStatusViewSection,
defaultNotificationStackScrollLayoutSection,
splitShadeGuidelines,
+ aodNotificationIconsSection,
)
override fun replaceViews(
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/ShortcutsBesideUdfpsKeyguardBlueprint.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/ShortcutsBesideUdfpsKeyguardBlueprint.kt
index bb3af6cc86a2..79a97fbd19df 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/ShortcutsBesideUdfpsKeyguardBlueprint.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/ShortcutsBesideUdfpsKeyguardBlueprint.kt
@@ -20,6 +20,7 @@ package com.android.systemui.keyguard.ui.view.layout.blueprints
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.keyguard.shared.model.KeyguardBlueprint
import com.android.systemui.keyguard.ui.view.layout.sections.AlignShortcutsToUdfpsSection
+import com.android.systemui.keyguard.ui.view.layout.sections.AodNotificationIconsSection
import com.android.systemui.keyguard.ui.view.layout.sections.DefaultAmbientIndicationAreaSection
import com.android.systemui.keyguard.ui.view.layout.sections.DefaultIndicationAreaSection
import com.android.systemui.keyguard.ui.view.layout.sections.DefaultLockIconSection
@@ -42,6 +43,7 @@ constructor(
defaultStatusViewSection: DefaultStatusViewSection,
splitShadeGuidelines: SplitShadeGuidelines,
defaultNotificationStackScrollLayoutSection: DefaultNotificationStackScrollLayoutSection,
+ aodNotificationIconsSection: AodNotificationIconsSection,
) : KeyguardBlueprint {
override val id: String = SHORTCUTS_BESIDE_UDFPS
@@ -55,6 +57,7 @@ constructor(
defaultStatusViewSection,
defaultNotificationStackScrollLayoutSection,
splitShadeGuidelines,
+ aodNotificationIconsSection,
)
companion object {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AodNotificationIconsSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AodNotificationIconsSection.kt
new file mode 100644
index 000000000000..ac11ba5b5ec6
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AodNotificationIconsSection.kt
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.android.systemui.keyguard.ui.view.layout.sections
+
+import android.content.Context
+import android.view.View
+import androidx.constraintlayout.widget.ConstraintLayout
+import androidx.constraintlayout.widget.ConstraintSet
+import androidx.constraintlayout.widget.ConstraintSet.BOTTOM
+import androidx.constraintlayout.widget.ConstraintSet.END
+import androidx.constraintlayout.widget.ConstraintSet.PARENT_ID
+import androidx.constraintlayout.widget.ConstraintSet.START
+import androidx.constraintlayout.widget.ConstraintSet.TOP
+import com.android.systemui.R
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags
+import com.android.systemui.keyguard.shared.model.KeyguardSection
+import com.android.systemui.shade.NotificationPanelView
+import com.android.systemui.statusbar.phone.NotificationIconAreaController
+import com.android.systemui.statusbar.phone.NotificationIconContainer
+import javax.inject.Inject
+
+class AodNotificationIconsSection
+@Inject
+constructor(
+ private val context: Context,
+ private val featureFlags: FeatureFlags,
+ private val notificationPanelView: NotificationPanelView,
+ private val notificationIconAreaController: NotificationIconAreaController,
+) : KeyguardSection() {
+ private val nicId = R.id.aod_notification_icon_container
+ private lateinit var nic: NotificationIconContainer
+
+ override fun addViews(constraintLayout: ConstraintLayout) {
+ if (!featureFlags.isEnabled(Flags.MIGRATE_KEYGUARD_STATUS_VIEW)) {
+ return
+ }
+ nic =
+ NotificationIconContainer(context, null).apply {
+ id = nicId
+ setPaddingRelative(
+ resources.getDimensionPixelSize(R.dimen.below_clock_padding_start_icons),
+ 0,
+ 0,
+ 0
+ )
+ setVisibility(View.INVISIBLE)
+ }
+
+ constraintLayout.addView(nic)
+ }
+
+ override fun bindData(constraintLayout: ConstraintLayout) {
+ if (!featureFlags.isEnabled(Flags.MIGRATE_KEYGUARD_STATUS_VIEW)) {
+ return
+ }
+
+ notificationIconAreaController.setupAodIcons(nic)
+ }
+
+ override fun applyConstraints(constraintSet: ConstraintSet) {
+ if (!featureFlags.isEnabled(Flags.MIGRATE_KEYGUARD_STATUS_VIEW)) {
+ return
+ }
+ val bottomMargin =
+ context.resources.getDimensionPixelSize(R.dimen.keyguard_status_view_bottom_margin)
+
+ val useSplitShade = context.resources.getBoolean(R.bool.config_use_split_notification_shade)
+
+ val topAlignment =
+ if (useSplitShade) {
+ TOP
+ } else {
+ BOTTOM
+ }
+
+ constraintSet.apply {
+ connect(nicId, TOP, R.id.keyguard_status_view, topAlignment, bottomMargin)
+ connect(nicId, START, PARENT_ID, START)
+ connect(nicId, END, PARENT_ID, END)
+ constrainHeight(
+ nicId,
+ context.resources.getDimensionPixelSize(R.dimen.notification_shelf_height)
+ )
+ }
+ }
+
+ override fun removeViews(constraintLayout: ConstraintLayout) {
+ constraintLayout.removeView(nicId)
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultLockIconSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultLockIconSection.kt
index 3e91d9336b13..9c6e953ad2d5 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultLockIconSection.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultLockIconSection.kt
@@ -54,15 +54,15 @@ constructor(
if (!featureFlags.isEnabled(Flags.MIGRATE_LOCK_ICON)) {
return
}
- notificationPanelView.findViewById<View>(R.id.lock_icon_view).let {
+ notificationPanelView.findViewById<View>(lockIconViewId).let {
notificationPanelView.removeView(it)
}
- val view = LockIconView(context, null).apply { id = R.id.lock_icon_view }
+ val view = LockIconView(context, null).apply { id = lockIconViewId }
constraintLayout.addView(view)
}
override fun bindData(constraintLayout: ConstraintLayout) {
- constraintLayout.findViewById<LockIconView?>(R.id.lock_icon_view)?.let {
+ constraintLayout.findViewById<LockIconView?>(lockIconViewId)?.let {
lockIconViewController.setLockIconView(it)
}
}
@@ -97,7 +97,7 @@ constructor(
}
override fun removeViews(constraintLayout: ConstraintLayout) {
- constraintLayout.removeView(R.id.lock_icon_view)
+ constraintLayout.removeView(lockIconViewId)
}
@VisibleForTesting
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultNotificationStackScrollLayoutSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultNotificationStackScrollLayoutSection.kt
index 59c5d78bfce8..7fff43b82e93 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultNotificationStackScrollLayoutSection.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultNotificationStackScrollLayoutSection.kt
@@ -17,10 +17,16 @@
package com.android.systemui.keyguard.ui.view.layout.sections
+import android.content.Context
import android.view.View
import android.view.ViewGroup
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.ConstraintSet
+import androidx.constraintlayout.widget.ConstraintSet.BOTTOM
+import androidx.constraintlayout.widget.ConstraintSet.END
+import androidx.constraintlayout.widget.ConstraintSet.PARENT_ID
+import androidx.constraintlayout.widget.ConstraintSet.START
+import androidx.constraintlayout.widget.ConstraintSet.TOP
import com.android.systemui.R
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags
@@ -35,12 +41,15 @@ import javax.inject.Inject
class DefaultNotificationStackScrollLayoutSection
@Inject
constructor(
+ private val context: Context,
private val featureFlags: FeatureFlags,
private val notificationPanelView: NotificationPanelView,
private val sharedNotificationContainer: SharedNotificationContainer,
private val sharedNotificationContainerViewModel: SharedNotificationContainerViewModel,
private val controller: NotificationStackScrollLayoutController,
) : KeyguardSection() {
+ private val placeHolderId = R.id.nssl_placeholder
+
override fun addViews(constraintLayout: ConstraintLayout) {
if (!featureFlags.isEnabled(Flags.MIGRATE_NSSL)) {
return
@@ -51,19 +60,52 @@ constructor(
(it.parent as ViewGroup).removeView(it)
sharedNotificationContainer.addNotificationStackScrollLayout(it)
}
+
+ val view = View(context, null).apply { id = placeHolderId }
+ constraintLayout.addView(view)
}
override fun bindData(constraintLayout: ConstraintLayout) {
- if (featureFlags.isEnabled(Flags.MIGRATE_NSSL)) {
- SharedNotificationContainerBinder.bind(
- sharedNotificationContainer,
- sharedNotificationContainerViewModel,
- controller,
- )
+ if (!featureFlags.isEnabled(Flags.MIGRATE_NSSL)) {
+ return
}
+ SharedNotificationContainerBinder.bind(
+ sharedNotificationContainer,
+ sharedNotificationContainerViewModel,
+ controller,
+ )
}
- override fun applyConstraints(constraintSet: ConstraintSet) {}
+ override fun applyConstraints(constraintSet: ConstraintSet) {
+ if (!featureFlags.isEnabled(Flags.MIGRATE_NSSL)) {
+ return
+ }
+ constraintSet.apply {
+ val bottomMargin =
+ context.resources.getDimensionPixelSize(R.dimen.keyguard_status_view_bottom_margin)
+ val useSplitShade =
+ context.resources.getBoolean(R.bool.config_use_split_notification_shade)
+
+ val topAlignment =
+ if (useSplitShade) {
+ TOP
+ } else {
+ BOTTOM
+ }
+ connect(
+ R.id.nssl_placeholder,
+ TOP,
+ R.id.keyguard_status_view,
+ topAlignment,
+ bottomMargin
+ )
+ connect(R.id.nssl_placeholder, START, PARENT_ID, START)
+ connect(R.id.nssl_placeholder, END, PARENT_ID, END)
+ connect(R.id.nssl_placeholder, BOTTOM, R.id.lock_icon_view, TOP)
+ }
+ }
- override fun removeViews(constraintLayout: ConstraintLayout) {}
+ override fun removeViews(constraintLayout: ConstraintLayout) {
+ constraintLayout.removeView(placeHolderId)
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultStatusViewSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultStatusViewSection.kt
index b144f7ae6906..b1dd373a7657 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultStatusViewSection.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultStatusViewSection.kt
@@ -72,6 +72,11 @@ constructor(
.inflate(R.layout.keyguard_status_view, constraintLayout, false)
as KeyguardStatusView)
.apply { clipChildren = false }
+
+ // This is diassembled and moved to [AodNotificationIconsSection]
+ keyguardStatusView.findViewById<View>(R.id.left_aligned_notification_icon_container)?.let {
+ it.setVisibility(View.GONE)
+ }
constraintLayout.addView(keyguardStatusView)
}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java
index 4a76dd0df47b..2dbcbc9e0f22 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java
@@ -40,6 +40,7 @@ import android.view.IWindow;
import android.view.IWindowSession;
import android.view.View;
import android.view.ViewGroup;
+import android.view.WindowInsets;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
import android.view.WindowManagerGlobal;
@@ -409,9 +410,9 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW
private void applyForceShowNavigationFlag(NotificationShadeWindowState state) {
if (state.panelExpanded || state.bouncerShowing
|| ENABLE_REMOTE_INPUT && state.remoteInputActive) {
- mLpChanged.privateFlags |= LayoutParams.PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION;
+ mLpChanged.forciblyShownTypes |= WindowInsets.Type.navigationBars();
} else {
- mLpChanged.privateFlags &= ~LayoutParams.PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION;
+ mLpChanged.forciblyShownTypes &= ~WindowInsets.Type.navigationBars();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/RemoteInputController.java b/packages/SystemUI/src/com/android/systemui/statusbar/RemoteInputController.java
index ac8001058ef6..d5e4902366e7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/RemoteInputController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/RemoteInputController.java
@@ -102,18 +102,21 @@ public class RemoteInputController {
mLogger.logRemoveRemoteInput(
entry.getKey() /* entryKey*/,
true /* remoteEditImeVisible */,
- true /* remoteEditImeAnimatingAway */);
+ true /* remoteEditImeAnimatingAway */,
+ isRemoteInputActive(entry) /* isRemoteInputActiveForEntry */,
+ isRemoteInputActive() /* isRemoteInputActive */);
return;
}
// If the view is being removed, this may be called even though we're not active
- boolean remoteInputActive = isRemoteInputActive(entry);
+ boolean remoteInputActiveForEntry = isRemoteInputActive(entry);
mLogger.logRemoveRemoteInput(
- entry.getKey() /* entryKey*/,
+ entry.getKey() /* entryKey */,
entry.mRemoteEditImeVisible /* remoteEditImeVisible */,
entry.mRemoteEditImeAnimatingAway /* remoteEditImeAnimatingAway */,
- remoteInputActive /* isRemoteInputActive */);
+ remoteInputActiveForEntry /* isRemoteInputActiveForEntry */,
+ isRemoteInputActive()/* isRemoteInputActive */);
- if (!remoteInputActive) return;
+ if (!remoteInputActiveForEntry) return;
pruneWeakThenRemoveAndContains(null /* contains */, entry /* remove */, token);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/RemoteInputControllerLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/RemoteInputControllerLogger.kt
index 7809eaafe0b3..39b999cb4f35 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/RemoteInputControllerLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/RemoteInputControllerLogger.kt
@@ -51,7 +51,8 @@ constructor(@NotificationRemoteInputLog private val logBuffer: LogBuffer) {
entryKey: String,
remoteEditImeVisible: Boolean,
remoteEditImeAnimatingAway: Boolean,
- isRemoteInputActive: Boolean? = null
+ isRemoteInputActiveForEntry: Boolean,
+ isRemoteInputActive: Boolean
) =
logBuffer.log(
TAG,
@@ -60,11 +61,13 @@ constructor(@NotificationRemoteInputLog private val logBuffer: LogBuffer) {
str1 = entryKey
bool1 = remoteEditImeVisible
bool2 = remoteEditImeAnimatingAway
- str2 = isRemoteInputActive?.toString() ?: "N/A"
+ bool3 = isRemoteInputActiveForEntry
+ bool4 = isRemoteInputActive
},
{
"removeRemoteInput entry: $str1, remoteEditImeVisible: $bool1" +
- ", remoteEditImeAnimatingAway: $bool2, isActive: $str2"
+ ", remoteEditImeAnimatingAway: $bool2, isRemoteInputActiveForEntry: $bool3" +
+ ", isRemoteInputActive: $bool4"
}
)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
index b797c6339a34..b45a688e6760 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
@@ -2680,6 +2680,7 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
&& mStatusBarStateController.getDozeAmount() == 1f
&& mWakefulnessLifecycle.getLastWakeReason()
== PowerManager.WAKE_REASON_POWER_BUTTON
+ && mFingerprintManager.get() != null
&& mFingerprintManager.get().isPowerbuttonFps()
&& mKeyguardUpdateMonitor
.getCachedIsUnlockWithFingerprintPossible(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialogFactory.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialogFactory.kt
index 3b150656efc5..d91ca92747f3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialogFactory.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialogFactory.kt
@@ -48,13 +48,14 @@ constructor(
*/
fun create(
context: Context = this.applicationContext,
+ theme: Int = SystemUIDialog.DEFAULT_THEME,
dismissOnDeviceLock: Boolean = SystemUIDialog.DEFAULT_DISMISS_ON_DEVICE_LOCK,
): ComponentSystemUIDialog {
Assert.isMainThread()
return ComponentSystemUIDialog(
context,
- SystemUIDialog.DEFAULT_THEME,
+ theme,
dismissOnDeviceLock,
featureFlags,
dialogManager,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowController.java
index 24987abd7a85..f4cc0ed30781 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowController.java
@@ -21,7 +21,6 @@ import static android.view.WindowInsets.Type.statusBars;
import static android.view.WindowInsets.Type.tappableElement;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_COLOR_SPACE_AGNOSTIC;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR;
import static com.android.systemui.util.leak.RotationUtils.ROTATION_LANDSCAPE;
import static com.android.systemui.util.leak.RotationUtils.ROTATION_NONE;
@@ -44,6 +43,7 @@ import android.view.InsetsFrameProvider;
import android.view.Surface;
import android.view.View;
import android.view.ViewGroup;
+import android.view.WindowInsets;
import android.view.WindowManager;
import com.android.internal.policy.SystemBarUtils;
@@ -361,9 +361,9 @@ public class StatusBarWindowController {
|| state.mIsLaunchAnimationRunning
// Don't force-show the status bar if the user has already dismissed it.
|| state.mOngoingProcessRequiresStatusBarVisible) {
- mLpChanged.privateFlags |= PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR;
+ mLpChanged.forciblyShownTypes |= WindowInsets.Type.statusBars();
} else {
- mLpChanged.privateFlags &= ~PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR;
+ mLpChanged.forciblyShownTypes &= ~WindowInsets.Type.statusBars();
}
}
}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerBaseTest.java
index 1be87463250f..3d8719656a1e 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerBaseTest.java
@@ -20,6 +20,7 @@ import static android.view.View.INVISIBLE;
import static com.android.systemui.flags.Flags.FACE_AUTH_REFACTOR;
import static com.android.systemui.flags.Flags.LOCKSCREEN_WALLPAPER_DREAM_ENABLED;
+import static com.android.systemui.flags.Flags.MIGRATE_KEYGUARD_STATUS_VIEW;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.atLeast;
@@ -165,6 +166,7 @@ public class KeyguardClockSwitchControllerBaseTest extends SysuiTestCase {
mFakeFeatureFlags = new FakeFeatureFlags();
mFakeFeatureFlags.set(FACE_AUTH_REFACTOR, false);
mFakeFeatureFlags.set(LOCKSCREEN_WALLPAPER_DREAM_ENABLED, false);
+ mFakeFeatureFlags.set(MIGRATE_KEYGUARD_STATUS_VIEW, false);
mController = new KeyguardClockSwitchController(
mView,
mStatusBarStateController,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/blueprints/DefaultKeyguardBlueprintTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/blueprints/DefaultKeyguardBlueprintTest.kt
index 41ba1f422d92..681fce822342 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/blueprints/DefaultKeyguardBlueprintTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/blueprints/DefaultKeyguardBlueprintTest.kt
@@ -28,6 +28,7 @@ import com.android.systemui.flags.Flags
import com.android.systemui.keyguard.shared.model.KeyguardBlueprint
import com.android.systemui.keyguard.shared.model.KeyguardSection
import com.android.systemui.keyguard.ui.view.KeyguardRootView
+import com.android.systemui.keyguard.ui.view.layout.sections.AodNotificationIconsSection
import com.android.systemui.keyguard.ui.view.layout.sections.DefaultAmbientIndicationAreaSection
import com.android.systemui.keyguard.ui.view.layout.sections.DefaultIndicationAreaSection
import com.android.systemui.keyguard.ui.view.layout.sections.DefaultLockIconSection
@@ -61,6 +62,8 @@ class DefaultKeyguardBlueprintTest : SysuiTestCase() {
@Mock private lateinit var defaultStatusViewSection: DefaultStatusViewSection
@Mock private lateinit var defaultNSSLSection: DefaultNotificationStackScrollLayoutSection
@Mock private lateinit var splitShadeGuidelines: SplitShadeGuidelines
+ @Mock private lateinit var aodNotificationIconsSection: AodNotificationIconsSection
+
private val featureFlags = FakeFeatureFlags()
@Before
@@ -77,6 +80,7 @@ class DefaultKeyguardBlueprintTest : SysuiTestCase() {
defaultStatusViewSection,
defaultNSSLSection,
splitShadeGuidelines,
+ aodNotificationIconsSection,
featureFlags,
)
featureFlags.set(Flags.LAZY_INFLATE_KEYGUARD, false)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
index 137566bf1a2a..bd3fb9f1cae3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
@@ -399,7 +399,6 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
when(mGradientColors.supportsDarkText()).thenReturn(true);
when(mColorExtractor.getNeutralColors()).thenReturn(mGradientColors);
- ConfigurationController configurationController = new ConfigurationControllerImpl(mContext);
when(mLockscreenWallpaperLazy.get()).thenReturn(mLockscreenWallpaper);
when(mBiometricUnlockControllerLazy.get()).thenReturn(mBiometricUnlockController);
@@ -438,6 +437,11 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
when(mUserTracker.getUserHandle()).thenReturn(
UserHandle.of(ActivityManager.getCurrentUser()));
+ createCentralSurfaces();
+ }
+
+ private void createCentralSurfaces() {
+ ConfigurationController configurationController = new ConfigurationControllerImpl(mContext);
mCentralSurfaces = new CentralSurfacesImpl(
mContext,
mNotificationsController,
@@ -1083,6 +1087,27 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
verify(mNotificationPanelViewController).setTouchAndAnimationDisabled(true);
}
+ /** Regression test for b/298355063 */
+ @Test
+ public void fingerprintManagerNull_noNPE() {
+ // GIVEN null fingerprint manager
+ mFingerprintManager = null;
+ createCentralSurfaces();
+
+ // GIVEN should animate doze wakeup
+ when(mDozeServiceHost.shouldAnimateWakeup()).thenReturn(true);
+ when(mBiometricUnlockController.getMode()).thenReturn(
+ BiometricUnlockController.MODE_ONLY_WAKE);
+ when(mDozeServiceHost.isPulsing()).thenReturn(false);
+ when(mStatusBarStateController.getDozeAmount()).thenReturn(1f);
+
+ // WHEN waking up from the power button
+ mWakefulnessLifecycle.dispatchStartedWakingUp(PowerManager.WAKE_REASON_POWER_BUTTON);
+ mCentralSurfaces.mWakefulnessObserver.onStartedWakingUp();
+
+ // THEN no NPE when fingerprintManager is null
+ }
+
/**
* Configures the appropriate mocks and then calls {@link CentralSurfacesImpl#updateIsKeyguard}
* to reconfigure the keyguard to reflect the requested showing/occluded states.
diff --git a/services/accessibility/Android.bp b/services/accessibility/Android.bp
index bf8a9af99076..e9bb763e143a 100644
--- a/services/accessibility/Android.bp
+++ b/services/accessibility/Android.bp
@@ -27,4 +27,20 @@ java_library_static {
"services.core",
"androidx.annotation_annotation",
],
+ static_libs: [
+ "com_android_server_accessibility_flags_lib",
+ ],
+}
+
+aconfig_declarations {
+ name: "com_android_server_accessibility_flags",
+ package: "com.android.server.accessibility",
+ srcs: [
+ "accessibility.aconfig",
+ ],
+}
+
+java_aconfig_library {
+ name: "com_android_server_accessibility_flags_lib",
+ aconfig_declarations: "com_android_server_accessibility_flags",
}
diff --git a/services/accessibility/accessibility.aconfig b/services/accessibility/accessibility.aconfig
new file mode 100644
index 000000000000..b5fc2b6be22d
--- /dev/null
+++ b/services/accessibility/accessibility.aconfig
@@ -0,0 +1,7 @@
+package: "com.android.server.accessibility"
+flag {
+ name: "proxy_use_apps_on_virtual_device_listener"
+ namespace: "accessibility"
+ description: "Fixes race condition described in b/286587811"
+ bug: "286587811"
+}
diff --git a/services/accessibility/java/com/android/server/accessibility/ProxyManager.java b/services/accessibility/java/com/android/server/accessibility/ProxyManager.java
index 119f575011d8..ed77476a2295 100644
--- a/services/accessibility/java/com/android/server/accessibility/ProxyManager.java
+++ b/services/accessibility/java/com/android/server/accessibility/ProxyManager.java
@@ -33,6 +33,7 @@ import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
+import android.util.ArraySet;
import android.util.IntArray;
import android.util.Slog;
import android.util.SparseArray;
@@ -42,6 +43,7 @@ import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.IAccessibilityManagerClient;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.IntPair;
import com.android.server.LocalServices;
import com.android.server.companion.virtual.VirtualDeviceManagerInternal;
@@ -96,6 +98,9 @@ public class ProxyManager {
private final SystemSupport mSystemSupport;
+ private VirtualDeviceManagerInternal.AppsOnVirtualDeviceListener
+ mAppsOnVirtualDeviceListener;
+
/**
* Callbacks into AccessibilityManagerService.
*/
@@ -174,6 +179,16 @@ public class ProxyManager {
synchronized (mLock) {
mProxyA11yServiceConnections.put(displayId, connection);
+ if (Flags.proxyUseAppsOnVirtualDeviceListener()) {
+ if (mAppsOnVirtualDeviceListener == null) {
+ mAppsOnVirtualDeviceListener = allRunningUids ->
+ notifyProxyOfRunningAppsChange(allRunningUids);
+ final VirtualDeviceManagerInternal localVdm = getLocalVdm();
+ if (localVdm != null) {
+ localVdm.registerAppsOnVirtualDeviceListener(mAppsOnVirtualDeviceListener);
+ }
+ }
+ }
}
// If the client dies, make sure to remove the connection.
@@ -276,11 +291,21 @@ public class ProxyManager {
}
}
});
- // If there isn't an existing proxy for the device id, reset clients. Resetting
+ // If there isn't an existing proxy for the device id, reset app clients. Resetting
// will usually happen, since in most cases there will only be one proxy for a
// device.
if (!isProxyedDeviceId(deviceId)) {
synchronized (mLock) {
+ if (Flags.proxyUseAppsOnVirtualDeviceListener()) {
+ if (mProxyA11yServiceConnections.size() == 0) {
+ final VirtualDeviceManagerInternal localVdm = getLocalVdm();
+ if (localVdm != null && mAppsOnVirtualDeviceListener != null) {
+ localVdm.unregisterAppsOnVirtualDeviceListener(
+ mAppsOnVirtualDeviceListener);
+ mAppsOnVirtualDeviceListener = null;
+ }
+ }
+ }
mSystemSupport.removeDeviceIdLocked(deviceId);
mLastStates.delete(deviceId);
}
@@ -307,7 +332,7 @@ public class ProxyManager {
* Returns {@code true} if {@code deviceId} is being proxy-ed.
*/
public boolean isProxyedDeviceId(int deviceId) {
- if (deviceId == DEVICE_ID_DEFAULT && deviceId == DEVICE_ID_INVALID) {
+ if (deviceId == DEVICE_ID_DEFAULT || deviceId == DEVICE_ID_INVALID) {
return false;
}
boolean isTrackingDeviceId;
@@ -566,7 +591,7 @@ public class ProxyManager {
* This is similar to onUserStateChangeLocked and onClientChangeLocked, but does not require an
* A11yUserState and only checks proxy-relevant settings.
*/
- public void onProxyChanged(int deviceId) {
+ private void onProxyChanged(int deviceId, boolean forceUpdate) {
if (DEBUG) {
Slog.v(LOG_TAG, "onProxyChanged called for deviceId: " + deviceId);
}
@@ -584,7 +609,7 @@ public class ProxyManager {
// Calls A11yManager#setRelevantEventTypes (test these)
updateRelevantEventTypesLocked(deviceId);
// Calls A11yManager#setState
- scheduleUpdateProxyClientsIfNeededLocked(deviceId);
+ scheduleUpdateProxyClientsIfNeededLocked(deviceId, forceUpdate);
//Calls A11yManager#notifyServicesStateChanged(timeout)
scheduleNotifyProxyClientsOfServicesStateChangeLocked(deviceId);
// Calls A11yManager#setFocusAppearance
@@ -594,16 +619,25 @@ public class ProxyManager {
}
/**
+ * Handles proxy changes, but does not force an update of app clients.
+ */
+ public void onProxyChanged(int deviceId) {
+ onProxyChanged(deviceId, false);
+ }
+
+ /**
* Updates the states of the app AccessibilityManagers.
*/
- private void scheduleUpdateProxyClientsIfNeededLocked(int deviceId) {
+ private void scheduleUpdateProxyClientsIfNeededLocked(int deviceId, boolean forceUpdate) {
final int proxyState = getStateLocked(deviceId);
if (DEBUG) {
Slog.v(LOG_TAG, "State for device id " + deviceId + " is " + proxyState);
Slog.v(LOG_TAG, "Last state for device id " + deviceId + " is "
+ getLastSentStateLocked(deviceId));
+ Slog.v(LOG_TAG, "force update: " + forceUpdate);
}
- if ((getLastSentStateLocked(deviceId)) != proxyState) {
+ if ((getLastSentStateLocked(deviceId)) != proxyState
+ || (Flags.proxyUseAppsOnVirtualDeviceListener() && forceUpdate)) {
setLastStateLocked(deviceId, proxyState);
mMainHandler.post(() -> {
synchronized (mLock) {
@@ -792,7 +826,7 @@ public class ProxyManager {
}
/**
- * Updates the device ids of IAccessibilityManagerClients if needed.
+ * Updates the device ids of IAccessibilityManagerClients if needed after a proxy change.
*/
private void updateDeviceIdsIfNeededLocked(int deviceId,
@NonNull RemoteCallbackList<IAccessibilityManagerClient> clients) {
@@ -804,13 +838,66 @@ public class ProxyManager {
for (int i = 0; i < clients.getRegisteredCallbackCount(); i++) {
final AccessibilityManagerService.Client client =
((AccessibilityManagerService.Client) clients.getRegisteredCallbackCookie(i));
- if (deviceId != DEVICE_ID_DEFAULT && deviceId != DEVICE_ID_INVALID
+ if (Flags.proxyUseAppsOnVirtualDeviceListener()) {
+ if (deviceId == DEVICE_ID_DEFAULT || deviceId == DEVICE_ID_INVALID) {
+ continue;
+ }
+ boolean uidBelongsToDevice =
+ localVdm.getDeviceIdsForUid(client.mUid).contains(deviceId);
+ if (client.mDeviceId != deviceId && uidBelongsToDevice) {
+ if (DEBUG) {
+ Slog.v(LOG_TAG, "Packages moved to device id " + deviceId + " are "
+ + Arrays.toString(client.mPackageNames));
+ }
+ client.mDeviceId = deviceId;
+ } else if (client.mDeviceId == deviceId && !uidBelongsToDevice) {
+ client.mDeviceId = DEVICE_ID_DEFAULT;
+ if (DEBUG) {
+ Slog.v(LOG_TAG, "Packages moved to the default device from device id "
+ + deviceId + " are " + Arrays.toString(client.mPackageNames));
+ }
+ }
+ } else {
+ if (deviceId != DEVICE_ID_DEFAULT && deviceId != DEVICE_ID_INVALID
&& localVdm.getDeviceIdsForUid(client.mUid).contains(deviceId)) {
- if (DEBUG) {
- Slog.v(LOG_TAG, "Packages moved to device id " + deviceId + " are "
- + Arrays.toString(client.mPackageNames));
+ if (DEBUG) {
+ Slog.v(LOG_TAG, "Packages moved to device id " + deviceId + " are "
+ + Arrays.toString(client.mPackageNames));
+ }
+ client.mDeviceId = deviceId;
}
- client.mDeviceId = deviceId;
+ }
+ }
+ }
+
+ @VisibleForTesting
+ void notifyProxyOfRunningAppsChange(Set<Integer> allRunningUids) {
+ if (DEBUG) {
+ Slog.v(LOG_TAG, "notifyProxyOfRunningAppsChange: " + allRunningUids);
+ }
+ synchronized (mLock) {
+ if (mProxyA11yServiceConnections.size() == 0) {
+ return;
+ }
+ final VirtualDeviceManagerInternal localVdm = getLocalVdm();
+ if (localVdm == null) {
+ return;
+ }
+ final ArraySet<Integer> deviceIdsToUpdate = new ArraySet<>();
+ for (int i = 0; i < mProxyA11yServiceConnections.size(); i++) {
+ final ProxyAccessibilityServiceConnection proxy =
+ mProxyA11yServiceConnections.valueAt(i);
+ if (proxy != null) {
+ final int proxyDeviceId = proxy.getDeviceId();
+ for (Integer uid : allRunningUids) {
+ if (localVdm.getDeviceIdsForUid(uid).contains(proxyDeviceId)) {
+ deviceIdsToUpdate.add(proxyDeviceId);
+ }
+ }
+ }
+ }
+ for (Integer proxyDeviceId : deviceIdsToUpdate) {
+ onProxyChanged(proxyDeviceId, true);
}
}
}
@@ -843,6 +930,11 @@ public class ProxyManager {
return mLocalVdm;
}
+ @VisibleForTesting
+ void setLocalVirtualDeviceManager(VirtualDeviceManagerInternal localVdm) {
+ mLocalVdm = localVdm;
+ }
+
/**
* Prints information belonging to each display that is controlled by an
* AccessibilityDisplayProxy.
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceShellCommand.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceShellCommand.java
index 39756dfee7bf..cae047ff0624 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceShellCommand.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceShellCommand.java
@@ -18,7 +18,6 @@ package com.android.server.autofill;
import static android.service.autofill.AutofillFieldClassificationService.EXTRA_SCORES;
import static android.service.autofill.AutofillService.EXTRA_RESULT;
-
import static com.android.server.autofill.AutofillManagerService.RECEIVER_BUNDLE_EXTRA_SESSIONS;
import android.os.Bundle;
@@ -155,20 +154,31 @@ public final class AutofillManagerServiceShellCommand extends ShellCommand {
pw.println("");
}
+ Method[] flagMethods = {};
+
try {
- Method[] flagMethods = Flags.class.getMethods();
- // For some reason, unreferenced flags do not show up here
- // Maybe compiler optomized them out of bytecode?
- for (Method method : flagMethods) {
- if (Modifier.isPublic(method.getModifiers())) {
- pw.println(method.getName() + ": " + method.invoke(null));
- }
- }
- } catch (Exception ex) {
- pw.println(ex);
+ flagMethods = Flags.class.getDeclaredMethods();
+ } catch (SecurityException ex) {
+ ex.printStackTrace(pw);
return -1;
}
+ // For some reason, unreferenced flags do not show up here
+ // Maybe compiler optomized them out of bytecode?
+ for (Method method : flagMethods) {
+ if (!Modifier.isPublic(method.getModifiers())) {
+ continue;
+ }
+ try {
+ pw.print(method.getName() + ": ");
+ pw.print(method.invoke(null));
+ } catch (Exception ex) {
+ ex.printStackTrace(pw);
+ } finally {
+ pw.println("");
+ }
+ }
+
return 0;
}
diff --git a/services/core/Android.bp b/services/core/Android.bp
index 7329f1afb275..b941aaf32853 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -180,7 +180,6 @@ java_library_static {
"android.hardware.rebootescrow-V1-java",
"android.hardware.power.stats-V2-java",
"android.hidl.manager-V1.2-java",
- "com.android.server.security.flags-aconfig-java",
"cbor-java",
"display_flags_lib",
"icu4j_calendar_astronomer",
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 0d265a0f4c4a..b5911f69b156 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -9543,6 +9543,14 @@ public class ActivityManagerService extends IActivityManager.Stub
}
} else {
worker.start();
+ if (process != null && process.mPid == MY_PID && "crash".equals(eventType)) {
+ // We're actually crashing, let's wait for up to 2 seconds before killing ourselves,
+ // so the data could be persisted into the dropbox.
+ try {
+ worker.join(2000);
+ } catch (InterruptedException ignored) {
+ }
+ }
}
}
diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java
index d3176ee46464..87077a677758 100644
--- a/services/core/java/com/android/server/am/OomAdjuster.java
+++ b/services/core/java/com/android/server/am/OomAdjuster.java
@@ -2823,9 +2823,7 @@ public class OomAdjuster {
}
}
- if (schedGroup < SCHED_GROUP_TOP_APP
- && cr.hasFlag(Context.BIND_SCHEDULE_LIKE_TOP_APP)
- && clientIsSystem) {
+ if (cr.hasFlag(Context.BIND_SCHEDULE_LIKE_TOP_APP) && clientIsSystem) {
schedGroup = SCHED_GROUP_TOP_APP;
state.setScheduleLikeTopApp(true);
}
diff --git a/services/core/java/com/android/server/biometrics/AuthenticationStatsCollector.java b/services/core/java/com/android/server/biometrics/AuthenticationStatsCollector.java
index fdf607d04ec7..64691e0b062b 100644
--- a/services/core/java/com/android/server/biometrics/AuthenticationStatsCollector.java
+++ b/services/core/java/com/android/server/biometrics/AuthenticationStatsCollector.java
@@ -53,6 +53,9 @@ public class AuthenticationStatsCollector {
static final int MAXIMUM_ENROLLMENT_NOTIFICATIONS = 1;
@NonNull private final Context mContext;
+ @NonNull private final PackageManager mPackageManager;
+ @NonNull private final FaceManager mFaceManager;
+ @NonNull private final FingerprintManager mFingerprintManager;
private final float mThreshold;
private final int mModality;
@@ -86,6 +89,10 @@ public class AuthenticationStatsCollector {
mModality = modality;
mBiometricNotification = biometricNotification;
+ mPackageManager = context.getPackageManager();
+ mFaceManager = mContext.getSystemService(FaceManager.class);
+ mFingerprintManager = mContext.getSystemService(FingerprintManager.class);
+
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_USER_REMOVED);
context.registerReceiver(mBroadcastReceiver, intentFilter);
@@ -108,6 +115,13 @@ public class AuthenticationStatsCollector {
/** Update total authentication and rejected attempts. */
public void authenticate(int userId, boolean authenticated) {
+
+ // Don't collect data for single-modality devices or user has both biometrics enrolled.
+ if (isSingleModalityDevice()
+ || (hasEnrolledFace(userId) && hasEnrolledFingerprint(userId))) {
+ return;
+ }
+
// SharedPreference is not ready when starting system server, initialize
// mUserAuthenticationStatsMap in authentication to ensure SharedPreference
// is ready for application use.
@@ -150,25 +164,9 @@ public class AuthenticationStatsCollector {
authenticationStats.resetData();
- final PackageManager packageManager = mContext.getPackageManager();
-
- // Don't send notification to single-modality devices.
- if (!packageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)
- || !packageManager.hasSystemFeature(PackageManager.FEATURE_FACE)) {
- return;
- }
-
- final FaceManager faceManager = mContext.getSystemService(FaceManager.class);
- final boolean hasEnrolledFace = faceManager.hasEnrolledTemplates(userId);
+ final boolean hasEnrolledFace = hasEnrolledFace(userId);
+ final boolean hasEnrolledFingerprint = hasEnrolledFingerprint(userId);
- final FingerprintManager fingerprintManager = mContext
- .getSystemService(FingerprintManager.class);
- final boolean hasEnrolledFingerprint = fingerprintManager.hasEnrolledTemplates(userId);
-
- // Don't send notification when both face and fingerprint are enrolled.
- if (hasEnrolledFace && hasEnrolledFingerprint) {
- return;
- }
if (hasEnrolledFace && !hasEnrolledFingerprint) {
mBiometricNotification.sendFpEnrollNotification(mContext);
authenticationStats.updateNotificationCounter();
@@ -199,6 +197,19 @@ public class AuthenticationStatsCollector {
}
}
+ private boolean isSingleModalityDevice() {
+ return !mPackageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)
+ || !mPackageManager.hasSystemFeature(PackageManager.FEATURE_FACE);
+ }
+
+ private boolean hasEnrolledFace(int userId) {
+ return mFaceManager.hasEnrolledTemplates(userId);
+ }
+
+ private boolean hasEnrolledFingerprint(int userId) {
+ return mFingerprintManager.hasEnrolledTemplates(userId);
+ }
+
/**
* Only being used in tests. Callers should not make any changes to the returned
* authentication stats.
diff --git a/services/core/java/com/android/server/biometrics/sensors/BiometricNotificationUtils.java b/services/core/java/com/android/server/biometrics/sensors/BiometricNotificationUtils.java
index f1c74f0b9fb2..2aec9aefa8d1 100644
--- a/services/core/java/com/android/server/biometrics/sensors/BiometricNotificationUtils.java
+++ b/services/core/java/com/android/server/biometrics/sensors/BiometricNotificationUtils.java
@@ -176,6 +176,7 @@ public class BiometricNotificationUtils {
.setSmallIcon(R.drawable.ic_lock)
.setContentTitle(title)
.setContentText(content)
+ .setStyle(new Notification.BigTextStyle().bigText(content))
.setSubText(name)
.setOnlyAlertOnce(true)
.setLocalOnly(true)
diff --git a/services/core/java/com/android/server/broadcastradio/aidl/ConversionUtils.java b/services/core/java/com/android/server/broadcastradio/aidl/ConversionUtils.java
index adea13fcc13c..d4232ab60eec 100644
--- a/services/core/java/com/android/server/broadcastradio/aidl/ConversionUtils.java
+++ b/services/core/java/com/android/server/broadcastradio/aidl/ConversionUtils.java
@@ -29,7 +29,6 @@ import android.hardware.broadcastradio.Metadata;
import android.hardware.broadcastradio.ProgramFilter;
import android.hardware.broadcastradio.ProgramIdentifier;
import android.hardware.broadcastradio.ProgramInfo;
-import android.hardware.broadcastradio.ProgramListChunk;
import android.hardware.broadcastradio.Properties;
import android.hardware.broadcastradio.Result;
import android.hardware.broadcastradio.VendorKeyValue;
@@ -38,6 +37,7 @@ import android.hardware.radio.ProgramSelector;
import android.hardware.radio.RadioManager;
import android.hardware.radio.RadioMetadata;
import android.hardware.radio.RadioTuner;
+import android.hardware.radio.UniqueProgramIdentifier;
import android.os.Build;
import android.os.ParcelableException;
import android.os.ServiceSpecificException;
@@ -553,31 +553,6 @@ final class ConversionUtils {
return hwFilter;
}
- static ProgramList.Chunk chunkFromHalProgramListChunk(ProgramListChunk chunk) {
- Set<RadioManager.ProgramInfo> modified = new ArraySet<>(chunk.modified.length);
- for (int i = 0; i < chunk.modified.length; i++) {
- RadioManager.ProgramInfo modifiedInfo =
- programInfoFromHalProgramInfo(chunk.modified[i]);
- if (modifiedInfo == null) {
- Slogf.w(TAG, "Program info %s in program list chunk is not valid",
- chunk.modified[i]);
- continue;
- }
- modified.add(modifiedInfo);
- }
- Set<ProgramSelector.Identifier> removed = new ArraySet<>();
- if (chunk.removed != null) {
- for (int i = 0; i < chunk.removed.length; i++) {
- ProgramSelector.Identifier removedId =
- identifierFromHalProgramIdentifier(chunk.removed[i]);
- if (removedId != null) {
- removed.add(removedId);
- }
- }
- }
- return new ProgramList.Chunk(chunk.purge, chunk.complete, modified, removed);
- }
-
private static boolean isNewIdentifierInU(ProgramSelector.Identifier id) {
return id.getType() == ProgramSelector.IDENTIFIER_TYPE_DAB_DMB_SID_EXT;
}
@@ -630,11 +605,11 @@ final class ConversionUtils {
modified.add(info);
}
}
- Set<ProgramSelector.Identifier> removed = new ArraySet<>();
- Iterator<ProgramSelector.Identifier> removedIterator = chunk.getRemoved().iterator();
+ Set<UniqueProgramIdentifier> removed = new ArraySet<>();
+ Iterator<UniqueProgramIdentifier> removedIterator = chunk.getRemoved().iterator();
while (removedIterator.hasNext()) {
- ProgramSelector.Identifier id = removedIterator.next();
- if (!isNewIdentifierInU(id)) {
+ UniqueProgramIdentifier id = removedIterator.next();
+ if (!isNewIdentifierInU(id.getPrimaryId())) {
removed.add(id);
}
}
diff --git a/services/core/java/com/android/server/broadcastradio/aidl/ProgramInfoCache.java b/services/core/java/com/android/server/broadcastradio/aidl/ProgramInfoCache.java
index c9ae735d63e2..756dbbbc612b 100644
--- a/services/core/java/com/android/server/broadcastradio/aidl/ProgramInfoCache.java
+++ b/services/core/java/com/android/server/broadcastradio/aidl/ProgramInfoCache.java
@@ -17,9 +17,11 @@
package com.android.server.broadcastradio.aidl;
import android.annotation.Nullable;
+import android.hardware.broadcastradio.ProgramListChunk;
import android.hardware.radio.ProgramList;
-import android.hardware.radio.ProgramSelector;
+import android.hardware.radio.ProgramSelector.Identifier;
import android.hardware.radio.RadioManager;
+import android.hardware.radio.UniqueProgramIdentifier;
import android.util.ArrayMap;
import android.util.ArraySet;
@@ -30,7 +32,6 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
-import java.util.Map;
import java.util.Set;
/**
@@ -40,24 +41,25 @@ final class ProgramInfoCache {
private static final String TAG = "BcRadioAidlSrv.cache";
/**
- * Maximum number of {@link RadioManager#ProgramInfo} elements that will be put into a
+ * Maximum number of {@link RadioManager.ProgramInfo} elements that will be put into a
* ProgramList.Chunk.mModified array. Used to try to ensure a single ProgramList.Chunk
* stays within the AIDL data size limit.
*/
private static final int MAX_NUM_MODIFIED_PER_CHUNK = 100;
/**
- * Maximum number of {@link ProgramSelector#Identifier} elements that will be put
- * into the removed array of {@link ProgramList#Chunk}. Used to try to ensure a single
- * {@link ProgramList#Chunk} stays within the AIDL data size limit.
+ * Maximum number of {@link Identifier} elements that will be put into the removed array
+ * of {@link ProgramList.Chunk}. Use to attempt and keep the single {@link ProgramList.Chunk}
+ * within the AIDL data size limit.
*/
private static final int MAX_NUM_REMOVED_PER_CHUNK = 500;
/**
- * Map from primary identifier to corresponding {@link RadioManager#ProgramInfo}.
+ * Map from primary identifier to {@link UniqueProgramIdentifier} and then to corresponding
+ * {@link RadioManager.ProgramInfo}.
*/
- private final Map<ProgramSelector.Identifier, RadioManager.ProgramInfo> mProgramInfoMap =
- new ArrayMap<>();
+ private final ArrayMap<Identifier, ArrayMap<UniqueProgramIdentifier, RadioManager.ProgramInfo>>
+ mProgramInfoMap = new ArrayMap<>();
/**
* Flag indicating whether mProgramInfoMap is considered complete based upon the received
@@ -81,13 +83,17 @@ final class ProgramInfoCache {
mFilter = filter;
mComplete = complete;
for (int i = 0; i < programInfos.length; i++) {
- mProgramInfoMap.put(programInfos[i].getSelector().getPrimaryId(), programInfos[i]);
+ putInfo(programInfos[i]);
}
}
@VisibleForTesting
List<RadioManager.ProgramInfo> toProgramInfoList() {
- return new ArrayList<>(mProgramInfoMap.values());
+ List<RadioManager.ProgramInfo> programInfoList = new ArrayList<>();
+ for (int index = 0; index < mProgramInfoMap.size(); index++) {
+ programInfoList.addAll(mProgramInfoMap.valueAt(index).values());
+ }
+ return programInfoList;
}
@Override
@@ -97,10 +103,14 @@ final class ProgramInfoCache {
sb.append(", mFilter = ");
sb.append(mFilter);
sb.append(", mProgramInfoMap = [");
- mProgramInfoMap.forEach((id, programInfo) -> {
- sb.append(", ");
- sb.append(programInfo);
- });
+ for (int index = 0; index < mProgramInfoMap.size(); index++) {
+ ArrayMap<UniqueProgramIdentifier, RadioManager.ProgramInfo> entries =
+ mProgramInfoMap.valueAt(index);
+ for (int entryIndex = 0; entryIndex < entries.size(); entryIndex++) {
+ sb.append(", ");
+ sb.append(entries.valueAt(entryIndex));
+ }
+ }
return sb.append("])").toString();
}
@@ -114,8 +124,7 @@ final class ProgramInfoCache {
}
@VisibleForTesting
- void updateFromHalProgramListChunk(
- android.hardware.broadcastradio.ProgramListChunk chunk) {
+ void updateFromHalProgramListChunk(ProgramListChunk chunk) {
if (chunk.purge) {
mProgramInfoMap.clear();
}
@@ -125,8 +134,9 @@ final class ProgramInfoCache {
if (programInfo == null) {
Slogf.e(TAG, "Program info in program info %s in chunk is not valid",
chunk.modified[i]);
+ continue;
}
- mProgramInfoMap.put(programInfo.getSelector().getPrimaryId(), programInfo);
+ putInfo(programInfo);
}
if (chunk.removed != null) {
for (int i = 0; i < chunk.removed.length; i++) {
@@ -155,25 +165,31 @@ final class ProgramInfoCache {
purge = true;
}
- Set<RadioManager.ProgramInfo> modified = new ArraySet<>();
- Set<ProgramSelector.Identifier> removed = new ArraySet<>(mProgramInfoMap.keySet());
- for (Map.Entry<ProgramSelector.Identifier, RadioManager.ProgramInfo> entry
- : other.mProgramInfoMap.entrySet()) {
- ProgramSelector.Identifier id = entry.getKey();
+ ArraySet<RadioManager.ProgramInfo> modified = new ArraySet<>();
+ ArraySet<UniqueProgramIdentifier> removed = new ArraySet<>();
+ for (int index = 0; index < mProgramInfoMap.size(); index++) {
+ removed.addAll(mProgramInfoMap.valueAt(index).keySet());
+ }
+ for (int index = 0; index < other.mProgramInfoMap.size(); index++) {
+ Identifier id = other.mProgramInfoMap.keyAt(index);
if (!passesFilter(id)) {
continue;
}
- removed.remove(id);
+ ArrayMap<UniqueProgramIdentifier, RadioManager.ProgramInfo> entries =
+ other.mProgramInfoMap.valueAt(index);
+ for (int entryIndex = 0; entryIndex < entries.size(); entryIndex++) {
+ removed.remove(entries.keyAt(entryIndex));
- RadioManager.ProgramInfo newInfo = entry.getValue();
- if (!shouldIncludeInModified(newInfo)) {
- continue;
+ RadioManager.ProgramInfo newInfo = entries.valueAt(entryIndex);
+ if (!shouldIncludeInModified(newInfo)) {
+ continue;
+ }
+ putInfo(newInfo);
+ modified.add(newInfo);
}
- mProgramInfoMap.put(id, newInfo);
- modified.add(newInfo);
}
- for (ProgramSelector.Identifier rem : removed) {
- mProgramInfoMap.remove(rem);
+ for (int removedIndex = 0; removedIndex < removed.size(); removedIndex++) {
+ removeUniqueId(removed.valueAt(removedIndex));
}
mComplete = other.mComplete;
return buildChunks(purge, mComplete, modified, maxNumModifiedPerChunk, removed,
@@ -181,45 +197,61 @@ final class ProgramInfoCache {
}
@Nullable
- List<ProgramList.Chunk> filterAndApplyChunk(ProgramList.Chunk chunk) {
+ List<ProgramList.Chunk> filterAndApplyChunk(ProgramListChunk chunk) {
return filterAndApplyChunkInternal(chunk, MAX_NUM_MODIFIED_PER_CHUNK,
MAX_NUM_REMOVED_PER_CHUNK);
}
@VisibleForTesting
@Nullable
- List<ProgramList.Chunk> filterAndApplyChunkInternal(ProgramList.Chunk chunk,
+ List<ProgramList.Chunk> filterAndApplyChunkInternal(ProgramListChunk chunk,
int maxNumModifiedPerChunk, int maxNumRemovedPerChunk) {
- if (chunk.isPurge()) {
+ if (chunk.purge) {
mProgramInfoMap.clear();
}
Set<RadioManager.ProgramInfo> modified = new ArraySet<>();
- Set<ProgramSelector.Identifier> removed = new ArraySet<>();
- for (RadioManager.ProgramInfo info : chunk.getModified()) {
- ProgramSelector.Identifier id = info.getSelector().getPrimaryId();
- if (!passesFilter(id) || !shouldIncludeInModified(info)) {
+ for (int i = 0; i < chunk.modified.length; i++) {
+ RadioManager.ProgramInfo info =
+ ConversionUtils.programInfoFromHalProgramInfo(chunk.modified[i]);
+ if (info == null) {
+ Slogf.w(TAG, "Program info %s in program list chunk is not valid",
+ chunk.modified[i]);
+ continue;
+ }
+ Identifier primaryId = info.getSelector().getPrimaryId();
+ if (!passesFilter(primaryId) || !shouldIncludeInModified(info)) {
continue;
}
- mProgramInfoMap.put(id, info);
+ putInfo(info);
modified.add(info);
}
- for (ProgramSelector.Identifier id : chunk.getRemoved()) {
- if (mProgramInfoMap.containsKey(id)) {
- mProgramInfoMap.remove(id);
- removed.add(id);
+ Set<UniqueProgramIdentifier> removed = new ArraySet<>();
+ if (chunk.removed != null) {
+ for (int i = 0; i < chunk.removed.length; i++) {
+ Identifier removedId = ConversionUtils.identifierFromHalProgramIdentifier(
+ chunk.removed[i]);
+ if (removedId == null) {
+ Slogf.w(TAG, "Removed identifier %s in program list chunk is not valid",
+ chunk.modified[i]);
+ continue;
+ }
+ if (mProgramInfoMap.containsKey(removedId)) {
+ removed.addAll(mProgramInfoMap.get(removedId).keySet());
+ mProgramInfoMap.remove(removedId);
+ }
}
}
- if (modified.isEmpty() && removed.isEmpty() && mComplete == chunk.isComplete()
- && !chunk.isPurge()) {
+ if (modified.isEmpty() && removed.isEmpty() && mComplete == chunk.complete
+ && !chunk.purge) {
return null;
}
- mComplete = chunk.isComplete();
- return buildChunks(chunk.isPurge(), mComplete, modified, maxNumModifiedPerChunk, removed,
+ mComplete = chunk.complete;
+ return buildChunks(chunk.purge, mComplete, modified, maxNumModifiedPerChunk, removed,
maxNumRemovedPerChunk);
}
- private boolean passesFilter(ProgramSelector.Identifier id) {
+ private boolean passesFilter(Identifier id) {
if (mFilter == null) {
return true;
}
@@ -233,9 +265,32 @@ final class ProgramInfoCache {
return mFilter.areCategoriesIncluded() || !id.isCategoryType();
}
+ private void putInfo(RadioManager.ProgramInfo info) {
+ Identifier primaryId = info.getSelector().getPrimaryId();
+ if (!mProgramInfoMap.containsKey(primaryId)) {
+ mProgramInfoMap.put(primaryId, new ArrayMap<>());
+ }
+ mProgramInfoMap.get(primaryId).put(new UniqueProgramIdentifier(info.getSelector()), info);
+ }
+
+ private void removeUniqueId(UniqueProgramIdentifier uniqueId) {
+ Identifier primaryId = uniqueId.getPrimaryId();
+ if (!mProgramInfoMap.containsKey(primaryId)) {
+ return;
+ }
+ mProgramInfoMap.get(primaryId).remove(uniqueId);
+ if (mProgramInfoMap.get(primaryId).isEmpty()) {
+ mProgramInfoMap.remove(primaryId);
+ }
+ }
+
private boolean shouldIncludeInModified(RadioManager.ProgramInfo newInfo) {
- RadioManager.ProgramInfo oldInfo = mProgramInfoMap.get(
- newInfo.getSelector().getPrimaryId());
+ Identifier primaryId = newInfo.getSelector().getPrimaryId();
+ RadioManager.ProgramInfo oldInfo = null;
+ if (mProgramInfoMap.containsKey(primaryId)) {
+ UniqueProgramIdentifier uniqueId = new UniqueProgramIdentifier(newInfo.getSelector());
+ oldInfo = mProgramInfoMap.get(primaryId).get(uniqueId);
+ }
if (oldInfo == null) {
return true;
}
@@ -251,7 +306,7 @@ final class ProgramInfoCache {
private static List<ProgramList.Chunk> buildChunks(boolean purge, boolean complete,
@Nullable Collection<RadioManager.ProgramInfo> modified, int maxNumModifiedPerChunk,
- @Nullable Collection<ProgramSelector.Identifier> removed, int maxNumRemovedPerChunk) {
+ @Nullable Collection<UniqueProgramIdentifier> removed, int maxNumRemovedPerChunk) {
// Communication protocol requires that if purge is set, removed is empty.
if (purge) {
removed = null;
@@ -275,7 +330,7 @@ final class ProgramInfoCache {
int modifiedPerChunk = 0;
int removedPerChunk = 0;
Iterator<RadioManager.ProgramInfo> modifiedIter = null;
- Iterator<ProgramSelector.Identifier> removedIter = null;
+ Iterator<UniqueProgramIdentifier> removedIter = null;
if (modified != null) {
modifiedPerChunk = roundUpFraction(modified.size(), numChunks);
modifiedIter = modified.iterator();
@@ -287,7 +342,7 @@ final class ProgramInfoCache {
List<ProgramList.Chunk> chunks = new ArrayList<>(numChunks);
for (int i = 0; i < numChunks; i++) {
ArraySet<RadioManager.ProgramInfo> modifiedChunk = new ArraySet<>();
- ArraySet<ProgramSelector.Identifier> removedChunk = new ArraySet<>();
+ ArraySet<UniqueProgramIdentifier> removedChunk = new ArraySet<>();
if (modifiedIter != null) {
for (int j = 0; j < modifiedPerChunk && modifiedIter.hasNext(); j++) {
modifiedChunk.add(modifiedIter.next());
diff --git a/services/core/java/com/android/server/broadcastradio/aidl/RadioModule.java b/services/core/java/com/android/server/broadcastradio/aidl/RadioModule.java
index 7c87c6c55289..2ae7f9543540 100644
--- a/services/core/java/com/android/server/broadcastradio/aidl/RadioModule.java
+++ b/services/core/java/com/android/server/broadcastradio/aidl/RadioModule.java
@@ -142,12 +142,11 @@ final class RadioModule {
public void onProgramListUpdated(ProgramListChunk programListChunk) {
fireLater(() -> {
synchronized (mLock) {
- android.hardware.radio.ProgramList.Chunk chunk =
- ConversionUtils.chunkFromHalProgramListChunk(programListChunk);
- mProgramInfoCache.filterAndApplyChunk(chunk);
+ mProgramInfoCache.filterAndApplyChunk(programListChunk);
for (int i = 0; i < mAidlTunerSessions.size(); i++) {
- mAidlTunerSessions.valueAt(i).onMergedProgramListUpdateFromHal(chunk);
+ mAidlTunerSessions.valueAt(i).onMergedProgramListUpdateFromHal(
+ programListChunk);
}
}
});
diff --git a/services/core/java/com/android/server/broadcastradio/aidl/TunerSession.java b/services/core/java/com/android/server/broadcastradio/aidl/TunerSession.java
index beff7bd3cffd..4ed36ec9878c 100644
--- a/services/core/java/com/android/server/broadcastradio/aidl/TunerSession.java
+++ b/services/core/java/com/android/server/broadcastradio/aidl/TunerSession.java
@@ -20,6 +20,7 @@ import android.annotation.Nullable;
import android.graphics.Bitmap;
import android.hardware.broadcastradio.ConfigFlag;
import android.hardware.broadcastradio.IBroadcastRadio;
+import android.hardware.broadcastradio.ProgramListChunk;
import android.hardware.radio.ITuner;
import android.hardware.radio.ProgramList;
import android.hardware.radio.ProgramSelector;
@@ -297,7 +298,7 @@ final class TunerSession extends ITuner.Stub {
}
}
- void onMergedProgramListUpdateFromHal(ProgramList.Chunk mergedChunk) {
+ void onMergedProgramListUpdateFromHal(ProgramListChunk mergedChunk) {
List<ProgramList.Chunk> clientUpdateChunks;
synchronized (mLock) {
if (mProgramInfoCache == null) {
diff --git a/services/core/java/com/android/server/broadcastradio/hal2/Convert.java b/services/core/java/com/android/server/broadcastradio/hal2/Convert.java
index e6908b107d31..fb1138f4bc24 100644
--- a/services/core/java/com/android/server/broadcastradio/hal2/Convert.java
+++ b/services/core/java/com/android/server/broadcastradio/hal2/Convert.java
@@ -28,7 +28,6 @@ import android.hardware.broadcastradio.V2_0.MetadataKey;
import android.hardware.broadcastradio.V2_0.ProgramFilter;
import android.hardware.broadcastradio.V2_0.ProgramIdentifier;
import android.hardware.broadcastradio.V2_0.ProgramInfo;
-import android.hardware.broadcastradio.V2_0.ProgramListChunk;
import android.hardware.broadcastradio.V2_0.Properties;
import android.hardware.broadcastradio.V2_0.Result;
import android.hardware.broadcastradio.V2_0.VendorKeyValue;
@@ -425,16 +424,6 @@ class Convert {
return hwFilter;
}
- static @NonNull ProgramList.Chunk programListChunkFromHal(@NonNull ProgramListChunk chunk) {
- Set<RadioManager.ProgramInfo> modified = chunk.modified.stream().
- map(info -> programInfoFromHal(info)).collect(Collectors.toSet());
- Set<ProgramSelector.Identifier> removed = chunk.removed.stream().
- map(id -> Objects.requireNonNull(programIdentifierFromHal(id))).
- collect(Collectors.toSet());
-
- return new ProgramList.Chunk(chunk.purge, chunk.complete, modified, removed);
- }
-
public static @NonNull android.hardware.radio.Announcement announcementFromHal(
@NonNull Announcement hwAnnouncement) {
return new android.hardware.radio.Announcement(
diff --git a/services/core/java/com/android/server/broadcastradio/hal2/ProgramInfoCache.java b/services/core/java/com/android/server/broadcastradio/hal2/ProgramInfoCache.java
index 9831af6b523e..111953d9f6cf 100644
--- a/services/core/java/com/android/server/broadcastradio/hal2/ProgramInfoCache.java
+++ b/services/core/java/com/android/server/broadcastradio/hal2/ProgramInfoCache.java
@@ -16,21 +16,21 @@
package com.android.server.broadcastradio.hal2;
-import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.hardware.broadcastradio.V2_0.ProgramListChunk;
import android.hardware.radio.ProgramList;
-import android.hardware.radio.ProgramSelector;
+import android.hardware.radio.ProgramSelector.Identifier;
import android.hardware.radio.RadioManager;
+import android.hardware.radio.UniqueProgramIdentifier;
+import android.util.ArrayMap;
+import android.util.ArraySet;
import com.android.internal.annotations.VisibleForTesting;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
-import java.util.Map;
import java.util.Set;
final class ProgramInfoCache {
@@ -40,13 +40,14 @@ final class ProgramInfoCache {
private static final int MAX_NUM_MODIFIED_PER_CHUNK = 100;
// Maximum number of ProgramSelector.Identifier elements that will be put into a
- // ProgramList.Chunk.mRemoved array. Used to try to ensure a single ProgramList.Chunk stays
+ // ProgramList.Chunk.mRemoved array. Use to attempt and keep the single ProgramList.Chunk
// within the AIDL data size limit.
private static final int MAX_NUM_REMOVED_PER_CHUNK = 500;
- // Map from primary identifier to corresponding ProgramInfo.
- private final Map<ProgramSelector.Identifier, RadioManager.ProgramInfo> mProgramInfoMap =
- new HashMap<>();
+ // Map from primary identifier to a map of unique identifiers and program info, where the
+ // containing map has unique identifiers to program info.
+ private final ArrayMap<Identifier, ArrayMap<UniqueProgramIdentifier, RadioManager.ProgramInfo>>
+ mProgramInfoMap = new ArrayMap<>();
// Flag indicating whether mProgramInfoMap is considered complete based upon the received
// updates.
@@ -66,18 +67,18 @@ final class ProgramInfoCache {
RadioManager.ProgramInfo... programInfos) {
mFilter = filter;
mComplete = complete;
- for (RadioManager.ProgramInfo programInfo : programInfos) {
- mProgramInfoMap.put(programInfo.getSelector().getPrimaryId(), programInfo);
+ for (int i = 0; i < programInfos.length; i++) {
+ putInfo(programInfos[i]);
}
}
@VisibleForTesting
- boolean programInfosAreExactly(RadioManager.ProgramInfo... programInfos) {
- Map<ProgramSelector.Identifier, RadioManager.ProgramInfo> expectedMap = new HashMap<>();
- for (RadioManager.ProgramInfo programInfo : programInfos) {
- expectedMap.put(programInfo.getSelector().getPrimaryId(), programInfo);
+ List<RadioManager.ProgramInfo> toProgramInfoList() {
+ List<RadioManager.ProgramInfo> programInfoList = new ArrayList<>();
+ for (int index = 0; index < mProgramInfoMap.size(); index++) {
+ programInfoList.addAll(mProgramInfoMap.valueAt(index).values());
}
- return expectedMap.equals(mProgramInfoMap);
+ return programInfoList;
}
@Override
@@ -87,10 +88,14 @@ final class ProgramInfoCache {
sb.append(", mFilter = ");
sb.append(mFilter);
sb.append(", mProgramInfoMap = [");
- mProgramInfoMap.forEach((id, programInfo) -> {
- sb.append("\n");
- sb.append(programInfo.toString());
- });
+ for (int index = 0; index < mProgramInfoMap.size(); index++) {
+ ArrayMap<UniqueProgramIdentifier, RadioManager.ProgramInfo> entries =
+ mProgramInfoMap.valueAt(index);
+ for (int entryIndex = 0; entryIndex < entries.size(); entryIndex++) {
+ sb.append(", ");
+ sb.append(entries.valueAt(entryIndex));
+ }
+ }
sb.append("]");
return sb.toString();
}
@@ -103,14 +108,13 @@ final class ProgramInfoCache {
return mFilter;
}
- void updateFromHalProgramListChunk(
- @NonNull android.hardware.broadcastradio.V2_0.ProgramListChunk chunk) {
+ void updateFromHalProgramListChunk(ProgramListChunk chunk) {
if (chunk.purge) {
mProgramInfoMap.clear();
}
for (android.hardware.broadcastradio.V2_0.ProgramInfo halProgramInfo : chunk.modified) {
RadioManager.ProgramInfo programInfo = Convert.programInfoFromHal(halProgramInfo);
- mProgramInfoMap.put(programInfo.getSelector().getPrimaryId(), programInfo);
+ putInfo(programInfo);
}
for (android.hardware.broadcastradio.V2_0.ProgramIdentifier halProgramId : chunk.removed) {
mProgramInfoMap.remove(Convert.programIdentifierFromHal(halProgramId));
@@ -118,14 +122,13 @@ final class ProgramInfoCache {
mComplete = chunk.complete;
}
- @NonNull List<ProgramList.Chunk> filterAndUpdateFrom(@NonNull ProgramInfoCache other,
- boolean purge) {
+ List<ProgramList.Chunk> filterAndUpdateFrom(ProgramInfoCache other, boolean purge) {
return filterAndUpdateFromInternal(other, purge, MAX_NUM_MODIFIED_PER_CHUNK,
MAX_NUM_REMOVED_PER_CHUNK);
}
@VisibleForTesting
- @NonNull List<ProgramList.Chunk> filterAndUpdateFromInternal(@NonNull ProgramInfoCache other,
+ List<ProgramList.Chunk> filterAndUpdateFromInternal(ProgramInfoCache other,
boolean purge, int maxNumModifiedPerChunk, int maxNumRemovedPerChunk) {
if (purge) {
mProgramInfoMap.clear();
@@ -136,69 +139,82 @@ final class ProgramInfoCache {
purge = true;
}
- Set<RadioManager.ProgramInfo> modified = new HashSet<>();
- Set<ProgramSelector.Identifier> removed = new HashSet<>(mProgramInfoMap.keySet());
- for (Map.Entry<ProgramSelector.Identifier, RadioManager.ProgramInfo> entry
- : other.mProgramInfoMap.entrySet()) {
- ProgramSelector.Identifier id = entry.getKey();
+ ArraySet<RadioManager.ProgramInfo> modified = new ArraySet<>();
+ ArraySet<UniqueProgramIdentifier> removed = new ArraySet<>();
+ for (int index = 0; index < mProgramInfoMap.size(); index++) {
+ removed.addAll(mProgramInfoMap.valueAt(index).keySet());
+ }
+ for (int index = 0; index < other.mProgramInfoMap.size(); index++) {
+ Identifier id = other.mProgramInfoMap.keyAt(index);
if (!passesFilter(id)) {
continue;
}
- removed.remove(id);
+ ArrayMap<UniqueProgramIdentifier, RadioManager.ProgramInfo> entries =
+ other.mProgramInfoMap.valueAt(index);
+ for (int entryIndex = 0; entryIndex < entries.size(); entryIndex++) {
+ removed.remove(entries.keyAt(entryIndex));
- RadioManager.ProgramInfo newInfo = entry.getValue();
- if (!shouldIncludeInModified(newInfo)) {
- continue;
+ RadioManager.ProgramInfo newInfo = entries.valueAt(entryIndex);
+ if (!shouldIncludeInModified(newInfo)) {
+ continue;
+ }
+ putInfo(newInfo);
+ modified.add(newInfo);
}
- mProgramInfoMap.put(id, newInfo);
- modified.add(newInfo);
}
- for (ProgramSelector.Identifier rem : removed) {
- mProgramInfoMap.remove(rem);
+ for (int removedIndex = 0; removedIndex < removed.size(); removedIndex++) {
+ removeUniqueId(removed.valueAt(removedIndex));
}
mComplete = other.mComplete;
return buildChunks(purge, mComplete, modified, maxNumModifiedPerChunk, removed,
maxNumRemovedPerChunk);
}
- @Nullable List<ProgramList.Chunk> filterAndApplyChunk(@NonNull ProgramList.Chunk chunk) {
+ @Nullable
+ List<ProgramList.Chunk> filterAndApplyChunk(ProgramListChunk chunk) {
return filterAndApplyChunkInternal(chunk, MAX_NUM_MODIFIED_PER_CHUNK,
MAX_NUM_REMOVED_PER_CHUNK);
}
@VisibleForTesting
- @Nullable List<ProgramList.Chunk> filterAndApplyChunkInternal(@NonNull ProgramList.Chunk chunk,
+ @Nullable
+ List<ProgramList.Chunk> filterAndApplyChunkInternal(ProgramListChunk chunk,
int maxNumModifiedPerChunk, int maxNumRemovedPerChunk) {
- if (chunk.isPurge()) {
+ if (chunk.purge) {
mProgramInfoMap.clear();
}
- Set<RadioManager.ProgramInfo> modified = new HashSet<>();
- Set<ProgramSelector.Identifier> removed = new HashSet<>();
- for (RadioManager.ProgramInfo info : chunk.getModified()) {
- ProgramSelector.Identifier id = info.getSelector().getPrimaryId();
- if (!passesFilter(id) || !shouldIncludeInModified(info)) {
+ Set<RadioManager.ProgramInfo> modified = new ArraySet<>();
+ for (android.hardware.broadcastradio.V2_0.ProgramInfo halProgramInfo : chunk.modified) {
+ RadioManager.ProgramInfo info = Convert.programInfoFromHal(halProgramInfo);
+ Identifier primaryId = info.getSelector().getPrimaryId();
+ if (!passesFilter(primaryId) || !shouldIncludeInModified(info)) {
continue;
}
- mProgramInfoMap.put(id, info);
+ putInfo(info);
modified.add(info);
}
- for (ProgramSelector.Identifier id : chunk.getRemoved()) {
- if (mProgramInfoMap.containsKey(id)) {
- mProgramInfoMap.remove(id);
- removed.add(id);
+ Set<UniqueProgramIdentifier> removed = new ArraySet<>();
+ for (android.hardware.broadcastradio.V2_0.ProgramIdentifier halProgramId : chunk.removed) {
+ Identifier removedId = Convert.programIdentifierFromHal(halProgramId);
+ if (removedId == null) {
+ continue;
+ }
+ if (mProgramInfoMap.containsKey(removedId)) {
+ removed.addAll(mProgramInfoMap.get(removedId).keySet());
+ mProgramInfoMap.remove(removedId);
}
}
- if (modified.isEmpty() && removed.isEmpty() && mComplete == chunk.isComplete()
- && !chunk.isPurge()) {
+ if (modified.isEmpty() && removed.isEmpty() && mComplete == chunk.complete
+ && !chunk.purge) {
return null;
}
- mComplete = chunk.isComplete();
- return buildChunks(chunk.isPurge(), mComplete, modified, maxNumModifiedPerChunk, removed,
+ mComplete = chunk.complete;
+ return buildChunks(chunk.purge, mComplete, modified, maxNumModifiedPerChunk, removed,
maxNumRemovedPerChunk);
}
- private boolean passesFilter(ProgramSelector.Identifier id) {
+ private boolean passesFilter(Identifier id) {
if (mFilter == null) {
return true;
}
@@ -215,9 +231,33 @@ final class ProgramInfoCache {
return true;
}
+ private void putInfo(RadioManager.ProgramInfo info) {
+ Identifier primaryId = info.getSelector().getPrimaryId();
+ if (!mProgramInfoMap.containsKey(primaryId)) {
+ mProgramInfoMap.put(primaryId, new ArrayMap<>());
+ }
+ mProgramInfoMap.get(primaryId).put(new UniqueProgramIdentifier(
+ info.getSelector()), info);
+ }
+
+ private void removeUniqueId(UniqueProgramIdentifier uniqueId) {
+ Identifier primaryId = uniqueId.getPrimaryId();
+ if (!mProgramInfoMap.containsKey(primaryId)) {
+ return;
+ }
+ mProgramInfoMap.get(primaryId).remove(uniqueId);
+ if (mProgramInfoMap.get(primaryId).isEmpty()) {
+ mProgramInfoMap.remove(primaryId);
+ }
+ }
+
private boolean shouldIncludeInModified(RadioManager.ProgramInfo newInfo) {
- RadioManager.ProgramInfo oldInfo = mProgramInfoMap.get(
- newInfo.getSelector().getPrimaryId());
+ Identifier primaryId = newInfo.getSelector().getPrimaryId();
+ RadioManager.ProgramInfo oldInfo = null;
+ if (mProgramInfoMap.containsKey(primaryId)) {
+ UniqueProgramIdentifier uniqueId = new UniqueProgramIdentifier(newInfo.getSelector());
+ oldInfo = mProgramInfoMap.get(primaryId).get(uniqueId);
+ }
if (oldInfo == null) {
return true;
}
@@ -231,9 +271,9 @@ final class ProgramInfoCache {
return (numerator / denominator) + (numerator % denominator > 0 ? 1 : 0);
}
- private static @NonNull List<ProgramList.Chunk> buildChunks(boolean purge, boolean complete,
+ private static List<ProgramList.Chunk> buildChunks(boolean purge, boolean complete,
@Nullable Collection<RadioManager.ProgramInfo> modified, int maxNumModifiedPerChunk,
- @Nullable Collection<ProgramSelector.Identifier> removed, int maxNumRemovedPerChunk) {
+ @Nullable Collection<UniqueProgramIdentifier> removed, int maxNumRemovedPerChunk) {
// Communication protocol requires that if purge is set, removed is empty.
if (purge) {
removed = null;
@@ -257,7 +297,7 @@ final class ProgramInfoCache {
int modifiedPerChunk = 0;
int removedPerChunk = 0;
Iterator<RadioManager.ProgramInfo> modifiedIter = null;
- Iterator<ProgramSelector.Identifier> removedIter = null;
+ Iterator<UniqueProgramIdentifier> removedIter = null;
if (modified != null) {
modifiedPerChunk = roundUpFraction(modified.size(), numChunks);
modifiedIter = modified.iterator();
@@ -268,8 +308,8 @@ final class ProgramInfoCache {
}
List<ProgramList.Chunk> chunks = new ArrayList<ProgramList.Chunk>(numChunks);
for (int i = 0; i < numChunks; i++) {
- HashSet<RadioManager.ProgramInfo> modifiedChunk = new HashSet<>();
- HashSet<ProgramSelector.Identifier> removedChunk = new HashSet<>();
+ ArraySet<RadioManager.ProgramInfo> modifiedChunk = new ArraySet<>();
+ ArraySet<UniqueProgramIdentifier> removedChunk = new ArraySet<>();
if (modifiedIter != null) {
for (int j = 0; j < modifiedPerChunk && modifiedIter.hasNext(); j++) {
modifiedChunk.add(modifiedIter.next());
diff --git a/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java b/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java
index 7b5cb898b6b5..a54af2ef6e44 100644
--- a/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java
+++ b/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java
@@ -111,13 +111,11 @@ final class RadioModule {
@Override
public void onProgramListUpdated(ProgramListChunk programListChunk) {
fireLater(() -> {
- android.hardware.radio.ProgramList.Chunk chunk =
- Convert.programListChunkFromHal(programListChunk);
synchronized (mLock) {
- mProgramInfoCache.filterAndApplyChunk(chunk);
+ mProgramInfoCache.filterAndApplyChunk(programListChunk);
for (TunerSession tunerSession : mAidlTunerSessions) {
- tunerSession.onMergedProgramListUpdateFromHal(chunk);
+ tunerSession.onMergedProgramListUpdateFromHal(programListChunk);
}
}
});
diff --git a/services/core/java/com/android/server/broadcastradio/hal2/TunerSession.java b/services/core/java/com/android/server/broadcastradio/hal2/TunerSession.java
index 1efc4a50aa08..978dc01d1219 100644
--- a/services/core/java/com/android/server/broadcastradio/hal2/TunerSession.java
+++ b/services/core/java/com/android/server/broadcastradio/hal2/TunerSession.java
@@ -21,6 +21,7 @@ import android.annotation.Nullable;
import android.graphics.Bitmap;
import android.hardware.broadcastradio.V2_0.ConfigFlag;
import android.hardware.broadcastradio.V2_0.ITunerSession;
+import android.hardware.broadcastradio.V2_0.ProgramListChunk;
import android.hardware.broadcastradio.V2_0.Result;
import android.hardware.radio.ITuner;
import android.hardware.radio.ProgramList;
@@ -267,7 +268,7 @@ class TunerSession extends ITuner.Stub {
}
}
- void onMergedProgramListUpdateFromHal(ProgramList.Chunk mergedChunk) {
+ void onMergedProgramListUpdateFromHal(ProgramListChunk mergedChunk) {
List<ProgramList.Chunk> clientUpdateChunks = null;
synchronized (mLock) {
if (mProgramInfoCache == null) {
diff --git a/services/core/java/com/android/server/pm/DeletePackageHelper.java b/services/core/java/com/android/server/pm/DeletePackageHelper.java
index 4d3bf4007e92..b5a373e35571 100644
--- a/services/core/java/com/android/server/pm/DeletePackageHelper.java
+++ b/services/core/java/com/android/server/pm/DeletePackageHelper.java
@@ -464,10 +464,7 @@ final class DeletePackageHelper {
if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
clearPackageStateAndReturn = true;
} else {
- // We need to set it back to 'installed' so the uninstall
- // broadcasts will be sent correctly.
if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
- ps.setInstalled(true, userId);
mPm.mSettings.writeKernelMappingLPr(ps);
clearPackageStateAndReturn = false;
}
diff --git a/services/core/java/com/android/server/pm/PackageArchiverService.java b/services/core/java/com/android/server/pm/PackageArchiverService.java
index c7f067be8581..e0524077e9c1 100644
--- a/services/core/java/com/android/server/pm/PackageArchiverService.java
+++ b/services/core/java/com/android/server/pm/PackageArchiverService.java
@@ -16,6 +16,7 @@
package com.android.server.pm;
+import static android.app.ComponentOptions.MODE_BACKGROUND_ACTIVITY_START_DENIED;
import static android.content.pm.PackageManager.DELETE_KEEP_DATA;
import static android.os.PowerExemptionManager.REASON_PACKAGE_UNARCHIVE;
import static android.os.PowerExemptionManager.TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED;
@@ -24,6 +25,7 @@ import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
+import android.annotation.UserIdInt;
import android.app.AppOpsManager;
import android.app.BroadcastOptions;
import android.content.Context;
@@ -33,24 +35,37 @@ import android.content.pm.IPackageArchiverService;
import android.content.pm.LauncherActivityInfo;
import android.content.pm.LauncherApps;
import android.content.pm.PackageArchiver;
+import android.content.pm.PackageInstaller;
import android.content.pm.PackageManager;
import android.content.pm.VersionedPackage;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
import android.os.Binder;
import android.os.Bundle;
+import android.os.Environment;
import android.os.ParcelableException;
+import android.os.SELinux;
import android.os.UserHandle;
import android.text.TextUtils;
+import android.util.Slog;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.server.pm.pkg.ArchiveState;
import com.android.server.pm.pkg.ArchiveState.ArchiveActivityInfo;
import com.android.server.pm.pkg.PackageStateInternal;
import com.android.server.pm.pkg.PackageUserStateInternal;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
+import java.util.concurrent.CompletableFuture;
/**
* Responsible archiving apps and returning information about archived apps.
@@ -61,6 +76,8 @@ import java.util.Objects;
*/
public class PackageArchiverService extends IPackageArchiverService.Stub {
+ private static final String TAG = "PackageArchiverService";
+
/**
* The maximum time granted for an app store to start a foreground service when unarchival
* is requested.
@@ -68,6 +85,8 @@ public class PackageArchiverService extends IPackageArchiverService.Stub {
// TODO(b/297358628) Make this configurable through a flag.
private static final int DEFAULT_UNARCHIVE_FOREGROUND_TIMEOUT_MS = 120 * 1000;
+ private static final String ARCHIVE_ICONS_DIR = "package_archiver";
+
private final Context mContext;
private final PackageManagerService mPm;
@@ -97,25 +116,44 @@ public class PackageArchiverService extends IPackageArchiverService.Stub {
snapshot.enforceCrossUserPermission(binderUid, userId, true, true,
"archiveApp");
verifyCaller(providedUid, binderUid);
- ArchiveState archiveState;
+ CompletableFuture<ArchiveState> archiveStateFuture;
try {
- archiveState = createArchiveState(packageName, userId);
- // TODO(b/282952870) Should be reverted if uninstall fails/cancels
- storeArchiveState(packageName, archiveState, userId);
+ archiveStateFuture = createArchiveState(packageName, userId);
} catch (PackageManager.NameNotFoundException e) {
+ Slog.d(TAG, TextUtils.formatSimple("Failed to archive %s with message %s",
+ packageName, e.getMessage()));
throw new ParcelableException(e);
}
- // TODO(b/278553670) Add special strings for the delete dialog
- mPm.mInstallerService.uninstall(
- new VersionedPackage(packageName, PackageManager.VERSION_CODE_HIGHEST),
- callerPackageName, DELETE_KEEP_DATA, intentSender, userId);
+ archiveStateFuture
+ .thenAccept(
+ archiveState -> {
+ // TODO(b/282952870) Should be reverted if uninstall fails/cancels
+ try {
+ storeArchiveState(packageName, archiveState, userId);
+ } catch (PackageManager.NameNotFoundException e) {
+ sendFailureStatus(intentSender, packageName, e.getMessage());
+ return;
+ }
+
+ // TODO(b/278553670) Add special strings for the delete dialog
+ mPm.mInstallerService.uninstall(
+ new VersionedPackage(packageName,
+ PackageManager.VERSION_CODE_HIGHEST),
+ callerPackageName, DELETE_KEEP_DATA, intentSender, userId,
+ binderUid);
+ })
+ .exceptionally(
+ e -> {
+ sendFailureStatus(intentSender, packageName, e.getMessage());
+ return null;
+ });
}
/**
* Creates archived state for the package and user.
*/
- public ArchiveState createArchiveState(String packageName, int userId)
+ public CompletableFuture<ArchiveState> createArchiveState(String packageName, int userId)
throws PackageManager.NameNotFoundException {
PackageStateInternal ps = getPackageState(packageName, mPm.snapshotComputer(),
Binder.getCallingUid(), userId);
@@ -123,16 +161,56 @@ public class PackageArchiverService extends IPackageArchiverService.Stub {
verifyInstaller(responsibleInstallerPackage);
List<LauncherActivityInfo> mainActivities = getLauncherActivityInfos(ps, userId);
+ final CompletableFuture<ArchiveState> archiveState = new CompletableFuture<>();
+ mPm.mHandler.post(() -> {
+ try {
+ archiveState.complete(
+ createArchiveStateInternal(packageName, userId, mainActivities,
+ responsibleInstallerPackage));
+ } catch (IOException e) {
+ archiveState.completeExceptionally(e);
+ }
+ });
+ return archiveState;
+ }
+
+ private ArchiveState createArchiveStateInternal(String packageName, int userId,
+ List<LauncherActivityInfo> mainActivities, String installerPackage)
+ throws IOException {
List<ArchiveActivityInfo> archiveActivityInfos = new ArrayList<>();
for (int i = 0; i < mainActivities.size(); i++) {
- // TODO(b/278553670) Extract and store launcher icons
+ LauncherActivityInfo mainActivity = mainActivities.get(i);
+ Path iconPath = storeIcon(packageName, mainActivity, userId);
ArchiveActivityInfo activityInfo = new ArchiveActivityInfo(
- mainActivities.get(i).getLabel().toString(),
- Path.of("/TODO"), null);
+ mainActivity.getLabel().toString(), iconPath, null);
archiveActivityInfos.add(activityInfo);
}
- return new ArchiveState(archiveActivityInfos, responsibleInstallerPackage);
+ return new ArchiveState(archiveActivityInfos, installerPackage);
+ }
+
+ // TODO(b/298452477) Handle monochrome icons.
+ @VisibleForTesting
+ Path storeIcon(String packageName, LauncherActivityInfo mainActivity,
+ @UserIdInt int userId)
+ throws IOException {
+ int iconResourceId = mainActivity.getActivityInfo().getIconResource();
+ if (iconResourceId == 0) {
+ // The app doesn't define an icon. No need to store anything.
+ return null;
+ }
+ File iconsDir = createIconsDir(userId);
+ File iconFile = new File(iconsDir, packageName + "-" + mainActivity.getName() + ".png");
+ Bitmap icon = drawableToBitmap(mainActivity.getIcon(/* density= */ 0));
+ try (FileOutputStream out = new FileOutputStream(iconFile)) {
+ // Note: Quality is ignored for PNGs.
+ if (!icon.compress(Bitmap.CompressFormat.PNG, /* quality= */ 100, out)) {
+ throw new IOException(TextUtils.formatSimple("Failure to store icon file %s",
+ iconFile.getName()));
+ }
+ out.flush();
+ }
+ return iconFile.toPath();
}
private void verifyInstaller(String installerPackage)
@@ -313,6 +391,29 @@ public class PackageArchiverService extends IPackageArchiverService.Stub {
return ps;
}
+ private void sendFailureStatus(IntentSender statusReceiver, String packageName,
+ String message) {
+ Slog.d(TAG, TextUtils.formatSimple("Failed to archive %s with message %s", packageName,
+ message));
+ final Intent fillIn = new Intent();
+ fillIn.putExtra(PackageInstaller.EXTRA_PACKAGE_NAME, packageName);
+ fillIn.putExtra(PackageInstaller.EXTRA_STATUS, PackageInstaller.STATUS_FAILURE);
+ fillIn.putExtra(PackageInstaller.EXTRA_STATUS_MESSAGE, message);
+ try {
+ final BroadcastOptions options = BroadcastOptions.makeBasic();
+ options.setPendingIntentBackgroundActivityStartMode(
+ MODE_BACKGROUND_ACTIVITY_START_DENIED);
+ statusReceiver.sendIntent(mContext, 0, fillIn, /* onFinished= */ null,
+ /* handler= */ null, /* requiredPermission= */ null, options.toBundle());
+ } catch (IntentSender.SendIntentException e) {
+ Slog.e(
+ TAG,
+ TextUtils.formatSimple("Failed to send failure status for %s with message %s",
+ packageName, message),
+ e);
+ }
+ }
+
private static void verifyCaller(int providedUid, int binderUid) {
if (providedUid != binderUid) {
throw new SecurityException(
@@ -323,4 +424,44 @@ public class PackageArchiverService extends IPackageArchiverService.Stub {
binderUid));
}
}
+
+ private File createIconsDir(@UserIdInt int userId) throws IOException {
+ File iconsDir = getIconsDir(userId);
+ if (!iconsDir.isDirectory()) {
+ iconsDir.delete();
+ iconsDir.mkdirs();
+ if (!iconsDir.isDirectory()) {
+ throw new IOException("Unable to create directory " + iconsDir);
+ }
+ }
+ SELinux.restorecon(iconsDir);
+ return iconsDir;
+ }
+
+ private File getIconsDir(int userId) {
+ return new File(Environment.getDataSystemCeDirectory(userId), ARCHIVE_ICONS_DIR);
+ }
+
+ private static Bitmap drawableToBitmap(Drawable drawable) {
+ if (drawable instanceof BitmapDrawable) {
+ return ((BitmapDrawable) drawable).getBitmap();
+
+ }
+
+ Bitmap bitmap;
+ if (drawable.getIntrinsicWidth() <= 0 || drawable.getIntrinsicHeight() <= 0) {
+ // Needed for drawables that are just a single color.
+ bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
+ } else {
+ bitmap =
+ Bitmap.createBitmap(
+ drawable.getIntrinsicWidth(),
+ drawable.getIntrinsicHeight(),
+ Bitmap.Config.ARGB_8888);
+ }
+ Canvas canvas = new Canvas(bitmap);
+ drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
+ drawable.draw(canvas);
+ return bitmap;
+ }
}
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index e3602565ef5b..fabef7609546 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -1240,8 +1240,18 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
@Override
public void uninstall(VersionedPackage versionedPackage, String callerPackageName, int flags,
IntentSender statusReceiver, int userId) {
+ uninstall(
+ versionedPackage,
+ callerPackageName,
+ flags,
+ statusReceiver,
+ userId,
+ Binder.getCallingUid());
+ }
+
+ void uninstall(VersionedPackage versionedPackage, String callerPackageName, int flags,
+ IntentSender statusReceiver, int userId, int callingUid) {
final Computer snapshot = mPm.snapshotComputer();
- final int callingUid = Binder.getCallingUid();
snapshot.enforceCrossUserPermission(callingUid, userId, true, true, "uninstall");
if (!PackageManagerServiceUtils.isRootOrShell(callingUid)) {
mAppOps.checkPackage(callingUid, callerPackageName);
@@ -1257,7 +1267,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
final PackageDeleteObserverAdapter adapter = new PackageDeleteObserverAdapter(mContext,
statusReceiver, versionedPackage.getPackageName(),
canSilentlyInstallPackage, userId);
- if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DELETE_PACKAGES)
+ if (mContext.checkCallingOrSelfPermission(Manifest.permission.DELETE_PACKAGES)
== PackageManager.PERMISSION_GRANTED) {
// Sweet, call straight through!
mPm.deletePackageVersioned(versionedPackage, adapter.getBinder(), userId, flags);
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index e8e647010b82..0dd4111adbfa 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -3641,9 +3641,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
@GuardedBy("mLock")
private void maybeStageFsveritySignatureLocked(File origFile, File targetFile,
boolean fsVerityRequired) throws PackageManagerException {
- if (com.android.server.security.Flags.deprecateFsvSig()) {
- return;
- }
final File originalSignature = new File(
VerityUtils.getFsveritySignatureFilePath(origFile.getPath()));
if (originalSignature.exists()) {
diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
index 04232494a026..2028231ab36b 100644
--- a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
+++ b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
@@ -543,9 +543,6 @@ public class PackageManagerServiceUtils {
/** Returns true if standard APK Verity is enabled. */
static boolean isApkVerityEnabled() {
- if (com.android.server.security.Flags.deprecateFsvSig()) {
- return false;
- }
return Build.VERSION.DEVICE_INITIAL_SDK_INT >= Build.VERSION_CODES.R
|| SystemProperties.getInt("ro.apk_verity.mode", FSVERITY_DISABLED)
== FSVERITY_ENABLED;
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index d9f1df5e02c9..a0c9cd1757c3 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -2784,33 +2784,111 @@ class PackageManagerShellCommand extends ShellCommand {
private int runGrantRevokePermission(boolean grant) throws RemoteException {
int userId = UserHandle.USER_SYSTEM;
- String opt = null;
+ String opt;
+ boolean allPermissions = false;
while ((opt = getNextOption()) != null) {
if (opt.equals("--user")) {
userId = UserHandle.parseUserArg(getNextArgRequired());
}
+ if (opt.equals("--all-permissions")) {
+ allPermissions = true;
+ }
}
String pkg = getNextArg();
- if (pkg == null) {
+ if (!allPermissions && pkg == null) {
getErrPrintWriter().println("Error: no package specified");
return 1;
}
String perm = getNextArg();
- if (perm == null) {
+ if (!allPermissions && perm == null) {
getErrPrintWriter().println("Error: no permission specified");
return 1;
}
+ if (allPermissions && perm != null) {
+ getErrPrintWriter().println("Error: permission specified but not expected");
+ return 1;
+ }
final UserHandle translatedUser = UserHandle.of(translateUserId(userId,
UserHandle.USER_NULL, "runGrantRevokePermission"));
- if (grant) {
- mPermissionManager.grantRuntimePermission(pkg, perm, translatedUser);
+
+ List<PackageInfo> packageInfos;
+ if (pkg == null) {
+ packageInfos = mContext.getPackageManager().getInstalledPackages(
+ PackageManager.GET_PERMISSIONS);
} else {
- mPermissionManager.revokeRuntimePermission(pkg, perm, translatedUser, null);
+ try {
+ packageInfos = Collections.singletonList(
+ mContext.getPackageManager().getPackageInfo(pkg,
+ PackageManager.GET_PERMISSIONS));
+ } catch (NameNotFoundException e) {
+ getErrPrintWriter().println("Error: package not found");
+ return 1;
+ }
+ }
+
+ for (PackageInfo packageInfo : packageInfos) {
+ List<String> permissions = Collections.singletonList(perm);
+ if (allPermissions) {
+ permissions = getRequestedRuntimePermissions(packageInfo);
+ }
+ for (String permission : permissions) {
+ if (grant) {
+ try {
+ mPermissionManager.grantRuntimePermission(packageInfo.packageName,
+ permission,
+ translatedUser);
+ } catch (Exception e) {
+ if (!allPermissions) {
+ throw e;
+ } else {
+ Slog.w(TAG, "Could not grant permission " + permission, e);
+ }
+ }
+ } else {
+ try {
+ mPermissionManager.revokeRuntimePermission(packageInfo.packageName,
+ permission,
+ translatedUser, null);
+ } catch (Exception e) {
+ if (!allPermissions) {
+ throw e;
+ } else {
+ Slog.w(TAG, "Could not grant permission " + permission, e);
+ }
+ }
+ }
+ }
}
return 0;
}
+ private List<String> getRequestedRuntimePermissions(PackageInfo info) {
+ // No requested permissions
+ if (info.requestedPermissions == null) {
+ return new ArrayList<>();
+ }
+ List<String> result = new ArrayList<>();
+ PackageManager pm = mContext.getPackageManager();
+ // Iterate through requested permissions for denied ones
+ for (String permission : info.requestedPermissions) {
+ PermissionInfo pi = null;
+ try {
+ pi = pm.getPermissionInfo(permission, 0);
+ } catch (NameNotFoundException nnfe) {
+ // ignore
+ }
+ if (pi == null) {
+ continue;
+ }
+ if (pi.getProtection() != PermissionInfo.PROTECTION_DANGEROUS) {
+ continue;
+ }
+ result.add(permission);
+ }
+ return result;
+ }
+
private int runResetPermissions() throws RemoteException {
mLegacyPermissionManager.resetRuntimePermissions();
return 0;
@@ -4643,11 +4721,15 @@ class PackageManagerShellCommand extends ShellCommand {
pw.println(" get-distracting-restriction [--user USER_ID] PACKAGE [PACKAGE...]");
pw.println(" Gets the specified restriction flags of given package(s) (of the user).");
pw.println("");
- pw.println(" grant [--user USER_ID] PACKAGE PERMISSION");
- pw.println(" revoke [--user USER_ID] PACKAGE PERMISSION");
+ pw.println(" grant [--user USER_ID] [--all-permissions] PACKAGE PERMISSION");
+ pw.println(" revoke [--user USER_ID] [--all-permissions] PACKAGE PERMISSION");
pw.println(" These commands either grant or revoke permissions to apps. The permissions");
pw.println(" must be declared as used in the app's manifest, be runtime permissions");
pw.println(" (protection level dangerous), and the app targeting SDK greater than Lollipop MR1.");
+ pw.println(" Flags are:");
+ pw.println(" --user: Specifies the user for which the operation needs to be performed");
+ pw.println(" --all-permissions: If specified all the missing runtime permissions will");
+ pw.println(" be granted to the PACKAGE or to all the packages if none is specified.");
pw.println("");
pw.println(" set-permission-flags [--user USER_ID] PACKAGE PERMISSION [FLAGS..]");
pw.println(" clear-permission-flags [--user USER_ID] PACKAGE PERMISSION [FLAGS..]");
diff --git a/services/core/java/com/android/server/pm/PackageSetting.java b/services/core/java/com/android/server/pm/PackageSetting.java
index 88184c0cb490..114f80d7998f 100644
--- a/services/core/java/com/android/server/pm/PackageSetting.java
+++ b/services/core/java/com/android/server/pm/PackageSetting.java
@@ -35,6 +35,7 @@ import android.content.pm.overlay.OverlayPaths;
import android.os.UserHandle;
import android.os.incremental.IncrementalManager;
import android.service.pm.PackageProto;
+import android.service.pm.PackageProto.UserInfoProto.ArchiveState.ArchiveActivityInfo;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
@@ -1161,18 +1162,15 @@ public class PackageSetting extends SettingBase implements PackageStateInternal
for (ArchiveState.ArchiveActivityInfo activityInfo : archiveState.getActivityInfos()) {
long activityInfoToken = proto.start(
PackageProto.UserInfoProto.ArchiveState.ACTIVITY_INFOS);
- proto.write(PackageProto.UserInfoProto.ArchiveState.ArchiveActivityInfo.TITLE,
- activityInfo.getTitle());
- proto.write(
- PackageProto.UserInfoProto.ArchiveState.ArchiveActivityInfo.ICON_BITMAP_PATH,
- activityInfo.getIconBitmap().toAbsolutePath().toString());
- proto.write(
- PackageProto
- .UserInfoProto
- .ArchiveState
- .ArchiveActivityInfo
- .MONOCHROME_ICON_BITMAP_PATH,
- activityInfo.getMonochromeIconBitmap().toAbsolutePath().toString());
+ proto.write(ArchiveActivityInfo.TITLE, activityInfo.getTitle());
+ if (activityInfo.getIconBitmap() != null) {
+ proto.write(ArchiveActivityInfo.ICON_BITMAP_PATH,
+ activityInfo.getIconBitmap().toAbsolutePath().toString());
+ }
+ if (activityInfo.getMonochromeIconBitmap() != null) {
+ proto.write(ArchiveActivityInfo.MONOCHROME_ICON_BITMAP_PATH,
+ activityInfo.getMonochromeIconBitmap().toAbsolutePath().toString());
+ }
proto.end(activityInfoToken);
}
diff --git a/services/core/java/com/android/server/pm/RemovePackageHelper.java b/services/core/java/com/android/server/pm/RemovePackageHelper.java
index 2aedf0d8960c..8dec425f074d 100644
--- a/services/core/java/com/android/server/pm/RemovePackageHelper.java
+++ b/services/core/java/com/android/server/pm/RemovePackageHelper.java
@@ -22,7 +22,6 @@ import static android.os.incremental.IncrementalManager.isIncrementalPath;
import static android.os.storage.StorageManager.FLAG_STORAGE_CE;
import static android.os.storage.StorageManager.FLAG_STORAGE_DE;
import static android.os.storage.StorageManager.FLAG_STORAGE_EXTERNAL;
-
import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
import static com.android.server.pm.PackageManagerService.DEBUG_INSTALL;
import static com.android.server.pm.PackageManagerService.DEBUG_REMOVE;
@@ -400,6 +399,21 @@ final class RemovePackageHelper {
changedUsers);
mPm.postPreferredActivityChangedBroadcast(UserHandle.USER_ALL);
}
+ } else if (!deletedPs.isSystem() && outInfo != null && !outInfo.mIsUpdate
+ && outInfo.mRemovedUsers != null) {
+ // For non-system uninstalls with DELETE_KEEP_DATA, set the installed state to false
+ // for affected users. This does not apply to app updates where the old apk is replaced
+ // but the old data remains.
+ if (DEBUG_REMOVE) {
+ Slog.d(TAG, "Updating installed state to false because of DELETE_KEEP_DATA");
+ }
+ for (int userId : outInfo.mRemovedUsers) {
+ if (DEBUG_REMOVE) {
+ final boolean wasInstalled = deletedPs.getInstalled(userId);
+ Slog.d(TAG, " user " + userId + ": " + wasInstalled + " => " + false);
+ }
+ deletedPs.setInstalled(/* installed= */ false, userId);
+ }
}
// make sure to preserve per-user installed state if this removal was just
// a downgrade of a system app to the factory package
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 1137681de5cf..111a32d03b4c 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -2062,8 +2062,9 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile
if (tagName.equals(TAG_ARCHIVE_ACTIVITY_INFO)) {
String title = parser.getAttributeValue(null,
ATTR_ARCHIVE_ACTIVITY_TITLE);
- Path iconPath = Path.of(parser.getAttributeValue(null,
- ATTR_ARCHIVE_ICON_PATH));
+ String iconAttribute = parser.getAttributeValue(null,
+ ATTR_ARCHIVE_ICON_PATH);
+ Path iconPath = iconAttribute == null ? null : Path.of(iconAttribute);
String monochromeAttribute = parser.getAttributeValue(null,
ATTR_ARCHIVE_MONOCHROME_ICON_PATH);
Path monochromeIconPath = monochromeAttribute == null ? null : Path.of(
@@ -2447,8 +2448,10 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile
for (ArchiveState.ArchiveActivityInfo activityInfo : archiveState.getActivityInfos()) {
serializer.startTag(null, TAG_ARCHIVE_ACTIVITY_INFO);
serializer.attribute(null, ATTR_ARCHIVE_ACTIVITY_TITLE, activityInfo.getTitle());
- serializer.attribute(null, ATTR_ARCHIVE_ICON_PATH,
- activityInfo.getIconBitmap().toAbsolutePath().toString());
+ if (activityInfo.getIconBitmap() != null) {
+ serializer.attribute(null, ATTR_ARCHIVE_ICON_PATH,
+ activityInfo.getIconBitmap().toAbsolutePath().toString());
+ }
if (activityInfo.getMonochromeIconBitmap() != null) {
serializer.attribute(null, ATTR_ARCHIVE_MONOCHROME_ICON_PATH,
activityInfo.getMonochromeIconBitmap().toAbsolutePath().toString());
diff --git a/services/core/java/com/android/server/pm/pkg/ArchiveState.java b/services/core/java/com/android/server/pm/pkg/ArchiveState.java
index d44ae1652da5..4916a4a6d72a 100644
--- a/services/core/java/com/android/server/pm/pkg/ArchiveState.java
+++ b/services/core/java/com/android/server/pm/pkg/ArchiveState.java
@@ -56,8 +56,11 @@ public class ArchiveState {
@NonNull
private final String mTitle;
- /** The path to the stored icon of the activity in the app's locale. */
- @NonNull
+ /**
+ * The path to the stored icon of the activity in the app's locale. Null if the app does
+ * not define any icon (default icon would be shown on the launcher).
+ */
+ @Nullable
private final Path mIconBitmap;
/** See {@link #mIconBitmap}. Only set if the app defined a monochrome icon. */
@@ -85,21 +88,20 @@ public class ArchiveState {
* @param title
* Corresponds to the activity's android:label in the app's locale.
* @param iconBitmap
- * The path to the stored icon of the activity in the app's locale.
+ * The path to the stored icon of the activity in the app's locale. Null if the app does
+ * not define any icon (default icon would be shown on the launcher).
* @param monochromeIconBitmap
* See {@link #mIconBitmap}. Only set if the app defined a monochrome icon.
*/
@DataClass.Generated.Member
public ArchiveActivityInfo(
@NonNull String title,
- @NonNull Path iconBitmap,
+ @Nullable Path iconBitmap,
@Nullable Path monochromeIconBitmap) {
this.mTitle = title;
com.android.internal.util.AnnotationValidations.validate(
NonNull.class, null, mTitle);
this.mIconBitmap = iconBitmap;
- com.android.internal.util.AnnotationValidations.validate(
- NonNull.class, null, mIconBitmap);
this.mMonochromeIconBitmap = monochromeIconBitmap;
// onConstructed(); // You can define this method to get a callback
@@ -114,10 +116,11 @@ public class ArchiveState {
}
/**
- * The path to the stored icon of the activity in the app's locale.
+ * The path to the stored icon of the activity in the app's locale. Null if the app does
+ * not define any icon (default icon would be shown on the launcher).
*/
@DataClass.Generated.Member
- public @NonNull Path getIconBitmap() {
+ public @Nullable Path getIconBitmap() {
return mIconBitmap;
}
@@ -174,10 +177,10 @@ public class ArchiveState {
}
@DataClass.Generated(
- time = 1689169065133L,
+ time = 1693590309015L,
codegenVersion = "1.0.23",
sourceFile = "frameworks/base/services/core/java/com/android/server/pm/pkg/ArchiveState.java",
- inputSignatures = "private final @android.annotation.NonNull java.lang.String mTitle\nprivate final @android.annotation.NonNull java.nio.file.Path mIconBitmap\nprivate final @android.annotation.Nullable java.nio.file.Path mMonochromeIconBitmap\nclass ArchiveActivityInfo extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genToString=true)")
+ inputSignatures = "private final @android.annotation.NonNull java.lang.String mTitle\nprivate final @android.annotation.Nullable java.nio.file.Path mIconBitmap\nprivate final @android.annotation.Nullable java.nio.file.Path mMonochromeIconBitmap\nclass ArchiveActivityInfo extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genToString=true)")
@Deprecated
private void __metadata() {}
@@ -292,7 +295,7 @@ public class ArchiveState {
}
@DataClass.Generated(
- time = 1689169065144L,
+ time = 1693590309027L,
codegenVersion = "1.0.23",
sourceFile = "frameworks/base/services/core/java/com/android/server/pm/pkg/ArchiveState.java",
inputSignatures = "private final @android.annotation.NonNull java.util.List<com.android.server.pm.pkg.ArchiveActivityInfo> mActivityInfos\nprivate final @android.annotation.NonNull java.lang.String mInstallerTitle\nclass ArchiveState extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genToString=true)")
diff --git a/services/core/java/com/android/server/security/FileIntegrityService.java b/services/core/java/com/android/server/security/FileIntegrityService.java
index 0879d9575c97..3aed6e30cf87 100644
--- a/services/core/java/com/android/server/security/FileIntegrityService.java
+++ b/services/core/java/com/android/server/security/FileIntegrityService.java
@@ -90,13 +90,6 @@ public class FileIntegrityService extends SystemService {
@NonNull String packageName) {
checkCallerPermission(packageName);
- if (Flags.deprecateFsvSig()) {
- // When deprecated, stop telling the caller that any app source certificate is
- // trusted on the current device. This behavior is also consistent with devices
- // without this feature support.
- return false;
- }
-
try {
if (!VerityUtils.isFsVeritySupported()) {
return false;
diff --git a/services/core/java/com/android/server/wm/ActivityClientController.java b/services/core/java/com/android/server/wm/ActivityClientController.java
index d430dda1b463..b823e7353a84 100644
--- a/services/core/java/com/android/server/wm/ActivityClientController.java
+++ b/services/core/java/com/android/server/wm/ActivityClientController.java
@@ -1170,9 +1170,7 @@ class ActivityClientController extends IActivityClientController.Stub {
fullscreenRequest, r);
reportMultiwindowFullscreenRequestValidatingResult(callback, validateResult);
if (validateResult != RESULT_APPROVED) {
- if (queued) {
- transition.abort();
- }
+ transition.abort();
return;
}
transition.collect(topFocusedRootTask);
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index f47007b28e5b..4aea70c6dd64 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -3659,6 +3659,9 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
synchronized (mGlobalLock) {
if (r.getParent() == null) {
Slog.e(TAG, "Skip enterPictureInPictureMode, destroyed " + r);
+ if (transition != null) {
+ transition.abort();
+ }
return;
}
EventLogTags.writeWmEnterPip(r.mUserId, System.identityHashCode(r),
diff --git a/services/core/java/com/android/server/wm/ContentRecorder.java b/services/core/java/com/android/server/wm/ContentRecorder.java
index 5aa7c97ecb08..f0e4149a9159 100644
--- a/services/core/java/com/android/server/wm/ContentRecorder.java
+++ b/services/core/java/com/android/server/wm/ContentRecorder.java
@@ -35,6 +35,7 @@ import android.os.RemoteException;
import android.os.ServiceManager;
import android.provider.DeviceConfig;
import android.view.ContentRecordingSession;
+import android.view.ContentRecordingSession.RecordContent;
import android.view.Display;
import android.view.SurfaceControl;
@@ -84,6 +85,7 @@ final class ContentRecorder implements WindowContainerListener {
/**
* The last configuration orientation.
*/
+ @Configuration.Orientation
private int mLastOrientation = ORIENTATION_UNDEFINED;
ContentRecorder(@NonNull DisplayContent displayContent) {
@@ -156,7 +158,8 @@ final class ContentRecorder implements WindowContainerListener {
// Retrieve the size of the region to record, and continue with the update
// if the bounds or orientation has changed.
final Rect recordedContentBounds = mRecordedWindowContainer.getBounds();
- int recordedContentOrientation = mRecordedWindowContainer.getOrientation();
+ @Configuration.Orientation int recordedContentOrientation =
+ mRecordedWindowContainer.getConfiguration().orientation;
if (!mLastRecordedBounds.equals(recordedContentBounds)
|| lastOrientation != recordedContentOrientation) {
Point surfaceSize = fetchSurfaceSizeIfPresent();
@@ -356,7 +359,7 @@ final class ContentRecorder implements WindowContainerListener {
*/
@Nullable
private WindowContainer retrieveRecordedWindowContainer() {
- final int contentToRecord = mContentRecordingSession.getContentToRecord();
+ @RecordContent final int contentToRecord = mContentRecordingSession.getContentToRecord();
final IBinder tokenToRecord = mContentRecordingSession.getTokenToRecord();
switch (contentToRecord) {
case RECORD_CONTENT_DISPLAY:
@@ -472,6 +475,12 @@ final class ContentRecorder implements WindowContainerListener {
shiftedY = (surfaceSize.y - scaledHeight) / 2;
}
+ ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
+ "Content Recording: Apply transformations of shift %d x %d, scale %f, crop %d x "
+ + "%d for display %d",
+ shiftedX, shiftedY, scale, recordedContentBounds.width(),
+ recordedContentBounds.height(), mDisplayContent.getDisplayId());
+
transaction
// Crop the area to capture to exclude the 'extra' wallpaper that is used
// for parallax (b/189930234).
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 707b7799460e..395ab3a641b4 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -269,6 +269,8 @@ public class DisplayPolicy {
private boolean mIsFreeformWindowOverlappingWithNavBar;
+ private @InsetsType int mForciblyShownTypes;
+
private boolean mIsImmersiveMode;
// The windows we were told about in focusChanged.
@@ -1402,6 +1404,7 @@ public class DisplayPolicy {
mAllowLockscreenWhenOn = false;
mShowingDream = false;
mIsFreeformWindowOverlappingWithNavBar = false;
+ mForciblyShownTypes = 0;
}
/**
@@ -1459,6 +1462,10 @@ public class DisplayPolicy {
}
}
+ if (win.mSession.mCanForceShowingInsets) {
+ mForciblyShownTypes |= win.mAttrs.forciblyShownTypes;
+ }
+
if (!affectsSystemUi) {
return;
}
@@ -1640,6 +1647,10 @@ public class DisplayPolicy {
mService.mPolicy.setAllowLockscreenWhenOn(getDisplayId(), mAllowLockscreenWhenOn);
}
+ boolean areTypesForciblyShownTransiently(@InsetsType int types) {
+ return (mForciblyShownTypes & types) == types;
+ }
+
/**
* Applies the keyguard policy to a specific window.
*
diff --git a/services/core/java/com/android/server/wm/InsetsPolicy.java b/services/core/java/com/android/server/wm/InsetsPolicy.java
index 835c92d0a30d..03f025b1f0f4 100644
--- a/services/core/java/com/android/server/wm/InsetsPolicy.java
+++ b/services/core/java/com/android/server/wm/InsetsPolicy.java
@@ -23,8 +23,6 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.view.InsetsSource.ID_IME;
import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION;
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
import android.annotation.NonNull;
@@ -473,7 +471,7 @@ class InsetsPolicy {
// we will dispatch the real visibility of status bar to the client.
return mPermanentControlTarget;
}
- if (forceShowsStatusBarTransiently() && !fake) {
+ if (mPolicy.areTypesForciblyShownTransiently(Type.statusBars()) && !fake) {
// Status bar is forcibly shown transiently, and its new visibility won't be
// dispatched to the client so that we can keep the layout stable. We will dispatch the
// fake control to the client, so that it can re-show the bar during this scenario.
@@ -505,7 +503,7 @@ class InsetsPolicy {
if (imeWin != null && imeWin.isVisible() && !mHideNavBarForKeyboard) {
// Force showing navigation bar while IME is visible and if navigation bar is not
// configured to be hidden by the IME.
- return null;
+ return mPermanentControlTarget;
}
if (!fake && isTransient(Type.navigationBars())) {
return mTransientControlTarget;
@@ -533,7 +531,7 @@ class InsetsPolicy {
// bar, and we will dispatch the real visibility of navigation bar to the client.
return mPermanentControlTarget;
}
- if (forceShowsNavigationBarTransiently() && !fake) {
+ if (mPolicy.areTypesForciblyShownTransiently(Type.navigationBars()) && !fake) {
// Navigation bar is forcibly shown transiently, and its new visibility won't be
// dispatched to the client so that we can keep the layout stable. We will dispatch the
// fake control to the client, so that it can re-show the bar during this scenario.
@@ -603,17 +601,6 @@ class InsetsPolicy {
&& focusedWin.getAttrs().type <= WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
}
- private boolean forceShowsStatusBarTransiently() {
- final WindowState win = mPolicy.getStatusBar();
- return win != null && (win.mAttrs.privateFlags & PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR) != 0;
- }
-
- private boolean forceShowsNavigationBarTransiently() {
- final WindowState win = mPolicy.getNotificationShade();
- return win != null
- && (win.mAttrs.privateFlags & PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION) != 0;
- }
-
private void dispatchTransientSystemBarsVisibilityChanged(
@Nullable WindowState focusedWindow,
boolean areVisible,
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index 1845ae8cd92b..0c45eea2d365 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -23,6 +23,7 @@ import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
import static android.Manifest.permission.SET_UNRESTRICTED_GESTURE_EXCLUSION;
import static android.Manifest.permission.SET_UNRESTRICTED_KEEP_CLEAR_AREAS;
import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
+import static android.Manifest.permission.STATUS_BAR_SERVICE;
import static android.Manifest.permission.SYSTEM_APPLICATION_OVERLAY;
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
import static android.content.ClipDescription.MIMETYPE_APPLICATION_ACTIVITY;
@@ -108,6 +109,7 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient {
private final ArraySet<WindowSurfaceController> mAlertWindowSurfaces = new ArraySet<>();
private final DragDropController mDragDropController;
final boolean mCanAddInternalSystemWindow;
+ final boolean mCanForceShowingInsets;
private final boolean mCanStartTasksFromRecents;
final boolean mCanCreateSystemApplicationOverlay;
@@ -131,6 +133,9 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient {
mLastReportedAnimatorScale = service.getCurrentAnimatorScale();
mCanAddInternalSystemWindow = service.mContext.checkCallingOrSelfPermission(
INTERNAL_SYSTEM_WINDOW) == PERMISSION_GRANTED;
+ mCanForceShowingInsets = service.mAtmService.isCallerRecents(mUid)
+ || service.mContext.checkCallingOrSelfPermission(STATUS_BAR_SERVICE)
+ == PERMISSION_GRANTED;
mCanHideNonSystemOverlayWindows = service.mContext.checkCallingOrSelfPermission(
HIDE_NON_SYSTEM_OVERLAY_WINDOWS) == PERMISSION_GRANTED
|| service.mContext.checkCallingOrSelfPermission(HIDE_OVERLAY_WINDOWS)
diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java
index a6c64912edd3..843e6d154ecb 100644
--- a/services/core/java/com/android/server/wm/Transition.java
+++ b/services/core/java/com/android/server/wm/Transition.java
@@ -1487,6 +1487,11 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
return;
}
+ if (mState != STATE_STARTED) {
+ Slog.e(TAG, "Playing a Transition which hasn't started! #" + mSyncId + " This will "
+ + "likely cause an exception in Shell");
+ }
+
mState = STATE_PLAYING;
mStartTransaction = transaction;
mFinishTransaction = mController.mAtm.mWindowManager.mTransactionFactory.get();
diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp
index 55deb2203a03..176bc28389e5 100644
--- a/services/core/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/core/jni/com_android_server_input_InputManagerService.cpp
@@ -42,6 +42,7 @@
#include <android_view_VerifiedMotionEvent.h>
#include <batteryservice/include/batteryservice/BatteryServiceConstants.h>
#include <binder/IServiceManager.h>
+#include <com_android_input_flags.h>
#include <input/Input.h>
#include <input/PointerController.h>
#include <input/SpriteController.h>
@@ -81,6 +82,8 @@ static constexpr std::chrono::duration MAX_VIBRATE_PATTERN_DELAY = 100s;
static constexpr std::chrono::milliseconds MAX_VIBRATE_PATTERN_DELAY_MILLIS =
std::chrono::duration_cast<std::chrono::milliseconds>(MAX_VIBRATE_PATTERN_DELAY);
+namespace input_flags = com::android::input::flags;
+
namespace android {
// The exponent used to calculate the pointer speed scaling factor.
@@ -733,7 +736,7 @@ std::shared_ptr<PointerControllerInterface> NativeInputManager::obtainPointerCon
ensureSpriteControllerLocked();
static const bool ENABLE_POINTER_CHOREOGRAPHER =
- sysprop::InputProperties::enable_pointer_choreographer().value_or(false);
+ input_flags::enable_pointer_choreographer();
// Disable the functionality of the legacy PointerController if PointerChoreographer is
// enabled.
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
index b4a66bd75a6e..76b41b70cdf4 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
@@ -1895,6 +1895,13 @@ public class MockingOomAdjusterTests {
assertProcStates(app2, PROCESS_STATE_FOREGROUND_SERVICE, PERCEPTIBLE_APP_ADJ,
SCHED_GROUP_DEFAULT);
assertBfsl(app2);
+
+ bindService(client2, app1, null, 0, mock(IBinder.class));
+ bindService(app1, client2, null, 0, mock(IBinder.class));
+ client2.mServices.setHasForegroundServices(false, 0, /* hasNoneType=*/false);
+ updateOomAdj(app1, client1, client2);
+ assertProcStates(app1, PROCESS_STATE_IMPORTANT_FOREGROUND, VISIBLE_APP_ADJ,
+ SCHED_GROUP_TOP_APP);
}
@SuppressWarnings("GuardedBy")
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/PackageArchiverServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/pm/PackageArchiverServiceTest.java
index 80576a688fdd..60b28d3a2ff0 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/PackageArchiverServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/PackageArchiverServiceTest.java
@@ -25,6 +25,7 @@ import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
@@ -34,11 +35,15 @@ import android.app.AppOpsManager;
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
+import android.content.pm.ActivityInfo;
import android.content.pm.LauncherActivityInfo;
import android.content.pm.LauncherApps;
import android.content.pm.PackageArchiver;
+import android.content.pm.PackageInstaller;
import android.content.pm.PackageManager;
import android.content.pm.VersionedPackage;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
@@ -62,6 +67,7 @@ import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import java.io.IOException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
@@ -74,9 +80,10 @@ public class PackageArchiverServiceTest {
private static final String PACKAGE = "com.example";
private static final String CALLER_PACKAGE = "com.caller";
private static final String INSTALLER_PACKAGE = "com.installer";
+ private static final Path ICON_PATH = Path.of("icon.png");
@Rule
- public final MockSystemRule mMockSystem = new MockSystemRule();
+ public final MockSystemRule rule = new MockSystemRule();
@Mock
private IntentSender mIntentSender;
@@ -87,9 +94,13 @@ public class PackageArchiverServiceTest {
@Mock
private LauncherApps mLauncherApps;
@Mock
+ private PackageManager mPackageManager;
+ @Mock
private PackageInstallerService mInstallerService;
@Mock
private PackageStateInternal mPackageState;
+ @Mock
+ private Bitmap mIcon;
private final InstallSource mInstallSource =
InstallSource.create(
@@ -102,7 +113,6 @@ public class PackageArchiverServiceTest {
/* packageSource= */ 0);
private final List<LauncherActivityInfo> mLauncherActivityInfos = createLauncherActivities();
-
private final int mUserId = UserHandle.CURRENT.getIdentifier();
private PackageUserStateImpl mUserState;
@@ -114,10 +124,10 @@ public class PackageArchiverServiceTest {
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
- mMockSystem.system().stageNominalSystemState();
- when(mMockSystem.mocks().getInjector().getPackageInstallerService()).thenReturn(
+ rule.system().stageNominalSystemState();
+ when(rule.mocks().getInjector().getPackageInstallerService()).thenReturn(
mInstallerService);
- PackageManagerService pm = spy(new PackageManagerService(mMockSystem.mocks().getInjector(),
+ PackageManagerService pm = spy(new PackageManagerService(rule.mocks().getInjector(),
/* factoryTest= */false,
MockSystem.Companion.getDEFAULT_VERSION_INFO().fingerprint,
/* isEngBuild= */ false,
@@ -132,18 +142,27 @@ public class PackageArchiverServiceTest {
when(mPackageState.getPackageName()).thenReturn(PACKAGE);
when(mPackageState.getInstallSource()).thenReturn(mInstallSource);
mPackageSetting = createBasicPackageSetting();
- when(mMockSystem.mocks().getSettings().getPackageLPr(eq(PACKAGE))).thenReturn(
+ when(rule.mocks().getSettings().getPackageLPr(eq(PACKAGE))).thenReturn(
mPackageSetting);
mUserState = new PackageUserStateImpl().setInstalled(true);
mPackageSetting.setUserState(mUserId, mUserState);
when(mPackageState.getUserStateOrDefault(eq(mUserId))).thenReturn(mUserState);
+
when(mContext.getSystemService(LauncherApps.class)).thenReturn(mLauncherApps);
when(mLauncherApps.getActivityList(eq(PACKAGE), eq(UserHandle.CURRENT))).thenReturn(
mLauncherActivityInfos);
doReturn(mComputer).when(pm).snapshotComputer();
when(mComputer.getPackageUid(eq(CALLER_PACKAGE), eq(0L), eq(mUserId))).thenReturn(
Binder.getCallingUid());
- mArchiveService = new PackageArchiverService(mContext, pm);
+
+ when(mContext.getPackageManager()).thenReturn(mPackageManager);
+ when(mPackageManager.getResourcesForApplication(eq(PACKAGE))).thenReturn(
+ mock(Resources.class));
+ when(mIcon.compress(eq(Bitmap.CompressFormat.PNG), eq(100), any())).thenReturn(true);
+
+ mArchiveService = spy(new PackageArchiverService(mContext, pm));
+ doReturn(ICON_PATH).when(mArchiveService).storeIcon(eq(PACKAGE),
+ any(LauncherActivityInfo.class), eq(mUserId));
}
@Test
@@ -175,15 +194,20 @@ public class PackageArchiverServiceTest {
}
@Test
- public void archiveApp_packageNotInstalledForUser() {
+ public void archiveApp_packageNotInstalledForUser() throws IntentSender.SendIntentException {
mPackageSetting.modifyUserState(UserHandle.CURRENT.getIdentifier()).setInstalled(false);
- Exception e = assertThrows(
- ParcelableException.class,
- () -> mArchiveService.requestArchive(PACKAGE, CALLER_PACKAGE, mIntentSender,
- UserHandle.CURRENT));
- assertThat(e.getCause()).isInstanceOf(PackageManager.NameNotFoundException.class);
- assertThat(e.getCause()).hasMessageThat().isEqualTo(
+ mArchiveService.requestArchive(PACKAGE, CALLER_PACKAGE, mIntentSender, UserHandle.CURRENT);
+ rule.mocks().getHandler().flush();
+
+ ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+ verify(mIntentSender).sendIntent(any(), anyInt(), intentCaptor.capture(), any(), any(),
+ any(), any());
+ Intent value = intentCaptor.getValue();
+ assertThat(value.getStringExtra(PackageInstaller.EXTRA_PACKAGE_NAME)).isEqualTo(PACKAGE);
+ assertThat(value.getIntExtra(PackageInstaller.EXTRA_STATUS, 0)).isEqualTo(
+ PackageInstaller.STATUS_FAILURE);
+ assertThat(value.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE)).isEqualTo(
String.format("Package %s not found.", PACKAGE));
}
@@ -223,13 +247,34 @@ public class PackageArchiverServiceTest {
}
@Test
+ public void archiveApp_storeIconFails() throws IntentSender.SendIntentException, IOException {
+ IOException e = new IOException("IO");
+ doThrow(e).when(mArchiveService).storeIcon(eq(PACKAGE),
+ any(LauncherActivityInfo.class), eq(mUserId));
+
+ mArchiveService.requestArchive(PACKAGE, CALLER_PACKAGE, mIntentSender, UserHandle.CURRENT);
+ rule.mocks().getHandler().flush();
+
+ ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+ verify(mIntentSender).sendIntent(any(), anyInt(), intentCaptor.capture(), any(), any(),
+ any(), any());
+ Intent value = intentCaptor.getValue();
+ assertThat(value.getStringExtra(PackageInstaller.EXTRA_PACKAGE_NAME)).isEqualTo(PACKAGE);
+ assertThat(value.getIntExtra(PackageInstaller.EXTRA_STATUS, 0)).isEqualTo(
+ PackageInstaller.STATUS_FAILURE);
+ assertThat(value.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE)).isEqualTo(
+ e.toString());
+ }
+
+ @Test
public void archiveApp_success() {
mArchiveService.requestArchive(PACKAGE, CALLER_PACKAGE, mIntentSender, UserHandle.CURRENT);
+ rule.mocks().getHandler().flush();
verify(mInstallerService).uninstall(
eq(new VersionedPackage(PACKAGE, PackageManager.VERSION_CODE_HIGHEST)),
eq(CALLER_PACKAGE), eq(DELETE_KEEP_DATA), eq(mIntentSender),
- eq(UserHandle.CURRENT.getIdentifier()));
+ eq(UserHandle.CURRENT.getIdentifier()), anyInt());
assertThat(mPackageSetting.readUserState(
UserHandle.CURRENT.getIdentifier()).getArchiveState()).isEqualTo(
createArchiveState());
@@ -305,7 +350,7 @@ public class PackageArchiverServiceTest {
mUserState.setArchiveState(createArchiveState()).setInstalled(false);
mArchiveService.requestUnarchive(PACKAGE, CALLER_PACKAGE, UserHandle.CURRENT);
- mMockSystem.mocks().getHandler().flush();
+ rule.mocks().getHandler().flush();
ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
verify(mContext).sendOrderedBroadcastAsUser(
@@ -331,20 +376,22 @@ public class PackageArchiverServiceTest {
private static ArchiveState createArchiveState() {
List<ArchiveState.ArchiveActivityInfo> activityInfos = new ArrayList<>();
for (LauncherActivityInfo mainActivity : createLauncherActivities()) {
- // TODO(b/278553670) Extract and store launcher icons
ArchiveState.ArchiveActivityInfo activityInfo = new ArchiveState.ArchiveActivityInfo(
mainActivity.getLabel().toString(),
- Path.of("/TODO"), null);
+ ICON_PATH, null);
activityInfos.add(activityInfo);
}
return new ArchiveState(activityInfos, INSTALLER_PACKAGE);
}
private static List<LauncherActivityInfo> createLauncherActivities() {
+ ActivityInfo activityInfo = mock(ActivityInfo.class);
LauncherActivityInfo activity1 = mock(LauncherActivityInfo.class);
when(activity1.getLabel()).thenReturn("activity1");
+ when(activity1.getActivityInfo()).thenReturn(activityInfo);
LauncherActivityInfo activity2 = mock(LauncherActivityInfo.class);
when(activity2.getLabel()).thenReturn("activity2");
+ when(activity2.getActivityInfo()).thenReturn(activityInfo);
return List.of(activity1, activity2);
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/tare/AgentTest.java b/services/tests/mockingservicestests/src/com/android/server/tare/AgentTest.java
index 94fff22cffe1..a3917765e4b8 100644
--- a/services/tests/mockingservicestests/src/com/android/server/tare/AgentTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/tare/AgentTest.java
@@ -55,6 +55,7 @@ public class AgentTest {
@Mock
private InternalResourceService mIrs;
+ private Agent mAgent;
private Scribe mScribe;
private static class MockScribe extends Scribe {
@@ -80,10 +81,13 @@ public class AgentTest {
doReturn(mIrs).when(mIrs).getLock();
doReturn(mock(AlarmManager.class)).when(mContext).getSystemService(Context.ALARM_SERVICE);
mScribe = new MockScribe(mIrs, mAnalyst);
+ mAgent = new Agent(mIrs, mScribe, mAnalyst);
}
@After
public void tearDown() {
+ mAgent.tearDownLocked();
+
if (mMockingSession != null) {
mMockingSession.finishMocking();
}
@@ -99,7 +103,6 @@ public class AgentTest {
final int userId = 0;
final String pkgName = "com.test";
- final Agent agent = new Agent(mIrs, mScribe, mAnalyst);
final Ledger ledger = mScribe.getLedgerLocked(userId, pkgName);
doReturn(consumptionLimit).when(mIrs).getConsumptionLimitLocked();
@@ -107,66 +110,64 @@ public class AgentTest {
.getMaxSatiatedBalance(anyInt(), anyString());
Ledger.Transaction transaction = new Ledger.Transaction(0, 0, 0, null, 5, 10);
- agent.recordTransactionLocked(userId, pkgName, ledger, transaction, false);
+ mAgent.recordTransactionLocked(userId, pkgName, ledger, transaction, false);
assertEquals(5, ledger.getCurrentBalance());
assertEquals(remainingCakes - 10, mScribe.getRemainingConsumableCakesLocked());
- agent.onPackageRemovedLocked(userId, pkgName);
+ mAgent.onPackageRemovedLocked(userId, pkgName);
assertEquals(remainingCakes - 10, mScribe.getRemainingConsumableCakesLocked());
assertLedgersEqual(new Ledger(), mScribe.getLedgerLocked(userId, pkgName));
}
@Test
public void testRecordTransaction_UnderMax() {
- Agent agent = new Agent(mIrs, mScribe, mAnalyst);
Ledger ledger = new Ledger();
doReturn(1_000_000L).when(mIrs).getConsumptionLimitLocked();
doReturn(1_000_000L).when(mEconomicPolicy).getMaxSatiatedBalance(anyInt(), anyString());
Ledger.Transaction transaction = new Ledger.Transaction(0, 0, 0, null, 5, 0);
- agent.recordTransactionLocked(0, "com.test", ledger, transaction, false);
+ mAgent.recordTransactionLocked(0, "com.test", ledger, transaction, false);
assertEquals(5, ledger.getCurrentBalance());
transaction = new Ledger.Transaction(0, 0, 0, null, 995, 0);
- agent.recordTransactionLocked(0, "com.test", ledger, transaction, false);
+ mAgent.recordTransactionLocked(0, "com.test", ledger, transaction, false);
assertEquals(1000, ledger.getCurrentBalance());
transaction = new Ledger.Transaction(0, 0, 0, null, -500, 250);
- agent.recordTransactionLocked(0, "com.test", ledger, transaction, false);
+ mAgent.recordTransactionLocked(0, "com.test", ledger, transaction, false);
assertEquals(500, ledger.getCurrentBalance());
transaction = new Ledger.Transaction(0, 0, 0, null, 999_500L, 500);
- agent.recordTransactionLocked(0, "com.test", ledger, transaction, false);
+ mAgent.recordTransactionLocked(0, "com.test", ledger, transaction, false);
assertEquals(1_000_000L, ledger.getCurrentBalance());
transaction = new Ledger.Transaction(0, 0, 0, null, -1_000_001L, 1000);
- agent.recordTransactionLocked(0, "com.test", ledger, transaction, false);
+ mAgent.recordTransactionLocked(0, "com.test", ledger, transaction, false);
assertEquals(-1, ledger.getCurrentBalance());
}
@Test
public void testRecordTransaction_MaxConsumptionLimit() {
- Agent agent = new Agent(mIrs, mScribe, mAnalyst);
Ledger ledger = new Ledger();
doReturn(1000L).when(mIrs).getConsumptionLimitLocked();
doReturn(1_000_000L).when(mEconomicPolicy).getMaxSatiatedBalance(anyInt(), anyString());
Ledger.Transaction transaction = new Ledger.Transaction(0, 0, 0, null, 5, 0);
- agent.recordTransactionLocked(0, "com.test", ledger, transaction, false);
+ mAgent.recordTransactionLocked(0, "com.test", ledger, transaction, false);
assertEquals(5, ledger.getCurrentBalance());
transaction = new Ledger.Transaction(0, 0, 0, null, 995, 0);
- agent.recordTransactionLocked(0, "com.test", ledger, transaction, false);
+ mAgent.recordTransactionLocked(0, "com.test", ledger, transaction, false);
assertEquals(1000, ledger.getCurrentBalance());
transaction = new Ledger.Transaction(0, 0, 0, null, -500, 250);
- agent.recordTransactionLocked(0, "com.test", ledger, transaction, false);
+ mAgent.recordTransactionLocked(0, "com.test", ledger, transaction, false);
assertEquals(500, ledger.getCurrentBalance());
transaction = new Ledger.Transaction(0, 0, 0, null, 2000, 0);
- agent.recordTransactionLocked(0, "com.test", ledger, transaction, false);
+ mAgent.recordTransactionLocked(0, "com.test", ledger, transaction, false);
assertEquals(2500, ledger.getCurrentBalance());
// ConsumptionLimit can change as the battery level changes. Ledger balances shouldn't be
@@ -174,57 +175,56 @@ public class AgentTest {
doReturn(900L).when(mIrs).getConsumptionLimitLocked();
transaction = new Ledger.Transaction(0, 0, 0, null, 100, 0);
- agent.recordTransactionLocked(0, "com.test", ledger, transaction, false);
+ mAgent.recordTransactionLocked(0, "com.test", ledger, transaction, false);
assertEquals(2600, ledger.getCurrentBalance());
transaction = new Ledger.Transaction(0, 0, 0, null, -50, 50);
- agent.recordTransactionLocked(0, "com.test", ledger, transaction, false);
+ mAgent.recordTransactionLocked(0, "com.test", ledger, transaction, false);
assertEquals(2550, ledger.getCurrentBalance());
transaction = new Ledger.Transaction(0, 0, 0, null, -200, 100);
- agent.recordTransactionLocked(0, "com.test", ledger, transaction, false);
+ mAgent.recordTransactionLocked(0, "com.test", ledger, transaction, false);
assertEquals(2350, ledger.getCurrentBalance());
doReturn(800L).when(mIrs).getConsumptionLimitLocked();
transaction = new Ledger.Transaction(0, 0, 0, null, 100, 0);
- agent.recordTransactionLocked(0, "com.test", ledger, transaction, false);
+ mAgent.recordTransactionLocked(0, "com.test", ledger, transaction, false);
assertEquals(2450, ledger.getCurrentBalance());
}
@Test
public void testRecordTransaction_MaxSatiatedBalance() {
- Agent agent = new Agent(mIrs, mScribe, mAnalyst);
Ledger ledger = new Ledger();
doReturn(1_000_000L).when(mIrs).getConsumptionLimitLocked();
doReturn(1000L).when(mEconomicPolicy).getMaxSatiatedBalance(anyInt(), anyString());
Ledger.Transaction transaction = new Ledger.Transaction(0, 0, 0, null, 5, 0);
- agent.recordTransactionLocked(0, "com.test", ledger, transaction, false);
+ mAgent.recordTransactionLocked(0, "com.test", ledger, transaction, false);
assertEquals(5, ledger.getCurrentBalance());
transaction = new Ledger.Transaction(0, 0, 0, null, 995, 0);
- agent.recordTransactionLocked(0, "com.test", ledger, transaction, false);
+ mAgent.recordTransactionLocked(0, "com.test", ledger, transaction, false);
assertEquals(1000, ledger.getCurrentBalance());
transaction = new Ledger.Transaction(0, 0, 0, null, -500, 250);
- agent.recordTransactionLocked(0, "com.test", ledger, transaction, false);
+ mAgent.recordTransactionLocked(0, "com.test", ledger, transaction, false);
assertEquals(500, ledger.getCurrentBalance());
transaction = new Ledger.Transaction(0, 0, 0, null, 999_500L, 1000);
- agent.recordTransactionLocked(0, "com.test", ledger, transaction, false);
+ mAgent.recordTransactionLocked(0, "com.test", ledger, transaction, false);
assertEquals(1_000, ledger.getCurrentBalance());
// Shouldn't change in normal operation, but adding test case in case it does.
doReturn(900L).when(mEconomicPolicy).getMaxSatiatedBalance(anyInt(), anyString());
transaction = new Ledger.Transaction(0, 0, 0, null, 500, 0);
- agent.recordTransactionLocked(0, "com.test", ledger, transaction, false);
+ mAgent.recordTransactionLocked(0, "com.test", ledger, transaction, false);
assertEquals(1_000, ledger.getCurrentBalance());
transaction = new Ledger.Transaction(0, 0, 0, null, -1001, 500);
- agent.recordTransactionLocked(0, "com.test", ledger, transaction, false);
+ mAgent.recordTransactionLocked(0, "com.test", ledger, transaction, false);
assertEquals(-1, ledger.getCurrentBalance());
}
}
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/ProxyManagerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/ProxyManagerTest.java
index 6c7b995d07a2..035bef6b8feb 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/ProxyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/ProxyManagerTest.java
@@ -23,7 +23,14 @@ import static com.android.server.accessibility.ProxyAccessibilityServiceConnecti
import static com.android.server.accessibility.ProxyManager.PROXY_COMPONENT_CLASS_NAME;
import static com.android.server.accessibility.ProxyManager.PROXY_COMPONENT_PACKAGE_NAME;
+import static com.google.common.truth.Truth.assertThat;
+
import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
import android.accessibilityservice.AccessibilityGestureEvent;
import android.accessibilityservice.AccessibilityServiceInfo;
@@ -40,6 +47,7 @@ import android.graphics.Region;
import android.os.IBinder;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
+import android.platform.test.flag.junit.SetFlagsRule;
import android.util.ArraySet;
import android.view.KeyEvent;
import android.view.MotionEvent;
@@ -48,6 +56,8 @@ import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.IAccessibilityManagerClient;
import android.view.inputmethod.EditorInfo;
+import androidx.test.InstrumentationRegistry;
+
import com.android.internal.R;
import com.android.internal.inputmethod.IAccessibilityInputMethodSession;
import com.android.internal.inputmethod.IAccessibilityInputMethodSessionCallback;
@@ -58,20 +68,12 @@ import com.android.server.accessibility.test.MessageCapturingHandler;
import com.android.server.companion.virtual.VirtualDeviceManagerInternal;
import com.android.server.wm.WindowManagerInternal;
-import static com.google.common.truth.Truth.assertThat;
-
-import androidx.test.InstrumentationRegistry;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.mockito.Mock;
+import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import java.util.ArrayList;
@@ -87,6 +89,10 @@ public class ProxyManagerTest {
private static final int DEVICE_ID = 10;
private static final int STREAMED_CALLING_UID = 9876;
+ @Rule
+ public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+
+
@Mock private Context mMockContext;
@Mock private AccessibilitySecurityPolicy mMockSecurityPolicy;
@Mock private AccessibilityWindowManager mMockA11yWindowManager;
@@ -110,6 +116,8 @@ public class ProxyManagerTest {
MockitoAnnotations.initMocks(this);
final Resources resources = InstrumentationRegistry.getContext().getResources();
+ mSetFlagsRule.enableFlags(Flags.FLAG_PROXY_USE_APPS_ON_VIRTUAL_DEVICE_LISTENER);
+
mFocusStrokeWidthDefaultValue =
resources.getDimensionPixelSize(R.dimen.accessibility_focus_highlight_stroke_width);
mFocusColorDefaultValue = resources.getColor(R.color.accessibility_focus_highlight_color);
@@ -218,6 +226,39 @@ public class ProxyManagerTest {
}
/**
+ * Tests that the manager's AppsOnVirtualDeviceListener implementation propagates the running
+ * app changes to the proxy device.
+ */
+ @Test
+ public void testUpdateProxyOfRunningAppsChange_changedUidIsStreamedApp_propagatesChange() {
+ final VirtualDeviceManagerInternal localVdm =
+ Mockito.mock(VirtualDeviceManagerInternal.class);
+ when(localVdm.getDeviceIdsForUid(anyInt())).thenReturn(new ArraySet(Set.of(DEVICE_ID)));
+
+ mProxyManager.setLocalVirtualDeviceManager(localVdm);
+ registerProxy(DISPLAY_ID);
+ verify(localVdm).registerAppsOnVirtualDeviceListener(any());
+
+ final ArraySet<Integer> runningUids = new ArraySet(Set.of(STREAMED_CALLING_UID));
+
+ // Flush any existing messages. The messages after this come from onProxyChanged.
+ mMessageCapturingHandler.sendAllMessages();
+
+ // The virtual device has been updated with the streamed app's UID, so the proxy is
+ // updated.
+ mProxyManager.notifyProxyOfRunningAppsChange(runningUids);
+
+ verify(localVdm).getDeviceIdsForUid(STREAMED_CALLING_UID);
+ verify(mMockProxySystemSupport).getCurrentUserClientsLocked();
+ verify(mMockProxySystemSupport).getGlobalClientsLocked();
+ // Messages to notify IAccessibilityManagerClients should be posted.
+ assertThat(mMessageCapturingHandler.hasMessages()).isTrue();
+
+ mProxyManager.unregisterProxy(DISPLAY_ID);
+ verify(localVdm).unregisterAppsOnVirtualDeviceListener(any());
+ }
+
+ /**
* Tests that getting the first device id for an app uid, such as when an app queries for
* device-specific state, returns the right device id.
*/
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/AuthenticationStatsCollectorTest.java b/services/tests/servicestests/src/com/android/server/biometrics/AuthenticationStatsCollectorTest.java
index 0b730f139f3e..fa6e7f60c1b0 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/AuthenticationStatsCollectorTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/AuthenticationStatsCollectorTest.java
@@ -115,6 +115,11 @@ public class AuthenticationStatsCollectorTest {
// Assert that the user doesn't exist in the map initially.
assertThat(mAuthenticationStatsCollector.getAuthenticationStatsForUser(USER_ID_1)).isNull();
+ when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT))
+ .thenReturn(true);
+ when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FACE)).thenReturn(true);
+ when(mFaceManager.hasEnrolledTemplates(anyInt())).thenReturn(true);
+
mAuthenticationStatsCollector.authenticate(USER_ID_1, true /* authenticated */);
AuthenticationStats authenticationStats =
@@ -130,6 +135,11 @@ public class AuthenticationStatsCollectorTest {
// Assert that the user doesn't exist in the map initially.
assertThat(mAuthenticationStatsCollector.getAuthenticationStatsForUser(USER_ID_1)).isNull();
+ when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT))
+ .thenReturn(true);
+ when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FACE)).thenReturn(true);
+ when(mFingerprintManager.hasEnrolledTemplates(anyInt())).thenReturn(true);
+
mAuthenticationStatsCollector.authenticate(USER_ID_1, false /* authenticated */);
AuthenticationStats authenticationStats =
@@ -176,6 +186,11 @@ public class AuthenticationStatsCollectorTest {
40 /* rejectedAttempts */, 0 /* enrollmentNotifications */,
0 /* modality */));
+ when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT))
+ .thenReturn(true);
+ when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FACE)).thenReturn(true);
+ when(mFingerprintManager.hasEnrolledTemplates(anyInt())).thenReturn(true);
+
mAuthenticationStatsCollector.authenticate(USER_ID_1, false /* authenticated */);
// Assert that no notification should be sent.
@@ -233,13 +248,13 @@ public class AuthenticationStatsCollectorTest {
// Assert that no notification should be sent.
verify(mBiometricNotification, never()).sendFaceEnrollNotification(any());
verify(mBiometricNotification, never()).sendFpEnrollNotification(any());
- // Assert that data has been reset.
+ // Assert that data hasn't been reset.
AuthenticationStats authenticationStats = mAuthenticationStatsCollector
.getAuthenticationStatsForUser(USER_ID_1);
- assertThat(authenticationStats.getTotalAttempts()).isEqualTo(0);
- assertThat(authenticationStats.getRejectedAttempts()).isEqualTo(0);
+ assertThat(authenticationStats.getTotalAttempts()).isEqualTo(500);
+ assertThat(authenticationStats.getRejectedAttempts()).isEqualTo(400);
assertThat(authenticationStats.getEnrollmentNotifications()).isEqualTo(0);
- assertThat(authenticationStats.getFrr()).isWithin(0f).of(-1.0f);
+ assertThat(authenticationStats.getFrr()).isWithin(0f).of(0.8f);
}
@Test
@@ -260,13 +275,13 @@ public class AuthenticationStatsCollectorTest {
// Assert that no notification should be sent.
verify(mBiometricNotification, never()).sendFaceEnrollNotification(any());
verify(mBiometricNotification, never()).sendFpEnrollNotification(any());
- // Assert that data has been reset.
+ // Assert that data hasn't been reset.
AuthenticationStats authenticationStats = mAuthenticationStatsCollector
.getAuthenticationStatsForUser(USER_ID_1);
- assertThat(authenticationStats.getTotalAttempts()).isEqualTo(0);
- assertThat(authenticationStats.getRejectedAttempts()).isEqualTo(0);
+ assertThat(authenticationStats.getTotalAttempts()).isEqualTo(500);
+ assertThat(authenticationStats.getRejectedAttempts()).isEqualTo(400);
assertThat(authenticationStats.getEnrollmentNotifications()).isEqualTo(0);
- assertThat(authenticationStats.getFrr()).isWithin(0f).of(-1.0f);
+ assertThat(authenticationStats.getFrr()).isWithin(0f).of(0.8f);
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
index b22798e6eaed..5dfce0613190 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
@@ -326,24 +326,6 @@ public final class UserManagerTest {
assertThat(hasUser(user2.id)).isTrue();
}
-
- @MediumTest
- @Test
- public void testGetFullUserCount() throws Exception {
- assertThat(mUserManager.getFullUserCount()).isEqualTo(1);
- UserInfo user1 = createUser("User 1", UserInfo.FLAG_FULL);
- UserInfo user2 = createUser("User 2", UserInfo.FLAG_ADMIN);
-
- assertThat(user1).isNotNull();
- assertThat(user2).isNotNull();
-
- assertThat(mUserManager.getFullUserCount()).isEqualTo(3);
- removeUser(user1.id);
- assertThat(mUserManager.getFullUserCount()).isEqualTo(2);
- removeUser(user2.id);
- assertThat(mUserManager.getFullUserCount()).isEqualTo(1);
- }
-
/**
* Tests that UserManager knows how many users can be created.
*
diff --git a/services/tests/vibrator/src/com/android/server/vibrator/VibratorManagerServiceTest.java b/services/tests/vibrator/src/com/android/server/vibrator/VibratorManagerServiceTest.java
index c25f0cb91caa..0eec9cd93f3b 100644
--- a/services/tests/vibrator/src/com/android/server/vibrator/VibratorManagerServiceTest.java
+++ b/services/tests/vibrator/src/com/android/server/vibrator/VibratorManagerServiceTest.java
@@ -89,6 +89,7 @@ import android.view.HapticFeedbackConstants;
import android.view.InputDevice;
import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.FlakyTest;
import com.android.internal.app.IBatteryStats;
import com.android.internal.util.FrameworkStatsLog;
@@ -834,6 +835,7 @@ public class VibratorManagerServiceTest {
eq(AudioAttributes.USAGE_UNKNOWN), anyInt(), anyString());
}
+ @FlakyTest
@Test
public void vibrate_withOngoingRepeatingVibration_ignoresEffect() throws Exception {
mockVibrators(1);
@@ -920,6 +922,7 @@ public class VibratorManagerServiceTest {
cancelVibrate(service); // Clean up repeating effect.
}
+ @FlakyTest
@Test
public void vibrate_withNewSameImportanceVibrationButOngoingIsRepeating_ignoreNewVibration()
throws Exception {
@@ -973,6 +976,7 @@ public class VibratorManagerServiceTest {
cancelVibrate(service); // Clean up repeating effect.
}
+ @FlakyTest
@Test
public void vibrate_withNewUnknownUsageVibrationAndNotRepeating_ignoreNewVibration()
throws Exception {
@@ -1764,6 +1768,7 @@ public class VibratorManagerServiceTest {
cancelVibrate(service); // Clean up long effect.
}
+ @FlakyTest
@Test
public void onExternalVibration_withNewSameImportanceButRepeating_cancelsOngoingVibration()
throws Exception {
diff --git a/services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java b/services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java
index c84eab3a6660..622e81eab611 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java
@@ -16,6 +16,8 @@
package com.android.server.wm;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR;
+import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;
@@ -77,6 +79,7 @@ import java.util.concurrent.CountDownLatch;
@RunWith(WindowTestRunner.class)
public class ContentRecorderTests extends WindowTestsBase {
private static IBinder sTaskWindowContainerToken;
+ private DisplayContent mVirtualDisplayContent;
private Task mTask;
private final ContentRecordingSession mDisplaySession =
ContentRecordingSession.createDisplaySession(DEFAULT_DISPLAY);
@@ -107,11 +110,11 @@ public class ContentRecorderTests extends WindowTestsBase {
displayInfo.logicalWidth = sSurfaceSize.x;
displayInfo.logicalHeight = sSurfaceSize.y;
displayInfo.state = STATE_ON;
- final DisplayContent virtualDisplayContent = createNewDisplay(displayInfo);
- final int displayId = virtualDisplayContent.getDisplayId();
- mContentRecorder = new ContentRecorder(virtualDisplayContent,
+ mVirtualDisplayContent = createNewDisplay(displayInfo);
+ final int displayId = mVirtualDisplayContent.getDisplayId();
+ mContentRecorder = new ContentRecorder(mVirtualDisplayContent,
mMediaProjectionManagerWrapper);
- spyOn(virtualDisplayContent);
+ spyOn(mVirtualDisplayContent);
// GIVEN MediaProjection has already initialized the WindowToken of the DisplayArea to
// record.
@@ -119,7 +122,7 @@ public class ContentRecorderTests extends WindowTestsBase {
mDisplaySession.setDisplayToRecord(mDefaultDisplay.mDisplayId);
// GIVEN there is a window token associated with a task to record.
- sTaskWindowContainerToken = setUpTaskWindowContainerToken(virtualDisplayContent);
+ sTaskWindowContainerToken = setUpTaskWindowContainerToken(mVirtualDisplayContent);
mTaskSession = ContentRecordingSession.createTaskSession(sTaskWindowContainerToken);
mTaskSession.setVirtualDisplayId(displayId);
@@ -252,7 +255,11 @@ public class ContentRecorderTests extends WindowTestsBase {
public void testOnConfigurationChanged_resizesSurface() {
mContentRecorder.setContentRecordingSession(mDisplaySession);
mContentRecorder.updateRecording();
- mContentRecorder.onConfigurationChanged(ORIENTATION_PORTRAIT);
+ // Ensure a different orientation when we check if something has changed.
+ @Configuration.Orientation final int lastOrientation =
+ mDisplayContent.getConfiguration().orientation == ORIENTATION_PORTRAIT
+ ? ORIENTATION_LANDSCAPE : ORIENTATION_PORTRAIT;
+ mContentRecorder.onConfigurationChanged(lastOrientation);
verify(mTransaction, atLeast(2)).setPosition(eq(mRecordedSurface), anyFloat(),
anyFloat());
@@ -261,12 +268,53 @@ public class ContentRecorderTests extends WindowTestsBase {
}
@Test
+ public void testOnConfigurationChanged_resizesVirtualDisplay() {
+ final int newWidth = 55;
+ mContentRecorder.setContentRecordingSession(mDisplaySession);
+ mContentRecorder.updateRecording();
+
+ // The user rotates the device, so the host app resizes the virtual display for the capture.
+ resizeDisplay(mDisplayContent, newWidth, sSurfaceSize.y);
+ resizeDisplay(mVirtualDisplayContent, newWidth, sSurfaceSize.y);
+ mContentRecorder.onConfigurationChanged(mDisplayContent.getConfiguration().orientation);
+
+ verify(mTransaction, atLeast(2)).setPosition(eq(mRecordedSurface), anyFloat(),
+ anyFloat());
+ verify(mTransaction, atLeast(2)).setMatrix(eq(mRecordedSurface), anyFloat(), anyFloat(),
+ anyFloat(), anyFloat());
+ }
+
+ @Test
+ public void testOnConfigurationChanged_rotateVirtualDisplay() {
+ mContentRecorder.setContentRecordingSession(mDisplaySession);
+ mContentRecorder.updateRecording();
+
+ // Change a value that we shouldn't rely upon; it has the wrong type.
+ mVirtualDisplayContent.setOverrideOrientation(SCREEN_ORIENTATION_FULL_SENSOR);
+ mContentRecorder.onConfigurationChanged(
+ mVirtualDisplayContent.getConfiguration().orientation);
+
+ // No resize is issued, only the initial transformations when we started recording.
+ verify(mTransaction).setPosition(eq(mRecordedSurface), anyFloat(),
+ anyFloat());
+ verify(mTransaction).setMatrix(eq(mRecordedSurface), anyFloat(), anyFloat(),
+ anyFloat(), anyFloat());
+ }
+
+ @Test
public void testOnTaskOrientationConfigurationChanged_resizesSurface() {
mContentRecorder.setContentRecordingSession(mTaskSession);
mContentRecorder.updateRecording();
Configuration config = mTask.getConfiguration();
- config.orientation = ORIENTATION_PORTRAIT;
+ // Ensure a different orientation when we compare.
+ @Configuration.Orientation final int orientation =
+ config.orientation == ORIENTATION_PORTRAIT ? ORIENTATION_LANDSCAPE
+ : ORIENTATION_PORTRAIT;
+ final Rect lastBounds = config.windowConfiguration.getBounds();
+ config.orientation = orientation;
+ config.windowConfiguration.setBounds(
+ new Rect(0, 0, lastBounds.height(), lastBounds.width()));
mTask.onConfigurationChanged(config);
verify(mTransaction, atLeast(2)).setPosition(eq(mRecordedSurface), anyFloat(),
@@ -279,13 +327,15 @@ public class ContentRecorderTests extends WindowTestsBase {
public void testOnTaskBoundsConfigurationChanged_notifiesCallback() {
mTask.getRootTask().setWindowingMode(WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW);
+ final int minWidth = 222;
+ final int minHeight = 777;
final int recordedWidth = 333;
final int recordedHeight = 999;
final ActivityInfo info = new ActivityInfo();
info.windowLayout = new ActivityInfo.WindowLayout(-1 /* width */,
-1 /* widthFraction */, -1 /* height */, -1 /* heightFraction */,
- Gravity.NO_GRAVITY, recordedWidth, recordedHeight);
+ Gravity.NO_GRAVITY, minWidth, minHeight);
mTask.setMinDimensions(info);
// WHEN a recording is ongoing.
diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java
index 994dcf1e2ea5..411712e6b577 100644
--- a/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java
@@ -23,8 +23,6 @@ import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
import static android.view.WindowInsets.Type.navigationBars;
import static android.view.WindowInsets.Type.statusBars;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
import static android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE;
@@ -108,7 +106,7 @@ public class InsetsPolicyTest extends WindowTestsBase {
@Test
public void testControlsForDispatch_forceStatusBarVisible() {
- addStatusBar().mAttrs.privateFlags |= PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR;
+ addStatusBar().mAttrs.forciblyShownTypes |= statusBars();
addNavigationBar();
final InsetsSourceControl[] controls = addAppWindowAndGetControlsForDispatch();
@@ -120,8 +118,8 @@ public class InsetsPolicyTest extends WindowTestsBase {
@Test
public void testControlsForDispatch_statusBarForceShowNavigation() {
- addWindow(TYPE_NOTIFICATION_SHADE, "notificationShade").mAttrs.privateFlags |=
- PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION;
+ addWindow(TYPE_NOTIFICATION_SHADE, "notificationShade").mAttrs.forciblyShownTypes |=
+ navigationBars();
addStatusBar();
addNavigationBar();
@@ -135,7 +133,7 @@ public class InsetsPolicyTest extends WindowTestsBase {
@Test
public void testControlsForDispatch_statusBarForceShowNavigation_butFocusedAnyways() {
WindowState notifShade = addWindow(TYPE_NOTIFICATION_SHADE, "notificationShade");
- notifShade.mAttrs.privateFlags |= PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION;
+ notifShade.mAttrs.forciblyShownTypes |= navigationBars();
addNavigationBar();
mDisplayContent.getInsetsPolicy().updateBarControlTarget(notifShade);
diff --git a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
index 0cdd9b8a9e0b..8f68c0fa0b73 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
@@ -112,6 +112,7 @@ import android.view.InsetsState;
import android.view.WindowInsets;
import android.view.WindowManager;
+import androidx.test.filters.FlakyTest;
import androidx.test.filters.MediumTest;
import com.android.internal.policy.SystemBarUtils;
@@ -2361,6 +2362,7 @@ public class SizeCompatTests extends WindowTestsBase {
}
@Test
+ @FlakyTest(bugId = 299220009)
public void testUserOverrideAspectRatioNotEnabled() {
setUpDisplaySizeWithApp(/* dw */ 1600, /* dh */ 1400);
@@ -2409,8 +2411,9 @@ public class SizeCompatTests extends WindowTestsBase {
.setUid(android.os.Process.myUid())
.build();
activity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
- activity.mWmService.mLetterboxConfiguration
- .setUserAppAspectRatioSettingsOverrideEnabled(enabled);
+ spyOn(activity.mWmService.mLetterboxConfiguration);
+ doReturn(enabled).when(activity.mWmService.mLetterboxConfiguration)
+ .isUserAppAspectRatioSettingsEnabled();
// Set user aspect ratio override
final IPackageManager pm = mAtm.getPackageManager();
try {
@@ -4249,6 +4252,7 @@ public class SizeCompatTests extends WindowTestsBase {
// Set up a display in landscape with a fixed-orientation PORTRAIT app
setUpDisplaySizeWithApp(2800, 1400);
mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+ mWm.mLetterboxConfiguration.setIsAutomaticReachabilityInBookModeEnabled(false);
mWm.mLetterboxConfiguration.setLetterboxHorizontalPositionMultiplier(0.5f);
prepareUnresizable(mActivity, 1.75f, SCREEN_ORIENTATION_PORTRAIT);
diff --git a/tools/aapt2/format/Archive_test.cpp b/tools/aapt2/format/Archive_test.cpp
index 3c44da710d94..fd50af92ceee 100644
--- a/tools/aapt2/format/Archive_test.cpp
+++ b/tools/aapt2/format/Archive_test.cpp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#include <stdlib.h>
+
#include "test/Test.h"
namespace aapt {
@@ -34,6 +36,29 @@ class TestData : public io::MallocData {
std::string error_;
};
+class TzSetter {
+ public:
+ explicit TzSetter(const std::string& new_tz) {
+ old_tz_ = getenv("TZ");
+ new_tz_ = "TZ=" + new_tz;
+ putenv(const_cast<char*>(new_tz_.c_str()));
+ tzset();
+ }
+
+ ~TzSetter() {
+ if (old_tz_) {
+ putenv(old_tz_);
+ } else {
+ putenv(const_cast<char*>("TZ"));
+ }
+ tzset();
+ }
+
+ private:
+ char* old_tz_;
+ std::string new_tz_;
+};
+
std::unique_ptr<uint8_t[]> MakeTestArray() {
auto array = std::make_unique<uint8_t[]>(kTestDataLength);
for (int index = 0; index < kTestDataLength; ++index) {
@@ -86,6 +111,22 @@ void VerifyZipFile(const std::string& output_path, const std::string& file, cons
}
}
+void VerifyZipFileTimestamps(const std::string& output_path) {
+ std::unique_ptr<io::ZipFileCollection> zip = io::ZipFileCollection::Create(output_path, nullptr);
+ auto it = zip->Iterator();
+ while (it->HasNext()) {
+ auto file = it->Next();
+ struct tm modification_time;
+ ASSERT_TRUE(file->GetModificationTime(&modification_time));
+ EXPECT_EQ(modification_time.tm_year, 80);
+ EXPECT_EQ(modification_time.tm_mon, 0);
+ EXPECT_EQ(modification_time.tm_mday, 1);
+ EXPECT_EQ(modification_time.tm_hour, 0);
+ EXPECT_EQ(modification_time.tm_min, 0);
+ EXPECT_EQ(modification_time.tm_sec, 0);
+ }
+}
+
TEST_F(ArchiveTest, DirectoryWriteEntrySuccess) {
std::string output_path = GetTestPath("output");
std::unique_ptr<IArchiveWriter> writer = MakeDirectoryWriter(output_path);
@@ -206,4 +247,73 @@ TEST_F(ArchiveTest, ZipFileWriteFileError) {
ASSERT_EQ("ZipFileWriteFileError", writer->GetError());
}
+TEST_F(ArchiveTest, ZipFileTimeZoneUTC) {
+ TzSetter tz("UTC0");
+ std::string output_path = GetTestPath("output.apk");
+ std::unique_ptr<IArchiveWriter> writer = MakeZipFileWriter(output_path);
+ std::unique_ptr<uint8_t[]> data1 = MakeTestArray();
+ std::unique_ptr<uint8_t[]> data2 = MakeTestArray();
+
+ ASSERT_TRUE(writer->StartEntry("test1", 0));
+ ASSERT_TRUE(writer->Write(static_cast<const void*>(data1.get()), kTestDataLength));
+ ASSERT_TRUE(writer->FinishEntry());
+ ASSERT_FALSE(writer->HadError());
+
+ ASSERT_TRUE(writer->StartEntry("test2", 0));
+ ASSERT_TRUE(writer->Write(static_cast<const void*>(data2.get()), kTestDataLength));
+ ASSERT_TRUE(writer->FinishEntry());
+ ASSERT_FALSE(writer->HadError());
+
+ writer.reset();
+
+ // All zip file entries must have the same timestamp, regardless of time zone. See: b/277978832
+ VerifyZipFileTimestamps(output_path);
+}
+
+TEST_F(ArchiveTest, ZipFileTimeZoneWestOfUTC) {
+ TzSetter tz("PST8");
+ std::string output_path = GetTestPath("output.apk");
+ std::unique_ptr<IArchiveWriter> writer = MakeZipFileWriter(output_path);
+ std::unique_ptr<uint8_t[]> data1 = MakeTestArray();
+ std::unique_ptr<uint8_t[]> data2 = MakeTestArray();
+
+ ASSERT_TRUE(writer->StartEntry("test1", 0));
+ ASSERT_TRUE(writer->Write(static_cast<const void*>(data1.get()), kTestDataLength));
+ ASSERT_TRUE(writer->FinishEntry());
+ ASSERT_FALSE(writer->HadError());
+
+ ASSERT_TRUE(writer->StartEntry("test2", 0));
+ ASSERT_TRUE(writer->Write(static_cast<const void*>(data2.get()), kTestDataLength));
+ ASSERT_TRUE(writer->FinishEntry());
+ ASSERT_FALSE(writer->HadError());
+
+ writer.reset();
+
+ // All zip file entries must have the same timestamp, regardless of time zone. See: b/277978832
+ VerifyZipFileTimestamps(output_path);
+}
+
+TEST_F(ArchiveTest, ZipFileTimeZoneEastOfUTC) {
+ TzSetter tz("EET-2");
+ std::string output_path = GetTestPath("output.apk");
+ std::unique_ptr<IArchiveWriter> writer = MakeZipFileWriter(output_path);
+ std::unique_ptr<uint8_t[]> data1 = MakeTestArray();
+ std::unique_ptr<uint8_t[]> data2 = MakeTestArray();
+
+ ASSERT_TRUE(writer->StartEntry("test1", 0));
+ ASSERT_TRUE(writer->Write(static_cast<const void*>(data1.get()), kTestDataLength));
+ ASSERT_TRUE(writer->FinishEntry());
+ ASSERT_FALSE(writer->HadError());
+
+ ASSERT_TRUE(writer->StartEntry("test2", 0));
+ ASSERT_TRUE(writer->Write(static_cast<const void*>(data2.get()), kTestDataLength));
+ ASSERT_TRUE(writer->FinishEntry());
+ ASSERT_FALSE(writer->HadError());
+
+ writer.reset();
+
+ // All zip file entries must have the same timestamp, regardless of time zone. See: b/277978832
+ VerifyZipFileTimestamps(output_path);
+}
+
} // namespace aapt
diff --git a/tools/aapt2/io/File.h b/tools/aapt2/io/File.h
index 08d497def8a4..673d1b75e660 100644
--- a/tools/aapt2/io/File.h
+++ b/tools/aapt2/io/File.h
@@ -57,6 +57,11 @@ class IFile {
return false;
}
+ // Fills in buf with the last modification time of the file. Returns true if successful,
+ // otherwise false (i.e., the operation is not supported or the file system is unable to provide
+ // a last modification time).
+ virtual bool GetModificationTime(struct tm* buf) const = 0;
+
private:
// Any segments created from this IFile need to be owned by this IFile, so
// keep them
@@ -79,6 +84,10 @@ class FileSegment : public IFile {
return file_->GetSource();
}
+ bool GetModificationTime(struct tm* buf) const override {
+ return file_->GetModificationTime(buf);
+ };
+
private:
DISALLOW_COPY_AND_ASSIGN(FileSegment);
diff --git a/tools/aapt2/io/FileSystem.cpp b/tools/aapt2/io/FileSystem.cpp
index a64982a7fa5c..6a692e497816 100644
--- a/tools/aapt2/io/FileSystem.cpp
+++ b/tools/aapt2/io/FileSystem.cpp
@@ -14,9 +14,12 @@
* limitations under the License.
*/
+#define _POSIX_THREAD_SAFE_FUNCTIONS // For mingw localtime_r().
+
#include "io/FileSystem.h"
#include <dirent.h>
+#include <sys/stat.h>
#include "android-base/errors.h"
#include "androidfw/Source.h"
@@ -54,6 +57,23 @@ const android::Source& RegularFile::GetSource() const {
return source_;
}
+bool RegularFile::GetModificationTime(struct tm* buf) const {
+ if (buf == nullptr) {
+ return false;
+ }
+ struct stat stat_buf;
+ if (stat(source_.path.c_str(), &stat_buf) != 0) {
+ return false;
+ }
+
+ struct tm* ptm;
+ struct tm tm_result;
+ ptm = localtime_r(&stat_buf.st_mtime, &tm_result);
+
+ *buf = *ptm;
+ return true;
+}
+
FileCollectionIterator::FileCollectionIterator(FileCollection* collection)
: current_(collection->files_.begin()), end_(collection->files_.end()) {}
diff --git a/tools/aapt2/io/FileSystem.h b/tools/aapt2/io/FileSystem.h
index 0e798fc1b975..f975196b9cfa 100644
--- a/tools/aapt2/io/FileSystem.h
+++ b/tools/aapt2/io/FileSystem.h
@@ -32,6 +32,7 @@ class RegularFile : public IFile {
std::unique_ptr<IData> OpenAsData() override;
std::unique_ptr<io::InputStream> OpenInputStream() override;
const android::Source& GetSource() const override;
+ bool GetModificationTime(struct tm* buf) const override;
private:
DISALLOW_COPY_AND_ASSIGN(RegularFile);
diff --git a/tools/aapt2/io/ZipArchive.cpp b/tools/aapt2/io/ZipArchive.cpp
index 4a5385d90d3b..cb5bbe96b8b7 100644
--- a/tools/aapt2/io/ZipArchive.cpp
+++ b/tools/aapt2/io/ZipArchive.cpp
@@ -75,6 +75,14 @@ bool ZipFile::WasCompressed() {
return zip_entry_.method != kCompressStored;
}
+bool ZipFile::GetModificationTime(struct tm* buf) const {
+ if (buf == nullptr) {
+ return false;
+ }
+ *buf = zip_entry_.GetModificationTime();
+ return true;
+}
+
ZipFileCollectionIterator::ZipFileCollectionIterator(
ZipFileCollection* collection)
: current_(collection->files_.begin()), end_(collection->files_.end()) {}
diff --git a/tools/aapt2/io/ZipArchive.h b/tools/aapt2/io/ZipArchive.h
index c263aa490d22..ac125d097983 100644
--- a/tools/aapt2/io/ZipArchive.h
+++ b/tools/aapt2/io/ZipArchive.h
@@ -38,6 +38,7 @@ class ZipFile : public IFile {
std::unique_ptr<io::InputStream> OpenInputStream() override;
const android::Source& GetSource() const override;
bool WasCompressed() override;
+ bool GetModificationTime(struct tm* buf) const override;
private:
::ZipArchiveHandle zip_handle_;
diff --git a/tools/aapt2/test/Common.h b/tools/aapt2/test/Common.h
index 83a0f3f3f652..e48668cf96a3 100644
--- a/tools/aapt2/test/Common.h
+++ b/tools/aapt2/test/Common.h
@@ -98,6 +98,10 @@ class TestFile : public io::IFile {
return source_;
}
+ bool GetModificationTime(struct tm* buf) const override {
+ return false;
+ };
+
private:
DISALLOW_COPY_AND_ASSIGN(TestFile);
diff --git a/tools/lint/common/Android.bp b/tools/lint/common/Android.bp
index 898f88b8759c..8bfbfe5f60b3 100644
--- a/tools/lint/common/Android.bp
+++ b/tools/lint/common/Android.bp
@@ -27,3 +27,30 @@ java_library_host {
libs: ["lint_api"],
kotlincflags: ["-Xjvm-default=all"],
}
+
+java_defaults {
+ name: "AndroidLintCheckerTestDefaults",
+ srcs: ["checks/src/test/java/**/*.kt"],
+ static_libs: [
+ "junit",
+ "lint",
+ "lint_tests",
+ ],
+ test_options: {
+ unit_test: true,
+ tradefed_options: [
+ {
+ // lint bundles in some classes that were built with older versions
+ // of libraries, and no longer load. Since tradefed tries to load
+ // all classes in the jar to look for tests, it crashes loading them.
+ // Exclude these classes from tradefed's search.
+ name: "exclude-paths",
+ value: "org/apache",
+ },
+ {
+ name: "exclude-paths",
+ value: "META-INF",
+ },
+ ],
+ },
+}
diff --git a/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/AidlImplementationDetector.kt b/tools/lint/common/src/main/java/com/google/android/lint/aidl/AidlImplementationDetector.kt
index ab6d871d6ea6..ab6d871d6ea6 100644
--- a/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/AidlImplementationDetector.kt
+++ b/tools/lint/common/src/main/java/com/google/android/lint/aidl/AidlImplementationDetector.kt
diff --git a/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/Constants.kt b/tools/lint/common/src/main/java/com/google/android/lint/aidl/Constants.kt
index f1727b78f135..a18ed1555998 100644
--- a/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/Constants.kt
+++ b/tools/lint/common/src/main/java/com/google/android/lint/aidl/Constants.kt
@@ -29,9 +29,10 @@ val AIDL_PERMISSION_ANNOTATIONS = listOf(
const val BINDER_CLASS = "android.os.Binder"
const val IINTERFACE_INTERFACE = "android.os.IInterface"
-const val AIDL_PERMISSION_HELPER_SUFFIX = "_enforcePermission"
const val PERMISSION_PREFIX_LITERAL = "android.permission."
+const val AIDL_PERMISSION_HELPER_SUFFIX = "_enforcePermission"
+
/**
* If a non java (e.g. c++) backend is enabled, the @EnforcePermission
* annotation cannot be used. At time of writing, the mechanism
diff --git a/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionUtils.kt b/tools/lint/common/src/main/java/com/google/android/lint/aidl/EnforcePermissionUtils.kt
index d41fee3fc0dc..d41fee3fc0dc 100644
--- a/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionUtils.kt
+++ b/tools/lint/common/src/main/java/com/google/android/lint/aidl/EnforcePermissionUtils.kt
diff --git a/tools/lint/fix/soong_lint_fix.py b/tools/lint/fix/soong_lint_fix.py
index cd4d778d1dec..acc0ad043171 100644
--- a/tools/lint/fix/soong_lint_fix.py
+++ b/tools/lint/fix/soong_lint_fix.py
@@ -29,6 +29,39 @@ PATH_PREFIX = "out/soong/.intermediates"
PATH_SUFFIX = "android_common/lint"
FIX_ZIP = "suggested-fixes.zip"
+
+class SoongModule:
+ """A Soong module to lint.
+
+ The constructor takes the name of the module (for example,
+ "framework-minus-apex"). find() must be called to extract the intermediate
+ module path from Soong's module-info.json
+ """
+ def __init__(self, name):
+ self._name = name
+
+ def find(self, module_info):
+ """Finds the module in the loaded module_info.json."""
+ if self._name not in module_info:
+ raise Exception(f"Module {self._name} not found!")
+
+ partial_path = module_info[self._name]["path"][0]
+ print(f"Found module {partial_path}/{self._name}.")
+ self._path = f"{PATH_PREFIX}/{partial_path}/{self._name}/{PATH_SUFFIX}"
+
+ @property
+ def name(self):
+ return self._name
+
+ @property
+ def lint_report(self):
+ return f"{self._path}/lint-report.txt"
+
+ @property
+ def suggested_fixes(self):
+ return f"{self._path}/{FIX_ZIP}"
+
+
class SoongLintFix:
"""
This class creates a command line tool that will
@@ -53,16 +86,14 @@ class SoongLintFix:
self._parser = _setup_parser()
self._args = None
self._kwargs = None
- self._path = None
- self._target = None
-
+ self._modules = []
- def run(self, additional_setup=None, custom_fix=None):
+ def run(self):
"""
Run the script
"""
self._setup()
- self._find_module()
+ self._find_modules()
self._lint()
if not self._args.no_fix:
@@ -87,8 +118,6 @@ class SoongLintFix:
os.chdir(ANDROID_BUILD_TOP)
-
- def _find_module(self):
print("Refreshing soong modules...")
try:
os.mkdir(ANDROID_PRODUCT_OUT)
@@ -97,48 +126,47 @@ class SoongLintFix:
subprocess.call(f"{SOONG_UI} --make-mode {PRODUCT_OUT}/module-info.json", **self._kwargs)
print("done.")
+
+ def _find_modules(self):
with open(f"{ANDROID_PRODUCT_OUT}/module-info.json") as f:
module_info = json.load(f)
- if self._args.module not in module_info:
- sys.exit(f"Module {self._args.module} not found!")
-
- module_path = module_info[self._args.module]["path"][0]
- print(f"Found module {module_path}/{self._args.module}.")
-
- self._path = f"{PATH_PREFIX}/{module_path}/{self._args.module}/{PATH_SUFFIX}"
- self._target = f"{self._path}/lint-report.txt"
-
+ for module_name in self._args.modules:
+ module = SoongModule(module_name)
+ module.find(module_info)
+ self._modules.append(module)
def _lint(self):
print("Cleaning up any old lint results...")
- try:
- os.remove(f"{self._target}")
- os.remove(f"{self._path}/{FIX_ZIP}")
- except FileNotFoundError:
- pass
+ for module in self._modules:
+ try:
+ os.remove(f"{module.lint_report}")
+ os.remove(f"{module.suggested_fixes}")
+ except FileNotFoundError:
+ pass
print("done.")
- print(f"Generating {self._target}")
- subprocess.call(f"{SOONG_UI} --make-mode {self._target}", **self._kwargs)
+ target = " ".join([ module.lint_report for module in self._modules ])
+ print(f"Generating {target}")
+ subprocess.call(f"{SOONG_UI} --make-mode {target}", **self._kwargs)
print("done.")
-
def _fix(self):
- print("Copying suggested fixes to the tree...")
- with zipfile.ZipFile(f"{self._path}/{FIX_ZIP}") as zip:
- for name in zip.namelist():
- if name.startswith("out") or not name.endswith(".java"):
- continue
- with zip.open(name) as src, open(f"{ANDROID_BUILD_TOP}/{name}", "wb") as dst:
- shutil.copyfileobj(src, dst)
+ for module in self._modules:
+ print(f"Copying suggested fixes for {module.name} to the tree...")
+ with zipfile.ZipFile(f"{module.suggested_fixes}") as zip:
+ for name in zip.namelist():
+ if name.startswith("out") or not name.endswith(".java"):
+ continue
+ with zip.open(name) as src, open(f"{ANDROID_BUILD_TOP}/{name}", "wb") as dst:
+ shutil.copyfileobj(src, dst)
print("done.")
-
def _print(self):
- print("### lint-report.txt ###", end="\n\n")
- with open(self._target, "r") as f:
- print(f.read())
+ for module in self._modules:
+ print(f"### lint-report.txt {module.name} ###", end="\n\n")
+ with open(module.lint_report, "r") as f:
+ print(f.read())
def _setup_parser():
@@ -151,7 +179,8 @@ def _setup_parser():
**Gotcha**: You must have run `source build/envsetup.sh` and `lunch` first.
""", formatter_class=argparse.RawTextHelpFormatter)
- parser.add_argument('module',
+ parser.add_argument('modules',
+ nargs='+',
help='The soong build module to run '
'(e.g. framework-minus-apex or services.core.unboosted)')
@@ -170,4 +199,4 @@ def _setup_parser():
return parser
if __name__ == "__main__":
- SoongLintFix().run() \ No newline at end of file
+ SoongLintFix().run()
diff --git a/tools/lint/framework/Android.bp b/tools/lint/framework/Android.bp
index 30a6daaef2a4..5acdf436ae08 100644
--- a/tools/lint/framework/Android.bp
+++ b/tools/lint/framework/Android.bp
@@ -37,28 +37,9 @@ java_library_host {
java_test_host {
name: "AndroidFrameworkLintCheckerTest",
+ defaults: ["AndroidLintCheckerTestDefaults"],
srcs: ["checks/src/test/java/**/*.kt"],
static_libs: [
"AndroidFrameworkLintChecker",
- "junit",
- "lint",
- "lint_tests",
],
- test_options: {
- unit_test: true,
- tradefed_options: [
- {
- // lint bundles in some classes that were built with older versions
- // of libraries, and no longer load. Since tradefed tries to load
- // all classes in the jar to look for tests, it crashes loading them.
- // Exclude these classes from tradefed's search.
- name: "exclude-paths",
- value: "org/apache",
- },
- {
- name: "exclude-paths",
- value: "META-INF",
- },
- ],
- },
}
diff --git a/tools/lint/global/Android.bp b/tools/lint/global/Android.bp
index bedb7bd78a29..3e74171814ab 100644
--- a/tools/lint/global/Android.bp
+++ b/tools/lint/global/Android.bp
@@ -38,28 +38,9 @@ java_library_host {
java_test_host {
name: "AndroidGlobalLintCheckerTest",
+ defaults: ["AndroidLintCheckerTestDefaults"],
srcs: ["checks/src/test/java/**/*.kt"],
static_libs: [
"AndroidGlobalLintChecker",
- "junit",
- "lint",
- "lint_tests",
],
- test_options: {
- unit_test: true,
- tradefed_options: [
- {
- // lint bundles in some classes that were built with older versions
- // of libraries, and no longer load. Since tradefed tries to load
- // all classes in the jar to look for tests, it crashes loading them.
- // Exclude these classes from tradefed's search.
- name: "exclude-paths",
- value: "org/apache",
- },
- {
- name: "exclude-paths",
- value: "META-INF",
- },
- ],
- },
}
diff --git a/tools/lint/utils/Android.bp b/tools/lint/utils/Android.bp
new file mode 100644
index 000000000000..75e8d6863c20
--- /dev/null
+++ b/tools/lint/utils/Android.bp
@@ -0,0 +1,45 @@
+// Copyright (C) 2023 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+ // 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: "AndroidUtilsLintChecker",
+ srcs: ["checks/src/main/java/**/*.kt"],
+ plugins: ["auto_service_plugin"],
+ libs: [
+ "auto_service_annotations",
+ "lint_api",
+ ],
+ static_libs: [
+ "AndroidCommonLint",
+ ],
+ kotlincflags: ["-Xjvm-default=all"],
+}
+
+java_test_host {
+ name: "AndroidUtilsLintCheckerTest",
+ defaults: ["AndroidLintCheckerTestDefaults"],
+ srcs: ["checks/src/test/java/**/*.kt"],
+ static_libs: [
+ "AndroidUtilsLintChecker",
+ ],
+}
diff --git a/tools/lint/utils/checks/src/main/java/com/google/android/lint/AndroidUtilsIssueRegistry.kt b/tools/lint/utils/checks/src/main/java/com/google/android/lint/AndroidUtilsIssueRegistry.kt
new file mode 100644
index 000000000000..fa61c42ef8e6
--- /dev/null
+++ b/tools/lint/utils/checks/src/main/java/com/google/android/lint/AndroidUtilsIssueRegistry.kt
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.android.lint
+
+import com.android.tools.lint.client.api.IssueRegistry
+import com.android.tools.lint.client.api.Vendor
+import com.android.tools.lint.detector.api.CURRENT_API
+import com.google.android.lint.aidl.AnnotatedAidlCounter
+import com.google.auto.service.AutoService
+
+@AutoService(IssueRegistry::class)
+@Suppress("UnstableApiUsage")
+class AndroidUtilsIssueRegistry : IssueRegistry() {
+ override val issues = listOf(
+ AnnotatedAidlCounter.ISSUE_ANNOTATED_AIDL_COUNTER,
+ )
+
+ override val api: Int
+ get() = CURRENT_API
+
+ override val minApi: Int
+ get() = 8
+
+ override val vendor: Vendor = Vendor(
+ vendorName = "Android",
+ feedbackUrl = "http://b/issues/new?component=315013",
+ contact = "tweek@google.com"
+ )
+}
diff --git a/tools/lint/utils/checks/src/main/java/com/google/android/lint/aidl/AnnotatedAidlCounter.kt b/tools/lint/utils/checks/src/main/java/com/google/android/lint/aidl/AnnotatedAidlCounter.kt
new file mode 100644
index 000000000000..f0ec3f44f6c4
--- /dev/null
+++ b/tools/lint/utils/checks/src/main/java/com/google/android/lint/aidl/AnnotatedAidlCounter.kt
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.android.lint.aidl
+
+import com.android.tools.lint.detector.api.Category
+import com.android.tools.lint.detector.api.Context
+import com.android.tools.lint.detector.api.Implementation
+import com.android.tools.lint.detector.api.Issue
+import com.android.tools.lint.detector.api.JavaContext
+import com.android.tools.lint.detector.api.Location
+import com.android.tools.lint.detector.api.Scope
+import com.android.tools.lint.detector.api.Severity
+import org.jetbrains.uast.UBlockExpression
+import org.jetbrains.uast.UMethod
+
+import java.util.TreeMap
+
+/**
+ * Count the number of AIDL interfaces. Reports the number of annotated and
+ * non-annotated methods.
+ */
+@Suppress("UnstableApiUsage")
+class AnnotatedAidlCounter : AidlImplementationDetector() {
+
+ private data class Stat(
+ var unannotated: Int = 0,
+ var enforced: Int = 0,
+ var notRequired: Int = 0,
+ )
+
+ private var packagesStats: TreeMap<String, Stat> = TreeMap<String, Stat>()
+
+ override fun visitAidlMethod(
+ context: JavaContext,
+ node: UMethod,
+ interfaceName: String,
+ body: UBlockExpression
+ ) {
+ val packageName = context.uastFile?.packageName ?: "<unknown>"
+ var packageStat = packagesStats.getOrDefault(packageName, Stat())
+ when {
+ node.hasAnnotation(ANNOTATION_ENFORCE_PERMISSION) -> packageStat.enforced += 1
+ node.hasAnnotation(ANNOTATION_REQUIRES_NO_PERMISSION) -> packageStat.notRequired += 1
+ else -> packageStat.unannotated += 1
+ }
+ packagesStats.put(packageName, packageStat)
+ // context.driver.client.log(null, "%s.%s#%s".format(packageName, interfaceName, node.name))
+ }
+
+ override fun afterCheckRootProject(context: Context) {
+ var total = Stat()
+ for ((packageName, stat) in packagesStats) {
+ context.client.log(null, "package $packageName => $stat")
+ total.unannotated += stat.unannotated
+ total.enforced += stat.enforced
+ total.notRequired += stat.notRequired
+ }
+ val location = Location.create(context.project.dir)
+ context.report(
+ ISSUE_ANNOTATED_AIDL_COUNTER,
+ location,
+ "module ${context.project.name} => $total"
+ )
+ }
+
+ companion object {
+
+ @JvmField
+ val ISSUE_ANNOTATED_AIDL_COUNTER = Issue.create(
+ id = "AnnotatedAidlCounter",
+ briefDescription = "Statistics on the number of annotated AIDL methods.",
+ explanation = "",
+ category = Category.SECURITY,
+ priority = 5,
+ severity = Severity.INFORMATIONAL,
+ implementation = Implementation(
+ AnnotatedAidlCounter::class.java,
+ Scope.JAVA_FILE_SCOPE
+ ),
+ )
+ }
+}
diff --git a/tools/lint/utils/checks/src/test/java/com/google/android/lint/aidl/AnnotatedAidlCounterTest.kt b/tools/lint/utils/checks/src/test/java/com/google/android/lint/aidl/AnnotatedAidlCounterTest.kt
new file mode 100644
index 000000000000..692b7da243c9
--- /dev/null
+++ b/tools/lint/utils/checks/src/test/java/com/google/android/lint/aidl/AnnotatedAidlCounterTest.kt
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.android.lint.aidl
+
+import com.android.tools.lint.checks.infrastructure.LintDetectorTest
+import com.android.tools.lint.checks.infrastructure.TestFile
+import com.android.tools.lint.checks.infrastructure.TestLintTask
+import com.android.tools.lint.detector.api.Detector
+import com.android.tools.lint.detector.api.Issue
+
+@Suppress("UnstableApiUsage")
+class AnnotatedAidlCounterTest : LintDetectorTest() {
+ override fun getDetector(): Detector = AnnotatedAidlCounter()
+
+ override fun getIssues(): List<Issue> = listOf(
+ AnnotatedAidlCounter.ISSUE_ANNOTATED_AIDL_COUNTER,
+ )
+
+ override fun lint(): TestLintTask = super.lint().allowMissingSdk(true)
+
+ /** No issue scenario */
+
+ fun testDoesNotDetectIssuesCorrectAnnotationOnMethod() {
+ lint().files(java(
+ """
+ package test.pkg;
+ import android.annotation.EnforcePermission;
+ public class TestClass2 extends IFooMethod.Stub {
+ @Override
+ @EnforcePermission(android.Manifest.permission.READ_PHONE_STATE)
+ public void testMethod() {}
+ }
+ """).indented(),
+ *stubs
+ )
+ .run()
+ .expect("""
+ app: Information: module app => Stat(unannotated=0, enforced=1, notRequired=0) [AnnotatedAidlCounter]
+ 0 errors, 0 warnings
+ """)
+ }
+
+ // A service with permission annotation on the method.
+ private val interfaceIFooMethodStub: TestFile = java(
+ """
+ public interface IFooMethod extends android.os.IInterface {
+ public static abstract class Stub extends android.os.Binder implements IFooMethod {}
+ @android.annotation.EnforcePermission(android.Manifest.permission.READ_PHONE_STATE)
+ public void testMethod();
+ }
+ """
+ ).indented()
+
+ // A service without any permission annotation.
+ private val interfaceIBarStub: TestFile = java(
+ """
+ public interface IBar extends android.os.IInterface {
+ public static abstract class Stub extends android.os.Binder implements IBar {
+ @Override
+ public void testMethod() {}
+ }
+ public void testMethod();
+ }
+ """
+ ).indented()
+
+ private val manifestPermissionStub: TestFile = java(
+ """
+ package android.Manifest;
+ class permission {
+ public static final String READ_PHONE_STATE = "android.permission.READ_PHONE_STATE";
+ }
+ """
+ ).indented()
+
+ private val enforcePermissionAnnotationStub: TestFile = java(
+ """
+ package android.annotation;
+ public @interface EnforcePermission {}
+ """
+ ).indented()
+
+ private val stubs = arrayOf(interfaceIFooMethodStub, interfaceIBarStub,
+ manifestPermissionStub, enforcePermissionAnnotationStub)
+}