summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java4
-rw-r--r--apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java6
-rw-r--r--apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java15
-rw-r--r--apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java3
-rw-r--r--cmds/screencap/screencap.cpp39
-rw-r--r--core/java/android/view/InsetsController.java2
-rw-r--r--core/java/com/android/internal/os/anr/AnrLatencyTracker.java35
-rw-r--r--core/res/res/values-af/strings.xml1
-rw-r--r--core/res/res/values-am/strings.xml2
-rw-r--r--core/res/res/values-ar/strings.xml2
-rw-r--r--core/res/res/values-as/strings.xml2
-rw-r--r--core/res/res/values-az/strings.xml2
-rw-r--r--core/res/res/values-b+sr+Latn/strings.xml5
-rw-r--r--core/res/res/values-be/strings.xml2
-rw-r--r--core/res/res/values-bg/strings.xml1
-rw-r--r--core/res/res/values-bn/strings.xml1
-rw-r--r--core/res/res/values-bs/strings.xml9
-rw-r--r--core/res/res/values-ca/strings.xml6
-rw-r--r--core/res/res/values-cs/strings.xml1
-rw-r--r--core/res/res/values-da/strings.xml4
-rw-r--r--core/res/res/values-de/strings.xml1
-rw-r--r--core/res/res/values-el/strings.xml1
-rw-r--r--core/res/res/values-en-rAU/strings.xml1
-rw-r--r--core/res/res/values-en-rCA/strings.xml1
-rw-r--r--core/res/res/values-en-rGB/strings.xml1
-rw-r--r--core/res/res/values-en-rIN/strings.xml1
-rw-r--r--core/res/res/values-en-rXC/strings.xml1
-rw-r--r--core/res/res/values-es-rUS/strings.xml14
-rw-r--r--core/res/res/values-es/strings.xml3
-rw-r--r--core/res/res/values-et/strings.xml6
-rw-r--r--core/res/res/values-eu/strings.xml19
-rw-r--r--core/res/res/values-fa/strings.xml2
-rw-r--r--core/res/res/values-fi/strings.xml1
-rw-r--r--core/res/res/values-fr-rCA/strings.xml2
-rw-r--r--core/res/res/values-fr/strings.xml6
-rw-r--r--core/res/res/values-gl/strings.xml4
-rw-r--r--core/res/res/values-gu/strings.xml2
-rw-r--r--core/res/res/values-hi/strings.xml1
-rw-r--r--core/res/res/values-hr/strings.xml6
-rw-r--r--core/res/res/values-hu/strings.xml1
-rw-r--r--core/res/res/values-hy/strings.xml2
-rw-r--r--core/res/res/values-in/strings.xml5
-rw-r--r--core/res/res/values-is/strings.xml2
-rw-r--r--core/res/res/values-it/strings.xml12
-rw-r--r--core/res/res/values-iw/strings.xml5
-rw-r--r--core/res/res/values-ja/strings.xml1
-rw-r--r--core/res/res/values-ka/strings.xml1
-rw-r--r--core/res/res/values-kk/strings.xml2
-rw-r--r--core/res/res/values-km/strings.xml1
-rw-r--r--core/res/res/values-kn/strings.xml11
-rw-r--r--core/res/res/values-ko/strings.xml1
-rw-r--r--core/res/res/values-ky/strings.xml24
-rw-r--r--core/res/res/values-lo/strings.xml1
-rw-r--r--core/res/res/values-lt/strings.xml3
-rw-r--r--core/res/res/values-lv/strings.xml4
-rw-r--r--core/res/res/values-mk/strings.xml14
-rw-r--r--core/res/res/values-ml/strings.xml1
-rw-r--r--core/res/res/values-mn/strings.xml1
-rw-r--r--core/res/res/values-mr/strings.xml4
-rw-r--r--core/res/res/values-ms/strings.xml3
-rw-r--r--core/res/res/values-my/strings.xml5
-rw-r--r--core/res/res/values-nb/strings.xml2
-rw-r--r--core/res/res/values-ne/strings.xml11
-rw-r--r--core/res/res/values-nl/strings.xml1
-rw-r--r--core/res/res/values-or/strings.xml2
-rw-r--r--core/res/res/values-pa/strings.xml1
-rw-r--r--core/res/res/values-pl/strings.xml12
-rw-r--r--core/res/res/values-pt-rBR/strings.xml1
-rw-r--r--core/res/res/values-pt-rPT/strings.xml1
-rw-r--r--core/res/res/values-pt/strings.xml1
-rw-r--r--core/res/res/values-ro/strings.xml1
-rw-r--r--core/res/res/values-ru/strings.xml2
-rw-r--r--core/res/res/values-si/strings.xml2
-rw-r--r--core/res/res/values-sk/strings.xml2
-rw-r--r--core/res/res/values-sl/strings.xml5
-rw-r--r--core/res/res/values-sq/strings.xml5
-rw-r--r--core/res/res/values-sr/strings.xml5
-rw-r--r--core/res/res/values-sv/strings.xml1
-rw-r--r--core/res/res/values-sw/strings.xml7
-rw-r--r--core/res/res/values-ta/strings.xml2
-rw-r--r--core/res/res/values-te/strings.xml9
-rw-r--r--core/res/res/values-th/strings.xml1
-rw-r--r--core/res/res/values-tl/strings.xml1
-rw-r--r--core/res/res/values-tr/strings.xml2
-rw-r--r--core/res/res/values-uk/strings.xml2
-rw-r--r--core/res/res/values-ur/strings.xml2
-rw-r--r--core/res/res/values-uz/strings.xml1
-rw-r--r--core/res/res/values-vi/strings.xml1
-rw-r--r--core/res/res/values-zh-rCN/strings.xml5
-rw-r--r--core/res/res/values-zh-rHK/strings.xml3
-rw-r--r--core/res/res/values-zh-rTW/strings.xml1
-rw-r--r--core/res/res/values-zu/strings.xml1
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java3
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java20
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java50
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/UnlockKeyguardToSplitScreen.kt3
-rw-r--r--packages/SettingsLib/res/drawable/ic_docked_tablet.xml26
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothBroadcastUtils.java2
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothLeBroadcastMetadataExt.kt342
-rw-r--r--packages/SettingsLib/tests/unit/src/com/android/settingslib/bluetooth/BluetoothLeBroadcastMetadataExtTest.kt138
-rw-r--r--packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockRegistry.kt27
-rw-r--r--packages/SystemUI/customization/src/com/android/systemui/shared/quickaffordance/shared/model/KeyguardPreviewConstants.kt2
-rw-r--r--packages/SystemUI/monet/src/com/android/systemui/monet/dynamiccolor/MaterialDynamicColors.java410
-rw-r--r--packages/SystemUI/proguard_common.flags19
-rw-r--r--packages/SystemUI/res/layout/media_output_list_item_advanced.xml4
-rw-r--r--packages/SystemUI/res/values-night/colors.xml4
-rw-r--r--packages/SystemUI/res/values-night/styles.xml8
-rw-r--r--packages/SystemUI/res/values/styles.xml6
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/unfold/util/UnfoldOnlyProgressProvider.kt63
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt1
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/ui/DetailDialog.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/ui/StatusBehavior.kt7
-rw-r--r--packages/SystemUI/src/com/android/systemui/flags/Flags.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java41
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/CameraQuickAffordanceConfig.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfig.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfig.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfig.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceConfig.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceConfig.kt71
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfig.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfig.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/VideoCameraQuickAffordanceConfig.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepository.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt37
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardRemotePreviewManager.kt7
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java34
-rw-r--r--packages/SystemUI/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfig.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialog.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/smartspace/dagger/SmartspaceViewComponent.kt7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterImpl.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/theme/DynamicColors.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java11
-rw-r--r--packages/SystemUI/src/com/android/systemui/unfold/UnfoldTransitionModule.kt49
-rw-r--r--packages/SystemUI/src/com/android/systemui/wallet/ui/WalletView.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java10
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFingerprintAndFaceViewTest.kt2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsProviderSelectorActivityTest.kt2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/FakeKeyguardQuickAffordanceConfig.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt12
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java15
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/unfold/TestUnfoldTransitionProvider.kt2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/unfold/UnfoldHapticsPlayerTest.kt19
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/unfold/progress/TestUnfoldProgressListener.kt5
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/unfold/util/TestFoldProvider.kt34
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/unfold/util/UnfoldOnlyProgressProviderTest.kt128
-rw-r--r--services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java11
-rw-r--r--services/accessibility/java/com/android/server/accessibility/AccessibilitySecurityPolicy.java38
-rw-r--r--services/accessibility/java/com/android/server/accessibility/ProxyManager.java20
-rw-r--r--services/core/java/com/android/server/am/ActiveServices.java196
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerConstants.java19
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java4
-rw-r--r--services/core/java/com/android/server/am/BroadcastDeliveryFailedException.java32
-rw-r--r--services/core/java/com/android/server/am/BroadcastProcessQueue.java19
-rw-r--r--services/core/java/com/android/server/am/BroadcastQueue.java3
-rw-r--r--services/core/java/com/android/server/am/BroadcastQueueImpl.java8
-rw-r--r--services/core/java/com/android/server/am/BroadcastQueueModernImpl.java76
-rw-r--r--services/core/java/com/android/server/am/BroadcastRecord.java3
-rw-r--r--services/core/java/com/android/server/am/OomAdjuster.java4
-rw-r--r--services/core/java/com/android/server/am/ServiceRecord.java23
-rw-r--r--services/core/java/com/android/server/biometrics/AuthSession.java72
-rw-r--r--services/core/java/com/android/server/display/DisplayDeviceConfig.java7
-rw-r--r--services/core/java/com/android/server/display/DisplayManagerService.java13
-rw-r--r--services/core/java/com/android/server/display/LocalDisplayAdapter.java4
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiEarcLocalDeviceTx.java16
-rw-r--r--services/core/java/com/android/server/policy/PhoneWindowManager.java6
-rw-r--r--services/core/java/com/android/server/policy/WindowManagerPolicy.java20
-rw-r--r--services/core/java/com/android/server/power/PowerManagerService.java6
-rw-r--r--services/core/java/com/android/server/stats/pull/StatsPullAtomService.java6
-rw-r--r--services/core/java/com/android/server/wm/AnrController.java26
-rw-r--r--services/core/java/com/android/server/wm/DeviceStateController.java32
-rw-r--r--services/core/java/com/android/server/wm/DisplayPolicy.java4
-rw-r--r--services/core/java/com/android/server/wm/DisplayRotation.java4
-rw-r--r--services/core/java/com/android/server/wm/PhysicalDisplaySwitchTransitionLauncher.java5
-rw-r--r--services/core/java/com/android/server/wm/RootWindowContainer.java12
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerInternal.java7
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java9
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java4
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java13
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/PolicyEnforcerCallbacks.java2
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java14
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java2
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java12
-rw-r--r--services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java89
-rw-r--r--services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java42
-rw-r--r--services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java20
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DeviceStateControllerTests.java30
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java7
-rw-r--r--tests/InputMethodStressTest/AndroidManifest.xml3
-rw-r--r--tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/ImeOpenCloseStressTest.java37
-rw-r--r--tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/ImeStressTestUtil.java10
-rw-r--r--wifi/tests/src/android/net/wifi/nl80211/OWNERS1
198 files changed, 2182 insertions, 962 deletions
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
index 92fc78e273ed..4f5eb37d871d 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
@@ -1598,7 +1598,7 @@ public class JobSchedulerService extends com.android.server.SystemService
uId, null, jobStatus.getBatteryName(),
FrameworkStatsLog.SCHEDULED_JOB_STATE_CHANGED__STATE__SCHEDULED,
JobProtoEnums.INTERNAL_STOP_REASON_UNKNOWN, jobStatus.getStandbyBucket(),
- jobStatus.getJobId(),
+ jobStatus.getLoggingJobId(),
jobStatus.hasChargingConstraint(),
jobStatus.hasBatteryNotLowConstraint(),
jobStatus.hasStorageNotLowConstraint(),
@@ -2026,7 +2026,7 @@ public class JobSchedulerService extends com.android.server.SystemService
cancelled.getSourceUid(), null, cancelled.getBatteryName(),
FrameworkStatsLog.SCHEDULED_JOB_STATE_CHANGED__STATE__CANCELLED,
internalReasonCode, cancelled.getStandbyBucket(),
- cancelled.getJobId(),
+ cancelled.getLoggingJobId(),
cancelled.hasChargingConstraint(),
cancelled.hasBatteryNotLowConstraint(),
cancelled.hasStorageNotLowConstraint(),
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java b/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java
index bf2e4560a4ef..90f1523104ee 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java
@@ -465,7 +465,8 @@ public final class JobServiceContext implements ServiceConnection {
job.getSourceUid(), null, job.getBatteryName(),
FrameworkStatsLog.SCHEDULED_JOB_STATE_CHANGED__STATE__STARTED,
JobProtoEnums.INTERNAL_STOP_REASON_UNKNOWN,
- job.getStandbyBucket(), job.getJobId(),
+ job.getStandbyBucket(),
+ job.getLoggingJobId(),
job.hasChargingConstraint(),
job.hasBatteryNotLowConstraint(),
job.hasStorageNotLowConstraint(),
@@ -1521,7 +1522,8 @@ public final class JobServiceContext implements ServiceConnection {
FrameworkStatsLog.write_non_chained(FrameworkStatsLog.SCHEDULED_JOB_STATE_CHANGED,
completedJob.getSourceUid(), null, completedJob.getBatteryName(),
FrameworkStatsLog.SCHEDULED_JOB_STATE_CHANGED__STATE__FINISHED,
- loggingInternalStopReason, completedJob.getStandbyBucket(), completedJob.getJobId(),
+ loggingInternalStopReason, completedJob.getStandbyBucket(),
+ completedJob.getLoggingJobId(),
completedJob.hasChargingConstraint(),
completedJob.hasBatteryNotLowConstraint(),
completedJob.hasStorageNotLowConstraint(),
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java
index b5d763c17e59..a8b4c695889c 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java
@@ -231,6 +231,8 @@ public final class JobStatus {
final String sourceTag;
@Nullable
private final String mNamespace;
+ /** An ID that can be used to uniquely identify the job when logging statsd metrics. */
+ private final long mLoggingJobId;
final String tag;
@@ -568,6 +570,7 @@ public final class JobStatus {
this.callingUid = callingUid;
this.standbyBucket = standbyBucket;
mNamespace = namespace;
+ mLoggingJobId = generateLoggingId(namespace, job.getId());
int tempSourceUid = -1;
if (sourceUserId != -1 && sourcePackageName != null) {
@@ -804,6 +807,13 @@ public final class JobStatus {
/*innerFlags=*/ 0, /* dynamicConstraints */ 0);
}
+ private long generateLoggingId(@Nullable String namespace, int jobId) {
+ if (namespace == null) {
+ return jobId;
+ }
+ return ((long) namespace.hashCode()) << 31 | jobId;
+ }
+
public void enqueueWorkLocked(JobWorkItem work) {
if (pendingWork == null) {
pendingWork = new ArrayList<>();
@@ -956,6 +966,11 @@ public final class JobStatus {
return job.getId();
}
+ /** Returns an ID that can be used to uniquely identify the job when logging statsd metrics. */
+ public long getLoggingJobId() {
+ return mLoggingJobId;
+ }
+
public void printUniqueId(PrintWriter pw) {
if (mNamespace != null) {
pw.print(mNamespace);
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java
index 175c8d1cc4f3..07958dd0fef5 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java
@@ -3153,7 +3153,8 @@ public final class QuotaController extends StateController {
private static final int DEFAULT_MAX_SESSION_COUNT_PER_RATE_LIMITING_WINDOW = 20;
private static final long DEFAULT_TIMING_SESSION_COALESCING_DURATION_MS = 5000; // 5 seconds
private static final long DEFAULT_MIN_QUOTA_CHECK_DELAY_MS = MINUTE_IN_MILLIS;
- private static final long DEFAULT_EJ_LIMIT_EXEMPTED_MS = 45 * MINUTE_IN_MILLIS;
+ // TODO(267949143): set a different limit for headless system apps
+ private static final long DEFAULT_EJ_LIMIT_EXEMPTED_MS = 60 * MINUTE_IN_MILLIS;
private static final long DEFAULT_EJ_LIMIT_ACTIVE_MS = 30 * MINUTE_IN_MILLIS;
private static final long DEFAULT_EJ_LIMIT_WORKING_MS = DEFAULT_EJ_LIMIT_ACTIVE_MS;
private static final long DEFAULT_EJ_LIMIT_FREQUENT_MS = 10 * MINUTE_IN_MILLIS;
diff --git a/cmds/screencap/screencap.cpp b/cmds/screencap/screencap.cpp
index d7222d248911..863efffe3807 100644
--- a/cmds/screencap/screencap.cpp
+++ b/cmds/screencap/screencap.cpp
@@ -30,6 +30,8 @@
#include <binder/ProcessState.h>
+#include <ftl/concat.h>
+#include <ftl/optional.h>
#include <gui/ISurfaceComposer.h>
#include <gui/SurfaceComposerClient.h>
#include <gui/SyncScreenCaptureListener.h>
@@ -45,14 +47,7 @@ using namespace android;
#define COLORSPACE_SRGB 1
#define COLORSPACE_DISPLAY_P3 2
-static void usage(const char* pname, std::optional<PhysicalDisplayId> displayId)
-{
- std::string defaultDisplayStr = "";
- if (!displayId) {
- defaultDisplayStr = "";
- } else {
- defaultDisplayStr = " (default: " + to_string(*displayId) + ")";
- }
+void usage(const char* pname, ftl::Optional<DisplayId> displayIdOpt) {
fprintf(stderr,
"usage: %s [-hp] [-d display-id] [FILENAME]\n"
" -h: this message\n"
@@ -61,7 +56,13 @@ static void usage(const char* pname, std::optional<PhysicalDisplayId> displayId)
" see \"dumpsys SurfaceFlinger --display-id\" for valid display IDs.\n"
"If FILENAME ends with .png it will be saved as a png.\n"
"If FILENAME is not given, the results will be printed to stdout.\n",
- pname, defaultDisplayStr.c_str());
+ pname,
+ displayIdOpt
+ .transform([](DisplayId id) {
+ return std::string(ftl::Concat(" (default: ", id.value, ')').str());
+ })
+ .value_or(std::string())
+ .c_str());
}
static int32_t flinger2bitmapFormat(PixelFormat f)
@@ -132,7 +133,7 @@ int main(int argc, char** argv)
fprintf(stderr, "Failed to get ID for any displays.\n");
return 1;
}
- std::optional<PhysicalDisplayId> displayId;
+ std::optional<DisplayId> displayIdOpt;
const char* pname = argv[0];
bool png = false;
int c;
@@ -142,8 +143,8 @@ int main(int argc, char** argv)
png = true;
break;
case 'd':
- displayId = DisplayId::fromValue<PhysicalDisplayId>(atoll(optarg));
- if (!displayId) {
+ displayIdOpt = DisplayId::fromValue(atoll(optarg));
+ if (!displayIdOpt) {
fprintf(stderr, "Invalid display ID: %s\n", optarg);
return 1;
}
@@ -151,15 +152,15 @@ int main(int argc, char** argv)
case '?':
case 'h':
if (ids.size() == 1) {
- displayId = ids.front();
- }
- usage(pname, displayId);
+ displayIdOpt = ids.front();
+ }
+ usage(pname, displayIdOpt);
return 1;
}
}
- if (!displayId) { // no diplsay id is specified
- displayId = ids.front();
+ if (!displayIdOpt) {
+ displayIdOpt = ids.front();
if (ids.size() > 1) {
fprintf(stderr,
"[Warning] Multiple displays were found, but no display id was specified! "
@@ -191,7 +192,7 @@ int main(int argc, char** argv)
}
if (fd == -1) {
- usage(pname, displayId);
+ usage(pname, displayIdOpt);
return 1;
}
@@ -208,7 +209,7 @@ int main(int argc, char** argv)
ProcessState::self()->startThreadPool();
sp<SyncScreenCaptureListener> captureListener = new SyncScreenCaptureListener();
- status_t result = ScreenshotClient::captureDisplay(*displayId, captureListener);
+ status_t result = ScreenshotClient::captureDisplay(*displayIdOpt, captureListener);
if (result != NO_ERROR) {
close(fd);
return 1;
diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java
index f570c6d15672..7e4e4022f00f 100644
--- a/core/java/android/view/InsetsController.java
+++ b/core/java/android/view/InsetsController.java
@@ -1374,7 +1374,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
// The requested visibilities should be delayed as well. Otherwise, we might override
// the insets visibility before playing animation.
- setRequestedVisibleTypes(mReportedRequestedVisibleTypes, typesReady);
+ setRequestedVisibleTypes(mReportedRequestedVisibleTypes, types);
Trace.asyncTraceEnd(TRACE_TAG_VIEW, "IC.showRequestFromApi", 0);
if (!fromIme) {
diff --git a/core/java/com/android/internal/os/anr/AnrLatencyTracker.java b/core/java/com/android/internal/os/anr/AnrLatencyTracker.java
index 3ba4ea55b5d3..80d753c7ed09 100644
--- a/core/java/com/android/internal/os/anr/AnrLatencyTracker.java
+++ b/core/java/com/android/internal/os/anr/AnrLatencyTracker.java
@@ -120,6 +120,10 @@ public class AnrLatencyTracker implements AutoCloseable {
private long mPreDumpIfLockTooSlowStartUptime;
private long mPreDumpIfLockTooSlowDuration = 0;
+ private long mNotifyAppUnresponsiveStartUptime;
+ private long mNotifyAppUnresponsiveDuration = 0;
+ private long mNotifyWindowUnresponsiveStartUptime;
+ private long mNotifyWindowUnresponsiveDuration = 0;
private final int mAnrRecordPlacedOnQueueCookie =
sNextAnrRecordPlacedOnQueueCookieGenerator.incrementAndGet();
@@ -425,11 +429,36 @@ public class AnrLatencyTracker implements AutoCloseable {
anrSkipped("dumpStackTraces");
}
+ /** Records the start of AnrController#notifyAppUnresponsive. */
+ public void notifyAppUnresponsiveStarted() {
+ mNotifyAppUnresponsiveStartUptime = getUptimeMillis();
+ Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "notifyAppUnresponsive()");
+ }
+
+ /** Records the end of AnrController#notifyAppUnresponsive. */
+ public void notifyAppUnresponsiveEnded() {
+ mNotifyAppUnresponsiveDuration = getUptimeMillis() - mNotifyAppUnresponsiveStartUptime;
+ Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
+ }
+
+ /** Records the start of AnrController#notifyWindowUnresponsive. */
+ public void notifyWindowUnresponsiveStarted() {
+ mNotifyWindowUnresponsiveStartUptime = getUptimeMillis();
+ Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "notifyWindowUnresponsive()");
+ }
+
+ /** Records the end of AnrController#notifyWindowUnresponsive. */
+ public void notifyWindowUnresponsiveEnded() {
+ mNotifyWindowUnresponsiveDuration = getUptimeMillis()
+ - mNotifyWindowUnresponsiveStartUptime;
+ Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
+ }
+
/**
* Returns latency data as a comma separated value string for inclusion in ANR report.
*/
public String dumpAsCommaSeparatedArrayWithHeader() {
- return "DurationsV4: " + mAnrTriggerUptime
+ return "DurationsV5: " + mAnrTriggerUptime
/* triggering_to_app_not_responding_duration = */
+ "," + (mAppNotRespondingStartUptime - mAnrTriggerUptime)
/* app_not_responding_duration = */
@@ -480,6 +509,10 @@ public class AnrLatencyTracker implements AutoCloseable {
+ "," + (mCopyingFirstPidSucceeded ? 1 : 0)
/* preDumpIfLockTooSlow_duration = */
+ "," + mPreDumpIfLockTooSlowDuration
+ /* notifyAppUnresponsive_duration = */
+ + "," + mNotifyAppUnresponsiveDuration
+ /* notifyWindowUnresponsive_duration = */
+ + "," + mNotifyWindowUnresponsiveDuration
+ "\n\n";
}
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 33e7ec97d079..a6b1fdbc588d 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Jy kan nie op jou <xliff:g id="DEVICE">%1$s</xliff:g> toegang hiertoe kry nie. Probeer eerder op jou foon."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Hierdie program is vir ’n ouer weergawe van Android gebou. Dit sal dalk nie behoorlik werk nie en dit sluit nie die jongste sekuriteit en privaatheidbeskermings in nie. Kyk of daar ’n opdatering is of kontak die program se ontwikkelaar."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Kyk vir opdatering"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Hierdie app is nie met die jongste weergawe van Android versoenbaar nie. Kyk of daar ’n opdatering is, of kontak die app se ontwikkelaar."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Jy het nuwe boodskappe"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Maak SMS-program oop om te bekyk"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Sommige funksies kan beperk wees"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 90137083e95f..5a4f3c1ce8e1 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -1975,6 +1975,8 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"ይህ በእርስዎ <xliff:g id="DEVICE">%1$s</xliff:g> ላይ ሊደረስበት አይችልም። በምትኩ በስልክዎ ላይ ይሞክሩ።"</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"ይህ መተግበሪያ የተገነባው ለቆየ የAndroid ስሪት ነበር። በትክክል ላይሰራ ይችላል እና የቅርብ ጊዜዎቹን የደህንነት እና የግላዊነት ጥበቃዎች አያካትትም። ዝማኔ ካለ ይፈትሹ ወይም የመተግበሪያውን ገንቢ ያነጋግሩ።"</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"ዝማኔ ካለ አረጋግጥ"</string>
+ <!-- no translation found for deprecated_abi_message (6820548011196218091) -->
+ <skip />
<string name="new_sms_notification_title" msgid="6528758221319927107">"አዲስ መልዕክቶች አለዎት"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"ለመመልከት የኤስኤምኤስ መተግበሪያ ይክፈቱ"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"አንዳንድ ተግባሮች የተገደቡ ሊሆኑ ይችላሉ"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index bcfdef20ffca..26610733276c 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -1979,6 +1979,8 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"لا يمكن الوصول إلى هذه الإعدادات على <xliff:g id="DEVICE">%1$s</xliff:g>. بدلاً من ذلك، جرِّب استخدام هاتفك."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"‏تم إنشاء هذا التطبيق لإصدار قديم من Android. قد لا يعمل بشكل صحيح كما أنه لا يشتمِل على أحدث الإجراءات لحماية الأمان والخصوصية. ابحث عن تحديث أو تواصَل مع مطوّر التطبيق."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"البحث عن تحديث"</string>
+ <!-- no translation found for deprecated_abi_message (6820548011196218091) -->
+ <skip />
<string name="new_sms_notification_title" msgid="6528758221319927107">"لديك رسائل جديدة"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"‏فتح تطبيق الرسائل القصيرة SMS للعرض"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"قد تكون بعض الوظائف مُقيّدة."</string>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index f8f390a7ce8e..11694a20a2d5 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -1975,6 +1975,8 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"এইটো আপোনাৰ <xliff:g id="DEVICE">%1$s</xliff:g>ত এক্সেছ কৰিব নোৱাৰি। তাৰ পৰিৱৰ্তে আপোনাৰ ফ’নত চেষ্টা কৰি চাওক।"</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"এই এপ্‌টো Androidৰ এটা পুৰণা সংস্কৰণৰ বাবে বনোৱা হৈছিল। এইটোৱে সঠিকভাৱে কাম নকৰিব পাৰে আৰু ইয়াত শেহতীয়া সুৰক্ষা আৰু গোপনীয়তা সম্পৰ্কীয় সুৰক্ষাসমূহ নাথাকে। কোনো আপডে’ট আছে নেকি চাওক অথবা এপৰ বিকাশকৰ্তাগৰাকীৰ সৈতে যোগাযোগ কৰক।"</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"আপডে’ট আছে নেকি চাওক"</string>
+ <!-- no translation found for deprecated_abi_message (6820548011196218091) -->
+ <skip />
<string name="new_sms_notification_title" msgid="6528758221319927107">"আপুনি নতুন বার্তা লাভ কৰিছে"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"চাবলৈ এছএমএছ এপ্ খোলক"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"কিছুমান কাৰ্যকাৰিতা সীমিত হ’ব পাৰে"</string>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index 6e3a1cc992de..620df61a9c05 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -1975,6 +1975,8 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"<xliff:g id="DEVICE">%1$s</xliff:g> cihazınızda buna giriş mümkün deyil. Telefonunuzda sınayın."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Bu tətbiq köhnə Android versiyası üçün nəzərdə tutulub. O, düzgün işləməyə bilər və ən son təhlükəsizlik və məxfilik qorumalarını ehtiva etmir. Güncəlləməni yoxlayın və ya tətbiq tərtibatçısı ilə əlaqə saxlayın."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Güncəllənmə olmasını yoxlayın"</string>
+ <!-- no translation found for deprecated_abi_message (6820548011196218091) -->
+ <skip />
<string name="new_sms_notification_title" msgid="6528758221319927107">"Yeni mesajlarınız var"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Baxmaq üçün SMS tətbiqini açın"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Bəzi funksiyalar məhdudlaşdırıla bilər"</string>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index f68eab66e8dd..a310cfbad129 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -86,7 +86,7 @@
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Probajte da promenite željenu mrežu. Dodirnite da biste promenili."</string>
<string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Hitni pozivi nisu dostupni"</string>
<string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Ne možete da upućujete hitne pozive preko Wi‑Fi-ja"</string>
- <string name="notification_channel_network_alert" msgid="4788053066033851841">"Obaveštenja"</string>
+ <string name="notification_channel_network_alert" msgid="4788053066033851841">"Upozorenja"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"Preusmeravanje poziva"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"Režim za hitan povratni poziv"</string>
<string name="notification_channel_mobile_data_status" msgid="1941911162076442474">"Status mobilnih podataka"</string>
@@ -284,7 +284,7 @@
<string name="notification_channel_network_available" msgid="6083697929214165169">"Mreža je dostupna"</string>
<string name="notification_channel_vpn" msgid="1628529026203808999">"Status VPN-a"</string>
<string name="notification_channel_device_admin" msgid="6384932669406095506">"Obaveštenja od IT administratora"</string>
- <string name="notification_channel_alerts" msgid="5070241039583668427">"Obaveštenja"</string>
+ <string name="notification_channel_alerts" msgid="5070241039583668427">"Upozorenja"</string>
<string name="notification_channel_retail_mode" msgid="3732239154256431213">"Režim demonstracije za maloprodajne objekte"</string>
<string name="notification_channel_usb" msgid="1528280969406244896">"USB veza"</string>
<string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Aktivna aplikacija"</string>
@@ -1976,6 +1976,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Ovoj aplikaciji ne može da se pristupi sa uređaja <xliff:g id="DEVICE">%1$s</xliff:g>. Probajte na telefonu."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Ova aplikacija je napravljena za stariju verziju Android-a. Možda neće raditi ispravno i ne obuhvata najnovije bezbednosne funkcije i zaštite privatnosti. Proverite da li ima ažuriranja ili se obratite programeru aplikacije."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Potraži ažuriranje"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Ova aplikacija nije kompatibilna sa najnovijom verzijom Android-a. Proverite da li ima ažuriranja ili se obratite programeru aplikacije."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Imate nove poruke"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Otvorite aplikaciju za SMS da biste pregledali"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Neke funkcije su možda ograničene"</string>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index a47c5b9bfdca..ad2476fa0638 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -1977,6 +1977,8 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Не ўдаецца атрымаць доступ з прылады \"<xliff:g id="DEVICE">%1$s</xliff:g>\". Паспрабуйце скарыстаць тэлефон."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Гэта праграма створана для ранейшай версіі Android. Яна можа кепска працаваць, і ў ёй няма новых сродкаў абароны бяспекі і прыватнасці. Праверце наяўнасць абнаўленняў ці звярніцеся да распрацоўшчыка праграмы."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Праверыць наяўнасць абнаўленняў"</string>
+ <!-- no translation found for deprecated_abi_message (6820548011196218091) -->
+ <skip />
<string name="new_sms_notification_title" msgid="6528758221319927107">"У вас ёсць новыя паведамленні"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Праглядзець праз праграму для SMS"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Функцыі могуць быць абмежаваныя"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 4ed4a6601292..d2afdb2981bb 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Не може да се осъществи достъп от устройството ви <xliff:g id="DEVICE">%1$s</xliff:g>. Вместо това опитайте от телефона си."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Това приложение бе създадено за по-стара версия на Android. То може да не работи правилно и не включва най-новите защити на поверителността и сигурността. Проверете за актуализация или се свържете с програмиста му."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Проверка за актуализация"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Това приложение не е съвместимо с най-новата версия на Android. Проверете за актуализация или се свържете с програмиста му."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Имате нови съобщения"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Преглед в приложението за SMS"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Някои функции може да са ограничени"</string>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index 82532fbd5caa..42c00f4b043b 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"আপনার <xliff:g id="DEVICE">%1$s</xliff:g>-এ এটি অ্যাক্সেস করা যাবে না। পরিবর্তে আপনার ফোনে ব্যবহার করে দেখুন।"</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Android-এর আরও পুরনো ভার্সনের জন্য এই অ্যাপ তৈরি করা হয়েছিল। এটি সঠিকভাবে কাজ নাও করতে পারে এবং এর মধ্যে লেটেস্ট সুরক্ষা ও গোপনীয়তার নিরাপত্তা ব্যবস্থা অন্তর্ভুক্ত করা নেই। আপডেটের জন্য চেক করুন বা অ্যাপের ডেভেলপারের সাথে যোগাযোগ করুন।"</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"আপডেট পাওয়া যাচ্ছে কিনা দেখুন"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Android-এর লেটেস্ট ভার্সনের সাথে এই অ্যাপটি মানানসই নয়। আপডেটের জন্য চেক করুন বা অ্যাপ ডেভেলপারের সাথে যোগাযোগ করুন।"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"আপনার নতুন মেসেজ আছে"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"দেখার জন্য SMS অ্যাপ্লিকেশান খুলুন"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"কিছু ফাংশন হয়ত কাজ করবে না"</string>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index c625a3a41864..3e5700493c1b 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -995,8 +995,8 @@
<string name="lockscreen_sim_locked_message" msgid="5911944931911850164">"SIM je zaključan."</string>
<string name="lockscreen_sim_unlock_progress_dialog_message" msgid="8381565919325410939">"Otključavanje SIM-a…"</string>
<string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6458790975898594240">"Pogrešno ste nacrtali svoj uzorak za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nBroj sekundi do sljedećeg pokušaja: <xliff:g id="NUMBER_1">%2$d</xliff:g>"</string>
- <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="3118353451602377380">"Pogrešno ste unijeli svoju lozinku <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nBroj sekundi do sljedećeg pokušaja: <xliff:g id="NUMBER_1">%2$d</xliff:g>"</string>
- <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="2874278239714821984">"Pogrešno ste unijeli svoj PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nBroj sekundi do sljedećeg pokušaja: <xliff:g id="NUMBER_1">%2$d</xliff:g>"</string>
+ <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="3118353451602377380">"Pogrešno ste napisali svoju lozinku <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nBroj sekundi do sljedećeg pokušaja: <xliff:g id="NUMBER_1">%2$d</xliff:g>"</string>
+ <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="2874278239714821984">"Pogrešno ste napisali svoj PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nBroj sekundi do sljedećeg pokušaja: <xliff:g id="NUMBER_1">%2$d</xliff:g>"</string>
<string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="3069635524964070596">"Pogrešno ste unijeli uzorak za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Možete pokušati još <xliff:g id="NUMBER_1">%2$d</xliff:g> puta. Nakon toga ćete morati otključati tablet prijavom na svoj Google račun.\n\n Broj sekundi do sljedećeg pokušaja: <xliff:g id="NUMBER_2">%3$d</xliff:g>"</string>
<string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="6399092175942158529">"Pogrešno ste unijeli uzorak za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> put(a). U slučaju još <xliff:g id="NUMBER_1">%2$d</xliff:g> pokušaja bez uspjeha, morat ćete otključati Android TV uređaj prijavom na svoj Google račun.\n\n Pokušajte ponovo za <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
<string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="5691623136957148335">"Pogrešno ste unijeli uzorak za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Možete pokušati još <xliff:g id="NUMBER_1">%2$d</xliff:g> puta. Nakon toga ćete morati otključati telefon prijavom na svoj Google račun.\n\n Broj sekundi do sljedećeg pokušaja: <xliff:g id="NUMBER_2">%3$d</xliff:g>"</string>
@@ -1668,8 +1668,8 @@
<string name="kg_login_invalid_input" msgid="8292367491901220210">"Pogrešno korisničko ime ili lozinka."</string>
<string name="kg_login_account_recovery_hint" msgid="4892466171043541248">"Zaboravili ste korisničko ime ili lozinku?\nPosjetite "<b>"google.com/accounts/recovery"</b>"."</string>
<string name="kg_login_checking_password" msgid="4676010303243317253">"Provjeravanje računa…"</string>
- <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="23741434207544038">"Pogrešno ste unijeli PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nBroj sekundi do sljedećeg pokušaja: <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
- <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="3328686432962224215">"Pogrešno ste unijeli lozinku <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nBroj sekundi do sljedećeg pokušaja: <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="23741434207544038">"Pogrešno ste napisali PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nBroj sekundi do sljedećeg pokušaja: <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+ <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="3328686432962224215">"Pogrešno ste napisali lozinku <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nBroj sekundi do sljedećeg pokušaja: <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="7357404233979139075">"Pogrešno ste nacrtali uzorak <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nBroj sekundi do sljedećeg pokušaja: <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
<string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="3479940221343361587">"Pokušali ste otključati tablet na pogrešan način <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Ako napravite još <xliff:g id="NUMBER_1">%2$d</xliff:g> pokušaja bez uspjeha, tablet će biti vraćen na fabričke postavke i svi korisnički podaci će biti izgubljeni."</string>
<string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="9064457748587850217">"Pokušali ste neispravno otključati Android TV uređaj <xliff:g id="NUMBER_0">%1$d</xliff:g> put(a). U slučaju još <xliff:g id="NUMBER_1">%2$d</xliff:g> pokušaja bez uspjeha, vaš Android TV će se vratiti na fabričke postavke i svi korisnički podaci će biti izgubljeni."</string>
@@ -1976,6 +1976,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Ne možete pristupiti ovoj aplikaciji na uređaju <xliff:g id="DEVICE">%1$s</xliff:g>. Umjesto toga pokušajte na telefonu."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Ova aplikacija je izrađena za stariju verziju Androida. Možda neće pravilno funkcionirati i ne sadržava najnovije sigurnosne zaštite i zaštite privatnosti. Provjerite ima li ažuriranja ili se obratite programeru aplikacije."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Provjeri je li dostupno ažuriranje"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Aplikacija nije kompatibilna s najnovijom verzijom Androida. Provjerite ima li ažuriranja ili se obratite programeru aplikacije."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Imate nove poruke"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Otvorite SMS aplikaciju da biste pregledali poruke"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Neke funkcije mogu biti ograničene"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 4e22a1557f9a..d34b54f7f10a 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -702,7 +702,7 @@
<!-- no translation found for face_acquired_mouth_covering_detected (8219428572168642593) -->
<skip />
<string name="face_acquired_recalibrate_alt" msgid="5702674220280332115">"No es pot crear el model facial. Torna-ho a provar."</string>
- <string name="face_acquired_dark_glasses_detected_alt" msgid="4052123776406041972">"S\'han detectat ulleres fosques. La cara ha de ser completament visible."</string>
+ <string name="face_acquired_dark_glasses_detected_alt" msgid="4052123776406041972">"S\'han detectat ulleres fosques. La cara ha de veure\'s sencera."</string>
<string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"S\'ha detectat una mascareta. La cara ha de veure\'s sencera."</string>
<string-array name="face_acquired_vendor">
</string-array>
@@ -996,7 +996,7 @@
<string name="lockscreen_sim_unlock_progress_dialog_message" msgid="8381565919325410939">"S\'està desbloquejant la targeta SIM…"</string>
<string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6458790975898594240">"Has dibuixat el patró de desbloqueig de manera incorrecta <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades. \n\nTorna-ho a provar d\'aquí a <xliff:g id="NUMBER_1">%2$d</xliff:g> segons."</string>
<string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="3118353451602377380">"Has escrit malament la contrasenya <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades. \n\nTorna-ho a provar d\'aquí a <xliff:g id="NUMBER_1">%2$d</xliff:g> segons."</string>
- <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="2874278239714821984">"Has escrit malament la contrasenya <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades. \n\nTorna-ho a provar d\'aquí a <xliff:g id="NUMBER_1">%2$d</xliff:g> segons."</string>
+ <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="2874278239714821984">"Has escrit malament el PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades. \n\nTorna-ho a provar d\'aquí a <xliff:g id="NUMBER_1">%2$d</xliff:g> segons."</string>
<string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="3069635524964070596">"Has dibuixat el patró de desbloqueig <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades de manera incorrecta. Si falles <xliff:g id="NUMBER_1">%2$d</xliff:g> vegades més, se\'t demanarà que desbloquegis la tauleta amb l\'inici de sessió de Google.\n\n Torna-ho a provar d\'aquí a <xliff:g id="NUMBER_2">%3$d</xliff:g> segons."</string>
<string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="6399092175942158529">"Has dibuixat el patró de desbloqueig <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades de manera incorrecta. Si falles <xliff:g id="NUMBER_1">%2$d</xliff:g> vegades més, se\'t demanarà que desbloquegis el dispositiu Android TV iniciant la sessió a Google.\n\n Torna-ho a provar d\'aquí a <xliff:g id="NUMBER_2">%3$d</xliff:g> segons."</string>
<string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="5691623136957148335">"Has dibuixat el patró de desbloqueig <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades de manera incorrecta. Si falles <xliff:g id="NUMBER_1">%2$d</xliff:g> vegades més, se\'t demanarà que desbloquegis el telèfon amb l\'inici de sessió de Google.\n\n Torna-ho a provar d\'aquí a <xliff:g id="NUMBER_2">%3$d</xliff:g> segons."</string>
@@ -1976,6 +1976,8 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"No s\'hi pot accedir des del teu <xliff:g id="DEVICE">%1$s</xliff:g>. Prova-ho al telèfon."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Aquesta aplicació es va compilar per a una versió anterior d\'Android. Pot ser que no funcioni correctament i no inclou les darreres proteccions de seguretat i privadesa. Comprova si hi ha actualitzacions o contacta amb el desenvolupador de l\'aplicació."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Cerca actualitzacions"</string>
+ <!-- no translation found for deprecated_abi_message (6820548011196218091) -->
+ <skip />
<string name="new_sms_notification_title" msgid="6528758221319927107">"Tens missatges nous"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Obre l\'aplicació d\'SMS per veure\'ls"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Algunes funcions poden ser limitades"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 83589c3dcd44..01f4572345b6 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -1977,6 +1977,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Tato položka na vašem zařízení <xliff:g id="DEVICE">%1$s</xliff:g> není k dispozici. Zkuste to na telefonu."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Tato aplikace byla vytvořena pro starší verzi Androidu. Nemusí fungovat správně a neobsahuje nejnovější zabezpečení a ochranu soukromí. Zkontrolujte dostupnost aktualizace nebo kontaktujte vývojáře aplikace."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Zkontrolovat aktualizace"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Tato aplikace není kompatibilní s poslední verzí Androidu. Zkontrolujte dostupnost aktualizace nebo kontaktujte vývojáře aplikace."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Máte nové zprávy"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Zobrazíte je v aplikaci pro SMS"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Některé funkce mohou být omezeny"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index c845e72ae1d3..34d17574b36f 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -684,7 +684,7 @@
<string name="face_acquired_too_high" msgid="8278815780046368576">"Løft telefonen højere op"</string>
<string name="face_acquired_too_low" msgid="4075391872960840081">"Sænk telefonen"</string>
<string name="face_acquired_too_right" msgid="6245286514593540859">"Flyt telefonen længere til venstre for dig"</string>
- <string name="face_acquired_too_left" msgid="9201762240918405486">"Flyt telefonen længere til højre for dig"</string>
+ <string name="face_acquired_too_left" msgid="9201762240918405486">"Flyt telefonen længere til højre"</string>
<string name="face_acquired_poor_gaze" msgid="4427153558773628020">"Kig mere direkte på din enhed."</string>
<string name="face_acquired_not_detected" msgid="1057966913397548150">"Dit ansigt kan ikke registreres. Hold din telefon i øjenhøjde."</string>
<string name="face_acquired_too_much_motion" msgid="8199691445085189528">"Der er for meget bevægelse. Hold telefonen stille."</string>
@@ -1975,6 +1975,8 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Du kan ikke gøre dette på din <xliff:g id="DEVICE">%1$s</xliff:g>. Prøv på din telefon i stedet."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Denne app er udviklet til en ældre version af Android. Den fungerer muligvis ikke korrekt, og den omfatter ikke de nyeste sikkerhedsfunktioner og den nyeste privatlivsbeskyttelse. Tjek, om der er en opdatering, eller kontakt appudvikleren."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Søg efter opdatering"</string>
+ <!-- no translation found for deprecated_abi_message (6820548011196218091) -->
+ <skip />
<string name="new_sms_notification_title" msgid="6528758221319927107">"Du har nye beskeder"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Åbn sms-appen for at se beskeden"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Nogle funktioner er begrænsede"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 8576cb79cecd..865d1b56335d 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Auf deinem <xliff:g id="DEVICE">%1$s</xliff:g> ist kein Zugriff möglich. Versuch es stattdessen auf deinem Smartphone."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Diese App wurde für eine ältere Android-Version entwickelt. Sie funktioniert möglicherweise nicht richtig und enthält nicht die neuesten Sicherheits- und Datenschutzeinstellungen. Suche nach einem Update oder wende dich an den App-Entwickler."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Auf Updates prüfen"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Diese App ist nicht mit der neuesten Android-Version kompatibel. Suche nach einem Update oder wende dich an den App-Entwickler."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Du hast neue Nachrichten"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Zum Ansehen SMS-App öffnen"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Funktionen sind evtl. eingeschränkt"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index a39e988bd773..7a0f5c0520e9 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Δεν είναι δυνατή η πρόσβαση σε αυτό το στοιχείο από τη συσκευή <xliff:g id="DEVICE">%1$s</xliff:g>. Δοκιμάστε στο τηλέφωνό σας."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Αυτή η εφαρμογή σχεδιάστηκε για μια παλαιότερη έκδοση του Android. Ενδέχεται να μην λειτουργεί σωστά και δεν περιλαμβάνει τις πιο πρόσφατες λειτουργίες ασφάλειας και προστασίας απορρήτου. Ελέγξτε αν υπάρχει διαθέσιμη μια ενημέρωση ή επικοινωνήστε με τον προγραμματιστή της εφαρμογής."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Έλεγχος για ενημέρωση"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Αυτή η εφαρμογή δεν είναι συμβατή με την πιο πρόσφατη έκδοση Android. Ελέγξτε αν υπάρχει διαθέσιμη μια ενημέρωση ή επικοινωνήστε με τον προγραμματιστή της εφαρμογής."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Έχετε νέα μηνύματα"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Άνοιγμα της εφαρμογής SMS για προβολή"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Ορισμ. λειτ. ίσως είναι περιορισμ."</string>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index b43dfb9d6d7e..725f9fa3d00a 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"This can’t be accessed on your <xliff:g id="DEVICE">%1$s</xliff:g>. Try on your phone instead."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"This app was built for an older version of Android. It might not work properly and doesn\'t include the latest security and privacy protections. Check for an update or contact the app\'s developer."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Check for update"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"This app isn\'t compatible with the latest version of Android. Check for an update or contact the app\'s developer."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"You have new messages"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Open SMS app to view"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Some functionality may be limited"</string>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index 13b1c93333a2..86e1267eca9d 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"This can’t be accessed on your <xliff:g id="DEVICE">%1$s</xliff:g>. Try on your phone instead."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"This app was built for an older version of Android. It might not work properly and doesn\'t include the latest security and privacy protections. Check for an update, or contact the app\'s developer."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Check for update"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"This app isn\'t compatible with the latest version of Android. Check for an update or contact the app\'s developer."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"You have new messages"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Open SMS app to view"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Some functionality may be limited"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 623f8293dd77..f0af9de9e6a9 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"This can’t be accessed on your <xliff:g id="DEVICE">%1$s</xliff:g>. Try on your phone instead."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"This app was built for an older version of Android. It might not work properly and doesn\'t include the latest security and privacy protections. Check for an update or contact the app\'s developer."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Check for update"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"This app isn\'t compatible with the latest version of Android. Check for an update or contact the app\'s developer."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"You have new messages"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Open SMS app to view"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Some functionality may be limited"</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index e79afd5870d7..2677a55b7aeb 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"This can’t be accessed on your <xliff:g id="DEVICE">%1$s</xliff:g>. Try on your phone instead."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"This app was built for an older version of Android. It might not work properly and doesn\'t include the latest security and privacy protections. Check for an update or contact the app\'s developer."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Check for update"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"This app isn\'t compatible with the latest version of Android. Check for an update or contact the app\'s developer."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"You have new messages"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Open SMS app to view"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Some functionality may be limited"</string>
diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml
index a908198bfc80..fc93b3cccc43 100644
--- a/core/res/res/values-en-rXC/strings.xml
+++ b/core/res/res/values-en-rXC/strings.xml
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‏‏‎‏‏‏‏‎‎‏‏‏‎‎‎‎‏‎‏‎‏‏‏‏‏‎‏‎‏‎‏‏‏‏‏‏‎‏‎‎‏‏‎‎‏‎‎‏‏‎‎‎‏‏‏‎This can’t be accessed on your ‎‏‎‎‏‏‎<xliff:g id="DEVICE">%1$s</xliff:g>‎‏‎‎‏‏‏‎. Try on your phone instead.‎‏‎‎‏‎"</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‏‎‏‎‎‎‎‏‏‎‎‎‎‎‏‎‏‏‏‎‏‏‏‎‏‏‎‎‏‎‏‎‎‎‎‎‏‏‎‏‏‎‏‏‎‎‏‏‎‏‏‎‏‎‎‎This app was built for an older version of Android. It might not work properly and doesn\'t include the latest security and privacy protections. Check for an update, or contact the app\'s developer.‎‏‎‎‏‎"</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‏‎‏‎‏‏‏‎‎‏‎‎‎‏‎‎‎‎‏‎‎‏‎‎‏‎‏‎‎‎‏‎‎‏‎‎‎‏‎‎‏‏‎‎‏‏‏‏‏‎‏‎‎‏‏‎‏‎Check for update‎‏‎‎‏‎"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‎‏‎‎‏‏‏‎‏‏‏‎‏‎‎‎‏‎‎‎‏‏‏‏‎‎‎‎‏‎‎‏‏‎‏‏‎‎‎‏‏‏‏‏‎‏‎‏‏‏‎‏‎‏‏‎This app isn\'t compatible with the latest version of Android. Check for an update or contact the app\'s developer.‎‏‎‎‏‎"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‎‎‏‏‎‏‎‏‏‎‎‏‏‏‏‎‎‎‎‎‎‏‎‏‏‏‎‏‏‏‎‎‎‏‎‏‏‏‏‎‏‏‏‎‏‎‏‎‏‎‎‎‎‏‏‎You have new messages‎‏‎‎‏‎"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‎‎‏‏‎‎‎‎‏‎‏‏‎‎‏‏‎‏‎‎‎‎‏‎‏‏‎‎‎‏‎‏‎‏‎‏‏‎‎‏‏‎‏‏‎‏‎‏‏‏‎‎‏‏‏‏‏‎Open SMS app to view‎‏‎‎‏‎"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‏‎‏‎‏‎‏‏‎‏‏‏‏‎‎‏‎‏‏‏‏‎‏‏‏‎‎‎‏‏‎‎‎‏‎‏‏‎‏‏‎‎‏‏‎‎‏‎‏‎‎‎‎Some functionality may be limited‎‏‎‎‏‎"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 433ba3851600..70de08477b22 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -692,10 +692,10 @@
<string name="face_acquired_recalibrate" msgid="8724013080976469746">"Vuelve a registrar tu rostro."</string>
<string name="face_acquired_too_different" msgid="2520389515612972889">"No se reconoce el rostro. Vuelve a intentarlo."</string>
<string name="face_acquired_too_similar" msgid="8882920552674125694">"Cambia levemente la posición de la cabeza"</string>
- <string name="face_acquired_pan_too_extreme" msgid="5417928604710621088">"Mira el teléfono de forma más directa"</string>
- <string name="face_acquired_tilt_too_extreme" msgid="5715715666540716620">"Mira el teléfono de forma más directa"</string>
- <string name="face_acquired_roll_too_extreme" msgid="8261939882838881194">"Mira el teléfono de forma más directa"</string>
- <string name="face_acquired_obscured" msgid="4917643294953326639">"Quítate cualquier objeto que te cubra el rostro."</string>
+ <string name="face_acquired_pan_too_extreme" msgid="5417928604710621088">"Mira directamente al teléfono"</string>
+ <string name="face_acquired_tilt_too_extreme" msgid="5715715666540716620">"Mira directamente al teléfono"</string>
+ <string name="face_acquired_roll_too_extreme" msgid="8261939882838881194">"Mira directamente al teléfono"</string>
+ <string name="face_acquired_obscured" msgid="4917643294953326639">"Quítate cualquier objeto que te cubra el rostro"</string>
<string name="face_acquired_sensor_dirty" msgid="8968391891086721678">"Limpia la parte superior de la pantalla, incluida la barra negra"</string>
<!-- no translation found for face_acquired_dark_glasses_detected (5643703296620631986) -->
<skip />
@@ -1976,6 +1976,8 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"No se puede acceder a esto en tu <xliff:g id="DEVICE">%1$s</xliff:g>. Inténtalo en tu teléfono."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Esta app se compiló para una versión anterior de Android. Es posible que no funcione correctamente ni incluya las protecciones de la privacidad más recientes. Consulta si hay actualizaciones o comunícate con el desarrollador."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Buscar actualización"</string>
+ <!-- no translation found for deprecated_abi_message (6820548011196218091) -->
+ <skip />
<string name="new_sms_notification_title" msgid="6528758221319927107">"Tienes mensajes nuevos"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Abrir app de SMS para ver el mensaje"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Podrían limitarse algunas funciones"</string>
@@ -2324,7 +2326,7 @@
<string name="mic_access_on_toast" msgid="2666925317663845156">"El micrófono está disponible"</string>
<string name="mic_access_off_toast" msgid="8111040892954242437">"El micrófono está bloqueado"</string>
<string name="concurrent_display_notification_name" msgid="1526911253558311131">"Pantalla dual"</string>
- <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"La Pantalla dual está activada"</string>
+ <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"La función Dual Screen está activada"</string>
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> está usando ambas pantallas para mostrar contenido"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"El dispositivo está muy caliente"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"La Pantalla dual no está disponible porque el teléfono se está calentando demasiado"</string>
@@ -2336,7 +2338,7 @@
<string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Diseño de teclado establecido en <xliff:g id="LAYOUT_1">%s</xliff:g>. Presiona para cambiar esta opción."</string>
<string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Diseño de teclado establecido en <xliff:g id="LAYOUT_1">%1$s</xliff:g> y <xliff:g id="LAYOUT_2">%2$s</xliff:g>. Presiona para cambiar esta opción."</string>
<string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Diseño de teclado establecido en <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g> y <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Presiona para cambiar esta opción."</string>
- <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Diseño de teclado establecido en <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g> y <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Presiona para cambiar esta opción."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Diseño de teclado establecido en <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g> y <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Presiona para cambiarlo."</string>
<string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Teclados físicos configurados"</string>
<string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Presiona para ver los teclados"</string>
</resources>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 03a12a0d7be4..28b2ec56a63a 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -703,7 +703,7 @@
<skip />
<string name="face_acquired_recalibrate_alt" msgid="5702674220280332115">"No se puede crear tu modelo. Inténtalo de nuevo."</string>
<string name="face_acquired_dark_glasses_detected_alt" msgid="4052123776406041972">"Gafas oscuras detectadas. Tu cara se debe poder ver entera."</string>
- <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"Mascarilla detectada. Tu cara se debe poder ver entera."</string>
+ <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"Cara parcialmente cubierta. Tu cara se debe poder ver entera."</string>
<string-array name="face_acquired_vendor">
</string-array>
<string name="face_error_hw_not_available" msgid="5085202213036026288">"No se puede verificar. Hardware no disponible."</string>
@@ -1976,6 +1976,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"No se puede acceder desde tu <xliff:g id="DEVICE">%1$s</xliff:g>. Prueba en tu teléfono."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Esta aplicación se creó para una versión anterior de Android. Puede que no funcione correctamente y que no incluya las protecciones de seguridad y privacidad más recientes. Comprueba si hay actualizaciones o ponte en contacto con el desarrollador de la aplicación."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Buscar actualizaciones"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Esta aplicación no es compatible con la última versión de Android. Comprueba si hay actualizaciones o contacta con el desarrollador de la aplicación."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Tienes mensajes nuevos"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Abre la aplicación de SMS para ver el mensaje"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Algunas funciones limitadas"</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index 0328a05c70d9..9d1a03ff91a4 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -1696,7 +1696,7 @@
<string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"SEES"</string>
<string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"VÄLJAS"</string>
<string name="accessibility_enable_service_title" msgid="3931558336268541484">"Kas anda teenusele <xliff:g id="SERVICE">%1$s</xliff:g> teie seadme üle täielik kontroll?"</string>
- <string name="accessibility_service_warning_description" msgid="291674995220940133">"Täielik haldusõigus sobib rakendustele, mis pakuvad juurdepääsufunktsioone. Enamiku rakenduste puhul seda ei soovitata."</string>
+ <string name="accessibility_service_warning_description" msgid="291674995220940133">"Täielik kontroll sobib rakendustele, mis pakuvad juurdepääsufunktsioone. Enamiku rakenduste puhul seda ei soovitata."</string>
<string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Ekraanikuva vaatamine ja haldamine"</string>
<string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"See saab lugeda kogu ekraanil kuvatud sisu ja kuvada sisu rakenduste peal."</string>
<string name="accessibility_service_action_perform_title" msgid="779670378951658160">"Toimingute vaatamine ja tegemine"</string>
@@ -1975,6 +1975,8 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Sellele ei pääse teie seadmes <xliff:g id="DEVICE">%1$s</xliff:g> juurde. Proovige juurde pääseda oma telefonis."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"See rakendus on loodud Androidi vanema versiooni jaoks. See ei pruugi õigesti töötada ega hõlma uusimaid turva- ja privaatsusfunktsioone. Otsige värskendust või võtke ühendust rakenduse arendajaga."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Otsi värskendust"</string>
+ <!-- no translation found for deprecated_abi_message (6820548011196218091) -->
+ <skip />
<string name="new_sms_notification_title" msgid="6528758221319927107">"Teile on uusi sõnumeid"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Avage vaatamiseks SMS-rakendus"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Mõned funkts. võivad olla piiratud"</string>
@@ -2167,7 +2169,7 @@
<string name="miniresolver_open_in_work" msgid="941341494673509916">"Kas avada töörakenduses <xliff:g id="APP">%s</xliff:g>?"</string>
<string name="miniresolver_call_in_work" msgid="528779988307529039">"Kas helistada töörakendusest?"</string>
<string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Kas lülituda töörakendusele?"</string>
- <string name="miniresolver_call_information" msgid="6739417525304184083">"Teie organisatsioon lubab helistada ainult töörakendustest"</string>
+ <string name="miniresolver_call_information" msgid="6739417525304184083">"Teie organisatsioon lubab helistada ainult töörakendustest."</string>
<string name="miniresolver_sms_information" msgid="4311292661329483088">"Teie organisatsioon lubab sõnumeid saata ainult töörakendustest."</string>
<string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Kasuta isiklikku brauserit"</string>
<string name="miniresolver_use_work_browser" msgid="543575306251952994">"Kasuta tööbrauserit"</string>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index 1fd274f48cf5..f14a0070177f 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -47,8 +47,8 @@
<string name="needPuk2" msgid="3910763547447344963">"Idatzi PUK2-a SIMa desblokeatzeko."</string>
<string name="enablePin" msgid="2543771964137091212">"Ezin izan da aldatu. Gaitu SIM edo RUIM txartelaren blokeoa."</string>
<plurals name="pinpuk_attempts" formatted="false" msgid="1619867269012213584">
- <item quantity="other"><xliff:g id="NUMBER_1">%d</xliff:g> saiakera geratzen zaizkizu SIM txartela blokeatu aurretik.</item>
- <item quantity="one"><xliff:g id="NUMBER_0">%d</xliff:g> saiakera geratzen zaizu SIM txartela blokeatu aurretik.</item>
+ <item quantity="other"><xliff:g id="NUMBER_1">%d</xliff:g> saiakera geratzen zaizkizu SIMa blokeatu aurretik.</item>
+ <item quantity="one"><xliff:g id="NUMBER_0">%d</xliff:g> saiakera geratzen zaizu SIMa blokeatu aurretik.</item>
</plurals>
<string name="imei" msgid="2157082351232630390">"IMEIa"</string>
<string name="meid" msgid="3291227361605924674">"MEID"</string>
@@ -80,7 +80,7 @@
<string name="RestrictedOnNormalTitle" msgid="7009474589746551737">"Ez dago ahots-deien zerbitzurik"</string>
<string name="RestrictedOnAllVoiceTitle" msgid="3982069078579103087">"Ez dago ahozko zerbitzurik eta ezin da egin larrialdi-deirik"</string>
<string name="RestrictedStateContent" msgid="7693575344608618926">"Operadoreak desaktibatu egin du aldi baterako"</string>
- <string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"Operadoreak <xliff:g id="SIMNUMBER">%d</xliff:g> SIM txartela desaktibatu egin du aldi baterako"</string>
+ <string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"Operadoreak <xliff:g id="SIMNUMBER">%d</xliff:g> SIMa desaktibatu egin du aldi baterako"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Ezin da konektatu sare mugikorrera"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Aldatu sare hobetsia. Sakatu aldatzeko."</string>
<string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Ezin da egin larrialdi-deirik"</string>
@@ -1044,7 +1044,7 @@
<string name="keyguard_accessibility_face_unlock" msgid="4533832120787386728">"Aurpegi bidez desblokeatzea."</string>
<string name="keyguard_accessibility_pin_unlock" msgid="4020864007967340068">"PIN kodearen bidez desblokeatzea."</string>
<string name="keyguard_accessibility_sim_pin_unlock" msgid="4895939120871890557">"SIMa desblokeatzeko PINa."</string>
- <string name="keyguard_accessibility_sim_puk_unlock" msgid="3459003464041899101">"SIM txartela desblokeatzeko PUK kodea."</string>
+ <string name="keyguard_accessibility_sim_puk_unlock" msgid="3459003464041899101">"SIMa desblokeatzeko PUK kodea."</string>
<string name="keyguard_accessibility_password_unlock" msgid="6130186108581153265">"Pasahitzaren bidez desblokeatzea."</string>
<string name="keyguard_accessibility_pattern_area" msgid="1419570880512350689">"Eredua marrazteko eremua."</string>
<string name="keyguard_accessibility_slide_area" msgid="4331399051142520176">"Hatza lerratzeko eremua."</string>
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Aplikazioa ezin da <xliff:g id="DEVICE">%1$s</xliff:g> erabilita atzitu. Gailu horren ordez, erabili telefonoa."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Android-en bertsio zaharrago baterako sortu da aplikazio hau. Baliteke behar bezala ez funtzionatzea, eta ez ditu barne hartzen azken segurtasun- eta pribatutasun-babesak. Begiratu ea eguneratzerik dagoen edo jarri aplikazioaren garatzailearekin harremanetan."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Bilatu eguneratzeak"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Aplikazio hau ez da Androiden azken bertsioarekin bateragarria. Begiratu ea eguneratzerik dagoen edo jarri aplikazioaren garatzailearekin harremanetan."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Mezu berriak dituzu"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Mezuak ikusteko, ireki SMSetarako aplikazioa"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Baliteke funtzio batzuk mugatuta egotea"</string>
@@ -2044,14 +2045,14 @@
<string name="etws_primary_default_message_test" msgid="4583367373909549421">"Larrialdi-mezuen proba"</string>
<string name="notification_reply_button_accessibility" msgid="5235776156579456126">"Erantzun"</string>
<string name="etws_primary_default_message_others" msgid="7958161706019130739"></string>
- <string name="mmcc_authentication_reject" msgid="4891965994643876369">"SIM txartela ezin da erabili ahotsa erabiltzeko"</string>
- <string name="mmcc_imsi_unknown_in_hlr" msgid="227760698553988751">"SIM txartela ez dago hornituta ahotsa erabiltzeko"</string>
+ <string name="mmcc_authentication_reject" msgid="4891965994643876369">"SIMa ezin da erabili ahotsa erabiltzeko"</string>
+ <string name="mmcc_imsi_unknown_in_hlr" msgid="227760698553988751">"SIMa ez dago hornituta ahotsa erabiltzeko"</string>
<string name="mmcc_illegal_ms" msgid="7509650265233909445">"SIM txartela ezin da erabili ahotsa erabiltzeko"</string>
<string name="mmcc_illegal_me" msgid="6505557881889904915">"Telefonoa ezin da erabili ahotsa erabiltzeko"</string>
- <string name="mmcc_authentication_reject_msim_template" msgid="4480853038909922153">"Ezin da erabili <xliff:g id="SIMNUMBER">%d</xliff:g> SIM txartela"</string>
+ <string name="mmcc_authentication_reject_msim_template" msgid="4480853038909922153">"Ez da onartzen <xliff:g id="SIMNUMBER">%d</xliff:g> SIMa"</string>
<string name="mmcc_imsi_unknown_in_hlr_msim_template" msgid="3688508325248599657">"Ez dago <xliff:g id="SIMNUMBER">%d</xliff:g> SIMik"</string>
- <string name="mmcc_illegal_ms_msim_template" msgid="832644375774599327">"Ezin da erabili <xliff:g id="SIMNUMBER">%d</xliff:g> SIM txartela"</string>
- <string name="mmcc_illegal_me_msim_template" msgid="4802735138861422802">"Ezin da erabili <xliff:g id="SIMNUMBER">%d</xliff:g> SIM txartela"</string>
+ <string name="mmcc_illegal_ms_msim_template" msgid="832644375774599327">"Ezin da erabili <xliff:g id="SIMNUMBER">%d</xliff:g> SIMa"</string>
+ <string name="mmcc_illegal_me_msim_template" msgid="4802735138861422802">"Ezin da erabili <xliff:g id="SIMNUMBER">%d</xliff:g> SIMa"</string>
<string name="popup_window_default_title" msgid="6907717596694826919">"Leiho gainerakorra"</string>
<string name="slice_more_content" msgid="3377367737876888459">"Beste <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
<string name="shortcut_restored_on_lower_version" msgid="9206301954024286063">"Aplikazioaren bertsio zaharrago batera aldatu da, edo aplikazioa ez da lasterbide honekin bateragarria"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 415dce575740..2a77aa2cb947 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -1975,6 +1975,8 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"نمی‌توان در <xliff:g id="DEVICE">%1$s</xliff:g> به این مورد دسترسی داشت. دسترسی به آن را در تلفنتان امتحان کنید."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"‏این برنامه برای نسخه قدیمی‌تری از Android ساخته شده است. احتمال دارد به‌درستی کار نکند و شامل جدیدترین محافظت‌های حریم خصوصی و امنیت نمی‌شود. بررسی کنید به‌روزرسانی دردسترس باشد یا با توسعه‌دهنده برنامه تماس بگیرید."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"بررسی وجود به‌روزرسانی"</string>
+ <!-- no translation found for deprecated_abi_message (6820548011196218091) -->
+ <skip />
<string name="new_sms_notification_title" msgid="6528758221319927107">"پیام‌های جدیدی دارید"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"برای مشاهده، برنامه پیامک را باز کنید"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"برخی از عملکردها ممکن است محدود باشند"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index ccca9df10fac..a5a0a3f7d9b3 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"<xliff:g id="DEVICE">%1$s</xliff:g> ei saa pääsyä sovellukseen. Kokeile striimausta puhelimella."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Tämä sovellus on suunniteltu vanhemmalle Android-versiolle. Se ei välttämättä toimi oikein eikä sisällä uusimpia tietoturvan ja yksityisyyden suojauksia. Tarkista päivitykset tai ota yhteyttä sovelluksen kehittäjään."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Tarkista päivitykset"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Sovellus ei ole yhteensopiva uusimman Android-version kanssa. Tarkista päivitykset tai ota yhteyttä sovelluksen kehittäjään."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Sinulle on uusia viestejä"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Katso avaamalla tekstiviestisovellus."</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Osaa toiminnoista voidaan rajoittaa"</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 97bbfb41533e..a7803784af96 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -1976,6 +1976,8 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Impossible d\'accéder à ce contenu sur votre <xliff:g id="DEVICE">%1$s</xliff:g>. Essayez sur votre téléphone à la place."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Cette application a été conçue pour une ancienne version d\'Android. Elle pourrait ne pas fonctionner correctement, et ne comprend pas les dernières protections des données confidentielles et de sécurité. Vérifiez s\'il existe une mise à jour ou contactez le développeur de l\'application."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Vérifier la présence de mises à jour"</string>
+ <!-- no translation found for deprecated_abi_message (6820548011196218091) -->
+ <skip />
<string name="new_sms_notification_title" msgid="6528758221319927107">"Vous avez de nouveaux messages"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Ouvrez l\'application de messagerie texte pour l\'afficher"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Des fonctionnalités sont limitées"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 6e2e1f09b3d6..4022d3c48f37 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -1698,9 +1698,9 @@
<string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"DÉSACTIVÉE"</string>
<string name="accessibility_enable_service_title" msgid="3931558336268541484">"Accorder le contrôle total de votre appareil à <xliff:g id="SERVICE">%1$s</xliff:g> ?"</string>
<string name="accessibility_service_warning_description" msgid="291674995220940133">"Le contrôle total convient aux applications qui répondent à vos besoins d\'accessibilité. Il ne convient pas à la plupart des autres applications."</string>
- <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Afficher et contrôler l\'écran"</string>
+ <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Voir et contrôler l\'écran"</string>
<string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Le service peut lire l\'intégralité du contenu à l\'écran et afficher du contenu par-dessus d\'autres applications."</string>
- <string name="accessibility_service_action_perform_title" msgid="779670378951658160">"Afficher et effectuer des actions"</string>
+ <string name="accessibility_service_action_perform_title" msgid="779670378951658160">"Voir et effectuer des actions"</string>
<string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Le service peut suivre vos interactions avec une application ou un capteur matériel, et interagir avec des applications de votre part."</string>
<string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Autoriser"</string>
<string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Refuser"</string>
@@ -1976,6 +1976,8 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Impossible d\'accéder à ces paramètres sur votre <xliff:g id="DEVICE">%1$s</xliff:g>. Essayez plutôt sur votre téléphone."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Cette appli a été conçue pour une ancienne version d\'Android. Elle risque de ne pas fonctionner correctement et n\'inclut pas les derniers dispositifs de sécurité et de protection de la confidentialité. Recherchez une mise à jour ou contactez le développeur de l\'appli."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Rechercher une mise à jour"</string>
+ <!-- no translation found for deprecated_abi_message (6820548011196218091) -->
+ <skip />
<string name="new_sms_notification_title" msgid="6528758221319927107">"Vous avez de nouveaux messages"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Ouvrir l\'application de SMS pour afficher le message"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Des fonctions peuvent être limitées"</string>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index 9da299c02912..db56bfd6b9d5 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -702,7 +702,7 @@
<skip />
<string name="face_acquired_recalibrate_alt" msgid="5702674220280332115">"Non se puido crear o modelo facial. Téntao de novo."</string>
<string name="face_acquired_dark_glasses_detected_alt" msgid="4052123776406041972">"Levas lentes escuras, pero débeseche ver toda a cara"</string>
- <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"Levas máscara, pero débeseche ver toda a cara"</string>
+ <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"Tes a cara tapada, pero débeseche ver enteira"</string>
<string-array name="face_acquired_vendor">
</string-array>
<string name="face_error_hw_not_available" msgid="5085202213036026288">"Sen verificar a cara. Hardware non dispoñible."</string>
@@ -1975,6 +1975,8 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Non se puido acceder a este contido desde o teu dispositivo (<xliff:g id="DEVICE">%1$s</xliff:g>). Proba a facelo desde o teléfono."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Esta aplicación deseñouse para unha versión anterior de Android. Quizais non funcione correctamente e non inclúa as últimas medidas de protección de privacidade e seguranza. Comproba se hai actualizacións ou ponte en contacto co programador da aplicación."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Buscar actualización"</string>
+ <!-- no translation found for deprecated_abi_message (6820548011196218091) -->
+ <skip />
<string name="new_sms_notification_title" msgid="6528758221319927107">"Tes mensaxes novas"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Abre a aplicación de SMS para ver as mensaxes"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Pode haber funcións limitadas"</string>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index 1c7d98647f6c..12f43d288700 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -1975,6 +1975,8 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"આને તમારા <xliff:g id="DEVICE">%1$s</xliff:g> પર ઍક્સેસ કરી શકાતી નથી. તેના બદલે તમારા ફોન પર પ્રયાસ કરો."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Androidના કોઈ જૂના વર્ઝન માટે આ ઍપ બનાવવામાં આવી હતી. તે કદાચ યોગ્ય રીતે કામ કરતી નથી અને તેમાં નવીનતમ સુરક્ષા અને પ્રાઇવસી સંબંધિત સંરક્ષણો શામેલ નથી. કોઈ અપડેટ ચેક કરો અથવા ઍપના ડેવલપરનો સંપર્ક કરો."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"અપડેટ માટે તપાસો"</string>
+ <!-- no translation found for deprecated_abi_message (6820548011196218091) -->
+ <skip />
<string name="new_sms_notification_title" msgid="6528758221319927107">"તમારી પાસે નવા સંદેશા છે"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"જોવા માટે SMS ઍપ્લિકેશન ખોલો"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"કેટલીક કાર્યક્ષમતા મર્યાદિત હોઈ શકે છે"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index c750d50fb729..f26466bca6c8 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"आपके <xliff:g id="DEVICE">%1$s</xliff:g> पर इसे ऐक्सेस नहीं किया जा सकता. इसके बजाय, अपने फ़ोन पर ऐक्सेस करने की कोशिश करें."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"यह ऐप्लिकेशन, Android के पुराने वर्शन के लिए बनाया गया था. इसमें सिक्योरिटी और निजता सुरक्षा से जुड़ी नई सुविधाएं शामिल नहीं हैं. साथ ही, ऐसा हो सकता है कि यह ठीक से काम न करे. अपडेट के बारे में पता करें या ऐप्लिकेशन के डेवलपर से संपर्क करें."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"देखें कि अपडेट मौजूद है या नहीं"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"यह ऐप्लिकेशन, Android के सबसे नए वर्शन पर काम नहीं करता है. अपडेट के बारे में पता करें या ऐप्लिकेशन के डेवलपर से संपर्क करें."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"आपके पास नए संदेश हैं"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"देखने के लिए मैसेज (एसएमएस) ऐप खोलें"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"शायद कुछ सुविधाएं काम न करें"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 38d3f01be2ff..6bf82308276b 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -996,7 +996,7 @@
<string name="lockscreen_sim_unlock_progress_dialog_message" msgid="8381565919325410939">"Otključavanje SIM-a…"</string>
<string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6458790975898594240">"Netočno ste iscrtali uzorak za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nPokušajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
<string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="3118353451602377380">"Netočno ste napisali zaporku <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nPokušajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
- <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="2874278239714821984">"Netočno ste napisali PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nPokušajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
+ <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="2874278239714821984">"Netočno ste unijeli PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nPokušajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
<string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="3069635524964070596">"Netočno ste iscrtali uzorak za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Nakon još ovoliko neuspješnih pokušaja: <xliff:g id="NUMBER_1">%2$d</xliff:g> zamolit ćemo vas da otključate tabletno računalo putem prijave na Google.\n\n Pokušajte ponovo za <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
<string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="6399092175942158529">"Netočno ste iscrtali uzorak za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> put/a. Nakon još ovoliko neuspješnih pokušaja: <xliff:g id="NUMBER_1">%2$d</xliff:g> zamolit ćemo vas da otključate Android TV uređaj putem prijave na Google.\n\n Pokušajte ponovo za <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
<string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="5691623136957148335">"Netočno ste iscrtali uzorak za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Nakon još ovoliko neuspješnih pokušaja: <xliff:g id="NUMBER_1">%2$d</xliff:g> morat ćete otključati telefon putem prijave na Google.\n\n Pokušajte ponovo za <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
@@ -1668,7 +1668,7 @@
<string name="kg_login_invalid_input" msgid="8292367491901220210">"Nevažeće korisničko ime ili zaporka."</string>
<string name="kg_login_account_recovery_hint" msgid="4892466171043541248">"Zaboravili ste korisničko ime ili zaporku?\nPosjetite "<b>"google.com/accounts/recovery"</b>"."</string>
<string name="kg_login_checking_password" msgid="4676010303243317253">"Provjera računa..."</string>
- <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="23741434207544038">"Netočno ste napisali PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nPokušajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="23741434207544038">"Netočno ste unijeli PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nPokušajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="3328686432962224215">"Netočno ste napisali zaporku <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nPokušajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="7357404233979139075">"Netočno ste iscrtali obrazac za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nPokušajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
<string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="3479940221343361587">"Netočno ste pokušali otključati tabletno računalo <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Ono će se vratiti na tvorničke postavke i svi korisnički podaci bit će izgubljeni nakon još ovoliko neuspjelih pokušaja: <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
@@ -1976,6 +1976,8 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Toj aplikaciji nije moguće pristupiti na vašem uređaju <xliff:g id="DEVICE">%1$s</xliff:g>. Pokušajte joj pristupiti na telefonu."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Ova je aplikacija razvijena za stariju verziju Androida. Možda neće funkcionirati pravilno i ne uključuje najnovije zaštite sigurnosti i privatnosti. Provjerite je li za tu aplikaciju dostupno ažuriranje ili se obratite razvojnom programeru."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Provjeri ažuriranja"</string>
+ <!-- no translation found for deprecated_abi_message (6820548011196218091) -->
+ <skip />
<string name="new_sms_notification_title" msgid="6528758221319927107">"Imate nove poruke"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Otvorite SMS aplikaciju da biste pregledali poruke"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Funkcije mogu biti ograničene"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 0525338b4abd..38fd4ac989a2 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Ehhez nem lehet hozzáférni a következő eszközön: <xliff:g id="DEVICE">%1$s</xliff:g>. Próbálja újra a telefonon."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Ez az alkalmazás az Android egy korábbi verziójához készült. Előfordulhat, hogy nem működik megfelelően, és nem tartalmazza a legfrissebb biztonsági és adatvédelmi megoldásokat. Keressen frissítést, vagy forduljon az app fejlesztőjéhez."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Frissítés keresése"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Ez az alkalmazás nem kompatibilis az Android legújabb verziójával. Keressen frissítést, vagy forduljon az app fejlesztőjéhez."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Új üzenetei érkeztek"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"SMS-alkalmazás megnyitása a megtekintéshez"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Egyes funkciók korlátozva lehetnek"</string>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index db5acb9349dd..e34bdc7884b5 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -1975,6 +1975,8 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Այս գործառույթը հասանելի չէ <xliff:g id="DEVICE">%1$s</xliff:g> սարքում։ Օգտագործեք ձեր հեռախոսը։"</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Այս հավելվածը մշակված է Android-ի ավելի հին տարբերակի համար։ Այն չի համապատասխանում անվտանգության և գաղտնիության ապահովման վերջին պահանջներին և կարող է պատշաճ կերպով չաշխատել։ Ստուգեք թարմացումների առկայությունը կամ դիմեք հավելվածի մշակողին։"</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Ստուգել նոր տարբերակի առկայությունը"</string>
+ <!-- no translation found for deprecated_abi_message (6820548011196218091) -->
+ <skip />
<string name="new_sms_notification_title" msgid="6528758221319927107">"Դուք ունեք նոր հաղորդագրություններ"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Դիտելու համար բացել SMS-ների փոխանակման հավելվածը"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Որոշ գործառույթներ կարող են չաշխատել"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 4609fdf0301f..c854e12fa4e3 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -475,7 +475,7 @@
<string name="permdesc_writeCalendar" product="default" msgid="5416380074475634233">"Aplikasi ini dapat menambahkan, menghapus, atau mengubah acara kalender di ponsel. Aplikasi ini dapat mengirim pesan yang kelihatannya berasal dari pemilik kalender, atau mengubah acara tanpa memberi tahu pemilik."</string>
<string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"akses perintah penyedia lokasi ekstra"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Memungkinkan aplikasi mengakses perintah penyedia lokasi ekstra. Tindakan ini memungkinkan aplikasi mengganggu pengoperasian GPS atau sumber lokasi lain."</string>
- <string name="permlab_accessFineLocation" msgid="6426318438195622966">"akses lokasi akurat hanya saat di latar depan"</string>
+ <string name="permlab_accessFineLocation" msgid="6426318438195622966">"akses lokasi presisi hanya saat di latar depan"</string>
<string name="permdesc_accessFineLocation" msgid="6732174080240016335">"Aplikasi ini bisa mendapatkan lokasi pasti Anda dari layanan lokasi saat aplikasi sedang digunakan. Layanan lokasi untuk perangkat harus diaktifkan agar aplikasi bisa mendapatkan lokasi. Ini dapat meningkatkan penggunaan baterai."</string>
<string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"akses perkiraan lokasi hanya saat berada di latar depan"</string>
<string name="permdesc_accessCoarseLocation" msgid="778521847873199160">"Aplikasi ini bisa mendapatkan perkiraan lokasi Anda dari layanan lokasi saat aplikasi sedang digunakan. Layanan lokasi untuk perangkat harus diaktifkan agar aplikasi bisa mendapatkan lokasi."</string>
@@ -1695,7 +1695,7 @@
<string name="accessibility_shortcut_off" msgid="3651336255403648739">"Jangan aktifkan"</string>
<string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"AKTIF"</string>
<string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"NONAKTIF"</string>
- <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Izinkan <xliff:g id="SERVICE">%1$s</xliff:g> memiliki kontrol penuh atas perangkat Anda?"</string>
+ <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Izinkan <xliff:g id="SERVICE">%1$s</xliff:g> mengontrol perangkat Anda secara penuh?"</string>
<string name="accessibility_service_warning_description" msgid="291674995220940133">"Kontrol penuh sesuai untuk aplikasi yang mendukung kebutuhan aksesibilitas Anda, tetapi tidak untuk sebagian besar aplikasi."</string>
<string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Melihat dan mengontrol layar"</string>
<string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Voice Access dapat membaca semua konten di layar dan menampilkan konten di atas aplikasi lain."</string>
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Setelan ini tidak dapat diakses di <xliff:g id="DEVICE">%1$s</xliff:g>. Coba di ponsel."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Aplikasi ini dibuat untuk versi lama Android. Aplikasi mungkin tidak berfungsi dengan baik dan tidak menyertakan perlindungan privasi dan keamanan terbaru. Periksa update, atau hubungi developer aplikasi."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Periksa apakah ada update"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Aplikasi ini tidak kompatibel dengan versi terbaru Android. Periksa update atau hubungi developer aplikasi."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Ada pesan baru"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Buka aplikasi SMS untuk melihat"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Beberapa fitur tidak dapat digunakan"</string>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index 30f0bd988f70..d61a1f12a2d3 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -1975,6 +1975,8 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Ekki er hægt að opna þetta í <xliff:g id="DEVICE">%1$s</xliff:g>. Prófaðu það í símanum í staðinn."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Þetta forrit var hannað fyrir eldri útgáfu af Android. Óvíst er að það virki rétt og það inniheldur ekki nýjustu öryggis- og persónuverndarvarnirnar. Leitaðu að uppfærslu eða hafðu samband við þróunaraðila forritsins."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Leita að uppfærslu"</string>
+ <!-- no translation found for deprecated_abi_message (6820548011196218091) -->
+ <skip />
<string name="new_sms_notification_title" msgid="6528758221319927107">"Þú ert með ný skilaboð"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Opnaðu SMS-forritið til að skoða"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Sum virkni kann að vera takmörkuð"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index f5c1c33e563a..71297fa5fb5b 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -682,10 +682,10 @@
<string name="face_acquired_too_dark" msgid="8539853432479385326">"Luce insufficiente"</string>
<string name="face_acquired_too_close" msgid="4453646176196302462">"Allontana il telefono"</string>
<string name="face_acquired_too_far" msgid="2922278214231064859">"Avvicina il telefono"</string>
- <string name="face_acquired_too_high" msgid="8278815780046368576">"Sposta il telefono più in alto"</string>
- <string name="face_acquired_too_low" msgid="4075391872960840081">"Sposta il telefono più in basso"</string>
- <string name="face_acquired_too_right" msgid="6245286514593540859">"Sposta il telefono verso sinistra"</string>
- <string name="face_acquired_too_left" msgid="9201762240918405486">"Sposta il telefono verso destra"</string>
+ <string name="face_acquired_too_high" msgid="8278815780046368576">"Sposta lo smartphone più in alto"</string>
+ <string name="face_acquired_too_low" msgid="4075391872960840081">"Sposta lo smartphone più in basso"</string>
+ <string name="face_acquired_too_right" msgid="6245286514593540859">"Sposta lo smartphone verso sinistra"</string>
+ <string name="face_acquired_too_left" msgid="9201762240918405486">"Sposta lo smartphone verso destra"</string>
<string name="face_acquired_poor_gaze" msgid="4427153558773628020">"Guarda più direttamente verso il dispositivo."</string>
<string name="face_acquired_not_detected" msgid="1057966913397548150">"Volto non visible. Tieni lo smartphone all\'altezza degli occhi."</string>
<string name="face_acquired_too_much_motion" msgid="8199691445085189528">"Troppo movimento. Tieni fermo il telefono."</string>
@@ -1716,7 +1716,7 @@
<string name="color_correction_feature_name" msgid="7975133554160979214">"Correzione del colore"</string>
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Modalità a una mano"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Attenuazione extra"</string>
- <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Apparecchi acustici"</string>
+ <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Protesi uditive"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Tieni premuti i tasti del volume. Servizio <xliff:g id="SERVICE_NAME">%1$s</xliff:g> attivato."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Tieni premuti i tasti del volume. Servizio <xliff:g id="SERVICE_NAME">%1$s</xliff:g> disattivato."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Rilascia i tasti del volume. Per attivare <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, tieni di nuovo premuti entrambi i tasti del volume per 3 secondi."</string>
@@ -1976,6 +1976,8 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Non è possibile accedere su <xliff:g id="DEVICE">%1$s</xliff:g>. Prova a usare il telefono."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Questa app è stata progettata per una versione precedente di Android. Potrebbe non funzionare correttamente e non include le protezioni della sicurezza e della privacy più recenti. Verifica la presenza di un aggiornamento o contatta lo sviluppatore dell\'app."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Cerca aggiornamenti"</string>
+ <!-- no translation found for deprecated_abi_message (6820548011196218091) -->
+ <skip />
<string name="new_sms_notification_title" msgid="6528758221319927107">"Hai nuovi messaggi"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Apri l\'app SMS per la visualizzazione"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Alcune funzionalità sono limitate"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 4b0a87415a7b..50685cb5994f 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -1696,8 +1696,8 @@
<string name="accessibility_shortcut_off" msgid="3651336255403648739">"לא להפעיל"</string>
<string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"מופעל"</string>
<string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"כבוי"</string>
- <string name="accessibility_enable_service_title" msgid="3931558336268541484">"להעניק לשירות <xliff:g id="SERVICE">%1$s</xliff:g> שליטה מלאה במכשיר?"</string>
- <string name="accessibility_service_warning_description" msgid="291674995220940133">"האפשרות לשליטה מלאה במכשיר לא מתאימה לכל האפליקציות, אלא רק לאפליקציות שעוזרות עם צורכי הנגישות שלך."</string>
+ <string name="accessibility_enable_service_title" msgid="3931558336268541484">"להעניק לשירות \'<xliff:g id="SERVICE">%1$s</xliff:g>\' שליטה מלאה במכשיר?"</string>
+ <string name="accessibility_service_warning_description" msgid="291674995220940133">"האפשרות לשליטה מלאה במכשיר לא מתאימה לרוב האפליקציות, אלא רק לאפליקציות שעוזרות עם צורכי הנגישות שלך."</string>
<string name="accessibility_service_screen_control_title" msgid="190017412626919776">"הצגת המסך ושליטה בו"</string>
<string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"אפשרות לקריאת כל התוכן במסך ולהצגת התוכן מעל אפליקציות אחרות."</string>
<string name="accessibility_service_action_perform_title" msgid="779670378951658160">"הצגה וביצוע של פעולות"</string>
@@ -1976,6 +1976,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"אי אפשר לגשת להגדרה הזו במכשיר <xliff:g id="DEVICE">%1$s</xliff:g>. במקום זאת, אפשר לנסות בטלפון."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"‏האפליקציה הזו תוכננה לגרסה ישנה יותר של Android. האפליקציה לא כוללת את אמצעי ההגנה האחרונים לאבטחה ופרטיות, ועלולה לא לעבוד כראוי. כדאי לבדוק אם יש עדכון או ליצור קשר עם מפתח האפליקציה."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"יש עדכון חדש?"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"‏האפליקציה הזו לא תואמת לגרסה העדכנית של Android. כדאי לבדוק אם יש עדכון או ליצור קשר עם מפתחי האפליקציה."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"יש לך הודעות חדשות"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"‏יש לפתוח את אפליקציית ה-SMS כדי להציג"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"ייתכן שחלק מהפונקציונליות תהיה מוגבלת"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 43925cc0b2af..dc4694d03bed 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"<xliff:g id="DEVICE">%1$s</xliff:g> からはアクセスできません。スマートフォンでのアクセスをお試しください。"</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"このアプリは Android の以前のバージョンを対象としているため、正しく動作しない可能性があります。最新のセキュリティ保護やプライバシー保護は組み込まれていません。アップデートをご確認いただくか、アプリのデベロッパーにお問い合わせください。"</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"アップデートを確認"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"このアプリは最新バージョンの Android に対応していません。アップデートをご確認いただくか、アプリのデベロッパーにお問い合わせください。"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"新着メッセージがあります"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"表示するには SMS アプリを開きます"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"一部の機能が制限されることがあります"</string>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index f22942d7bc20..f4d391bfbcba 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"ამჟამად ამ აპზე თქვენი <xliff:g id="DEVICE">%1$s</xliff:g>-დან წვდომა შეუძლებელია. ცადეთ ტელეფონიდან."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"ეს აპი Android-ის ძველი ვერსიისთვის შეიქმნა. ის შესაძლოა არ მიშაობდეს სწორად და არ შეიცავდეს უსაფრთხოებისა და კონფიდენციალურობის უახლეს დაცვას. შეამოწმეთ განახლება, ან დაუკავშირდით აპის დეველოპერს."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"განახლების შემოწმება"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"ეს აპი არ არის თავსებადი Android-ის უახლეს ვერსიასთან. შეამოწმეთ განახლება, ან დაუკავშირდით აპის დეველოპერს."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"თქვენ ახალი შეტყობინებები გაქვთ"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"სანახავად, გახსენით SMS აპი"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"ზოგიერთი ფუნქცია შეიძლება შეიზღუდოს"</string>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index e972e8c8ccd9..00c27d3daf16 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -1975,6 +1975,8 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Бұған <xliff:g id="DEVICE">%1$s</xliff:g> құрылғысынан кіру мүмкін емес. Оның орнына телефонды пайдаланып көріңіз."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Бұл қолданба Android жүйесінің ескі нұсқасына арналған. Ол дұрыс жұмыс істемеуі және онда соңғы қауіпсіздік пен құпиялықты сақтау құралдары болмауы мүмкін. Қолданбаның жаңа нұсқасы бар-жоғын тексеріңіз не оны әзірлеушіге хабарласыңыз."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Жаңарту бар-жоғын тексеру"</string>
+ <!-- no translation found for deprecated_abi_message (6820548011196218091) -->
+ <skip />
<string name="new_sms_notification_title" msgid="6528758221319927107">"Сізде жаңа хабарлар бар"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Көру үшін SMS қолданбасын ашыңыз"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Кейбір функциялар істемеуі мүмкін."</string>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index 9dc2d97be321..b4c746e03738 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"មិនអាច​ចូលប្រើប្រាស់​កម្មវិធី​នេះ​នៅលើ <xliff:g id="DEVICE">%1$s</xliff:g> របស់អ្នកបាន​ទេ។ សូមសាកល្បងប្រើ​នៅលើ​ទូរសព្ទរបស់អ្នក​ជំនួសវិញ។"</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"កម្មវិធីនេះ​ត្រូវបានបង្កើតឡើង​សម្រាប់​កំណែ Android ចាស់​ជាងនេះ។ កម្មវិធីនេះអាចមិនដំណើរការបានត្រឹមត្រូវ និងមិនរួមបញ្ចូលការការពារឯកជនភាព និងសុវត្ថិភាពចុងក្រោយបំផុតទេ។ ពិនិត្យរកមើលកំណែថ្មី ឬទាក់ទងទៅអ្នកអភិវឌ្ឍន៍កម្មវិធី។"</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"រក​មើល​កំណែ​ថ្មី"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"កម្មវិធីនេះ​មិនត្រូវគ្នាជាមួយ​កំណែ Android ចុងក្រោយបំផុត​ទេ។ សូមពិនិត្យរកមើល​កំណែថ្មី ឬទាក់ទងទៅ​អ្នកអភិវឌ្ឍន៍កម្មវិធី។"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"អ្នកមានសារថ្មី"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"បើកកម្មវិធីសារ SMS ដើម្បីមើល"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"មុខងារ​មួយចំនួន​អាច​ត្រូវ​បាន​កម្រិត"</string>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index c6d6affac1f4..55a0a8430122 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -66,7 +66,7 @@
<string name="ThreeWCMmi" msgid="2436550866139999411">"ಮೂರು ಮಾರ್ಗದಲ್ಲಿ ಕರೆ ಮಾಡುವಿಕೆ"</string>
<string name="RuacMmi" msgid="1876047385848991110">"ಅನಪೇಕ್ಷಿತ ಕಿರಿಕಿರಿ ಮಾಡುವ ಕರೆಗಳ ತಿರಸ್ಕಾರ"</string>
<string name="CndMmi" msgid="185136449405618437">"ಕರೆ ಮಾಡುವ ಸಂಖ್ಯೆಯ ಡೆಲಿವರಿ"</string>
- <string name="DndMmi" msgid="8797375819689129800">"ಅಡಚಣೆ ಮಾಡಬೇಡ"</string>
+ <string name="DndMmi" msgid="8797375819689129800">"ಅಡಚಣೆ ಮಾಡಬೇಡಿ"</string>
<string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"ಕರೆಮಾಡುವವರ ID ಅನ್ನು ನಿರ್ಬಂಧಿಸುವಂತೆ ಡಿಫಾಲ್ಟ್ ಮಾಡಲಾಗಿದೆ. ಮುಂದಿನ ಕರೆ: ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ"</string>
<string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"ಕರೆಮಾಡುವವರ ID ಅನ್ನು ನಿರ್ಬಂಧಿಸುವಂತೆ ಡಿಫಾಲ್ಟ್ ಮಾಡಲಾಗಿದೆ. ಮುಂದಿನ ಕರೆ: ನಿರ್ಬಂಧಿಸಿಲ್ಲ"</string>
<string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"ಕರೆಮಾಡುವವರ ID ಅನ್ನು ನಿರ್ಬಂಧಿಸದಿರುವಂತೆ ಡಿಫಾಲ್ಟ್ ಮಾಡಲಾಗಿದೆ. ಮುಂದಿನ ಕರೆ: ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ"</string>
@@ -638,8 +638,8 @@
<string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"ಪ್ರತಿ ಬಾರಿಯೂ ನಿಮ್ಮ ಬೆರಳಿನ ಸ್ಥಾನವನ್ನು ಸ್ವಲ್ಪ ಮಟ್ಟಿಗೆ ಬದಲಾಯಿಸಿ"</string>
<string-array name="fingerprint_acquired_vendor">
</string-array>
- <string name="fingerprint_error_not_match" msgid="4599441812893438961">"ಫಿಂಗರ್‌ ಪ್ರಿಂಟ್ ಅನ್ನು ಗುರುತಿಸಲಾಗಿಲ್ಲ"</string>
- <string name="fingerprint_udfps_error_not_match" msgid="8236930793223158856">"ಫಿಂಗರ್ ಪ್ರಿಂಟ್ ಅನ್ನು ಗುರುತಿಸಲಾಗಿಲ್ಲ"</string>
+ <string name="fingerprint_error_not_match" msgid="4599441812893438961">"ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಅನ್ನು ಗುರುತಿಸಲಾಗಿಲ್ಲ"</string>
+ <string name="fingerprint_udfps_error_not_match" msgid="8236930793223158856">"ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಅನ್ನು ಗುರುತಿಸಲಾಗಿಲ್ಲ"</string>
<string name="fingerprint_authenticated" msgid="2024862866860283100">"ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಅನ್ನು ಪ್ರಮಾಣೀಕರಣ ಮಾಡಲಾಗಿದೆ"</string>
<string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"ಮುಖವನ್ನು ದೃಢೀಕರಿಸಲಾಗಿದೆ"</string>
<string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"ಮುಖವನ್ನು ದೃಢೀಕರಿಸಲಾಗಿದೆ, ದೃಢೀಕರಣವನ್ನು ಒತ್ತಿ"</string>
@@ -1695,10 +1695,10 @@
<string name="accessibility_shortcut_off" msgid="3651336255403648739">"ಆನ್ ಮಾಡಬೇಡಿ"</string>
<string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"ಆನ್ ಆಗಿದೆ"</string>
<string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"ಆಫ್ ಆಗಿದೆ"</string>
- <string name="accessibility_enable_service_title" msgid="3931558336268541484">"ನಿಮ್ಮ ಸಾಧನದ ಸಂಪೂರ್ಣ ನಿಯಂತ್ರಣವನ್ನು ಹೊಂದಲು <xliff:g id="SERVICE">%1$s</xliff:g>ಗೆ ಅನುಮತಿಸಬೇಕೆ?"</string>
+ <string name="accessibility_enable_service_title" msgid="3931558336268541484">"ನಿಮ್ಮ ಸಾಧನದ ಸಂಪೂರ್ಣ ನಿಯಂತ್ರಣವನ್ನು ಹೊಂದಲು <xliff:g id="SERVICE">%1$s</xliff:g> ಗೆ ಅನುಮತಿಸಬೇಕೆ?"</string>
<string name="accessibility_service_warning_description" msgid="291674995220940133">"ಆ್ಯಕ್ಸೆಸಿಬಿಲಿಟಿ ಅವಶ್ಯಕತೆಗಳ ಕುರಿತು ನಿಮಗೆ ಸಹಾಯ ಮಾಡುವ ಆ್ಯಪ್‌ಗಳಿಗೆ ಸಂಪೂರ್ಣ ನಿಯಂತ್ರಣ ನೀಡುವುದು ಸೂಕ್ತವಾಗಿರುತ್ತದೆ, ಆದರೆ ಬಹುತೇಕ ಆ್ಯಪ್‌ಗಳಿಗೆ ಇದು ಸೂಕ್ತವಲ್ಲ."</string>
<string name="accessibility_service_screen_control_title" msgid="190017412626919776">"ಸ್ಕ್ರೀನ್ ವೀಕ್ಷಿಸಿ ಮತ್ತು ನಿಯಂತ್ರಿಸಿ"</string>
- <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"ಇದು ಪರದೆಯ ಮೇಲಿನ ಎಲ್ಲಾ ವಿಷಯವನ್ನು ಓದಬಹುದು ಮತ್ತು ಇತರ ಆ್ಯಪ್‌ಗಳ ಮೇಲೆ ವಿಷಯವನ್ನು ಪ್ರದರ್ಶಿಸಬಹುದು."</string>
+ <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"ಇದು ಪರದೆಯ ಮೇಲಿನ ಎಲ್ಲಾ ಕಂಟೆಂಟ್‌ ಅನ್ನು ಓದಬಹುದು ಮತ್ತು ಇತರ ಆ್ಯಪ್‌ಗಳ ಮೇಲೆ ಕಂಟೆಂಟ್‌ ಅನ್ನು ಪ್ರದರ್ಶಿಸಬಹುದು."</string>
<string name="accessibility_service_action_perform_title" msgid="779670378951658160">"ಕ್ರಿಯೆಗಳನ್ನು ವೀಕ್ಷಿಸಿ ಮತ್ತು ನಿರ್ವಹಿಸಿ"</string>
<string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"ಇದು ಆ್ಯಪ್ ಅಥವಾ ಹಾರ್ಡ್‌ವೇರ್ ಸೆನ್ಸರ್‌ನ ಜೊತೆಗಿನ ನಿಮ್ಮ ಸಂವಹನಗಳನ್ನು ಟ್ರ್ಯಾಕ್ ಮಾಡಬಹುದು, ಮತ್ತು ನಿಮ್ಮ ಪರವಾಗಿ ಆ್ಯಪ್‌ಗಳ ಜೊತೆ ಸಂವಹನ ನಡೆಸಬಹುದು."</string>
<string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"ಅನುಮತಿಸಿ"</string>
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"ನಿಮ್ಮ <xliff:g id="DEVICE">%1$s</xliff:g> ನಲ್ಲಿ ಇದನ್ನು ಆ್ಯಕ್ಸೆಸ್ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ. ಅದರ ಬದಲು ನಿಮ್ಮ ಫೋನ್‌ನಲ್ಲಿ ಪ್ರಯತ್ನಿಸಿ."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"ಈ ಆ್ಯಪ್ ಅನ್ನು Android ನ ಹಳೆಯ ಆವೃತ್ತಿಗಾಗಿ ರಚಿಸಲಾಗಿದೆ. ಇದು ಸರಿಯಾಗಿ ಕಾರ್ಯನಿರ್ವಹಿಸದೇ ಇರಬಹುದು ಮತ್ತು ಇತ್ತೀಚಿನ ಭದ್ರತೆ ಮತ್ತು ಗೌಪ್ಯತಾ ರಕ್ಷಣೆಗಳನ್ನು ಒಳಗೊಂಡಿರುವುದಿಲ್ಲ. ಅಪ್‌ಡೇಟ್‌ಗಾಗಿ ಪರಿಶೀಲಿಸಿ ಅಥವಾ ಆ್ಯಪ್ ಡೆವಲಪರ್ ಅವರನ್ನು ಸಂಪರ್ಕಿಸಿ."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"ಅಪ್‌ಡೇಟ್‌ಗಾಗಿ ಪರಿಶೀಲಿಸಿ"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"ಈ ಆ್ಯಪ್ Android ನ ಇತ್ತೀಚಿನ ಆವೃತ್ತಿಯ ಜೊತೆಗೆ ಹೊಂದಿಕೆಯಾಗುವುದಿಲ್ಲ. ಅಪ್‌ಡೇಟ್‌ಗಾಗಿ ಪರಿಶೀಲಿಸಿ ಅಥವಾ ಆ್ಯಪ್ ಡೆವಲಪರ್ ಅನ್ನು ಸಂಪರ್ಕಿಸಿ."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"ನೀವು ಹೊಸ ಸಂದೇಶಗಳನ್ನು ಹೊಂದಿರುವಿರಿ"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"ವೀಕ್ಷಿಸಲು SMS ಅಪ್ಲಿಕೇಶನ್ ತೆರೆಯಿರಿ"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"ಕೆಲವು ಕಾರ್ಯನಿರ್ವಹಣೆ ಸೀಮಿತವಾಗಿರಬಹುದು"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index a4d4a7338060..ec4c6827769b 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"<xliff:g id="DEVICE">%1$s</xliff:g>에서는 액세스할 수 없습니다. 대신 휴대전화에서 시도해 보세요."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"이 앱은 Android 이전 버전에 맞게 설계되었습니다. 정상 동작하지 않을 수 있으며 최신 보안 및 개인 정보 보호 기능을 포함하지 않습니다. 업데이트를 확인하거나 앱 개발자에게 문의하세요."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"업데이트 확인"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"이 앱은 Android 최신 버전과 호환되지 않습니다. 업데이트를 확인하거나 앱 개발자에게 문의하세요."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"새 메시지 있음"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"SMS 앱을 열고 확인"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"일부 기능이 제한될 수 있음"</string>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index f599c2cea0f7..d74b7ee88420 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -41,7 +41,7 @@
<string name="badPin" msgid="888372071306274355">"Терилген эски PIN код туура эмес."</string>
<string name="badPuk" msgid="4232069163733147376">"Терилген PUK код туура эмес."</string>
<string name="mismatchPin" msgid="2929611853228707473">"Терилген PIN\'дер дал келбейт."</string>
- <string name="invalidPin" msgid="7542498253319440408">"Узундугу 4төн 8ге чейинки сандан турган PIN-кодду териңиз."</string>
+ <string name="invalidPin" msgid="7542498253319440408">"Узундугу 4төн 8ге чейинки сандан турган PIN кодду териңиз."</string>
<string name="invalidPuk" msgid="8831151490931907083">"Узундугу 8 же көбүрөөк сандан турган PUK-кодду териңиз."</string>
<string name="needPuk" msgid="3503414069503752211">"SIM картаңыз PUK менен кулпуланган. Кулпусун ачуу үчүн PUK кодун териңиз."</string>
<string name="needPuk2" msgid="3910763547447344963">"SIM картаны бөгөттөн чыгаруу үчүн PUK2 кодун териңиз."</string>
@@ -957,7 +957,7 @@
<string name="keyguard_password_entry_touch_hint" msgid="4032288032993261520"><font size="17">"Сырсөздү терүү үчүн таптаңыз"</font></string>
<string name="keyguard_password_enter_password_code" msgid="2751130557661643482">"Кулпуну ачуу үчүн сырсөздү териңиз"</string>
<string name="keyguard_password_enter_pin_password_code" msgid="7792964196473964340">"Кулпуну ачуу үчүн PIN кодду териңиз"</string>
- <string name="keyguard_password_wrong_pin_code" msgid="8583732939138432793">"PIN-код туура эмес."</string>
+ <string name="keyguard_password_wrong_pin_code" msgid="8583732939138432793">"PIN код туура эмес."</string>
<string name="keyguard_label_text" msgid="3841953694564168384">"Кулпусун ачуу үчүн Менюну андан соң 0 баскычын басыңыз."</string>
<string name="emergency_call_dialog_number_for_display" msgid="2978165477085612673">"Өзгөчө кырдаалдар кызматы"</string>
<string name="lockscreen_carrier_default" msgid="6192313772955399160">"Интернет жок"</string>
@@ -995,7 +995,7 @@
<string name="lockscreen_sim_unlock_progress_dialog_message" msgid="8381565919325410939">"SIM картанын кулпусу ачылууда…"</string>
<string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6458790975898594240">"Графикалык ачкычты <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес тарттыңыз. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> секундадан кийин дагы аракет кылып көрүңүз."</string>
<string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="3118353451602377380">"Сырсөзүңүздү <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес тердиңиз. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> секундадан кийин дагы аракет кылып көрүңүз."</string>
- <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="2874278239714821984">"PIN-кодуңузду <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес тердиңиз. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> секундадан кийин дагы аракет кылып көрүңүз."</string>
+ <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="2874278239714821984">"PIN кодуңузду <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес тердиңиз. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> секундадан кийин дагы аракет кылып көрүңүз."</string>
<string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="3069635524964070596">"Графикалык ачкычты <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес тарттыңыз. Дагы <xliff:g id="NUMBER_1">%2$d</xliff:g> жолу туура эмес тартсаңыз, планшетиңиздин кулпусун Google\'га кирип ачууга туура келет.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> секундадан кийин дагы аракет кылып көрүңүз."</string>
<string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="6399092175942158529">"Графикалык ачкычыңызды <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес чийдиңиз. Дагы <xliff:g id="NUMBER_1">%2$d</xliff:g> ийгиликсиз аракеттен кийин, Android TV түзмөгүңүздүн кулпусун Google аккаунтуңузга кирип ачышыңыз керек болот.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> секунддан кийин кайталап көрүңүз."</string>
<string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="5691623136957148335">"Графикалык ачкычты <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес тарттыңыз. Дагы <xliff:g id="NUMBER_1">%2$d</xliff:g> жолу туура эмес тартсаңыз, телефонуңуздун кулпусун Google\'га кирип ачууга туура келет.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> секундадан кийин дагы аракет кылып көрүңүз."</string>
@@ -1043,7 +1043,7 @@
<string name="keyguard_accessibility_pattern_unlock" msgid="8669128146589233293">"Үлгү менен ачуу."</string>
<string name="keyguard_accessibility_face_unlock" msgid="4533832120787386728">"Жүзүнөн таанып ачуу."</string>
<string name="keyguard_accessibility_pin_unlock" msgid="4020864007967340068">"Пин код менен ачуу."</string>
- <string name="keyguard_accessibility_sim_pin_unlock" msgid="4895939120871890557">"SIM-картанын кулпусун PIN-код менен ачуу."</string>
+ <string name="keyguard_accessibility_sim_pin_unlock" msgid="4895939120871890557">"SIM-картанын кулпусун PIN код менен ачуу."</string>
<string name="keyguard_accessibility_sim_puk_unlock" msgid="3459003464041899101">"SIM-картанын кулпусун PUK-код менен ачуу."</string>
<string name="keyguard_accessibility_password_unlock" msgid="6130186108581153265">"Сырсөз менен ачуу."</string>
<string name="keyguard_accessibility_pattern_area" msgid="1419570880512350689">"Үлгү аймагы."</string>
@@ -1409,7 +1409,7 @@
<string name="ext_media_checking_notification_message" product="tv" msgid="7986154434946021415">"Медиа сактагычты талдоо"</string>
<string name="ext_media_new_notification_title" msgid="3517407571407687677">"Жаңы <xliff:g id="NAME">%s</xliff:g>"</string>
<string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> иштебей жатат"</string>
- <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Жөндөө үчүн таптаңыз"</string>
+ <string name="ext_media_new_notification_message" msgid="6095403121990786986">"Орнотуу үчүн басыңыз"</string>
<string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"Жөндөө үчүн тандаңыз"</string>
<string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"Түзмөктү форматташыңыз керек болушу мүмкүн. Чыгаруу үчүн таптап коюңуз."</string>
<string name="ext_media_ready_notification_message" msgid="7509496364380197369">"Сүрөттөрдү, видеолорду, ырларды жана башкаларды сактоо үчүн керек"</string>
@@ -1645,17 +1645,17 @@
<string name="kg_forgot_pattern_button_text" msgid="406145459223122537">"Үлгү унутулду"</string>
<string name="kg_wrong_pattern" msgid="1342812634464179931">"Графикалык ачкыч туура эмес"</string>
<string name="kg_wrong_password" msgid="2384677900494439426">"Сырсөз туура эмес"</string>
- <string name="kg_wrong_pin" msgid="3680925703673166482">"PIN-код туура эмес"</string>
+ <string name="kg_wrong_pin" msgid="3680925703673166482">"PIN код туура эмес"</string>
<string name="kg_pattern_instructions" msgid="8366024510502517748">"Бөгөттөн чыгаруу сүрөтүн тартыңыз"</string>
<string name="kg_sim_pin_instructions" msgid="6479401489471690359">"SIM-картанын PIN\'ин киргизиңиз"</string>
<string name="kg_pin_instructions" msgid="7355933174673539021">"PIN\'ди киргизиңиз"</string>
<string name="kg_password_instructions" msgid="7179782578809398050">"Сырсөз киргизиңиз"</string>
<string name="kg_puk_enter_puk_hint" msgid="6696187482616360994">"SIM-карта азыр жарактан чыкты. Улантыш үчүн, PUK-кодду киргизиңиз. Көбүрөөк маалымат үчүн операторуңузга кайрылыңыз."</string>
- <string name="kg_puk_enter_pin_hint" msgid="8190982314659429770">"Сиз каалаган PIN-кодду териңиз"</string>
- <string name="kg_enter_confirm_pin_hint" msgid="6372557107414074580">"Сиз каалаган PIN-кодду ырастаңыз"</string>
+ <string name="kg_puk_enter_pin_hint" msgid="8190982314659429770">"Сиз каалаган PIN кодду териңиз"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="6372557107414074580">"Сиз каалаган PIN кодду ырастаңыз"</string>
<string name="kg_sim_unlock_progress_dialog_message" msgid="5743634657721110967">"SIM картанын кулпусу ачылууда…"</string>
- <string name="kg_password_wrong_pin_code" msgid="9013856346870572451">"PIN-код туура эмес."</string>
- <string name="kg_invalid_sim_pin_hint" msgid="4821601451222564077">"Узундугу 4төн 8ге чейинки сандан турган PIN-кодду териңиз."</string>
+ <string name="kg_password_wrong_pin_code" msgid="9013856346870572451">"PIN код туура эмес."</string>
+ <string name="kg_invalid_sim_pin_hint" msgid="4821601451222564077">"Узундугу 4төн 8ге чейинки сандан турган PIN кодду териңиз."</string>
<string name="kg_invalid_sim_puk_hint" msgid="2539364558870734339">"PUK-код 8 сандан турушу керек."</string>
<string name="kg_invalid_puk" msgid="4809502818518963344">"Туура PUK-кодду кайрадан териңиз. Кайталанган аракеттер SIM картаны биротоло жараксыз кылат."</string>
<string name="kg_invalid_confirm_pin_hint" product="default" msgid="4705368340409816254">"PIN-коддор туура келбеди"</string>
@@ -1667,7 +1667,7 @@
<string name="kg_login_invalid_input" msgid="8292367491901220210">"Колдонуучу атыңыз же сырсөзүңүз туура эмес."</string>
<string name="kg_login_account_recovery_hint" msgid="4892466171043541248">"Колдонуучу атыңызды же сырсөзүңүздү унутуп калдыңызбы?\n"<b>"google.com/accounts/recovery"</b>" дарегине кайрылыңыз."</string>
<string name="kg_login_checking_password" msgid="4676010303243317253">"Эсеп текшерилүүдө…"</string>
- <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="23741434207544038">"Сиз PIN-кодуңузду <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес тердиңиз. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> секундадан кийин кайталаңыз."</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="23741434207544038">"Сиз PIN кодуңузду <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес тердиңиз. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> секундадан кийин кайталаңыз."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="3328686432962224215">"Сиз сырсөзүңүздү <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес тердиңиз. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> секундадан кийин кайталаңыз."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="7357404233979139075">"Сиз бөгөттөн чыгаруу үлгүсүн <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес көрсөттүңүз. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> секундадан кийин кайталаңыз."</string>
<string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="3479940221343361587">"Сиз планшетиңизди <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу ийгиликсиз бөгөттөн чыгаруу аракетин кылдыңыз. Дагы <xliff:g id="NUMBER_1">%2$d</xliff:g> ийгиликсиз аракеттен кийин, планшет баштапкы абалына кайтарылат жана бардык берилиштериңиз өчүрүлөт."</string>
@@ -1975,6 +1975,8 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Буга <xliff:g id="DEVICE">%1$s</xliff:g> түзмөгүңүздөн кире албайсыз. Анын ордуна телефондон кирип көрүңүз."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Бул колдонмо эски Android версиясы үчүн түзүлгөн. Ал туура иштебеши мүмкүн жана анда коопсуздукту жана купуялыкты коргоонун эң акыркы мүмкүнчүлүктөрү камтылган эмес. Жаңыртууну издеп көрүңүз же колдонмону иштеп чыгуучуга кайрылыңыз."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Жаңыртууларды текшерүү"</string>
+ <!-- no translation found for deprecated_abi_message (6820548011196218091) -->
+ <skip />
<string name="new_sms_notification_title" msgid="6528758221319927107">"Сизге жаңы билдирүүлөр келди"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Көрүү үчүн SMS колдонмосун ачыңыз"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Айрым функциялар иштебеши мүмкүн"</string>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index 767720661335..a686349c1d13 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"ບໍ່ສາມາດເຂົ້າເຖິງແອັບນີ້ໄດ້ຢູ່ <xliff:g id="DEVICE">%1$s</xliff:g> ຂອງທ່ານ. ກະລຸນາລອງຢູ່ໂທລະສັບຂອງທ່ານແທນ."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"ແອັບນີ້ສ້າງຂຶ້ນສຳລັບ Android ເວີຊັນເກົ່າ. ມັນອາດເຮັດວຽກບໍ່ຖືກຕ້ອງ ແລະ ຮວມທັງບໍ່ມີຄວາມປອດໄພ ແລະ ການປ້ອງກັນຄວາມເປັນສ່ວນຕົວຫຼ້າສຸດ. ກວດສອບເພື່ອອັບເດດ ຫຼື ຕິດຕໍ່ນັກພັດທະນາແອັບ."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"ກວດເບິ່ງອັບເດດ"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"ແອັບນີ້ບໍ່ສາມາດໃຊ້ໄດ້ກັບ Android ເວີຊັນຫຼ້າສຸດ. ກວດສອບເພື່ອອັບເດດ ຫຼື ຕິດຕໍ່ນັກພັດທະນາແອັບ."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"ທ່ານມີຂໍ້ຄວາມໃໝ່"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"ເປີດແອັບ SMS ເພື່ອເບິ່ງ"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"ຄຸນສົມບັດບາງຢ່າງອາດຖືກຈຳກັດໄວ້"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index eb1ab564c283..4ae49ac1207d 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -1977,6 +1977,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Nepavyksta pasiekti nuotolinio įrenginio iš jūsų „<xliff:g id="DEVICE">%1$s</xliff:g>“. Pabandykite naudoti telefoną."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Ši programa sukurta senesnės versijos „Android“. Ji gali tinkamai neveikti ir joje nėra naujausių saugos ir privatumo apsaugos priemonių. Patikrinkite, ar yra naujinių, arba susisiekite su programos kūrėju."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Tikrinti, ar yra naujinių"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Ši programa nesuderinama su naujausios versijos „Android“. Patikrinkite, ar yra naujinių, arba susisiekite su programos kūrėju."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Turite naujų pranešimų"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Atidaryti SMS programą, norint peržiūrėti"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Kai kurios funkcijos ribojamos"</string>
@@ -2337,7 +2338,7 @@
<string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Klaviatūros išdėstymas nustatytas į <xliff:g id="LAYOUT_1">%s</xliff:g>. Palieskite, kad pakeistumėte."</string>
<string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Klaviatūros išdėstymas nustatytas į <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>. Palieskite, kad pakeistumėte."</string>
<string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Klaviatūros išdėstymas nustatytas į <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Palieskite, kad pakeistumėte."</string>
- <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Klaviatūros išdėstymas nustatytas į <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Palieskite, kad pakeistumėte."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Išdėstymas nustatytas į <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Palieskite, kad pakeistumėte."</string>
<string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Sukonfigūruotos fizinės klaviatūros"</string>
<string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Palieskite, kad peržiūrėtumėte klaviatūras"</string>
</resources>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 249fb1f29464..38530f1d82f1 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -1698,7 +1698,7 @@
<string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"IZSLĒGTA"</string>
<string name="accessibility_enable_service_title" msgid="3931558336268541484">"Vai atļaut pakalpojumam <xliff:g id="SERVICE">%1$s</xliff:g> pilnībā kontrolēt jūsu ierīci?"</string>
<string name="accessibility_service_warning_description" msgid="291674995220940133">"Pilnīga kontrole ir piemērota lietotnēm, kas nepieciešamas lietotājiem ar īpašām vajadzībām, taču ne lielākajai daļai lietotņu."</string>
- <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Skatīt un pārvaldīt ekrānu"</string>
+ <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Ekrāna skatīšana un pārvaldīšana"</string>
<string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Tā var nolasīt visu ekrānā esošo saturu un attēlot saturu citām lietotnēm."</string>
<string name="accessibility_service_action_perform_title" msgid="779670378951658160">"Darbību skatīšana un veikšana"</string>
<string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Tā var izsekot jūsu mijiedarbību ar lietotni vai aparatūras sensoru un mijiedarboties ar lietotnēm jūsu vārdā."</string>
@@ -1976,6 +1976,8 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Ierīcē <xliff:g id="DEVICE">%1$s</xliff:g> nevar piekļūt šai funkcijai. Mēģiniet tai piekļūt tālrunī."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Šī lietotne ir paredzēta vecākai Android versijai. Tā var nedarboties pareizi un neietver jaunākās drošības un konfidencialitātes aizsardzības funkcijas. Pārbaudiet atjauninājumu pieejamību vai sazinieties ar lietotnes izstrādātāju."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Meklēt atjauninājumu"</string>
+ <!-- no translation found for deprecated_abi_message (6820548011196218091) -->
+ <skip />
<string name="new_sms_notification_title" msgid="6528758221319927107">"Jums ir jaunas īsziņas."</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Lai skatītu, atveriet īsziņu lietotni."</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Funkcijas var būt ierobežotas"</string>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index 6c570c230c56..7fa2fc510886 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -91,7 +91,7 @@
<string name="notification_channel_mobile_data_status" msgid="1941911162076442474">"Статус на мобилна мрежа"</string>
<string name="notification_channel_sms" msgid="1243384981025535724">"SMS-пораки"</string>
<string name="notification_channel_voice_mail" msgid="8457433203106654172">"Пораки од говорна пошта"</string>
- <string name="notification_channel_wfc" msgid="9048240466765169038">"Повикување преку Wi-Fi"</string>
+ <string name="notification_channel_wfc" msgid="9048240466765169038">"Повици преку Wi-Fi"</string>
<string name="notification_channel_sim" msgid="5098802350325677490">"Статус на SIM-картичка"</string>
<string name="notification_channel_sim_high_prio" msgid="642361929452850928">"Статус на SIM-известувања со висок приоритет"</string>
<string name="peerTtyModeFull" msgid="337553730440832160">"Рамноправен уред го побара режимот на TTY „FULL“"</string>
@@ -122,7 +122,7 @@
<string name="roamingTextSearching" msgid="5323235489657753486">"Пребарување за услуга"</string>
<string name="wfcRegErrorTitle" msgid="3193072971584858020">"Не може да се постави функцијата „Повици преку Wi-Fi“"</string>
<string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="468830943567116703">"За да воспоставувате повици и да испраќате пораки преку Wi-Fi, прво побарајте од операторот да ја постави услугава. Потоа, вклучете ја повторно „Повикување преку Wi-Fi“ во „Поставки“. (Код за грешка: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
+ <item msgid="468830943567116703">"За да воспоставувате повици и да испраќате пораки преку Wi-Fi, прво побарајте од операторот да ја постави услугава. Потоа, вклучете ја повторно „Повици преку Wi-Fi“ во „Поставки“. (Код за грешка: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
<item msgid="4795145070505729156">"Проблем при регистрирањето на функцијата „Повици преку Wi‑Fi“ со операторот: <xliff:g id="CODE">%1$s</xliff:g>"</item>
@@ -130,15 +130,15 @@
<!-- no translation found for wfcSpnFormat_spn (2982505428519096311) -->
<skip />
<string name="wfcSpnFormat_spn_wifi_calling" msgid="3165949348000906194">"Повици преку Wi-Fi на <xliff:g id="SPN">%s</xliff:g>"</string>
- <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="3836827895369365298">"Повикување преку Wi-Fi на <xliff:g id="SPN">%s</xliff:g>"</string>
+ <string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="3836827895369365298">"Повици преку Wi-Fi на <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_wlan_call" msgid="4895315549916165700">"Повик преку WLAN"</string>
<string name="wfcSpnFormat_spn_wlan_call" msgid="255919245825481510">"Повик преку WLAN на <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_wifi" msgid="7232899594327126970">"Wi-Fi на <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="8383917598312067365">"Повици преку Wi-Fi | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="6865214948822061486">"Глас преку Wi-Fi на <xliff:g id="SPN">%s</xliff:g>"</string>
- <string name="wfcSpnFormat_wifi_calling" msgid="6178935388378661755">"Повикување преку Wi-Fi"</string>
+ <string name="wfcSpnFormat_wifi_calling" msgid="6178935388378661755">"Повици преку Wi-Fi"</string>
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
- <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Повикување преку Wi-Fi"</string>
+ <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Повици преку Wi-Fi"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"Глас преку Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_call" msgid="434016592539090004">"Повик преку WiFi"</string>
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"Исклучено"</string>
@@ -1723,7 +1723,7 @@
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Изберете ја функцијата што ќе ја користите со движењето за пристапност (повлекување нагоре од дното на екранот со два прста):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Изберете ја функцијата што ќе ја користите со движењето за пристапност (повлекување нагоре од дното на екранот со три прста):"</string>
<string name="accessibility_button_instructional_text" msgid="8853928358872550500">"За префрлање помеѓу функциите, допрете и задржете го копчето за пристапност."</string>
- <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"За префрлање помеѓу функциите, повлечете нагоре со два прста и задржете."</string>
+ <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"За да се префрлите на друга функција, повлечете нагоре со два прста и задржете."</string>
<string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"За префрлање помеѓу функциите, повлечете нагоре со три прста и задржете."</string>
<string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Зголемување"</string>
<string name="user_switched" msgid="7249833311585228097">"Тековен корисник <xliff:g id="NAME">%1$s</xliff:g>."</string>
@@ -1975,6 +1975,8 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Ова не може да се отвори на <xliff:g id="DEVICE">%1$s</xliff:g>. Пробајте на вашиот телефон како алтернатива."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Оваа апликација е создадена за постара верзија на Android. Можеби нема да работи правилно и не ги вклучува најновите мерки за заштита на безбедноста и приватноста. Проверете дали има ажурирање или контактирајте со програмерот на апликацијата."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Проверка за ажурирање"</string>
+ <!-- no translation found for deprecated_abi_message (6820548011196218091) -->
+ <skip />
<string name="new_sms_notification_title" msgid="6528758221319927107">"Имате нови пораки"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Отворете ја апликацијата за SMS за приказ"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Некои функции се ограничени"</string>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index 23e3b3a4fbaf..5fa3b52d7000 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"നിങ്ങളുടെ <xliff:g id="DEVICE">%1$s</xliff:g> ഉപകരണത്തിൽ ഇത് ആക്‌സസ് ചെയ്യാനാകില്ല. പകരം നിങ്ങളുടെ ഫോണിൽ ശ്രമിച്ച് നോക്കൂ."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"ഈ ആപ്പ് Android-ന്റെ പഴയ പതിപ്പിനായാണ് സൃഷ്ടിച്ചിരിക്കുന്നത്. ഇത് ശരിയായി പ്രവർത്തിക്കണമെന്നില്ല, ഏറ്റവും പുതിയ സുരക്ഷാ, സ്വകാര്യതാ പരിരക്ഷകൾ ഇതിൽ ഉൾപ്പെടുന്നുമില്ല. അപ്ഡേറ്റിനായി തിരയുക അല്ലെങ്കിൽ ആപ്പിന്റെ ഡെവലപ്പറെ ബന്ധപ്പെടുക."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"അപ്‌ഡേറ്റിനായി പരിശോധിക്കുക"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"ഈ ആപ്പ്, Android-ന്റെ എറ്റവും പുതിയ പതിപ്പിന് അനുയോജ്യമല്ല. അപ്ഡേറ്റിന് തിരയുക അല്ലെങ്കിൽ ആപ്പിന്റെ ഡെവലപ്പറെ ബന്ധപ്പെടുക."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"നിങ്ങൾക്ക് പുതിയ സന്ദേശങ്ങൾ ഉണ്ട്"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"കാണുന്നതിന് SMS ആപ്പ് തുറക്കുക"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"ചില പ്രവർത്തനം പരിമിതപ്പെടാം"</string>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index 00c62404ab2b..204cf39de5f6 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Үүнд таны <xliff:g id="DEVICE">%1$s</xliff:g>-с хандах боломжгүй. Оронд нь утсан дээрээ туршиж үзнэ үү."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Энэ аппыг Android-н хуучин хувилбарт зориулж бүтээсэн. Энэ нь зохих ёсоор ажиллахгүй байж магадгүй бөгөөд хамгийн сүүлийн үеийн аюулгүй байдал болон нууцлалын хамгаалалтыг агуулдаггүй. Шинэчлэлт байгаа эсэхийг шалгах эсвэл аппын хөгжүүлэгчтэй холбогдоно уу."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Шинэчлэлтийг шалгах"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Энэ апп Android-н хамгийн сүүлийн үеийн хувилбартай тохиромжгүй. Шинэчлэлт байгаа эсэхийг шалгах эсвэл аппын хөгжүүлэгчтэй холбогдоно уу."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Танд шинэ мессежүүд байна"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Үзэхийн тулд SMS аппыг нээх"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Зарим функцийг хязгаарласан байж болзошгүй"</string>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index c74a1ca59ce0..899c8a9c260a 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -1715,7 +1715,7 @@
<string name="color_correction_feature_name" msgid="7975133554160979214">"रंग सुधारणा"</string>
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"एकहाती मोड"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"आणखी डिम"</string>
- <string name="hearing_aids_feature_name" msgid="1125892105105852542">"श्रवणयंत्र डिव्हाइस"</string>
+ <string name="hearing_aids_feature_name" msgid="1125892105105852542">"श्रवणयंत्रे"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"धरून ठेवलेल्या व्हॉल्यूम की. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> सुरू केला आहे."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"धरून ठेवलेल्या व्हॉल्यूम की. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> बंद केले आहे."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"व्हॉल्यूम की रिलीझ करा. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> सुरू करण्यासाठी, दोन्ही व्हॉल्यूम की पुन्हा प्रेस करा आणि तीन सेकंदांसाठी धरून ठेवा."</string>
@@ -1975,6 +1975,8 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"हे तुमच्या <xliff:g id="DEVICE">%1$s</xliff:g> वर अ‍ॅक्सेस केले जाऊ शकत नाही. त्याऐवजी तुमच्या फोनवर अ‍ॅक्सेस करून पहा."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"हे ॲप Android च्या जुन्या आवृत्तीसाठी तयार केले होते. ते कदाचित व्यवस्थित काम करणार नाही आणि त्यामध्ये सुरक्षा व गोपनीयतेशी संबंधित नवीनतम संरक्षणे समाविष्ट नाहीत. अपडेटसाठी तपासा किंवा अ‍ॅपच्या डेव्हलपरशी संपर्क साधा."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"अपडेटसाठी तपासा"</string>
+ <!-- no translation found for deprecated_abi_message (6820548011196218091) -->
+ <skip />
<string name="new_sms_notification_title" msgid="6528758221319927107">"आपल्याकडे नवीन मेसेज आहेत"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"पाहण्‍यासाठी SMS अ‍ॅप उघडा"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"काही कार्यक्षमता मर्यादित असू शकतात"</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index e8c5ab9a1058..5cb9c09890fe 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -1696,7 +1696,7 @@
<string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"HIDUP"</string>
<string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"MATI"</string>
<string name="accessibility_enable_service_title" msgid="3931558336268541484">"Benarkan <xliff:g id="SERVICE">%1$s</xliff:g> mempunyai kawalan penuh atas peranti anda?"</string>
- <string name="accessibility_service_warning_description" msgid="291674995220940133">"Kawalan penuh sesuai untuk apl yang membantu anda dengan keperluan kebolehaksesan tetapi bukan untuk kebanyakan apl."</string>
+ <string name="accessibility_service_warning_description" msgid="291674995220940133">"Kawalan penuh sesuai untuk apl yang membantu anda berkaitan dengan keperluan kebolehaksesan tetapi bukan untuk kebanyakan apl."</string>
<string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Melihat dan mengawal skrin"</string>
<string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Ciri ini boleh membaca semua kandungan pada skrin dan memaparkan kandungan di atas apl lain."</string>
<string name="accessibility_service_action_perform_title" msgid="779670378951658160">"Lihat dan laksanakan tindakan"</string>
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Apl ini tidak boleh diakses pada <xliff:g id="DEVICE">%1$s</xliff:g> anda. Cuba pada telefon anda."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Apl ini dibina untuk versi Android yang lebih lama. Apl ini mungkin tidak berfungsi dengan betul dan tidak termasuk perlindungan keselamatan dan privasi yang terkini. Semak kemas kini atau hubungi pembangun apl."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Semak kemaskinian"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Apl ini tidak serasi dengan versi terbaharu Android. Semak kemaskinian atau hubungi pembangun apl."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Anda mempunyai mesej baharu"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Buka apl SMS untuk melihat"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Sesetengah fungsi mungkin terhad"</string>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index e206ad389d0f..d90c5b825537 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -681,8 +681,8 @@
<string name="face_acquired_too_dark" msgid="8539853432479385326">"အလင်းရောင် အားနည်းသည်"</string>
<string name="face_acquired_too_close" msgid="4453646176196302462">"ဖုန်းကို အဝေးသို့ခွာပါ"</string>
<string name="face_acquired_too_far" msgid="2922278214231064859">"ဖုန်းကို အနားသို့ပိုတိုးပါ"</string>
- <string name="face_acquired_too_high" msgid="8278815780046368576">"ဖုန်းကို ပိုမြှင့်လိုက်ပါ"</string>
- <string name="face_acquired_too_low" msgid="4075391872960840081">"ဖုန်းကို ပိုနှိမ့်လိုက်ပါ"</string>
+ <string name="face_acquired_too_high" msgid="8278815780046368576">"ဖုန်းကို မြှင့်လိုက်ပါ"</string>
+ <string name="face_acquired_too_low" msgid="4075391872960840081">"ဖုန်းကို နှိမ့်လိုက်ပါ"</string>
<string name="face_acquired_too_right" msgid="6245286514593540859">"ဖုန်းကို သင့်ဘယ်ဘက်သို့ ရွှေ့ပါ"</string>
<string name="face_acquired_too_left" msgid="9201762240918405486">"ဖုန်းကို သင့်ညာဘက်သို့ ရွှေ့ပါ"</string>
<string name="face_acquired_poor_gaze" msgid="4427153558773628020">"သင့်စက်ပစ္စည်းကို တည့်တည့်ကြည့်ပါ။"</string>
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"၎င်းကို သင်၏ <xliff:g id="DEVICE">%1$s</xliff:g> တွင် သုံး၍မရပါ။ ဖုန်းတွင် စမ်းကြည့်ပါ။"</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"ဤအက်ပ်ကို ဗားရှင်းဟောင်းအတွက် ရေးထားသည်။ ၎င်းကမှန်ကန်စွာ လုပ်ဆောင်နိုင်မည်မဟုတ်ဘဲ နောက်ဆုံးထုတ် လုံခြုံရေးနှင့် ကိုယ်ရေးအချက်အလက်လုံခြုံမှု အကာအကွယ်များ မပါဝင်ပါ။ အပ်ဒိတ်ရှာကြည့်ပါ (သို့) အက်ပ်ရေးသူထံ ဆက်သွယ်ပါ။"</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"အပ်ဒိတ်စစ်ရန်"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"ဤအက်ပ်သည် Android နောက်ဆုံးဗားရှင်းနှင့် တွဲမသုံးနိုင်ပါ။ အပ်ဒိတ်ရှာကြည့်ပါ (သို့) အက်ပ်ရေးသူထံ ဆက်သွယ်ပါ။"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"သင့်ထံတွင် စာအသစ်များရောက်နေသည်"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"ကြည့်ရှုရန် SMS အက်ပ်ကိုဖွင့်ပါ"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"လုပ်ဆောင်ချက် ကန့်သတ်မှုရှိနိုင်သည်"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index a2102bcd6688..3453bb48e070 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -1975,6 +1975,8 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Dette er ikke tilgjengelig på <xliff:g id="DEVICE">%1$s</xliff:g>. Prøv på telefonen din i stedet."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Denne appen er utviklet for en eldre Android-versjon. Det er ikke sikkert at den fungerer som den skal, og den mangler det nyeste innen sikkerhet og personvern. Se etter en oppdatering, eller kontakt utvikleren av appen."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Se etter oppdateringer"</string>
+ <!-- no translation found for deprecated_abi_message (6820548011196218091) -->
+ <skip />
<string name="new_sms_notification_title" msgid="6528758221319927107">"Du har nye meldinger"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Åpne SMS-appen for å se"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Enkelte funksjoner kan begrenses"</string>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 83cde3c7ccaf..47bdcf07ea1e 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -206,7 +206,7 @@
<string name="printing_disabled_by" msgid="3517499806528864633">"<xliff:g id="OWNER_APP">%s</xliff:g> ले छाप्ने कार्यलाई असक्षम पार्यो।"</string>
<string name="personal_apps_suspension_title" msgid="7561416677884286600">"आफ्नो कार्य प्रोफाइल अन गर्नुहोस्"</string>
<string name="personal_apps_suspension_text" msgid="6115455688932935597">"तपाईंले आफ्नो कार्य प्रोफाइल सक्रिय नगरुन्जेल तपाईंका व्यक्तिगत एपहरूलाई रोक लगाइन्छ"</string>
- <string name="personal_apps_suspension_soon_text" msgid="8123898693479590">"मिति <xliff:g id="DATE">%1$s</xliff:g> <xliff:g id="TIME">%2$s</xliff:g> बजे व्यक्तिगत एपहरूलाई रोक लगाइने छ। तपाईंका IT एडमिन तपाईंलाई आफ्नो कार्य प्रोफाइल <xliff:g id="NUMBER">%3$d</xliff:g> भन्दा धेरै दिन निष्क्रिय राख्ने अनुमति दिनुहुन्न।"</string>
+ <string name="personal_apps_suspension_soon_text" msgid="8123898693479590">"मिति <xliff:g id="DATE">%1$s</xliff:g> <xliff:g id="TIME">%2$s</xliff:g> बजे व्यक्तिगत एपहरूलाई रोक लगाइने छ। तपाईंका IT एड्मिन तपाईंलाई आफ्नो कार्य प्रोफाइल <xliff:g id="NUMBER">%3$d</xliff:g> भन्दा धेरै दिन निष्क्रिय राख्ने अनुमति दिनुहुन्न।"</string>
<string name="personal_apps_suspended_turn_profile_on" msgid="2758012869627513689">"अन गर्नुहोस्"</string>
<string name="work_profile_telephony_paused_title" msgid="7690804479291839519">"कल वा म्यासेज अफ गरिएको छ"</string>
<string name="work_profile_telephony_paused_text" msgid="8065762301100978221">"तपाईंले कामसम्बन्धी एपहरू पज गर्नुभएको छ। तपाईं फोन कल वा टेक्स्ट म्यासेजहरू प्राप्त गर्नु हुने छैन।"</string>
@@ -995,7 +995,7 @@
<string name="lockscreen_sim_unlock_progress_dialog_message" msgid="8381565919325410939">"SIM कार्ड अनलक गरिँदै छ…"</string>
<string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6458790975898594240">"तपाईँले तपाईँको अनलक प्याटर्न गलत तरिकाले <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक खिच्नु भएको छ। \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> सेकेन्डमा फेरि कोसिस गर्नुहोस्।"</string>
<string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="3118353451602377380">"तपाईंले गलत तरिकाले आफ्नो पासवर्ड <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक टाइप गर्नुभयो। \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> सेकेन्डमा फेरि प्रयास गर्नुहोस्।"</string>
- <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="2874278239714821984">"तपाईँले गलत तरिकाले तपाईँको PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक टाइप गर्नु भएको छ। \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> सेकेन्डमा फेरि प्रयास गर्नुहोस्।"</string>
+ <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="2874278239714821984">"तपाईंले <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक गलत PIN टाइप गर्नुभएको छ। \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> सेकेन्डमा फेरि प्रयास गर्नुहोस्।"</string>
<string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="3069635524964070596">"तपाईँले तपाईँको अनलक प्याटर्न गलत तरिकाले <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक खिच्नु भएको छ। पछि <xliff:g id="NUMBER_1">%2$d</xliff:g> थप असफल कोसिसहरू, तपाईँको Google साइन इन प्रयोग गरी तपाईँको ट्याब्लेट अनलक गर्न भनिने छ।\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> सेकेन्डमा फरि प्रयास गर्नुहोस्।"</string>
<string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="6399092175942158529">"तपाईंले आफ्नो अनलक शैली <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक गलत तरिकाले कोर्नुभएको छ। थप <xliff:g id="NUMBER_1">%2$d</xliff:g> प्रयासहरू असफल भएपछि तपाईंलाई आफ्नो Google खाता मार्फत साइन इन गरेर आफ्नो Android टिभी डिभाइस अनलक गर्न अनुरोध गरिने छ।\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> सेकेन्डपछि फेरि प्रयास गर्नुहोस्।"</string>
<string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="5691623136957148335">"तपाईँले <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक गलत तरिकाले तपाईँको अनलक ढाँचालाई कोर्नु भएको छ। पछि <xliff:g id="NUMBER_1">%2$d</xliff:g> अरू धेरै असफल कोसिसहरूपछि, तपाईँलाई तपाईँको फोन Google साइन इन प्रयोग गरेर अनलक गर्नको लागि सोधिने छ। \n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> सेकेन्डमा पुनः प्रयास गर्नुहोस्।"</string>
@@ -1633,7 +1633,7 @@
<string name="media_route_chooser_extended_settings" msgid="2506352159381327741">"सेटिंङहरू"</string>
<string name="media_route_controller_disconnect" msgid="7362617572732576959">"डिस्कनेक्ट गर्नुहोस्"</string>
<string name="media_route_status_scanning" msgid="8045156315309594482">"स्क्यान गर्दै ..."</string>
- <string name="media_route_status_connecting" msgid="5845597961412010540">"जडान हुँदै..."</string>
+ <string name="media_route_status_connecting" msgid="5845597961412010540">"कनेक्ट गरिँदै छ..."</string>
<string name="media_route_status_available" msgid="1477537663492007608">"उपलब्ध"</string>
<string name="media_route_status_not_available" msgid="480912417977515261">"उपलब्ध छैन"</string>
<string name="media_route_status_in_use" msgid="6684112905244944724">"प्रयोगमा छ"</string>
@@ -1667,7 +1667,7 @@
<string name="kg_login_invalid_input" msgid="8292367491901220210">"अमान्य प्रयोगकर्तानाम वा पासवर्ड।"</string>
<string name="kg_login_account_recovery_hint" msgid="4892466171043541248">"के तपाईँले उपयोगकर्ता नाम वा पासवर्ड बिर्सनुभयो?\n"<b>"google.com/accounts/recovery"</b>" मा जानुहोस्।"</string>
<string name="kg_login_checking_password" msgid="4676010303243317253">"खाता जाँच हुँदै…"</string>
- <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="23741434207544038">"तपाईँले गलत तरिकाले तपाईँको PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक टाइप गर्नु भएको छ। \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> सेकेन्डमा फेरि प्रयास गर्नुहोस्।"</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="23741434207544038">"तपाईंले <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक गलत PIN टाइप गर्नुभएको छ। \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> सेकेन्डमा फेरि प्रयास गर्नुहोस्।"</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="3328686432962224215">"तपाईँले तपाईँक पासवर्ड <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक गलत टाइप गर्नुभएको छ। \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> सेकेन्डमा फेरि प्रयास गर्नुहोस्।"</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="7357404233979139075">"तपाईँले तपाईँको अनलक प्याटर्न गलत तरिकाले <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक खिच्नु भएको छ। \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> सेकेन्डमा फेरि कोसिस गर्नुहोस्।"</string>
<string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="3479940221343361587">"तपाईँले ट्याब्लेटलाई अनलक गर्न गलत तरिकाले <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक कोसिस गर्नु भएको छ। <xliff:g id="NUMBER_1">%2$d</xliff:g> पछि थप असफल प्रयासहरू, ट्याब्लेट डिफल्ट कार्यशालामा रिसेट गरिने छ र सबै प्रयोग डेटा हराउने छ।"</string>
@@ -1696,7 +1696,7 @@
<string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"सक्रिय"</string>
<string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"निष्क्रिय"</string>
<string name="accessibility_enable_service_title" msgid="3931558336268541484">"<xliff:g id="SERVICE">%1$s</xliff:g> लाई तपाईंको यन्त्र पूर्ण रूपमा नियन्त्रण गर्न दिने हो?"</string>
- <string name="accessibility_service_warning_description" msgid="291674995220940133">"एक्सेसिबिलिटीसम्बन्धी आवश्यकतामा सहयोग गर्ने एपको पूर्ण नियन्त्रण गर्नु उपयुक्त हुन्छ तर अधिकांश एपका हकमा यस्तो नियन्त्रण उपयुक्त हुँदैन।"</string>
+ <string name="accessibility_service_warning_description" msgid="291674995220940133">"एक्सेसिबिलिटीसम्बन्धी आवश्यकतामा सहयोग गर्ने एपको पूर्ण नियन्त्रण गर्न दिनु उपयुक्त हुन्छ तर अधिकांश एपका हकमा यस्तो नियन्त्रण उपयुक्त हुँदैन।"</string>
<string name="accessibility_service_screen_control_title" msgid="190017412626919776">"स्क्रिन हेर्नुहोस् र नियन्त्रण गर्नुहोस्"</string>
<string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"यसले स्क्रिनमा देखिने सबै सामग्री पढ्न सक्छ र अन्य एपहरूमा उक्त सामग्री देखाउन सक्छ।"</string>
<string name="accessibility_service_action_perform_title" msgid="779670378951658160">"कारबाहीहरू हेर्नुहोस् र तिनमा कार्य गर्नुहोस्"</string>
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"तपाईंको <xliff:g id="DEVICE">%1$s</xliff:g> मा यो एप चलाउन मिल्दैन। बरु तपाईंको फोनमा स्ट्रिम गरी हेर्नुहोस्।"</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"यो एप Android को पुरानो संस्करणका लागि निर्माण गरिएको थियो। यो एपले राम्ररी काम नगर्न सक्छ र यसमा सुरक्षा तथा गोपनीयतासम्बन्धी पछिल्ला सुरक्षा सुविधाहरू समावेश नहुन सक्छन्। यस एपको नवीनतम संस्करण उपलब्ध छ कि छैन हेर्नुहोस् वा एपका विकासकर्तासँग सम्पर्क गर्नुहोस्।"</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"अपडेट उपलब्ध छ वा छैन जाँच्नुहोस्"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"यो एप Android को नवीनतम संस्करणसँग कम्प्याटिबल छैन। यस एपको नवीनतम संस्करण उपलब्ध छ कि छैन भन्ने कुरा हेर्नुहोस् वा एपका विकासकर्तालाई सम्पर्क गर्नुहोस्।"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"तपाईंलाई नयाँ सन्देश आएको छ"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"हेर्नका लागि SMS एप खोल्नुहोस्"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"केही सुविधा राम्ररी नचल्न सक्छन्"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 345807b7300d..f2b03086ea94 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Je hebt hier geen toegang toe op je <xliff:g id="DEVICE">%1$s</xliff:g>. Probeer het in plaats daarvan op je telefoon."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Deze app is ontworpen voor een oudere versie van Android. De app werkt misschien niet goed en bevat niet de nieuwste beveiligings- en privacybeschermingsopties. Check op een update of neem contact op met de ontwikkelaar van de app."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Controleren op updates"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Deze app is niet compatibel met de nieuwste versie van Android. Check of er updates zijn of neem contact op met de ontwikkelaar van de app."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Je hebt nieuwe berichten"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Open je sms-app om ze te bekijken"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Functionaliteit kan beperkt zijn"</string>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index cf8aa30a2d8a..5635853927d8 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -1975,6 +1975,8 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"ଏହାକୁ ଆପଣଙ୍କ <xliff:g id="DEVICE">%1$s</xliff:g>ରେ ଆକ୍ସେସ କରାଯାଇପାରିବ ନାହିଁ। ଏହା ପରିବର୍ତ୍ତେ ଆପଣଙ୍କ ଫୋନରେ ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"ଏହି ଆପକୁ Androidର ଏକ ପୁରୁଣା ସଂସ୍କରଣ ପାଇଁ ତିଆରି କରାଯାଇଛି। ଏହା ସଠିକ୍ ଭାବେ କାମ କରିନପାରେ ଏବଂ ଏଥିରେ ନବୀନତମ ସୁରକ୍ଷା ଏବଂ ଗୋପନୀୟତା ସୁରକ୍ଷାଗୁଡ଼ିକ ଅନ୍ତର୍ଭୁକ୍ତ ନାହିଁ। ଏକ ଅପଡେଟ ପାଇଁ ଯାଞ୍ଚ କରନ୍ତୁ କିମ୍ବା ଆପର ଡେଭେଲପରଙ୍କ ସହ କଣ୍ଟାକ୍ଟ କରନ୍ତୁ।"</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"ଅପଡେଟ୍‌ ପାଇଁ ଯାଞ୍ଚ କରନ୍ତୁ"</string>
+ <!-- no translation found for deprecated_abi_message (6820548011196218091) -->
+ <skip />
<string name="new_sms_notification_title" msgid="6528758221319927107">"ଆପଣଙ୍କ ପାଖରେ ନୂଆ ମେସେଜ୍‍ ରହିଛି"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"ଦେଖିବା ପାଇଁ SMS ଆପ୍‍ ଖୋଲନ୍ତୁ"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"ହୁଏତ କିଛି ପ୍ରକାର୍ଯ୍ୟ ସୀମିତ ହୋଇପାରେ"</string>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index 9c083fa2b4f4..d77d4ff38338 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"ਤੁਹਾਡੇ <xliff:g id="DEVICE">%1$s</xliff:g> \'ਤੇ ਇਸ ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ। ਇਸਦੀ ਬਜਾਏ ਆਪਣੇ ਫ਼ੋਨ \'ਤੇ ਵਰਤ ਕੇ ਦੇਖੋ।"</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"ਇਹ ਐਪ Android ਦੇ ਕਿਸੇ ਪੁਰਾਣੇ ਵਰਜਨ ਲਈ ਬਣਾਈ ਗਿਆ ਸੀ। ਸ਼ਾਇਦ ਇਹ ਠੀਕ ਢੰਗ ਨਾਲ ਕੰਮ ਨਾ ਕਰੇ ਅਤੇ ਨਵੀਨਤਮ ਸੁਰੱਖਿਆ ਅਤੇ ਪਰਦੇਦਾਰੀ ਸੰਬੰਧੀ ਸੁਰੱਖਿਆਵਾਂ ਸ਼ਾਮਲ ਨਾ ਹੋਣ। ਅੱਪਡੇਟ ਲਈ ਜਾਂਚ ਕਰੋ ਜਾਂ ਐਪ ਦੇ ਵਿਕਾਸਕਾਰ ਨੂੰ ਸੰਪਰਕ ਕਰੋ।"</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"ਅੱਪਡੇਟ ਲਈ ਜਾਂਚ ਕਰੋ"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"ਇਹ ਐਪ Android ਦੇ ਨਵੀਨਤਮ ਵਰਜਨ ਦੇ ਅਨੁਰੂਪ ਨਹੀਂ ਹੈ। ਅੱਪਡੇਟ ਲਈ ਜਾਂਚ ਕਰੋ ਜਾਂ ਐਪ ਦੇ ਵਿਕਾਸਕਾਰ ਨੂੰ ਸੰਪਰਕ ਕਰੋ।"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"ਤੁਹਾਨੂੰ ਨਵੇਂ ਸੁਨੇਹੇ ਪ੍ਰਾਪਤ ਹੋਏ ਹਨ"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"ਦੇਖਣ ਲਈ SMS ਐਪ ਖੋਲ੍ਹੋ"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"ਕੁਝ ਪ੍ਰਕਾਰਜਾਤਮਕਤਾ ਸੀਮਤ ਹੋ ਸਕਦੀ ਹੈ"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 46202c91d7f0..fd0f0eda12bd 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -688,7 +688,7 @@
<string name="face_acquired_too_right" msgid="6245286514593540859">"Przesuń telefon w lewo"</string>
<string name="face_acquired_too_left" msgid="9201762240918405486">"Przesuń telefon w prawo"</string>
<string name="face_acquired_poor_gaze" msgid="4427153558773628020">"Patrz prosto na urządzenie."</string>
- <string name="face_acquired_not_detected" msgid="1057966913397548150">"Nie widać twarzy. Trzymaj telefon na wysokości oczu."</string>
+ <string name="face_acquired_not_detected" msgid="1057966913397548150">"Nie widać twarzy – trzymaj telefon na wysokości oczu"</string>
<string name="face_acquired_too_much_motion" msgid="8199691445085189528">"Telefon się porusza. Trzymaj go nieruchomo."</string>
<string name="face_acquired_recalibrate" msgid="8724013080976469746">"Zarejestruj swoją twarz ponownie."</string>
<string name="face_acquired_too_different" msgid="2520389515612972889">"Nie rozpoznaję twarzy. Spróbuj ponownie."</string>
@@ -704,7 +704,7 @@
<skip />
<string name="face_acquired_recalibrate_alt" msgid="5702674220280332115">"Nie można utworzyć modelu twarzy. Spróbuj ponownie."</string>
<string name="face_acquired_dark_glasses_detected_alt" msgid="4052123776406041972">"Wykryto ciemne okulary. Twarz musi być widoczna w całości."</string>
- <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"Wykryto zasłonę twarzy. Twarz musi być widoczna w całości."</string>
+ <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"Wykryto zasłonę twarzy – twarz musi być widoczna w całości"</string>
<string-array name="face_acquired_vendor">
</string-array>
<string name="face_error_hw_not_available" msgid="5085202213036026288">"Nie można zweryfikować twarzy. Sprzęt niedostępny."</string>
@@ -967,7 +967,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Naciśnij Menu, aby odblokować lub wykonać połączenie alarmowe."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"Naciśnij Menu, aby odblokować."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"Narysuj wzór, aby odblokować"</string>
- <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Alarmowe"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"Funkcje alarmowe"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"Powrót do połączenia"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"Poprawnie!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"Spróbuj ponownie."</string>
@@ -1669,8 +1669,8 @@
<string name="kg_login_invalid_input" msgid="8292367491901220210">"Nieprawidłowa nazwa użytkownika lub hasło."</string>
<string name="kg_login_account_recovery_hint" msgid="4892466171043541248">"Nie pamiętasz nazwy użytkownika lub hasła?\nWejdź na "<b>"google.com/accounts/recovery"</b>"."</string>
<string name="kg_login_checking_password" msgid="4676010303243317253">"Sprawdzam konto"</string>
- <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="23741434207544038">"Wpisałeś nieprawidłowy kod PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> razy. \n\nSpróbuj ponownie za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
- <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="3328686432962224215">"Po raz <xliff:g id="NUMBER_0">%1$d</xliff:g> wpisałeś nieprawidłowe hasło. \n\nSpróbuj ponownie za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
+ <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="23741434207544038">"Po raz <xliff:g id="NUMBER_0">%1$d</xliff:g> został wpisany nieprawidłowy kod PIN. \n\nSpróbuj ponownie za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
+ <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="3328686432962224215">"Po raz <xliff:g id="NUMBER_0">%1$d</xliff:g> zostało wpisane nieprawidłowe hasło. \n\nSpróbuj ponownie za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="7357404233979139075">"Narysowałeś nieprawidłowy wzór odblokowania <xliff:g id="NUMBER_0">%1$d</xliff:g> razy. \n\nSpróbuj ponownie za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
<string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="3479940221343361587">"Po raz <xliff:g id="NUMBER_0">%1$d</xliff:g> próbowałeś nieprawidłowo odblokować tablet. Po kolejnych <xliff:g id="NUMBER_1">%2$d</xliff:g> nieudanych próbach tablet zostanie zresetowany do ustawień fabrycznych, a wszystkie dane użytkownika zostaną utracone."</string>
<string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="9064457748587850217">"Próbujesz odblokować urządzenie z Androidem TV w nieprawidłowy sposób. To była <xliff:g id="NUMBER_0">%1$d</xliff:g> próba. Po kolejnych <xliff:g id="NUMBER_1">%2$d</xliff:g> nieudanych próbach urządzenie zostanie zresetowane do ustawień fabrycznych, a wszystkie dane użytkownika zostaną utracone."</string>
@@ -1977,6 +1977,8 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Nie można z tego skorzystać na urządzeniu <xliff:g id="DEVICE">%1$s</xliff:g>. Użyj telefonu."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Ta aplikacja jest na starszą wersję Androida. Może nie działać prawidłowo i nie uwzględnia najnowszych zabezpieczeń oraz ustawień ochrony prywatności. Sprawdź, czy możesz ją zaktualizować, lub skontaktuj się z deweloperem."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Sprawdź dostępność aktualizacji"</string>
+ <!-- no translation found for deprecated_abi_message (6820548011196218091) -->
+ <skip />
<string name="new_sms_notification_title" msgid="6528758221319927107">"Masz nowe wiadomości"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Otwórz aplikację do SMS-ów, by wyświetlić wiadomość"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Część funkcji może być niedostępnych"</string>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index ced295833d94..2ce7094055ed 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -1976,6 +1976,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Não é possível acessar essa configuração pelo seu <xliff:g id="DEVICE">%1$s</xliff:g>. Tente pelo smartphone."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Este app foi criado para uma versão mais antiga do Android. Ele pode não funcionar corretamente e não inclui as proteções de privacidade e segurança mais recentes. Verifique se há uma atualização ou entre em contato com o desenvolvedor do app."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Procurar atualizações"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Este app não é compatível com a versão mais recente do Android. Verifique se há uma atualização ou entre em contato com o desenvolvedor do app."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Você tem mensagens novas"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Abra o app de SMS para ver"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Algumas funções são limitadas"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 3511eac680d9..ea30d7c3e322 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -1976,6 +1976,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Não é possível aceder a esta app no seu dispositivo <xliff:g id="DEVICE">%1$s</xliff:g>. Em alternativa, experimente no telemóvel."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Esta app foi criada para uma versão mais antiga do Android. Pode não funcionar corretamente e não inclui as proteções de privacidade e segurança mais recentes. Verifique se existem atualizações ou contacte o programador da app."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Rever atualizações"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Esta app não é compatível com a versão mais recente do Android. Verifique se existem atualizações ou contacte o programador da app."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Tem mensagens novas"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Abra a app de SMS para ver"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Algumas funcionalidades limitadas"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index ced295833d94..2ce7094055ed 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -1976,6 +1976,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Não é possível acessar essa configuração pelo seu <xliff:g id="DEVICE">%1$s</xliff:g>. Tente pelo smartphone."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Este app foi criado para uma versão mais antiga do Android. Ele pode não funcionar corretamente e não inclui as proteções de privacidade e segurança mais recentes. Verifique se há uma atualização ou entre em contato com o desenvolvedor do app."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Procurar atualizações"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Este app não é compatível com a versão mais recente do Android. Verifique se há uma atualização ou entre em contato com o desenvolvedor do app."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Você tem mensagens novas"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Abra o app de SMS para ver"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Algumas funções são limitadas"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index d4bddd3dbef7..e103148cba3b 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -1976,6 +1976,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Nu se poate accesa pe <xliff:g id="DEVICE">%1$s</xliff:g>. Încearcă pe telefon."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Aplicația a fost creată pentru o versiune mai veche de Android. Poate să nu funcționeze corect și nu include cele mai recente măsuri de protecție a securității și a confidențialității. Caută o actualizare sau contactează dezvoltatorul aplicației."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Caută actualizări"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Aplicația nu este compatibilă cu cea mai recentă versiune de Android. Caută o actualizare sau contactează dezvoltatorul aplicației."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Ai mesaje noi"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Deschide aplicația pentru SMS-uri ca să vezi"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Unele funcții ar putea fi limitate"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index fb1d5c6c4418..77475cdba7fb 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -1977,6 +1977,8 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"На устройстве <xliff:g id="DEVICE">%1$s</xliff:g> эта функция недоступна. Используйте телефон."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Это приложение было разработано для более ранней версии Android. Оно не соответствует последним требованиям к обеспечению конфиденциальности и безопасности данных и может работать некорректно. Проверьте наличие обновлений или свяжитесь с разработчиком приложения."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Проверить обновления"</string>
+ <!-- no translation found for deprecated_abi_message (6820548011196218091) -->
+ <skip />
<string name="new_sms_notification_title" msgid="6528758221319927107">"Новые сообщения"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Чтобы просмотреть, откройте приложение для обмена SMS"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Некоторые функции могут не работать"</string>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index f1636dbe0825..cfdfc31b9bdd 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -1975,6 +1975,8 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"මෙයට ඔබේ <xliff:g id="DEVICE">%1$s</xliff:g> මත ප්‍රවේශ විය නොහැක. ඒ වෙනුවට ඔබේ දුරකථනයෙහි උත්සාහ කරන්න."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"මෙම යෙදුම Android හි පැරණි අනුවාදයක් සඳහා තනා ඇත. එය නිසි ලෙස ක්‍රියා නොකරන අතර නවතම ආරක්ෂාව සහ රහස්‍යතා ආරක්‍ෂාව ඇතුළත් නොවේ. යාවත්කාලීනයක් සඳහා පරීක්ෂා කරන්න, නැතහොත් යෙදුමේ සංවර්ධකයා සම්බන්ධ කර ගන්න."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"යාවත්කාලීන සඳහා පරික්ෂා කරන්න"</string>
+ <!-- no translation found for deprecated_abi_message (6820548011196218091) -->
+ <skip />
<string name="new_sms_notification_title" msgid="6528758221319927107">"ඔබට නව පණිවිඩ තිබේ"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"බැලීමට විවෘත SMS යෙදුම විවෘත කරන්න"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"ඇතැම් ක්‍රියාකාරිත්ව සීමිත විය හැක"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index f9c2a9b3dcb4..6c0e637d0e8d 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -1977,6 +1977,8 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"V zariadení <xliff:g id="DEVICE">%1$s</xliff:g> momentálne nemáte prístup k tomuto obsahu. Skúste použiť telefón."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Táto aplikácia bola vytvorená pre staršiu verziu Androidu. Nemusí správne fungovať a obsahovať najnovšie prvky zabezpečenia a ochrany súkromia. Skontrolujte dostupnosť aktualizácie alebo kontaktujte jej vývojára."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Skontrolovať dostupnosť aktualizácie"</string>
+ <!-- no translation found for deprecated_abi_message (6820548011196218091) -->
+ <skip />
<string name="new_sms_notification_title" msgid="6528758221319927107">"Máte nové správy."</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Otvorte aplikáciu pre SMS a zobrazte správu"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Niektoré funkcie môžu byť obmedzené"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index a661ad8b7543..90fa4ae188aa 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -1702,7 +1702,7 @@
<string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Ogledovanje in upravljanje zaslona"</string>
<string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Bere lahko vso vsebino na zaslonu ter prikaže vsebino prek drugih aplikacij."</string>
<string name="accessibility_service_action_perform_title" msgid="779670378951658160">"Ogledovanje in izvajanje dejanj"</string>
- <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Spremlja lahko vaše interakcije z aplikacijo ali senzorjem strojne opreme ter komunicira z aplikacijami v vašem imenu."</string>
+ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Spremlja lahko vaše interakcije z aplikacijo ali tipalom strojne opreme ter komunicira z aplikacijami v vašem imenu."</string>
<string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Dovoli"</string>
<string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Zavrni"</string>
<string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Če želite začeti uporabljati funkcijo, se je dotaknite:"</string>
@@ -1717,7 +1717,7 @@
<string name="color_correction_feature_name" msgid="7975133554160979214">"Popravljanje barv"</string>
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Enoročni način"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Zelo zatemnjen zaslon"</string>
- <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Slušni aparati"</string>
+ <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Slušni pripomočki"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Tipki za glasnost sta pridržani. Storitev <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je vklopljena."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Tipki za glasnost sta pridržani. Storitev <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je izklopljena."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Spustite gumba za glasnost. Če želite vklopiti storitev <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, znova pritisnite in 3 sekunde pridržite oba gumba za glasnost."</string>
@@ -1977,6 +1977,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"V napravi <xliff:g id="DEVICE">%1$s</xliff:g> ni mogoče dostopati do te vsebine. Poskusite s telefonom."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Ta aplikacija je bila razvita za starejšo različico Androida. Morda ne bo delovala pravilno ter ne vključuje najnovejših varnostnih funkcij in funkcij za varovanje zasebnosti. Preverite, ali je na voljo posodobitev, ali pa se obrnite na razvijalca aplikacije."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Preveri, ali je na voljo posodobitev"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Ta aplikacija ni združljiva z najnovejšo različico Androida. Preverite, ali je na voljo posodobitev, ali pa se obrnite na razvijalca aplikacije."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Imate nova sporočila."</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Za ogled odprite aplikacijo za SMS-je"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Nekatere funkcije bodo morda omejene"</string>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index 6cbbd28e97dc..b0762d29b3cb 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -1698,9 +1698,9 @@
<string name="accessibility_enable_service_title" msgid="3931558336268541484">"Do të lejosh që <xliff:g id="SERVICE">%1$s</xliff:g> të ketë kontroll të plotë të pajisjes sate?"</string>
<string name="accessibility_service_warning_description" msgid="291674995220940133">"Kontrolli i plotë është i përshtatshëm për aplikacionet që të ndihmojnë me nevojat e qasshmërisë, por jo për shumicën e aplikacioneve."</string>
<string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Shiko dhe kontrollo ekranin"</string>
- <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Ai mund të lexojë të gjithë përmbajtjen në ekran dhe të shfaqë përmbajtjen mbi aplikacione të tjera."</string>
+ <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Mund të lexojë të gjithë përmbajtjen në ekran dhe të shfaqë përmbajtjen mbi aplikacione të tjera."</string>
<string name="accessibility_service_action_perform_title" msgid="779670378951658160">"Shiko dhe kryej veprimet"</string>
- <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Ai mund të monitorojë ndërveprimet me një aplikacion ose një sensor hardueri dhe të ndërveprojë me aplikacionet në emrin tënd."</string>
+ <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Mund të monitorojë ndërveprimet me një aplikacion ose një sensor hardueri dhe të ndërveprojë me aplikacionet në emrin tënd."</string>
<string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Lejo"</string>
<string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Refuzo"</string>
<string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Trokit te një veçori për të filluar ta përdorësh atë:"</string>
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Qasja është e pamundur në <xliff:g id="DEVICE">%1$s</xliff:g>. Provoje në telefon më mirë."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Ky aplikacion është krijuar për një version më të vjetër të Android. Mund të mos funksionojë siç duhet dhe nuk përfshin mbrojtjet më të fundit të sigurisë dhe privatësisë. Kontrollo për një përditësim ose kontakto zhvilluesin e aplikacionit."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Kontrollo për përditësim"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Ky aplikacion nuk është i përputhshëm me versionin më të fundit të Android. Kontrollo për një përditësim ose kontakto me zhvilluesin e aplikacionit."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Ke mesazhe të reja"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Hap aplikacionin SMS për ta parë"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Disa veçori mund të jenë të kufizuara"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 9753ee04e135..ab47275db2b8 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -86,7 +86,7 @@
<string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Пробајте да промените жељену мрежу. Додирните да бисте променили."</string>
<string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Хитни позиви нису доступни"</string>
<string name="EmergencyCallWarningSummary" msgid="1194185880092805497">"Не можете да упућујете хитне позиве преко Wi‑Fi-ја"</string>
- <string name="notification_channel_network_alert" msgid="4788053066033851841">"Обавештења"</string>
+ <string name="notification_channel_network_alert" msgid="4788053066033851841">"Упозорења"</string>
<string name="notification_channel_call_forward" msgid="8230490317314272406">"Преусмеравање позива"</string>
<string name="notification_channel_emergency_callback" msgid="54074839059123159">"Режим за хитан повратни позив"</string>
<string name="notification_channel_mobile_data_status" msgid="1941911162076442474">"Статус мобилних података"</string>
@@ -284,7 +284,7 @@
<string name="notification_channel_network_available" msgid="6083697929214165169">"Мрежа је доступна"</string>
<string name="notification_channel_vpn" msgid="1628529026203808999">"Статус VPN-а"</string>
<string name="notification_channel_device_admin" msgid="6384932669406095506">"Обавештења од ИТ администратора"</string>
- <string name="notification_channel_alerts" msgid="5070241039583668427">"Обавештења"</string>
+ <string name="notification_channel_alerts" msgid="5070241039583668427">"Упозорења"</string>
<string name="notification_channel_retail_mode" msgid="3732239154256431213">"Режим демонстрације за малопродајне објекте"</string>
<string name="notification_channel_usb" msgid="1528280969406244896">"USB веза"</string>
<string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Активна апликација"</string>
@@ -1976,6 +1976,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Овој апликацији не може да се приступи са уређаја <xliff:g id="DEVICE">%1$s</xliff:g>. Пробајте на телефону."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Ова апликација је направљена за старију верзију Android-а. Можда неће радити исправно и не обухвата најновије безбедносне функције и заштите приватности. Проверите да ли има ажурирања или се обратите програмеру апликације."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Потражи ажурирање"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Ова апликација није компатибилна са најновијом верзијом Android-а. Проверите да ли има ажурирања или се обратите програмеру апликације."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Имате нове поруке"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Отворите апликацију за SMS да бисте прегледали"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Неке функције су можда ограничене"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 6da10ecb1d2e..871107ad65a8 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Det går inte att streama detta till <xliff:g id="DEVICE">%1$s</xliff:g>. Testa med telefonen i stället."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Den här appen byggdes för en äldre version av Android. Den kanske inte fungerar som den ska och har inte de senaste säkerhets- och integritetsskydden. Sök efter en uppdatering eller kontakta appens utvecklare."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Sök efter uppdateringar"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Denna app är inte kompatibel med den senaste versionen av Android. Sök efter en uppdatering eller kontakta appens utvecklare."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Du har nya meddelanden"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Öppna sms-appen och visa meddelandet"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Vissa funktioner är begränsade"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 2fb0d1710bcc..7c23928c97e7 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -702,7 +702,7 @@
<skip />
<string name="face_acquired_recalibrate_alt" msgid="5702674220280332115">"Imeshindwa kuunda muundo wa uso wako. Jaribu tena."</string>
<string name="face_acquired_dark_glasses_detected_alt" msgid="4052123776406041972">"Vioo vyeusi vimetambuliwa. Ni lazima uso wako wote uonekane."</string>
- <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"Kifuniko cha uso kimetambuliwa. Ni lazima uso wako wote uonekane."</string>
+ <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"Uso umefunikwa. Lazima uso wako wote uonekane."</string>
<string-array name="face_acquired_vendor">
</string-array>
<string name="face_error_hw_not_available" msgid="5085202213036026288">"Imeshindwa kuthibitisha uso. Maunzi hayapatikani."</string>
@@ -839,7 +839,7 @@
<string-array name="phoneTypes">
<item msgid="8996339953292723951">"Ya nyumbani"</item>
<item msgid="7740243458912727194">"Simu ya mkononi"</item>
- <item msgid="8526146065496663766">"Ya kazini"</item>
+ <item msgid="8526146065496663766">"Kazini"</item>
<item msgid="8150904584178569699">"Pepesi ya Kazini"</item>
<item msgid="4537253139152229577">"Pepesi ya Nyumbani"</item>
<item msgid="6751245029698664340">"Kurasa anwani"</item>
@@ -882,7 +882,7 @@
<string name="phoneTypeCustom" msgid="5120365721260686814">"Maalum"</string>
<string name="phoneTypeHome" msgid="3880132427643623588">"Ya nyumbani"</string>
<string name="phoneTypeMobile" msgid="1178852541462086735">"Simu ya mkononi"</string>
- <string name="phoneTypeWork" msgid="6604967163358864607">"Ya kazini"</string>
+ <string name="phoneTypeWork" msgid="6604967163358864607">"Kazini"</string>
<string name="phoneTypeFaxWork" msgid="6757519896109439123">"Pepesi ya Kazini"</string>
<string name="phoneTypeFaxHome" msgid="6678559953115904345">"Pepesi ya Nyumbani"</string>
<string name="phoneTypePager" msgid="576402072263522767">"Peja"</string>
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Huwezi kufikia mipangilio hii kwenye <xliff:g id="DEVICE">%1$s</xliff:g> yako. Badala yake jaribu kwenye simu yako."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Programu hii ilisanidiwa kwa ajili ya toleo la zamani la Android. Huenda isifanye kazi ipasavyo na haijumuishi ulinzi wa faragha na usalama wa hivi karibuni. Angalia kama ina sasisho au wasiliana na msanidi wa programu."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Angalia masasisho"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Programu hii haitumiki kwenye toleo jipya zaidi la Android. Angalia iwapo sasisho linapatikana au wasiliana na msanidi programu."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Una ujumbe mpya"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Fungua programu ya SMS ili uweze kuangalia"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Huenda baadhi ya vipengele vinadhibitiwa"</string>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index 146703366385..567c11f161b3 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -1975,6 +1975,8 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"உங்கள் <xliff:g id="DEVICE">%1$s</xliff:g> சாதனத்தில் இதை அணுக முடியாது. அதற்குப் பதிலாக உங்கள் மொபைலில் முயன்று பாருங்கள்."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"இந்த ஆப்ஸ் Androidன் பழைய பதிப்பிற்காக உருவாக்கப்பட்டது. இது சரியாகச் செயல்படாமல் போகலாம். மேலும் சமீபத்திய பாதுகாப்பு மற்றும் தனியுரிமை அம்சங்கள் இதில் இல்லை. புதுப்பிப்பு உள்ளதா எனப் பாருங்கள் அல்லது ஆப்ஸ் டெவெலப்பரைத் தொடர்புகொள்ளுங்கள்."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"புதுப்பிப்பு உள்ளதா எனப் பார்"</string>
+ <!-- no translation found for deprecated_abi_message (6820548011196218091) -->
+ <skip />
<string name="new_sms_notification_title" msgid="6528758221319927107">"புதிய செய்திகள் வந்துள்ளன"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"பார்க்க, SMS பயன்பாட்டைத் திறக்கவும்"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"சில செயலுக்கு கட்டுப்பாடு இருக்கலாம்"</string>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index f0e9201f1dd4..d5fef40f689a 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -965,7 +965,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"అన్‌లాక్ చేయడానికి లేదా అత్యవసర కాల్ చేయడానికి మెనూ నొక్కండి."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="7434061749374801753">"అన్‌లాక్ చేయడానికి మెనూ నొక్కండి."</string>
<string name="lockscreen_pattern_instructions" msgid="3169991838169244941">"అన్‌లాక్ చేయడానికి నమూనాను గీయండి"</string>
- <string name="lockscreen_emergency_call" msgid="7500692654885445299">"అత్యవసరం"</string>
+ <string name="lockscreen_emergency_call" msgid="7500692654885445299">"ఎమర్జెన్సీ"</string>
<string name="lockscreen_return_to_call" msgid="3156883574692006382">"కాల్‌కు తిరిగి వెళ్లు"</string>
<string name="lockscreen_pattern_correct" msgid="8050630103651508582">"సరైనది!"</string>
<string name="lockscreen_pattern_wrong" msgid="2940138714468358458">"మళ్లీ ట్రై చేయండి"</string>
@@ -1698,11 +1698,11 @@
<string name="accessibility_enable_service_title" msgid="3931558336268541484">"<xliff:g id="SERVICE">%1$s</xliff:g>కి మీ పరికరంపై పూర్తి కంట్రోల్‌ను ఇవ్వాలనుకుంటున్నారా?"</string>
<string name="accessibility_service_warning_description" msgid="291674995220940133">"అవసరమైన యాక్సెసిబిలిటీ కోసం యాప్‌లకు పూర్తి కంట్రోల్ ఇవ్వడం తగిన పనే అయినా, అన్ని యాప్‌లకు అలా ఇవ్వడం సరికాదు."</string>
<string name="accessibility_service_screen_control_title" msgid="190017412626919776">"స్క్రీన్‌ను చూసి, కంట్రోల్ చేయగలగడం"</string>
- <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"స్క్రీన్‌పై ఉండే కంటెంట్‌ మొత్తాన్ని చదవగలుగుతుంది మరియు ఇతర యాప్‌లలో కూడా ఈ కంటెంట్‌ను ప్రదర్శిస్తుంది."</string>
+ <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"స్క్రీన్‌పై ఉండే కంటెంట్‌ మొత్తాన్ని చదవగలుగుతుంది. అంతే కాక, ఇతర యాప్‌లపై కంటెంట్‌ను డిస్‌ప్లే చేస్తుంది."</string>
<string name="accessibility_service_action_perform_title" msgid="779670378951658160">"చర్యలను చూసి, అమలు చేయగలగడం"</string>
<string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"మీరు ఒక యాప్‌‌తో చేసే ఇంటరాక్షన్‌లను లేదా హార్డ్‌వేర్ సెన్సార్‌ను ట్రాక్ చేస్తూ మీ త‌ర‌ఫున యాప్‌లతో ఇంటరాక్ట్ చేయగలదు."</string>
<string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"అనుమతించండి"</string>
- <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"నిరాకరించు"</string>
+ <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"వద్దు"</string>
<string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"ఫీచర్‌ని ఉపయోగించడం ప్రారంభించడానికి, దాన్ని ట్యాప్ చేయండి:"</string>
<string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"యాక్సెసిబిలిటీ బటన్‌తో ఉపయోగించడానికి ఫీచర్లను ఎంచుకోండి"</string>
<string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"వాల్యూమ్ కీ షార్ట్‌కట్‌తో ఉపయోగించడానికి ఫీచర్లను ఎంచుకోండి"</string>
@@ -1715,7 +1715,7 @@
<string name="color_correction_feature_name" msgid="7975133554160979214">"కలర్ కరెక్షన్"</string>
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"వన్-హ్యాండెడ్ మోడ్"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"ఎక్స్‌ట్రా డిమ్"</string>
- <string name="hearing_aids_feature_name" msgid="1125892105105852542">"వినికిడి పరికరం"</string>
+ <string name="hearing_aids_feature_name" msgid="1125892105105852542">"వినికిడి పరికరాలు"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"వాల్యూమ్ కీలు నొక్కి ఉంచబడ్డాయి. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ఆన్ చేయబడింది"</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"వాల్యూమ్ కీలు నొక్కి ఉంచబడ్డాయి. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ఆఫ్ చేయబడింది"</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"వాల్యూమ్ కీలను రిలీజ్ చేయండి. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>‌ను ఆన్ చేయడానికి, రెండు వాల్యూమ్ కీలను మళ్లీ 3 సెకన్ల పాటు నొక్కి పట్టుకోండి."</string>
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"మీ <xliff:g id="DEVICE">%1$s</xliff:g>లో దీన్ని యాక్సెస్ చేయడం సాధ్యపడదు. బదులుగా మీ ఫోన్‌లో ట్రై చేయండి."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"ఈ యాప్ పాత Android వెర్షన్ కోసం రూపొందించబడింది. ఇది సరిగ్గా పని చేయకపోవచ్చు, ఇంకా దీనిలో తాజా సెక్యూరిటీ, గోప్యతా రక్షణలు ఉండకపోవచ్చు. అప్‌డేట్ కోసం చెక్ చేయండి, లేదా యాప్ డెవలపర్‌ను సంప్రదించండి."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"అప్‌డేట్ కోసం చెక్ చేయండి"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"ఈ యాప్ Android ఇటీవలి వెర్షన్‌కు అనుకూలంగా లేదు. అప్‌డేట్ కోసం చెక్ చేయండి లేదా యాప్ డెవలపర్‌ను కాంటాక్ట్ చేయండి."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"మీకు కొత్త మెసేజ్‌లు ఉన్నాయి"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"చూడటానికి SMS యాప్‌ను తెరవండి"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"కొంత ఫంక్షనాలిటీ పరిమితం కావచ్చు"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index bfe85bf2b7a5..e5f76431d357 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"เข้าถึงการตั้งค่านี้ใน <xliff:g id="DEVICE">%1$s</xliff:g> ของคุณไม่ได้ โปรดลองเข้าถึงในโทรศัพท์แทน"</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"แอปนี้สร้างมาเพื่อ Android เวอร์ชันเก่า ซึ่งอาจทำงานไม่ถูกต้องและไม่มีการคุ้มครองความปลอดภัยและความเป็นส่วนตัวเวอร์ชันล่าสุด ตรวจหาอัปเดตหรือติดต่อนักพัฒนาแอป"</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"ตรวจสอบอัปเดต"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"แอปนี้ไม่สามารถใช้งานร่วมกับ Android เวอร์ชันล่าสุด ตรวจหาอัปเดตหรือติดต่อนักพัฒนาแอป"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"คุณมีข้อความใหม่"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"เปิดแอป SMS เพื่อดู"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"อาจมีข้อจำกัดในบางฟังก์ชัน"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 0a1b9a09eda7..1371de6143e9 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Hindi ito maa-access sa iyong <xliff:g id="DEVICE">%1$s</xliff:g>. Subukan na lang sa iyong telepono."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Ginawa ang app na ito para sa mas lumang bersyon ng Android. Baka hindi ito gumana nang maayos at wala itong pinakabagong proteksyon sa seguridad at privacy. Tingnan kung may update, o makipag-ugnayan sa developer ng app."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Tingnan kung may update"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Hindi compatible ang app sa pinakabagong bersyon ng Android. Tingnan kung may update o makipag-ugnayan sa developer ng app."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Mayroon kang mga bagong mensahe"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Buksan ang SMS app upang tingnan"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Puwedeng limitado ang ilang function"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index f5228565807d..af808e8c1bcd 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -1975,6 +1975,8 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Bu uygulamaya <xliff:g id="DEVICE">%1$s</xliff:g> cihazınızdan erişilemiyor. Bunun yerine telefonunuzu kullanmayı deneyin."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Bu uygulama Android\'in daha eski bir sürümü için geliştirildi. Bu nedenle, düzgün çalışmayabilir ve son güvenlik ile gizlilik korumalarını içermemektedir. Güncelleme olup olmadığını kontrol edin veya uygulamanın geliştiricisiyle iletişime geçin."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Güncellemeleri denetle"</string>
+ <!-- no translation found for deprecated_abi_message (6820548011196218091) -->
+ <skip />
<string name="new_sms_notification_title" msgid="6528758221319927107">"Yeni mesajlarınız var"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Görüntülemek için SMS uygulamasını açın"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Bazı işlevler sınırlanabilir"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index b5d4bb7cc111..98efe9d4b0f8 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -1977,6 +1977,8 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Немає доступу на вашому пристрої (<xliff:g id="DEVICE">%1$s</xliff:g>). Спробуйте натомість скористатися телефоном."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Цей додаток створено для старішої версії ОС Android. Він може не працювати належним чином і не містить найновіших засобів захисту конфіденційності та безпеки. Перевірте наявність оновлень або зв’яжіться з розробником додатка."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Шукати оновлення"</string>
+ <!-- no translation found for deprecated_abi_message (6820548011196218091) -->
+ <skip />
<string name="new_sms_notification_title" msgid="6528758221319927107">"У вас є нові повідомлення"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Щоб переглянути, відкрийте додаток для SMS"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Деякі функції може бути обмежено"</string>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index ea41d9dd10eb..1f60c9ceff6e 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -1975,6 +1975,8 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"آپ کے <xliff:g id="DEVICE">%1$s</xliff:g> پر اس تک رسائی حاصل نہیں ہو سکتی۔ اس کے بجائے اپنے فون پر کوشش کریں۔"</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"‏یہ ایپ Android کے پرانے ورژن کے لیے بنائی گئی تھی۔ ہو سکتا ہے یہ ٹھیک سے کام نہ کرے اور اس میں تازہ ترین سیکیورٹی اور رازداری کے تحفظات شامل نہ ہوں۔ اپ ڈیٹ کے لیے چیک کریں یا ایپ کے ڈویلپر سے رابطہ کریں۔"</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"اپ ڈیٹ چیک کریں"</string>
+ <!-- no translation found for deprecated_abi_message (6820548011196218091) -->
+ <skip />
<string name="new_sms_notification_title" msgid="6528758221319927107">"آپ کے پاس نئے پیغامات ہیں"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"‏دیکھنے کیلئے SMS ایپ کھولیں"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"کچھ فعالیت محدود ہو سکتی ہے"</string>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index 154402e0e4ac..0e749faeb8aa 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Bu <xliff:g id="DEVICE">%1$s</xliff:g> qurilmangizda ochilmaydi. Telefon orqali urininb koʻring."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Bu ilova Androidning eskiroq versiyasiga moʻljallab ishlab chiqilgan. Xatosiz ishlashi mumkin, lekin xavfsizlik va maxfiylik himoyasiga oid oxirgi yangilanishlarini olmaydi. Yangilanish borligini tekshiring yoki ilova ishlab chiquvchisiga murojaat qiling."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Yangilanish borligini tekshirish"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Bu ilova Androidning oxirgi versiyasiga mos emas. Yangilanish borligini tekshiring yoki ilova ishlab chiquvchisiga murojaat qiling."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Sizga yangi SMS keldi"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Ko‘rish uchun SMS ilovasini oching"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Ayrim funksiyalar ishlamasligi mumkin"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 628f02abfeca..ac4358ba717e 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Hiện tại, bạn không thể truy cập vào ứng dụng này trên <xliff:g id="DEVICE">%1$s</xliff:g>. Hãy thử trên điện thoại."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Ứng dụng này được xây dựng cho một phiên bản Android cũ. Ứng dụng này có thể không hoạt động đúng cách và không có các biện pháp bảo vệ mới nhất về bảo mật và quyền riêng tư. Hãy kiểm tra để tìm bản cập nhật hoặc liên hệ với nhà phát triển của ứng dụng."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Kiểm tra để tìm bản cập nhật"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Ứng dụng này không tương thích với phiên bản Android mới nhất. Hãy kiểm tra để tìm bản cập nhật hoặc liên hệ với nhà phát triển của ứng dụng."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Bạn có tin nhắn mới"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Mở ứng dụng SMS để xem"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Một số chức năng có thể bị hạn chế"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 3272694f693f..e938fbfa1a66 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -702,7 +702,7 @@
<skip />
<string name="face_acquired_recalibrate_alt" msgid="5702674220280332115">"无法创建您的脸部模型,请重试。"</string>
<string name="face_acquired_dark_glasses_detected_alt" msgid="4052123776406041972">"检测到墨镜,您的脸部必须完全可见。"</string>
- <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"检测到脸部有遮挡物,您的脸部必须完全可见。"</string>
+ <string name="face_acquired_mouth_covering_detected_alt" msgid="1122294982850589766">"检测到脸部存在遮挡,请露出整张脸。"</string>
<string-array name="face_acquired_vendor">
</string-array>
<string name="face_error_hw_not_available" msgid="5085202213036026288">"无法验证人脸。硬件无法使用。"</string>
@@ -1715,7 +1715,7 @@
<string name="color_correction_feature_name" msgid="7975133554160979214">"色彩校正"</string>
<string name="one_handed_mode_feature_name" msgid="2334330034828094891">"单手模式"</string>
<string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"极暗"</string>
- <string name="hearing_aids_feature_name" msgid="1125892105105852542">"助听设备"</string>
+ <string name="hearing_aids_feature_name" msgid="1125892105105852542">"助听装置"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"已按住音量键。<xliff:g id="SERVICE_NAME">%1$s</xliff:g>已开启。"</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"已按住音量键。<xliff:g id="SERVICE_NAME">%1$s</xliff:g>已关闭。"</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"松开音量键。如要启用 <xliff:g id="SERVICE_NAME">%1$s</xliff:g>,请再次同时按住两个音量键 3 秒。"</string>
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"无法在您的<xliff:g id="DEVICE">%1$s</xliff:g>上访问此设置,您可以尝试在手机上访问。"</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"此应用专为旧版 Android 系统打造。它可能无法正常运行,也不包含最新的安全和隐私保护功能。请检查是否有更新,或与应用开发者联系。"</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"检查更新"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"此应用与最新版 Android 不兼容。请检查是否有更新,或与应用开发者联系。"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"您有新消息"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"打开短信应用查看"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"部分功能可能会受到限制"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 997f963ce802..69bf3f358140 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -1695,7 +1695,7 @@
<string name="accessibility_shortcut_off" msgid="3651336255403648739">"不要開啟"</string>
<string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"開啟"</string>
<string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"關閉"</string>
- <string name="accessibility_enable_service_title" msgid="3931558336268541484">"要授予「<xliff:g id="SERVICE">%1$s</xliff:g>」裝置的完整控制權?"</string>
+ <string name="accessibility_enable_service_title" msgid="3931558336268541484">"要授予「<xliff:g id="SERVICE">%1$s</xliff:g>」裝置的完整控制權嗎?"</string>
<string name="accessibility_service_warning_description" msgid="291674995220940133">"對於為你提供無障礙功能的應用程式,你可授予完整控制權,但大部分應用程式都不應獲授予此權限。"</string>
<string name="accessibility_service_screen_control_title" msgid="190017412626919776">"查看和控制螢幕"</string>
<string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"這項功能可以讀出螢幕上的所有內容,並透過其他應用程式顯示內容。"</string>
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"無法在 <xliff:g id="DEVICE">%1$s</xliff:g> 上存取此應用程式,請改用手機。"</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"此應用程式專為舊版 Android 而設。因此可能無法正常運作,且不提供最新的安全性和私隱保護。請檢查是否有更新版本,或聯絡應用程式開發人員。"</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"檢查更新"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"這個應用程式與最新版的 Android 不相容。請檢查是否有可用的更新,或與應用程式發人員聯絡。"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"你有新的訊息"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"開啟短訊應用程式查看內容"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"部分功能可能會受到限制"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index ea04067f4e86..5b647fac3ca2 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"無法在 <xliff:g id="DEVICE">%1$s</xliff:g> 上存取這個應用程式,請改用手機。"</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"這個應用程式是專為舊版 Android 所打造,因此可能無法正常運作,且不提供最新的安全性和隱私保護服務。請檢查是否有更新版本,或與應用程式的開發人員聯絡。"</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"檢查更新"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"這個應用程式與最新版的 Android 不相容。請檢查是否有可用的更新,或與應用程式發人員聯絡。"</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"你有新訊息"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"開啟簡訊應用程式來查看內容"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"部分功能可能遭到鎖定"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index b2ef74a5b5d6..e432c69d36de 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -1975,6 +1975,7 @@
<string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Lokhu akukwazi ukufinyelelwa ku-<xliff:g id="DEVICE">%1$s</xliff:g> yakho. Zama efonini yakho kunalokho."</string>
<string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Le app yakhelwe uhlobo lwakudala le-Android. Ingase ingasebenzi kahle futhi ayinakho ukuvikeleka kwakamuva nokuvikelwa kobumfihlo. Hlola isibuyekezo, noma uthinte unjiniyela we-app."</string>
<string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Hlola izibuyekezo"</string>
+ <string name="deprecated_abi_message" msgid="6820548011196218091">"Le app ayihambisani nohlobo lwakamuva lwe-Android. Hlola isibuyekezo, noma uthinte unjiniyela we-app."</string>
<string name="new_sms_notification_title" msgid="6528758221319927107">"Unemilayezo emisha"</string>
<string name="new_sms_notification_content" msgid="3197949934153460639">"Vula uhlelo lokusebenza lwe-SMS ukuze ubuke"</string>
<string name="profile_encrypted_title" msgid="9001208667521266472">"Okunye ukusebenza kungakhawulelwe"</string>
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java
index c25352b6e57d..513638eeb960 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java
@@ -185,6 +185,9 @@ public class KeyguardTransitionHandler implements Transitions.TransitionHandler
@Override
public void onTransitionFinished(
WindowContainerTransaction wct, SurfaceControl.Transaction sct) {
+ if (sct != null) {
+ finishTransaction.merge(sct);
+ }
mMainExecutor.execute(() -> {
mStartedTransitions.remove(transition);
finishCallback.onTransitionFinished(wct, null);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
index dc0a2943d394..f9d615ad0cf6 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
@@ -1079,10 +1079,28 @@ public class PipTransition extends PipTransitionController {
}
final float alphaStart = show ? 0 : 1;
final float alphaEnd = show ? 1 : 0;
+ final PipAnimationController.PipTransactionHandler transactionHandler =
+ new PipAnimationController.PipTransactionHandler() {
+ @Override
+ public boolean handlePipTransaction(SurfaceControl leash,
+ SurfaceControl.Transaction tx, Rect destinationBounds, float alpha) {
+ if (alpha == 0) {
+ if (show) {
+ tx.setPosition(leash, destinationBounds.left, destinationBounds.top);
+ } else {
+ // Put PiP out of the display so it won't block touch when it is hidden.
+ final Rect displayBounds = mPipDisplayLayoutState.getDisplayBounds();
+ final int max = Math.max(displayBounds.width(), displayBounds.height());
+ tx.setPosition(leash, max, max);
+ }
+ }
+ return false;
+ }
+ };
mPipAnimationController
.getAnimator(taskInfo, leash, mPipBoundsState.getBounds(), alphaStart, alphaEnd)
.setTransitionDirection(TRANSITION_DIRECTION_SAME)
- .setPipAnimationCallback(mPipAnimationCallback)
+ .setPipTransactionHandler(transactionHandler)
.setDuration(mEnterExitAnimationDuration)
.start();
mHasFadeOut = !show;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
index c2869592dbb6..e5e06df003c9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
@@ -35,6 +35,7 @@ import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.ArrayMap;
+import android.util.Pair;
import android.util.Slog;
import android.view.Display;
import android.view.IRecentsAnimationController;
@@ -135,8 +136,12 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
@Override
public WindowContainerTransaction handleRequest(IBinder transition,
TransitionRequestInfo request) {
- // do not directly handle requests. Only entry point should be via startRecentsTransition
- // TODO: Only log an error if the transition is a recents transition
+ if (mControllers.isEmpty()) {
+ // Ignore if there is no running recents transition
+ return null;
+ }
+ final RecentsController controller = mControllers.get(mControllers.size() - 1);
+ controller.handleMidTransitionRequest(request);
return null;
}
@@ -239,6 +244,11 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
/** The latest state that the recents animation is operating in. */
private int mState = STATE_NORMAL;
+ // Snapshots taken when a new display change transition is requested, prior to the display
+ // change being applied. This pending set of snapshots will only be applied when cancel is
+ // next called.
+ private Pair<int[], TaskSnapshot[]> mPendingPauseSnapshotsForCancel;
+
RecentsController(IRecentsAnimationRunner listener) {
mInstanceId = System.identityHashCode(this);
mListener = listener;
@@ -290,6 +300,16 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
* "replace-with-screenshot" like behavior.
*/
private boolean sendCancelWithSnapshots() {
+ Pair<int[], TaskSnapshot[]> snapshots = mPendingPauseSnapshotsForCancel != null
+ ? mPendingPauseSnapshotsForCancel
+ : getSnapshotsForPausingTasks();
+ return sendCancel(snapshots.first, snapshots.second);
+ }
+
+ /**
+ * Snapshots the pausing tasks and returns the mapping of the taskId -> snapshot.
+ */
+ private Pair<int[], TaskSnapshot[]> getSnapshotsForPausingTasks() {
int[] taskIds = null;
TaskSnapshot[] snapshots = null;
if (mPausingTasks.size() > 0) {
@@ -298,6 +318,9 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
try {
for (int i = 0; i < mPausingTasks.size(); ++i) {
TaskState state = mPausingTasks.get(0);
+ ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
+ "[%d] RecentsController.sendCancel: Snapshotting task=%d",
+ mInstanceId, state.mTaskInfo.taskId);
snapshots[i] = ActivityTaskManager.getService().takeTaskSnapshot(
state.mTaskInfo.taskId, true /* updateCache */);
}
@@ -306,7 +329,7 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
snapshots = null;
}
}
- return sendCancel(taskIds, snapshots);
+ return new Pair(taskIds, snapshots);
}
/**
@@ -315,7 +338,7 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
private boolean sendCancel(@Nullable int[] taskIds,
@Nullable TaskSnapshot[] taskSnapshots) {
try {
- final String cancelDetails = taskSnapshots != null ? " with snapshots" : "";
+ final String cancelDetails = taskSnapshots != null ? "with snapshots" : "";
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
"[%d] RecentsController.cancel: calling onAnimationCanceled %s",
mInstanceId, cancelDetails);
@@ -348,6 +371,7 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
mOpeningTasks = null;
mInfo = null;
mTransition = null;
+ mPendingPauseSnapshotsForCancel = null;
mControllers.remove(this);
}
@@ -460,6 +484,22 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
return true;
}
+ /**
+ * Updates this controller when a new transition is requested mid-recents transition.
+ */
+ void handleMidTransitionRequest(TransitionRequestInfo request) {
+ if (request.getType() == TRANSIT_CHANGE && request.getDisplayChange() != null) {
+ final TransitionRequestInfo.DisplayChange dispChange = request.getDisplayChange();
+ if (dispChange.getStartRotation() != dispChange.getEndRotation()) {
+ ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
+ "[%d] RecentsController.prepareForMerge: "
+ + "Snapshot due to requested display change",
+ mInstanceId);
+ mPendingPauseSnapshotsForCancel = getSnapshotsForPausingTasks();
+ }
+ }
+ }
+
@SuppressLint("NewApi")
void merge(TransitionInfo info, SurfaceControl.Transaction t,
Transitions.TransitionFinishCallback finishCallback) {
@@ -526,6 +566,8 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
// Finish recents animation if the display is changed, so the default
// transition handler can play the animation such as rotation effect.
if (change.hasFlags(TransitionInfo.FLAG_IS_DISPLAY)) {
+ // This call to cancel will use the screenshots taken preemptively in
+ // handleMidTransitionRequest() prior to the display changing
cancel(mWillFinishToHome, true /* withScreenshots */, "display change");
return;
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/UnlockKeyguardToSplitScreen.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/UnlockKeyguardToSplitScreen.kt
index e0dbfa3853cc..676c150815ad 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/UnlockKeyguardToSplitScreen.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/UnlockKeyguardToSplitScreen.kt
@@ -18,7 +18,6 @@ package com.android.wm.shell.flicker.splitscreen
import android.platform.test.annotations.Postsubmit
import android.tools.common.NavBar
-import android.tools.common.Rotation
import android.tools.common.flicker.subject.region.RegionSubject
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
@@ -105,8 +104,6 @@ class UnlockKeyguardToSplitScreen(override val flicker: FlickerTest) :
@JvmStatic
fun getParams(): List<FlickerTest> {
return FlickerTestFactory.nonRotationTests(
- // TODO(b/283963801) address entireScreenCovered test faliure in landscape.
- supportedRotations = listOf(Rotation.ROTATION_0),
supportedNavigationModes = listOf(NavBar.MODE_GESTURAL)
)
}
diff --git a/packages/SettingsLib/res/drawable/ic_docked_tablet.xml b/packages/SettingsLib/res/drawable/ic_docked_tablet.xml
new file mode 100644
index 000000000000..96a4900f361f
--- /dev/null
+++ b/packages/SettingsLib/res/drawable/ic_docked_tablet.xml
@@ -0,0 +1,26 @@
+<!--
+ ~ 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.
+ -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="960"
+ android:viewportHeight="960"
+ android:tint="?attr/colorControlNormal">
+ <path
+ android:fillColor="#000000"
+ android:pathData="M480,280Q497,280 508.5,268.5Q520,257 520,240Q520,223 508.5,211.5Q497,200 480,200Q463,200 451.5,211.5Q440,223 440,240Q440,257 451.5,268.5Q463,280 480,280ZM120,720Q87,720 63.5,696.5Q40,673 40,640L60,160Q60,127 83.5,103.5Q107,80 140,80L820,80Q853,80 876.5,103.5Q900,127 900,160L920,640Q920,673 896.5,696.5Q873,720 840,720L120,720ZM120,640L840,640Q840,640 840,640Q840,640 840,640L820,160Q820,160 820,160Q820,160 820,160L140,160Q140,160 140,160Q140,160 140,160L120,640Q120,640 120,640Q120,640 120,640ZM320,880Q259,880 209.5,850Q160,820 160,765L160,720L240,720L240,760Q253,780 274.5,790Q296,800 320,800L640,800Q664,800 685.5,790.5Q707,781 720,761L720,720L800,720L800,765Q800,820 750.5,850Q701,880 640,880L320,880ZM480,400Q480,400 480,400Q480,400 480,400L480,400Q480,400 480,400Q480,400 480,400L480,400Q480,400 480,400Q480,400 480,400L480,400Q480,400 480,400Q480,400 480,400L480,400Z"/>
+</vector> \ No newline at end of file
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothBroadcastUtils.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothBroadcastUtils.java
index 2bca7cf9762e..1ff2befd19ed 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothBroadcastUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothBroadcastUtils.java
@@ -43,5 +43,5 @@ public final class BluetoothBroadcastUtils {
/**
* Bluetooth scheme.
*/
- public static final String SCHEME_BT_BROADCAST_METADATA = "BT:BluetoothLeBroadcastMetadata:";
+ public static final String SCHEME_BT_BROADCAST_METADATA = "BT:";
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothLeBroadcastMetadataExt.kt b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothLeBroadcastMetadataExt.kt
index b54b115213d5..9bb11f8da645 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothLeBroadcastMetadataExt.kt
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothLeBroadcastMetadataExt.kt
@@ -15,23 +15,92 @@
*/
package com.android.settingslib.bluetooth
+import android.annotation.TargetApi
+import android.bluetooth.BluetoothAdapter
+import android.bluetooth.BluetoothDevice
+import android.bluetooth.BluetoothLeAudioCodecConfigMetadata
+import android.bluetooth.BluetoothLeAudioContentMetadata
+import android.bluetooth.BluetoothLeBroadcastChannel
import android.bluetooth.BluetoothLeBroadcastMetadata
-import android.os.Parcel
-import android.os.Parcelable
+import android.bluetooth.BluetoothLeBroadcastSubgroup
+import android.os.Build
import android.util.Base64
import android.util.Log
import com.android.settingslib.bluetooth.BluetoothBroadcastUtils.SCHEME_BT_BROADCAST_METADATA
object BluetoothLeBroadcastMetadataExt {
- private const val TAG = "BluetoothLeBroadcastMetadataExt"
+ private const val TAG = "BtLeBroadcastMetadataExt"
+
+ // BluetoothLeBroadcastMetadata
+ private const val KEY_BT_QR_VER = "R"
+ private const val KEY_BT_ADDRESS_TYPE = "T"
+ private const val KEY_BT_DEVICE = "D"
+ private const val KEY_BT_ADVERTISING_SID = "AS"
+ private const val KEY_BT_BROADCAST_ID = "B"
+ private const val KEY_BT_BROADCAST_NAME = "BN"
+ private const val KEY_BT_PUBLIC_BROADCAST_DATA = "PM"
+ private const val KEY_BT_SYNC_INTERVAL = "SI"
+ private const val KEY_BT_BROADCAST_CODE = "C"
+ private const val KEY_BT_SUBGROUPS = "SG"
+ private const val KEY_BT_VENDOR_SPECIFIC = "V"
+ private const val KEY_BT_ANDROID_VERSION = "VN"
+
+ // Subgroup data
+ private const val KEY_BTSG_BIS_SYNC = "BS"
+ private const val KEY_BTSG_BIS_MASK = "BM"
+ private const val KEY_BTSG_AUDIO_CONTENT = "AC"
+
+ // Vendor specific data
+ private const val KEY_BTVSD_COMPANY_ID = "VI"
+ private const val KEY_BTVSD_VENDOR_DATA = "VD"
+
+ private const val DELIMITER_KEY_VALUE = ":"
+ private const val DELIMITER_BT_LEVEL_1 = ";"
+ private const val DELIMITER_BT_LEVEL_2 = ","
+
+ private const val SUFFIX_QR_CODE = ";;"
+
+ private const val ANDROID_VER = "U"
+ private const val QR_CODE_VER = 0x010000
+
+ // BT constants
+ private const val BIS_SYNC_MAX_CHANNEL = 32
+ private const val BIS_SYNC_NO_PREFERENCE = 0xFFFFFFFFu
+ private const val SUBGROUP_LC3_CODEC_ID = 0x6L
/**
* Converts [BluetoothLeBroadcastMetadata] to QR code string.
*
- * QR code string will prefix with "BT:BluetoothLeBroadcastMetadata:".
+ * QR code string will prefix with "BT:".
*/
- fun BluetoothLeBroadcastMetadata.toQrCodeString(): String =
- SCHEME_BT_BROADCAST_METADATA + Base64.encodeToString(toBytes(this), Base64.NO_WRAP)
+ fun BluetoothLeBroadcastMetadata.toQrCodeString(): String {
+ val entries = mutableListOf<Pair<String, String>>()
+ entries.add(Pair(KEY_BT_QR_VER, QR_CODE_VER.toString()))
+ entries.add(Pair(KEY_BT_ADDRESS_TYPE, this.sourceAddressType.toString()))
+ entries.add(Pair(KEY_BT_DEVICE, this.sourceDevice.address.replace(":", "-")))
+ entries.add(Pair(KEY_BT_ADVERTISING_SID, this.sourceAdvertisingSid.toString()))
+ entries.add(Pair(KEY_BT_BROADCAST_ID, this.broadcastId.toString()))
+ if (this.broadcastName != null) {
+ entries.add(Pair(KEY_BT_BROADCAST_NAME, Base64.encodeToString(
+ this.broadcastName?.toByteArray(Charsets.UTF_8), Base64.NO_WRAP)))
+ }
+ if (this.publicBroadcastMetadata != null) {
+ entries.add(Pair(KEY_BT_PUBLIC_BROADCAST_DATA, Base64.encodeToString(
+ this.publicBroadcastMetadata?.rawMetadata, Base64.NO_WRAP)))
+ }
+ entries.add(Pair(KEY_BT_SYNC_INTERVAL, this.paSyncInterval.toString()))
+ if (this.broadcastCode != null) {
+ entries.add(Pair(KEY_BT_BROADCAST_CODE,
+ Base64.encodeToString(this.broadcastCode, Base64.NO_WRAP)))
+ }
+ this.subgroups.forEach {
+ subgroup -> entries.add(Pair(KEY_BT_SUBGROUPS, subgroup.toQrCodeString())) }
+ entries.add(Pair(KEY_BT_ANDROID_VERSION, ANDROID_VER))
+ val qrCodeString = SCHEME_BT_BROADCAST_METADATA +
+ entries.toQrCodeString(DELIMITER_BT_LEVEL_1) + SUFFIX_QR_CODE
+ Log.d(TAG, "Generated QR string : $qrCodeString")
+ return qrCodeString
+ }
/**
* Converts QR code string to [BluetoothLeBroadcastMetadata].
@@ -39,32 +108,255 @@ object BluetoothLeBroadcastMetadataExt {
* QR code string should prefix with "BT:BluetoothLeBroadcastMetadata:".
*/
fun convertToBroadcastMetadata(qrCodeString: String): BluetoothLeBroadcastMetadata? {
- if (!qrCodeString.startsWith(SCHEME_BT_BROADCAST_METADATA)) return null
+ if (!qrCodeString.startsWith(SCHEME_BT_BROADCAST_METADATA)) {
+ Log.e(TAG, "String \"$qrCodeString\" does not begin with " +
+ "\"$SCHEME_BT_BROADCAST_METADATA\"")
+ return null
+ }
return try {
- val encodedString = qrCodeString.removePrefix(SCHEME_BT_BROADCAST_METADATA)
- val bytes = Base64.decode(encodedString, Base64.NO_WRAP)
- createFromBytes(BluetoothLeBroadcastMetadata.CREATOR, bytes)
+ Log.d(TAG, "Parsing QR string: $qrCodeString")
+ val strippedString =
+ qrCodeString.removePrefix(SCHEME_BT_BROADCAST_METADATA)
+ .removeSuffix(SUFFIX_QR_CODE)
+ Log.d(TAG, "Stripped to: $strippedString")
+ parseQrCodeToMetadata(strippedString)
} catch (e: Exception) {
- Log.w(TAG, "Cannot convert QR code string to BluetoothLeBroadcastMetadata", e)
+ Log.w(TAG, "Cannot parse: $qrCodeString", e)
null
}
}
- private fun toBytes(parcelable: Parcelable): ByteArray =
- Parcel.obtain().run {
- parcelable.writeToParcel(this, 0)
- setDataPosition(0)
- val bytes = marshall()
- recycle()
- bytes
+ private fun BluetoothLeBroadcastSubgroup.toQrCodeString(): String {
+ val entries = mutableListOf<Pair<String, String>>()
+ entries.add(Pair(KEY_BTSG_BIS_SYNC, getBisSyncFromChannels(this.channels).toString()))
+ entries.add(Pair(KEY_BTSG_BIS_MASK, getBisMaskFromChannels(this.channels).toString()))
+ entries.add(Pair(KEY_BTSG_AUDIO_CONTENT,
+ Base64.encodeToString(this.contentMetadata.rawMetadata, Base64.NO_WRAP)))
+ return entries.toQrCodeString(DELIMITER_BT_LEVEL_2)
+ }
+
+ private fun List<Pair<String, String>>.toQrCodeString(delimiter: String): String {
+ val entryStrings = this.map{ it.first + DELIMITER_KEY_VALUE + it.second }
+ return entryStrings.joinToString(separator = delimiter)
+ }
+
+ @TargetApi(Build.VERSION_CODES.TIRAMISU)
+ private fun parseQrCodeToMetadata(input: String): BluetoothLeBroadcastMetadata {
+ // Split into a list of list
+ val level1Fields = input.split(DELIMITER_BT_LEVEL_1)
+ .map{it.split(DELIMITER_KEY_VALUE, limit = 2)}
+ var qrCodeVersion = -1
+ var sourceAddrType = BluetoothDevice.ADDRESS_TYPE_UNKNOWN
+ var sourceAddrString: String? = null
+ var sourceAdvertiserSid = -1
+ var broadcastId = -1
+ var broadcastName: String? = null
+ var publicBroadcastMetadata: BluetoothLeAudioContentMetadata? = null
+ var paSyncInterval = -1
+ var broadcastCode: ByteArray? = null
+ // List of VendorID -> Data Pairs
+ var vendorDataList = mutableListOf<Pair<Int, ByteArray?>>()
+ var androidVersion: String? = null
+ val builder = BluetoothLeBroadcastMetadata.Builder()
+
+ for (field: List<String> in level1Fields) {
+ if (field.isEmpty()) {
+ continue
+ }
+ val key = field[0]
+ // Ignore 3rd value and after
+ val value = if (field.size > 1) field[1] else ""
+ when (key) {
+ KEY_BT_QR_VER -> {
+ require(qrCodeVersion == -1) { "Duplicate qrCodeVersion: $input" }
+ qrCodeVersion = value.toInt()
+ }
+ KEY_BT_ADDRESS_TYPE -> {
+ require(sourceAddrType == BluetoothDevice.ADDRESS_TYPE_UNKNOWN) {
+ "Duplicate sourceAddrType: $input"
+ }
+ sourceAddrType = value.toInt()
+ }
+ KEY_BT_DEVICE -> {
+ require(sourceAddrString == null) { "Duplicate sourceAddr: $input" }
+ sourceAddrString = value.replace("-", ":")
+ }
+ KEY_BT_ADVERTISING_SID -> {
+ require(sourceAdvertiserSid == -1) { "Duplicate sourceAdvertiserSid: $input" }
+ sourceAdvertiserSid = value.toInt()
+ }
+ KEY_BT_BROADCAST_ID -> {
+ require(broadcastId == -1) { "Duplicate broadcastId: $input" }
+ broadcastId = value.toInt()
+ }
+ KEY_BT_BROADCAST_NAME -> {
+ require(broadcastName == null) { "Duplicate broadcastName: $input" }
+ broadcastName = String(Base64.decode(value, Base64.NO_WRAP))
+ }
+ KEY_BT_PUBLIC_BROADCAST_DATA -> {
+ require(publicBroadcastMetadata == null) {
+ "Duplicate publicBroadcastMetadata $input"
+ }
+ publicBroadcastMetadata = BluetoothLeAudioContentMetadata
+ .fromRawBytes(Base64.decode(value, Base64.NO_WRAP))
+ }
+ KEY_BT_SYNC_INTERVAL -> {
+ require(paSyncInterval == -1) { "Duplicate paSyncInterval: $input" }
+ paSyncInterval = value.toInt()
+ }
+ KEY_BT_BROADCAST_CODE -> {
+ require(broadcastCode == null) { "Duplicate broadcastCode: $input" }
+ broadcastCode = Base64.decode(value, Base64.NO_WRAP)
+ }
+ KEY_BT_ANDROID_VERSION -> {
+ require(androidVersion == null) { "Duplicate androidVersion: $input" }
+ androidVersion = value
+ Log.i(TAG, "QR code Android version: $androidVersion")
+ }
+ // Repeatable
+ KEY_BT_SUBGROUPS -> {
+ builder.addSubgroup(parseSubgroupData(value))
+ }
+ // Repeatable
+ KEY_BT_VENDOR_SPECIFIC -> {
+ vendorDataList.add(parseVendorData(value))
+ }
+ }
+ }
+ Log.d(TAG, "parseQrCodeToMetadata: sourceAddrType=$sourceAddrType, " +
+ "sourceAddr=$sourceAddrString, sourceAdvertiserSid=$sourceAdvertiserSid, " +
+ "broadcastId=$broadcastId, broadcastName=$broadcastName, " +
+ "publicBroadcastMetadata=${publicBroadcastMetadata != null}, " +
+ "paSyncInterval=$paSyncInterval, " +
+ "broadcastCode=${broadcastCode?.toString(Charsets.UTF_8)}")
+ Log.d(TAG, "Not used in current code, but part of the specification: " +
+ "qrCodeVersion=$qrCodeVersion, androidVersion=$androidVersion, " +
+ "vendorDataListSize=${vendorDataList.size}")
+ val adapter = BluetoothAdapter.getDefaultAdapter()
+ // add source device and set broadcast code
+ val device = adapter.getRemoteLeDevice(requireNotNull(sourceAddrString), sourceAddrType)
+ builder.apply {
+ setSourceDevice(device, sourceAddrType)
+ setSourceAdvertisingSid(sourceAdvertiserSid)
+ setBroadcastId(broadcastId)
+ setBroadcastName(broadcastName)
+ setPublicBroadcast(publicBroadcastMetadata != null)
+ setPublicBroadcastMetadata(publicBroadcastMetadata)
+ setPaSyncInterval(paSyncInterval)
+ setEncrypted(broadcastCode != null)
+ setBroadcastCode(broadcastCode)
+ // Presentation delay is unknown and not useful when adding source
+ // Broadcast sink needs to sync to the Broadcast source to get presentation delay
+ setPresentationDelayMicros(0)
+ }
+ return builder.build()
+ }
+
+ private fun parseSubgroupData(input: String): BluetoothLeBroadcastSubgroup {
+ Log.d(TAG, "parseSubgroupData: $input")
+ val fields = input.split(DELIMITER_BT_LEVEL_2)
+ var bisSync: UInt? = null
+ var bisMask: UInt? = null
+ var metadata: ByteArray? = null
+
+ fields.forEach { field ->
+ val(key, value) = field.split(DELIMITER_KEY_VALUE)
+ when (key) {
+ KEY_BTSG_BIS_SYNC -> {
+ require(bisSync == null) { "Duplicate bisSync: $input" }
+ bisSync = value.toUInt()
+ }
+ KEY_BTSG_BIS_MASK -> {
+ require(bisMask == null) { "Duplicate bisMask: $input" }
+ bisMask = value.toUInt()
+ }
+ KEY_BTSG_AUDIO_CONTENT -> {
+ require(metadata == null) { "Duplicate metadata: $input" }
+ metadata = Base64.decode(value, Base64.NO_WRAP)
+ }
+ }
}
+ val channels = convertToChannels(requireNotNull(bisSync), requireNotNull(bisMask))
+ val audioCodecConfigMetadata = BluetoothLeAudioCodecConfigMetadata.Builder()
+ .setAudioLocation(0).build()
+ return BluetoothLeBroadcastSubgroup.Builder().apply {
+ setCodecId(SUBGROUP_LC3_CODEC_ID)
+ setCodecSpecificConfig(audioCodecConfigMetadata)
+ setContentMetadata(
+ BluetoothLeAudioContentMetadata.fromRawBytes(metadata ?: ByteArray(0)))
+ channels.forEach(::addChannel)
+ }.build()
+ }
+
+ private fun parseVendorData(input: String): Pair<Int, ByteArray?> {
+ var companyId = -1
+ var data: ByteArray? = null
+ val fields = input.split(DELIMITER_BT_LEVEL_2)
+ fields.forEach { field ->
+ val(key, value) = field.split(DELIMITER_KEY_VALUE)
+ when (key) {
+ KEY_BTVSD_COMPANY_ID -> {
+ require(companyId == -1) { "Duplicate companyId: $input" }
+ companyId = value.toInt()
+ }
+ KEY_BTVSD_VENDOR_DATA -> {
+ require(data == null) { "Duplicate data: $input" }
+ data = Base64.decode(value, Base64.NO_WRAP)
+ }
+ }
+ }
+ return Pair(companyId, data)
+ }
- private fun <T> createFromBytes(creator: Parcelable.Creator<T>, bytes: ByteArray): T =
- Parcel.obtain().run {
- unmarshall(bytes, 0, bytes.size)
- setDataPosition(0)
- val created = creator.createFromParcel(this)
- recycle()
- created
+ private fun getBisSyncFromChannels(channels: List<BluetoothLeBroadcastChannel>): UInt {
+ var bisSync = 0u
+ // channel index starts from 1
+ channels.forEach { channel ->
+ if (channel.isSelected && channel.channelIndex > 0) {
+ bisSync = bisSync or (1u shl (channel.channelIndex - 1))
+ }
}
+ // No channel is selected means no preference on Android platform
+ return if (bisSync == 0u) BIS_SYNC_NO_PREFERENCE else bisSync
+ }
+
+ private fun getBisMaskFromChannels(channels: List<BluetoothLeBroadcastChannel>): UInt {
+ var bisMask = 0u
+ // channel index starts from 1
+ channels.forEach { channel ->
+ if (channel.channelIndex > 0) {
+ bisMask = bisMask or (1u shl (channel.channelIndex - 1))
+ }
+ }
+ return bisMask
+ }
+
+ private fun convertToChannels(bisSync: UInt, bisMask: UInt):
+ List<BluetoothLeBroadcastChannel> {
+ Log.d(TAG, "convertToChannels: bisSync=$bisSync, bisMask=$bisMask")
+ var selectionMask = bisSync
+ if (bisSync != BIS_SYNC_NO_PREFERENCE) {
+ require(bisMask == (bisMask or bisSync)) {
+ "bisSync($bisSync) must select a subset of bisMask($bisMask) if it has preferences"
+ }
+ } else {
+ // No channel preference means no channel is selected
+ selectionMask = 0u
+ }
+ val channels = mutableListOf<BluetoothLeBroadcastChannel>()
+ val audioCodecConfigMetadata = BluetoothLeAudioCodecConfigMetadata.Builder()
+ .setAudioLocation(0).build()
+ for (i in 0 until BIS_SYNC_MAX_CHANNEL) {
+ val channelMask = 1u shl i
+ if ((bisMask and channelMask) != 0u) {
+ val channel = BluetoothLeBroadcastChannel.Builder().apply {
+ setSelected((selectionMask and channelMask) != 0u)
+ setChannelIndex(i + 1)
+ setCodecMetadata(audioCodecConfigMetadata)
+ }
+ channels.add(channel.build())
+ }
+ }
+ return channels
+ }
} \ No newline at end of file
diff --git a/packages/SettingsLib/tests/unit/src/com/android/settingslib/bluetooth/BluetoothLeBroadcastMetadataExtTest.kt b/packages/SettingsLib/tests/unit/src/com/android/settingslib/bluetooth/BluetoothLeBroadcastMetadataExtTest.kt
index 0e3590d96a14..27d7078774d5 100644
--- a/packages/SettingsLib/tests/unit/src/com/android/settingslib/bluetooth/BluetoothLeBroadcastMetadataExtTest.kt
+++ b/packages/SettingsLib/tests/unit/src/com/android/settingslib/bluetooth/BluetoothLeBroadcastMetadataExtTest.kt
@@ -34,24 +34,33 @@ class BluetoothLeBroadcastMetadataExtTest {
@Test
fun toQrCodeString() {
val subgroup = BluetoothLeBroadcastSubgroup.Builder().apply {
- setCodecId(100)
+ setCodecId(0x6)
val audioCodecConfigMetadata = BluetoothLeAudioCodecConfigMetadata.Builder().build()
setCodecSpecificConfig(audioCodecConfigMetadata)
- setContentMetadata(BluetoothLeAudioContentMetadata.Builder().build())
+ setContentMetadata(BluetoothLeAudioContentMetadata.Builder()
+ .setProgramInfo("Test").setLanguage("eng").build())
addChannel(BluetoothLeBroadcastChannel.Builder().apply {
- setChannelIndex(1000)
+ setSelected(true)
+ setChannelIndex(2)
+ setCodecMetadata(audioCodecConfigMetadata)
+ }.build())
+ addChannel(BluetoothLeBroadcastChannel.Builder().apply {
+ setSelected(true)
+ setChannelIndex(1)
setCodecMetadata(audioCodecConfigMetadata)
}.build())
}.build()
val metadata = BluetoothLeBroadcastMetadata.Builder().apply {
- setSourceDevice(Device, 0)
+ setSourceDevice(Device, BluetoothDevice.ADDRESS_TYPE_RANDOM)
setSourceAdvertisingSid(1)
- setBroadcastId(2)
- setPaSyncInterval(3)
+ setBroadcastId(123456)
+ setBroadcastName("Test")
+ setPublicBroadcastMetadata(BluetoothLeAudioContentMetadata.Builder()
+ .setProgramInfo("pTest").build())
+ setPaSyncInterval(160)
setEncrypted(true)
- setBroadcastCode(byteArrayOf(10, 11, 12, 13))
- setPresentationDelayMicros(4)
+ setBroadcastCode("TestCode".toByteArray(Charsets.UTF_8))
addSubgroup(subgroup)
}.build()
@@ -61,6 +70,108 @@ class BluetoothLeBroadcastMetadataExtTest {
}
@Test
+ fun toQrCodeString_NoChannelSelected() {
+ val subgroup = BluetoothLeBroadcastSubgroup.Builder().apply {
+ setCodecId(0x6)
+ val audioCodecConfigMetadata = BluetoothLeAudioCodecConfigMetadata.Builder().build()
+ setCodecSpecificConfig(audioCodecConfigMetadata)
+ setContentMetadata(BluetoothLeAudioContentMetadata.Builder()
+ .setProgramInfo("Test").setLanguage("eng").build())
+ addChannel(BluetoothLeBroadcastChannel.Builder().apply {
+ setSelected(false)
+ setChannelIndex(2)
+ setCodecMetadata(audioCodecConfigMetadata)
+ }.build())
+ addChannel(BluetoothLeBroadcastChannel.Builder().apply {
+ setSelected(false)
+ setChannelIndex(1)
+ setCodecMetadata(audioCodecConfigMetadata)
+ }.build())
+ }.build()
+
+ val metadata = BluetoothLeBroadcastMetadata.Builder().apply {
+ setSourceDevice(Device, BluetoothDevice.ADDRESS_TYPE_RANDOM)
+ setSourceAdvertisingSid(1)
+ setBroadcastId(123456)
+ setBroadcastName("Test")
+ setPublicBroadcastMetadata(BluetoothLeAudioContentMetadata.Builder()
+ .setProgramInfo("pTest").build())
+ setPaSyncInterval(160)
+ setEncrypted(true)
+ setBroadcastCode("TestCode".toByteArray(Charsets.UTF_8))
+ addSubgroup(subgroup)
+ }.build()
+
+ val qrCodeString = metadata.toQrCodeString()
+
+ val parsedMetadata =
+ BluetoothLeBroadcastMetadataExt.convertToBroadcastMetadata(qrCodeString)!!
+
+ assertThat(parsedMetadata).isNotNull()
+ assertThat(parsedMetadata.subgroups).isNotNull()
+ assertThat(parsedMetadata.subgroups.size).isEqualTo(1)
+ assertThat(parsedMetadata.subgroups[0].channels).isNotNull()
+ assertThat(parsedMetadata.subgroups[0].channels.size).isEqualTo(2)
+ assertThat(parsedMetadata.subgroups[0].hasChannelPreference()).isFalse()
+ // Input order does not matter due to parsing through bisMask
+ assertThat(parsedMetadata.subgroups[0].channels[0].channelIndex).isEqualTo(1)
+ assertThat(parsedMetadata.subgroups[0].channels[0].isSelected).isFalse()
+ assertThat(parsedMetadata.subgroups[0].channels[1].channelIndex).isEqualTo(2)
+ assertThat(parsedMetadata.subgroups[0].channels[1].isSelected).isFalse()
+ }
+
+ @Test
+ fun toQrCodeString_OneChannelSelected() {
+ val subgroup = BluetoothLeBroadcastSubgroup.Builder().apply {
+ setCodecId(0x6)
+ val audioCodecConfigMetadata = BluetoothLeAudioCodecConfigMetadata.Builder().build()
+ setCodecSpecificConfig(audioCodecConfigMetadata)
+ setContentMetadata(BluetoothLeAudioContentMetadata.Builder()
+ .setProgramInfo("Test").setLanguage("eng").build())
+ addChannel(BluetoothLeBroadcastChannel.Builder().apply {
+ setSelected(false)
+ setChannelIndex(1)
+ setCodecMetadata(audioCodecConfigMetadata)
+ }.build())
+ addChannel(BluetoothLeBroadcastChannel.Builder().apply {
+ setSelected(true)
+ setChannelIndex(2)
+ setCodecMetadata(audioCodecConfigMetadata)
+ }.build())
+ }.build()
+
+ val metadata = BluetoothLeBroadcastMetadata.Builder().apply {
+ setSourceDevice(Device, BluetoothDevice.ADDRESS_TYPE_RANDOM)
+ setSourceAdvertisingSid(1)
+ setBroadcastId(123456)
+ setBroadcastName("Test")
+ setPublicBroadcastMetadata(BluetoothLeAudioContentMetadata.Builder()
+ .setProgramInfo("pTest").build())
+ setPaSyncInterval(160)
+ setEncrypted(true)
+ setBroadcastCode("TestCode".toByteArray(Charsets.UTF_8))
+ addSubgroup(subgroup)
+ }.build()
+
+ val qrCodeString = metadata.toQrCodeString()
+
+ val parsedMetadata =
+ BluetoothLeBroadcastMetadataExt.convertToBroadcastMetadata(qrCodeString)!!
+
+ assertThat(parsedMetadata).isNotNull()
+ assertThat(parsedMetadata.subgroups).isNotNull()
+ assertThat(parsedMetadata.subgroups.size).isEqualTo(1)
+ assertThat(parsedMetadata.subgroups[0].channels).isNotNull()
+ // Only selected channel can be recovered
+ assertThat(parsedMetadata.subgroups[0].channels.size).isEqualTo(2)
+ assertThat(parsedMetadata.subgroups[0].hasChannelPreference()).isTrue()
+ assertThat(parsedMetadata.subgroups[0].channels[0].channelIndex).isEqualTo(1)
+ assertThat(parsedMetadata.subgroups[0].channels[0].isSelected).isFalse()
+ assertThat(parsedMetadata.subgroups[0].channels[1].channelIndex).isEqualTo(2)
+ assertThat(parsedMetadata.subgroups[0].channels[1].isSelected).isTrue()
+ }
+
+ @Test
fun decodeAndEncodeAgain_sameString() {
val metadata = BluetoothLeBroadcastMetadataExt.convertToBroadcastMetadata(QR_CODE_STRING)!!
@@ -73,13 +184,12 @@ class BluetoothLeBroadcastMetadataExtTest {
const val TEST_DEVICE_ADDRESS = "00:A1:A1:A1:A1:A1"
val Device: BluetoothDevice =
- BluetoothAdapter.getDefaultAdapter().getRemoteDevice(TEST_DEVICE_ADDRESS)
+ BluetoothAdapter.getDefaultAdapter().getRemoteLeDevice(TEST_DEVICE_ADDRESS,
+ BluetoothDevice.ADDRESS_TYPE_RANDOM)
const val QR_CODE_STRING =
- "BT:BluetoothLeBroadcastMetadata:AAAAAAEAAAABAAAAEQAAADAAMAA6AEEAMQA6AEEAMQA6AEEAMQA6" +
- "AEEAMQA6AEEAMQAAAAAAAAABAAAAAgAAAAMAAAABAAAABAAAAAQAAAAKCwwNBAAAAAEAAAABAAAAZAAA" +
- "AAAAAAABAAAAAAAAAAAAAAAGAAAABgAAAAUDAAAAAAAAAAAAAAAAAAAAAAAAAQAAAP//////////AAAA" +
- "AAAAAAABAAAAAQAAAAAAAADoAwAAAQAAAAAAAAAAAAAABgAAAAYAAAAFAwAAAAAAAAAAAAAAAAAAAAAA" +
- "AAAAAAD/////AAAAAAAAAAA="
+ "BT:R:65536;T:1;D:00-A1-A1-A1-A1-A1;AS:1;B:123456;BN:VGVzdA==;" +
+ "PM:BgNwVGVzdA==;SI:160;C:VGVzdENvZGU=;SG:BS:3,BM:3,AC:BQNUZXN0BARlbmc=;" +
+ "VN:U;;"
}
} \ No newline at end of file
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockRegistry.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockRegistry.kt
index 7c76281e4bdd..0e20444347fd 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockRegistry.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockRegistry.kt
@@ -45,6 +45,7 @@ import java.util.concurrent.atomic.AtomicBoolean
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
private val KEY_TIMESTAMP = "appliedTimestamp"
@@ -320,20 +321,20 @@ open class ClockRegistry(
}
}
- public fun mutateSetting(mutator: (ClockSettings) -> ClockSettings) {
- scope.launch(bgDispatcher) { applySettings(mutator(settings ?: ClockSettings())) }
+ public suspend fun mutateSetting(mutator: (ClockSettings) -> ClockSettings) {
+ withContext(bgDispatcher) { applySettings(mutator(settings ?: ClockSettings())) }
}
var currentClockId: ClockId
get() = settings?.clockId ?: fallbackClockId
set(value) {
- mutateSetting { it.copy(clockId = value) }
+ scope.launch(bgDispatcher) { mutateSetting { it.copy(clockId = value) } }
}
var seedColor: Int?
get() = settings?.seedColor
set(value) {
- mutateSetting { it.copy(seedColor = value) }
+ scope.launch(bgDispatcher) { mutateSetting { it.copy(seedColor = value) } }
}
init {
@@ -501,11 +502,25 @@ open class ClockRegistry(
fun createExampleClock(clockId: ClockId): ClockController? = createClock(clockId)
- fun registerClockChangeListener(listener: ClockChangeListener) =
+ /**
+ * Adds [listener] to receive future clock changes.
+ *
+ * Calling from main thread to make sure the access is thread safe.
+ */
+ fun registerClockChangeListener(listener: ClockChangeListener) {
+ assertMainThread()
clockChangeListeners.add(listener)
+ }
- fun unregisterClockChangeListener(listener: ClockChangeListener) =
+ /**
+ * Removes [listener] from future clock changes.
+ *
+ * Calling from main thread to make sure the access is thread safe.
+ */
+ fun unregisterClockChangeListener(listener: ClockChangeListener) {
+ assertMainThread()
clockChangeListeners.remove(listener)
+ }
fun createCurrentClock(): ClockController {
val clockId = currentClockId
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/quickaffordance/shared/model/KeyguardPreviewConstants.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/quickaffordance/shared/model/KeyguardPreviewConstants.kt
index 6f363a4ffa26..08ee60204178 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/quickaffordance/shared/model/KeyguardPreviewConstants.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/quickaffordance/shared/model/KeyguardPreviewConstants.kt
@@ -20,8 +20,6 @@ package com.android.systemui.shared.quickaffordance.shared.model
object KeyguardPreviewConstants {
const val MESSAGE_ID_HIDE_SMART_SPACE = 1111
const val KEY_HIDE_SMART_SPACE = "hide_smart_space"
- const val MESSAGE_ID_COLOR_OVERRIDE = 1234
- const val KEY_COLOR_OVERRIDE = "color_override" // ColorInt Encoded as string
const val MESSAGE_ID_SLOT_SELECTED = 1337
const val KEY_SLOT_ID = "slot_id"
const val KEY_INITIALLY_SELECTED_SLOT_ID = "initially_selected_slot_id"
diff --git a/packages/SystemUI/monet/src/com/android/systemui/monet/dynamiccolor/MaterialDynamicColors.java b/packages/SystemUI/monet/src/com/android/systemui/monet/dynamiccolor/MaterialDynamicColors.java
index 21218a2dc8e2..9f075e521126 100644
--- a/packages/SystemUI/monet/src/com/android/systemui/monet/dynamiccolor/MaterialDynamicColors.java
+++ b/packages/SystemUI/monet/src/com/android/systemui/monet/dynamiccolor/MaterialDynamicColors.java
@@ -16,13 +16,15 @@
package com.android.systemui.monet.dynamiccolor;
+import android.annotation.NonNull;
+
import com.android.systemui.monet.dislike.DislikeAnalyzer;
import com.android.systemui.monet.hct.Hct;
import com.android.systemui.monet.hct.ViewingConditions;
import com.android.systemui.monet.scheme.DynamicScheme;
import com.android.systemui.monet.scheme.Variant;
-/** Named colors, otherwise known as tokens, or roles, in the Material Design system.*/
+/** Named colors, otherwise known as tokens, or roles, in the Material Design system. */
// Prevent lint for Function.apply not being available on Android before API level 14 (4.0.1).
// "AndroidJdkLibsChecker" for Function, "NewApi" for Function.apply().
// A java_library Bazel rule with an Android constraint cannot skip these warnings without this
@@ -32,190 +34,148 @@ import com.android.systemui.monet.scheme.Variant;
public final class MaterialDynamicColors {
private static final double CONTAINER_ACCENT_TONE_DELTA = 15.0;
-
- public MaterialDynamicColors() {
- }
-
- /**
- * These colors were present in Android framework before Android U, and used by MDC controls.
- * They
- * should be avoided, if possible. It's unclear if they're used on multiple backgrounds, and if
- * they are, they can't be adjusted for contrast.* For now, they will be set with no background,
- * and those won't adjust for contrast, avoiding issues.
- *
- * <p>* For example, if the same color is on a white background _and_ black background,
- * there's no
- * way to increase contrast with either without losing contrast with the other.
- */
- // colorControlActivated documented as colorAccent in M3 & GM3.
- // colorAccent documented as colorSecondary in M3 and colorPrimary in GM3.
- // Android used Material's Container as Primary/Secondary/Tertiary at launch.
- // Therefore, this is a duplicated version of Primary Container.
- public static DynamicColor controlActivated() {
- return DynamicColor.fromPalette((s) -> s.primaryPalette, (s) -> s.isDark ? 30.0 : 90.0, null);
- }
+ public MaterialDynamicColors() {}
// Compatibility Keys Colors for Android
- public static DynamicColor primaryPaletteKeyColor() {
+ public DynamicColor primaryPaletteKeyColor() {
return DynamicColor.fromPalette(
(s) -> s.primaryPalette, (s) -> s.primaryPalette.getKeyColor().getTone());
}
- public static DynamicColor secondaryPaletteKeyColor() {
+ public DynamicColor secondaryPaletteKeyColor() {
return DynamicColor.fromPalette(
(s) -> s.secondaryPalette, (s) -> s.secondaryPalette.getKeyColor().getTone());
}
- public static DynamicColor tertiaryPaletteKeyColor() {
+ public DynamicColor tertiaryPaletteKeyColor() {
return DynamicColor.fromPalette(
(s) -> s.tertiaryPalette, (s) -> s.tertiaryPalette.getKeyColor().getTone());
}
- public static DynamicColor neutralPaletteKeyColor() {
+ public DynamicColor neutralPaletteKeyColor() {
return DynamicColor.fromPalette(
(s) -> s.neutralPalette, (s) -> s.neutralPalette.getKeyColor().getTone());
}
- public static DynamicColor neutralVariantPaletteKeyColor() {
+ public DynamicColor neutralVariantPaletteKeyColor() {
return DynamicColor.fromPalette(
(s) -> s.neutralVariantPalette,
(s) -> s.neutralVariantPalette.getKeyColor().getTone());
}
- private static ViewingConditions viewingConditionsForAlbers(DynamicScheme scheme) {
- return ViewingConditions.defaultWithBackgroundLstar(scheme.isDark ? 30.0 : 80.0);
- }
-
- private static boolean isFidelity(DynamicScheme scheme) {
- return scheme.variant == Variant.FIDELITY || scheme.variant == Variant.CONTENT;
- }
-
- private static boolean isMonochrome(DynamicScheme scheme) {
- return scheme.variant == Variant.MONOCHROME;
- }
-
- static double findDesiredChromaByTone(
- double hue, double chroma, double tone, boolean byDecreasingTone) {
- double answer = tone;
-
- Hct closestToChroma = Hct.from(hue, chroma, tone);
- if (closestToChroma.getChroma() < chroma) {
- double chromaPeak = closestToChroma.getChroma();
- while (closestToChroma.getChroma() < chroma) {
- answer += byDecreasingTone ? -1.0 : 1.0;
- Hct potentialSolution = Hct.from(hue, chroma, answer);
- if (chromaPeak > potentialSolution.getChroma()) {
- break;
- }
- if (Math.abs(potentialSolution.getChroma() - chroma) < 0.4) {
- break;
- }
-
- double potentialDelta = Math.abs(potentialSolution.getChroma() - chroma);
- double currentDelta = Math.abs(closestToChroma.getChroma() - chroma);
- if (potentialDelta < currentDelta) {
- closestToChroma = potentialSolution;
- }
- chromaPeak = Math.max(chromaPeak, potentialSolution.getChroma());
- }
- }
-
- return answer;
- }
-
- static double performAlbers(Hct prealbers, DynamicScheme scheme) {
- final Hct albersd = prealbers.inViewingConditions(viewingConditionsForAlbers(scheme));
- if (DynamicColor.tonePrefersLightForeground(prealbers.getTone())
- && !DynamicColor.toneAllowsLightForeground(albersd.getTone())) {
- return DynamicColor.enableLightForeground(prealbers.getTone());
- } else {
- return DynamicColor.enableLightForeground(albersd.getTone());
- }
- }
-
- public static DynamicColor highestSurface(DynamicScheme s) {
+ @NonNull
+ public DynamicColor highestSurface(@NonNull DynamicScheme s) {
return s.isDark ? surfaceBright() : surfaceDim();
}
- public static DynamicColor background() {
+ @NonNull
+ public DynamicColor background() {
return DynamicColor.fromPalette((s) -> s.neutralPalette, (s) -> s.isDark ? 6.0 : 98.0);
}
- public static DynamicColor onBackground() {
+ @NonNull
+ public DynamicColor onBackground() {
return DynamicColor.fromPalette(
(s) -> s.neutralPalette, (s) -> s.isDark ? 90.0 : 10.0, (s) -> background());
}
- public static DynamicColor surface() {
+ @NonNull
+ public DynamicColor surface() {
return DynamicColor.fromPalette((s) -> s.neutralPalette, (s) -> s.isDark ? 6.0 : 98.0);
}
- public static DynamicColor inverseSurface() {
+ @NonNull
+ public DynamicColor inverseSurface() {
return DynamicColor.fromPalette((s) -> s.neutralPalette, (s) -> s.isDark ? 90.0 : 20.0);
}
- public static DynamicColor surfaceBright() {
+ @NonNull
+ public DynamicColor surfaceBright() {
return DynamicColor.fromPalette((s) -> s.neutralPalette, (s) -> s.isDark ? 24.0 : 98.0);
}
- public static DynamicColor surfaceDim() {
+ @NonNull
+ public DynamicColor surfaceDim() {
return DynamicColor.fromPalette((s) -> s.neutralPalette, (s) -> s.isDark ? 6.0 : 87.0);
}
- public static DynamicColor surfaceContainerLowest() {
+ @NonNull
+ public DynamicColor surfaceContainerLowest() {
return DynamicColor.fromPalette((s) -> s.neutralPalette, (s) -> s.isDark ? 4.0 : 100.0);
}
- public static DynamicColor surfaceContainerLow() {
+ @NonNull
+ public DynamicColor surfaceContainerLow() {
return DynamicColor.fromPalette((s) -> s.neutralPalette, (s) -> s.isDark ? 10.0 : 96.0);
}
- public static DynamicColor surfaceContainer() {
+ @NonNull
+ public DynamicColor surfaceContainer() {
return DynamicColor.fromPalette((s) -> s.neutralPalette, (s) -> s.isDark ? 12.0 : 94.0);
}
- public static DynamicColor surfaceContainerHigh() {
+ @NonNull
+ public DynamicColor surfaceContainerHigh() {
return DynamicColor.fromPalette((s) -> s.neutralPalette, (s) -> s.isDark ? 17.0 : 92.0);
}
- public static DynamicColor surfaceContainerHighest() {
+ @NonNull
+ public DynamicColor surfaceContainerHighest() {
return DynamicColor.fromPalette((s) -> s.neutralPalette, (s) -> s.isDark ? 22.0 : 90.0);
}
- public static DynamicColor onSurface() {
+ @NonNull
+ public DynamicColor onSurface() {
return DynamicColor.fromPalette(
- (s) -> s.neutralPalette, (s) -> s.isDark ? 90.0 : 10.0,
- MaterialDynamicColors::highestSurface);
+ (s) -> s.neutralPalette, (s) -> s.isDark ? 90.0 : 10.0, this::highestSurface);
}
- public static DynamicColor inverseOnSurface() {
+ @NonNull
+ public DynamicColor inverseOnSurface() {
return DynamicColor.fromPalette(
(s) -> s.neutralPalette, (s) -> s.isDark ? 20.0 : 95.0, (s) -> inverseSurface());
}
- public static DynamicColor surfaceVariant() {
- return DynamicColor.fromPalette((s) -> s.neutralVariantPalette,
- (s) -> s.isDark ? 30.0 : 90.0);
+ @NonNull
+ public DynamicColor surfaceVariant() {
+ return DynamicColor.fromPalette((s) -> s.neutralVariantPalette, (s) -> s.isDark ? 30.0 : 90.0);
}
- public static DynamicColor onSurfaceVariant() {
+ @NonNull
+ public DynamicColor onSurfaceVariant() {
return DynamicColor.fromPalette(
- (s) -> s.neutralVariantPalette, (s) -> s.isDark ? 80.0 : 30.0,
- (s) -> surfaceVariant());
+ (s) -> s.neutralVariantPalette, (s) -> s.isDark ? 80.0 : 30.0, (s) -> surfaceVariant());
}
- public static DynamicColor outline() {
+ @NonNull
+ public DynamicColor outline() {
return DynamicColor.fromPalette(
- (s) -> s.neutralVariantPalette, (s) -> 50.0, MaterialDynamicColors::highestSurface);
+ (s) -> s.neutralVariantPalette, (s) -> s.isDark ? 60.0 : 50.0, this::highestSurface);
}
- public static DynamicColor outlineVariant() {
+ @NonNull
+ public DynamicColor outlineVariant() {
return DynamicColor.fromPalette(
- (s) -> s.neutralVariantPalette, (s) -> s.isDark ? 30.0 : 80.0,
- MaterialDynamicColors::highestSurface);
+ (s) -> s.neutralVariantPalette, (s) -> s.isDark ? 30.0 : 80.0, this::highestSurface);
+ }
+
+ @NonNull
+ public DynamicColor shadow() {
+ return DynamicColor.fromPalette((s) -> s.neutralPalette, (s) -> 0.0);
}
- public static DynamicColor primaryContainer() {
+ @NonNull
+ public DynamicColor scrim() {
+ return DynamicColor.fromPalette((s) -> s.neutralPalette, (s) -> 0.0);
+ }
+
+ @NonNull
+ public DynamicColor surfaceTint() {
+ return DynamicColor.fromPalette((s) -> s.primaryPalette, (s) -> s.isDark ? 80.0 : 40.0);
+ }
+
+ @NonNull
+ public DynamicColor primaryContainer() {
return DynamicColor.fromPalette(
(s) -> s.primaryPalette,
(s) -> {
@@ -227,10 +187,11 @@ public final class MaterialDynamicColors {
}
return s.isDark ? 30.0 : 90.0;
},
- MaterialDynamicColors::highestSurface);
+ this::highestSurface);
}
- public static DynamicColor onPrimaryContainer() {
+ @NonNull
+ public DynamicColor onPrimaryContainer() {
return DynamicColor.fromPalette(
(s) -> s.primaryPalette,
(s) -> {
@@ -246,7 +207,8 @@ public final class MaterialDynamicColors {
null);
}
- public static DynamicColor primary() {
+ @NonNull
+ public DynamicColor primary() {
return DynamicColor.fromPalette(
(s) -> s.primaryPalette,
(s) -> {
@@ -255,7 +217,7 @@ public final class MaterialDynamicColors {
}
return s.isDark ? 80.0 : 40.0;
},
- MaterialDynamicColors::highestSurface,
+ this::highestSurface,
(s) ->
new ToneDeltaConstraint(
CONTAINER_ACCENT_TONE_DELTA,
@@ -263,12 +225,14 @@ public final class MaterialDynamicColors {
s.isDark ? TonePolarity.DARKER : TonePolarity.LIGHTER));
}
- public static DynamicColor inversePrimary() {
+ @NonNull
+ public DynamicColor inversePrimary() {
return DynamicColor.fromPalette(
(s) -> s.primaryPalette, (s) -> s.isDark ? 40.0 : 80.0, (s) -> inverseSurface());
}
- public static DynamicColor onPrimary() {
+ @NonNull
+ public DynamicColor onPrimary() {
return DynamicColor.fromPalette(
(s) -> s.primaryPalette,
(s) -> {
@@ -280,7 +244,8 @@ public final class MaterialDynamicColors {
(s) -> primary());
}
- public static DynamicColor secondaryContainer() {
+ @NonNull
+ public DynamicColor secondaryContainer() {
return DynamicColor.fromPalette(
(s) -> s.secondaryPalette,
(s) -> {
@@ -300,10 +265,11 @@ public final class MaterialDynamicColors {
answer = performAlbers(s.secondaryPalette.getHct(answer), s);
return answer;
},
- MaterialDynamicColors::highestSurface);
+ this::highestSurface);
}
- public static DynamicColor onSecondaryContainer() {
+ @NonNull
+ public DynamicColor onSecondaryContainer() {
return DynamicColor.fromPalette(
(s) -> s.secondaryPalette,
(s) -> {
@@ -315,11 +281,12 @@ public final class MaterialDynamicColors {
(s) -> secondaryContainer());
}
- public static DynamicColor secondary() {
+ @NonNull
+ public DynamicColor secondary() {
return DynamicColor.fromPalette(
(s) -> s.secondaryPalette,
(s) -> s.isDark ? 80.0 : 40.0,
- MaterialDynamicColors::highestSurface,
+ this::highestSurface,
(s) ->
new ToneDeltaConstraint(
CONTAINER_ACCENT_TONE_DELTA,
@@ -327,7 +294,8 @@ public final class MaterialDynamicColors {
s.isDark ? TonePolarity.DARKER : TonePolarity.LIGHTER));
}
- public static DynamicColor onSecondary() {
+ @NonNull
+ public DynamicColor onSecondary() {
return DynamicColor.fromPalette(
(s) -> s.secondaryPalette,
(s) -> {
@@ -339,7 +307,8 @@ public final class MaterialDynamicColors {
(s) -> secondary());
}
- public static DynamicColor tertiaryContainer() {
+ @NonNull
+ public DynamicColor tertiaryContainer() {
return DynamicColor.fromPalette(
(s) -> s.tertiaryPalette,
(s) -> {
@@ -354,10 +323,11 @@ public final class MaterialDynamicColors {
final Hct proposedHct = s.tertiaryPalette.getHct(albersTone);
return DislikeAnalyzer.fixIfDisliked(proposedHct).getTone();
},
- MaterialDynamicColors::highestSurface);
+ this::highestSurface);
}
- public static DynamicColor onTertiaryContainer() {
+ @NonNull
+ public DynamicColor onTertiaryContainer() {
return DynamicColor.fromPalette(
(s) -> s.tertiaryPalette,
(s) -> {
@@ -372,7 +342,8 @@ public final class MaterialDynamicColors {
(s) -> tertiaryContainer());
}
- public static DynamicColor tertiary() {
+ @NonNull
+ public DynamicColor tertiary() {
return DynamicColor.fromPalette(
(s) -> s.tertiaryPalette,
(s) -> {
@@ -381,7 +352,7 @@ public final class MaterialDynamicColors {
}
return s.isDark ? 80.0 : 40.0;
},
- MaterialDynamicColors::highestSurface,
+ this::highestSurface,
(s) ->
new ToneDeltaConstraint(
CONTAINER_ACCENT_TONE_DELTA,
@@ -389,7 +360,8 @@ public final class MaterialDynamicColors {
s.isDark ? TonePolarity.DARKER : TonePolarity.LIGHTER));
}
- public static DynamicColor onTertiary() {
+ @NonNull
+ public DynamicColor onTertiary() {
return DynamicColor.fromPalette(
(s) -> s.tertiaryPalette,
(s) -> {
@@ -401,22 +373,24 @@ public final class MaterialDynamicColors {
(s) -> tertiary());
}
- public static DynamicColor errorContainer() {
+ @NonNull
+ public DynamicColor errorContainer() {
return DynamicColor.fromPalette(
- (s) -> s.errorPalette, (s) -> s.isDark ? 30.0 : 90.0,
- MaterialDynamicColors::highestSurface);
+ (s) -> s.errorPalette, (s) -> s.isDark ? 30.0 : 90.0, this::highestSurface);
}
- public static DynamicColor onErrorContainer() {
+ @NonNull
+ public DynamicColor onErrorContainer() {
return DynamicColor.fromPalette(
(s) -> s.errorPalette, (s) -> s.isDark ? 90.0 : 10.0, (s) -> errorContainer());
}
- public static DynamicColor error() {
+ @NonNull
+ public DynamicColor error() {
return DynamicColor.fromPalette(
(s) -> s.errorPalette,
(s) -> s.isDark ? 80.0 : 40.0,
- MaterialDynamicColors::highestSurface,
+ this::highestSurface,
(s) ->
new ToneDeltaConstraint(
CONTAINER_ACCENT_TONE_DELTA,
@@ -424,113 +398,138 @@ public final class MaterialDynamicColors {
s.isDark ? TonePolarity.DARKER : TonePolarity.LIGHTER));
}
- public static DynamicColor onError() {
+ @NonNull
+ public DynamicColor onError() {
return DynamicColor.fromPalette(
(s) -> s.errorPalette, (s) -> s.isDark ? 20.0 : 100.0, (s) -> error());
}
- public static DynamicColor primaryFixed() {
+ @NonNull
+ public DynamicColor primaryFixed() {
return DynamicColor.fromPalette(
(s) -> s.primaryPalette,
(s) -> {
if (isMonochrome(s)) {
- return s.isDark ? 100.0 : 10.0;
+ return 40.0;
}
return 90.0;
},
- MaterialDynamicColors::highestSurface);
+ this::highestSurface);
}
- public static DynamicColor primaryFixedDim() {
+ @NonNull
+ public DynamicColor primaryFixedDim() {
return DynamicColor.fromPalette(
(s) -> s.primaryPalette,
(s) -> {
if (isMonochrome(s)) {
- return s.isDark ? 90.0 : 20.0;
+ return 30.0;
}
return 80.0;
},
- MaterialDynamicColors::highestSurface);
+ this::highestSurface);
}
- public static DynamicColor onPrimaryFixed() {
+ @NonNull
+ public DynamicColor onPrimaryFixed() {
return DynamicColor.fromPalette(
(s) -> s.primaryPalette,
(s) -> {
if (isMonochrome(s)) {
- return s.isDark ? 10.0 : 90.0;
+ return 100.0;
}
return 10.0;
},
(s) -> primaryFixedDim());
}
- public static DynamicColor onPrimaryFixedVariant() {
+ @NonNull
+ public DynamicColor onPrimaryFixedVariant() {
return DynamicColor.fromPalette(
(s) -> s.primaryPalette,
(s) -> {
if (isMonochrome(s)) {
- return s.isDark ? 30.0 : 70.0;
+ return 90.0;
}
return 30.0;
},
(s) -> primaryFixedDim());
}
- public static DynamicColor secondaryFixed() {
+ @NonNull
+ public DynamicColor secondaryFixed() {
return DynamicColor.fromPalette(
- (s) -> s.secondaryPalette, (s) -> isMonochrome(s) ? 80.0 : 90.0,
- MaterialDynamicColors::highestSurface);
+ (s) -> s.secondaryPalette, (s) -> isMonochrome(s) ? 80.0 : 90.0, this::highestSurface);
}
- public static DynamicColor secondaryFixedDim() {
+ @NonNull
+ public DynamicColor secondaryFixedDim() {
return DynamicColor.fromPalette(
- (s) -> s.secondaryPalette, (s) -> isMonochrome(s) ? 70.0 : 80.0,
- MaterialDynamicColors::highestSurface);
+ (s) -> s.secondaryPalette, (s) -> isMonochrome(s) ? 70.0 : 80.0, this::highestSurface);
}
- public static DynamicColor onSecondaryFixed() {
+ @NonNull
+ public DynamicColor onSecondaryFixed() {
return DynamicColor.fromPalette(
(s) -> s.secondaryPalette, (s) -> 10.0, (s) -> secondaryFixedDim());
}
- public static DynamicColor onSecondaryFixedVariant() {
+ @NonNull
+ public DynamicColor onSecondaryFixedVariant() {
return DynamicColor.fromPalette(
(s) -> s.secondaryPalette,
(s) -> isMonochrome(s) ? 25.0 : 30.0,
(s) -> secondaryFixedDim());
}
- public static DynamicColor tertiaryFixed() {
+ @NonNull
+ public DynamicColor tertiaryFixed() {
return DynamicColor.fromPalette(
- (s) -> s.tertiaryPalette, (s) -> isMonochrome(s) ? 40.0 : 90.0,
- MaterialDynamicColors::highestSurface);
+ (s) -> s.tertiaryPalette, (s) -> isMonochrome(s) ? 40.0 : 90.0, this::highestSurface);
}
- public static DynamicColor tertiaryFixedDim() {
+ @NonNull
+ public DynamicColor tertiaryFixedDim() {
return DynamicColor.fromPalette(
- (s) -> s.tertiaryPalette, (s) -> isMonochrome(s) ? 30.0 : 80.0,
- MaterialDynamicColors::highestSurface);
+ (s) -> s.tertiaryPalette, (s) -> isMonochrome(s) ? 30.0 : 80.0, this::highestSurface);
}
- public static DynamicColor onTertiaryFixed() {
+ @NonNull
+ public DynamicColor onTertiaryFixed() {
return DynamicColor.fromPalette(
- (s) -> s.tertiaryPalette, (s) -> isMonochrome(s) ? 90.0 : 10.0,
- (s) -> tertiaryFixedDim());
+ (s) -> s.tertiaryPalette, (s) -> isMonochrome(s) ? 100.0 : 10.0, (s) -> tertiaryFixedDim());
}
- public static DynamicColor onTertiaryFixedVariant() {
+ @NonNull
+ public DynamicColor onTertiaryFixedVariant() {
return DynamicColor.fromPalette(
- (s) -> s.tertiaryPalette, (s) -> isMonochrome(s) ? 70.0 : 30.0,
- (s) -> tertiaryFixedDim());
+ (s) -> s.tertiaryPalette, (s) -> isMonochrome(s) ? 90.0 : 30.0, (s) -> tertiaryFixedDim());
+ }
+
+ /**
+ * These colors were present in Android framework before Android U, and used by MDC controls. They
+ * should be avoided, if possible. It's unclear if they're used on multiple backgrounds, and if
+ * they are, they can't be adjusted for contrast.* For now, they will be set with no background,
+ * and those won't adjust for contrast, avoiding issues.
+ *
+ * <p>* For example, if the same color is on a white background _and_ black background, there's no
+ * way to increase contrast with either without losing contrast with the other.
+ */
+ // colorControlActivated documented as colorAccent in M3 & GM3.
+ // colorAccent documented as colorSecondary in M3 and colorPrimary in GM3.
+ // Android used Material's Container as Primary/Secondary/Tertiary at launch.
+ // Therefore, this is a duplicated version of Primary Container.
+ @NonNull
+ public DynamicColor controlActivated() {
+ return DynamicColor.fromPalette((s) -> s.primaryPalette, (s) -> s.isDark ? 30.0 : 90.0, null);
}
// colorControlNormal documented as textColorSecondary in M3 & GM3.
// In Material, textColorSecondary points to onSurfaceVariant in the non-disabled state,
// which is Neutral Variant T30/80 in light/dark.
- public static DynamicColor controlNormal() {
- return DynamicColor.fromPalette((s) -> s.neutralVariantPalette,
- (s) -> s.isDark ? 80.0 : 30.0);
+ @NonNull
+ public DynamicColor controlNormal() {
+ return DynamicColor.fromPalette((s) -> s.neutralVariantPalette, (s) -> s.isDark ? 80.0 : 30.0);
}
// colorControlHighlight documented, in both M3 & GM3:
@@ -541,7 +540,8 @@ public final class MaterialDynamicColors {
// DynamicColors do not support alpha currently, and _may_ not need it for this use case,
// depending on how MDC resolved alpha for the other cases.
// Returning black in dark mode, white in light mode.
- public static DynamicColor controlHighlight() {
+ @NonNull
+ public DynamicColor controlHighlight() {
return new DynamicColor(
s -> 0.0,
s -> 0.0,
@@ -549,40 +549,92 @@ public final class MaterialDynamicColors {
s -> s.isDark ? 0.20 : 0.12,
null,
scheme ->
-
- DynamicColor.toneMinContrastDefault((s) -> s.isDark ? 100.0 : 0.0, null,
- scheme, null),
+ DynamicColor.toneMinContrastDefault((s) -> s.isDark ? 100.0 : 0.0, null, scheme, null),
scheme ->
- DynamicColor.toneMaxContrastDefault((s) -> s.isDark ? 100.0 : 0.0, null,
- scheme, null),
+ DynamicColor.toneMaxContrastDefault((s) -> s.isDark ? 100.0 : 0.0, null, scheme, null),
null);
}
// textColorPrimaryInverse documented, in both M3 & GM3, documented as N10/N90.
- public static DynamicColor textPrimaryInverse() {
+ @NonNull
+ public DynamicColor textPrimaryInverse() {
return DynamicColor.fromPalette((s) -> s.neutralPalette, (s) -> s.isDark ? 10.0 : 90.0);
}
// textColorSecondaryInverse and textColorTertiaryInverse both documented, in both M3 & GM3, as
// NV30/NV80
- public static DynamicColor textSecondaryAndTertiaryInverse() {
- return DynamicColor.fromPalette((s) -> s.neutralVariantPalette,
- (s) -> s.isDark ? 30.0 : 80.0);
+ @NonNull
+ public DynamicColor textSecondaryAndTertiaryInverse() {
+ return DynamicColor.fromPalette((s) -> s.neutralVariantPalette, (s) -> s.isDark ? 30.0 : 80.0);
}
// textColorPrimaryInverseDisableOnly documented, in both M3 & GM3, as N10/N90
- public static DynamicColor textPrimaryInverseDisableOnly() {
+ @NonNull
+ public DynamicColor textPrimaryInverseDisableOnly() {
return DynamicColor.fromPalette((s) -> s.neutralPalette, (s) -> s.isDark ? 10.0 : 90.0);
}
// textColorSecondaryInverse and textColorTertiaryInverse in disabled state both documented,
// in both M3 & GM3, as N10/N90
- public static DynamicColor textSecondaryAndTertiaryInverseDisabled() {
+ @NonNull
+ public DynamicColor textSecondaryAndTertiaryInverseDisabled() {
return DynamicColor.fromPalette((s) -> s.neutralPalette, (s) -> s.isDark ? 10.0 : 90.0);
}
// textColorHintInverse documented, in both M3 & GM3, as N10/N90
- public static DynamicColor textHintInverse() {
+ @NonNull
+ public DynamicColor textHintInverse() {
return DynamicColor.fromPalette((s) -> s.neutralPalette, (s) -> s.isDark ? 10.0 : 90.0);
}
-}
+
+ private static ViewingConditions viewingConditionsForAlbers(DynamicScheme scheme) {
+ return ViewingConditions.defaultWithBackgroundLstar(scheme.isDark ? 30.0 : 80.0);
+ }
+
+ private static boolean isFidelity(DynamicScheme scheme) {
+ return scheme.variant == Variant.FIDELITY || scheme.variant == Variant.CONTENT;
+ }
+
+ private static boolean isMonochrome(DynamicScheme scheme) {
+ return scheme.variant == Variant.MONOCHROME;
+ }
+
+ static double findDesiredChromaByTone(
+ double hue, double chroma, double tone, boolean byDecreasingTone) {
+ double answer = tone;
+
+ Hct closestToChroma = Hct.from(hue, chroma, tone);
+ if (closestToChroma.getChroma() < chroma) {
+ double chromaPeak = closestToChroma.getChroma();
+ while (closestToChroma.getChroma() < chroma) {
+ answer += byDecreasingTone ? -1.0 : 1.0;
+ Hct potentialSolution = Hct.from(hue, chroma, answer);
+ if (chromaPeak > potentialSolution.getChroma()) {
+ break;
+ }
+ if (Math.abs(potentialSolution.getChroma() - chroma) < 0.4) {
+ break;
+ }
+
+ double potentialDelta = Math.abs(potentialSolution.getChroma() - chroma);
+ double currentDelta = Math.abs(closestToChroma.getChroma() - chroma);
+ if (potentialDelta < currentDelta) {
+ closestToChroma = potentialSolution;
+ }
+ chromaPeak = Math.max(chromaPeak, potentialSolution.getChroma());
+ }
+ }
+
+ return answer;
+ }
+
+ static double performAlbers(Hct prealbers, DynamicScheme scheme) {
+ final Hct albersd = prealbers.inViewingConditions(viewingConditionsForAlbers(scheme));
+ if (DynamicColor.tonePrefersLightForeground(prealbers.getTone())
+ && !DynamicColor.toneAllowsLightForeground(albersd.getTone())) {
+ return DynamicColor.enableLightForeground(prealbers.getTone());
+ } else {
+ return DynamicColor.enableLightForeground(albersd.getTone());
+ }
+ }
+} \ No newline at end of file
diff --git a/packages/SystemUI/proguard_common.flags b/packages/SystemUI/proguard_common.flags
index 02d55104c288..1f47e724e48c 100644
--- a/packages/SystemUI/proguard_common.flags
+++ b/packages/SystemUI/proguard_common.flags
@@ -64,15 +64,16 @@
# The plugins, log & common subpackages act as shared libraries that might be referenced in
# dynamically-loaded plugin APKs.
--keep class com.android.systemui.plugins.** {
- *;
-}
--keep class com.android.systemui.log.** {
- *;
-}
--keep class com.android.systemui.common.** {
- *;
-}
+-keep class com.android.systemui.plugins.** { *; }
+-keep class com.android.systemui.log.ConstantStringsLoggerImpl { *; }
+-keep class com.android.systemui.log.ConstantStringsLogger { *; }
+-keep class com.android.systemui.log.LogBuffer { *; }
+-keep class com.android.systemui.log.LogcatEchoTrackerDebug { *; }
+-keep class com.android.systemui.log.LogcatEchoTracker { *; }
+-keep class com.android.systemui.log.LogcatEchoTrackerProd { *; }
+-keep class com.android.systemui.log.LogLevel { *; }
+-keep class com.android.systemui.log.LogMessageImpl { *; }
+-keep class com.android.systemui.log.LogMessage { *; }
-keep class com.android.systemui.fragments.FragmentService$FragmentCreator {
*;
}
diff --git a/packages/SystemUI/res/layout/media_output_list_item_advanced.xml b/packages/SystemUI/res/layout/media_output_list_item_advanced.xml
index 054193a5b323..a595566ef817 100644
--- a/packages/SystemUI/res/layout/media_output_list_item_advanced.xml
+++ b/packages/SystemUI/res/layout/media_output_list_item_advanced.xml
@@ -65,6 +65,8 @@
<TextView
android:id="@+id/volume_value"
android:animateLayoutChanges="true"
+ android:focusable="false"
+ android:importantForAccessibility="no"
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -75,6 +77,8 @@
<TextView
android:id="@+id/title"
+ android:focusable="false"
+ android:importantForAccessibility="no"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|start"
diff --git a/packages/SystemUI/res/values-night/colors.xml b/packages/SystemUI/res/values-night/colors.xml
index 5efcef376817..99311e3d1e1b 100644
--- a/packages/SystemUI/res/values-night/colors.xml
+++ b/packages/SystemUI/res/values-night/colors.xml
@@ -100,4 +100,8 @@
<color name="accessibility_floating_menu_message_text">@*android:color/primary_text_default_material_dark</color>
<color name="people_tile_background">@color/material_dynamic_secondary20</color>
+
+ <!-- Internet Dialog -->
+ <color name="connected_network_primary_color">@color/material_dynamic_primary80</color>
+ <color name="connected_network_secondary_color">@color/material_dynamic_secondary80</color>
</resources>
diff --git a/packages/SystemUI/res/values-night/styles.xml b/packages/SystemUI/res/values-night/styles.xml
index 99bc794547f2..b6971d3c1fa4 100644
--- a/packages/SystemUI/res/values-night/styles.xml
+++ b/packages/SystemUI/res/values-night/styles.xml
@@ -58,17 +58,13 @@
<style name="TextAppearance.InternetDialog.Active">
<item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
<item name="android:textSize">16sp</item>
- <item name="android:textColor">?android:attr/textColorPrimaryInverse</item>
+ <item name="android:textColor">@color/material_dynamic_primary80</item>
<item name="android:textDirection">locale</item>
</style>
<style name="TextAppearance.InternetDialog.Secondary.Active">
<item name="android:textSize">14sp</item>
- <item name="android:textColor">?android:attr/textColorSecondaryInverse</item>
- </style>
-
- <style name="InternetDialog.Divider.Active">
- <item name="android:background">?android:attr/textColorSecondaryInverse</item>
+ <item name="android:textColor">@color/material_dynamic_secondary80</item>
</style>
</resources>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index cee21353bd68..cb5342a0d66b 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -1183,12 +1183,6 @@
<style name="TextAppearance.InternetDialog.Secondary.Active"/>
- <style name="InternetDialog.Divider">
- <item name="android:background">?android:attr/textColorSecondary</item>
- </style>
-
- <style name="InternetDialog.Divider.Active"/>
-
<style name="FgsManagerDialogTitle">
<item name="android:fontFamily">@*android:string/config_bodyFontFamily</item>
<item name="android:textStyle">bold</item>
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/util/UnfoldOnlyProgressProvider.kt b/packages/SystemUI/shared/src/com/android/systemui/unfold/util/UnfoldOnlyProgressProvider.kt
new file mode 100644
index 000000000000..495d3a13d961
--- /dev/null
+++ b/packages/SystemUI/shared/src/com/android/systemui/unfold/util/UnfoldOnlyProgressProvider.kt
@@ -0,0 +1,63 @@
+/*
+ * 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.unfold.util
+
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.unfold.UnfoldTransitionProgressProvider
+import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener
+import com.android.systemui.unfold.updates.FoldProvider
+import com.android.systemui.unfold.updates.FoldProvider.FoldCallback
+import java.util.concurrent.Executor
+
+/**
+ * [UnfoldTransitionProgressProvider] that emits transition progress only when unfolding but not
+ * when folding, so we can play the animation only one way but not the other way.
+ */
+class UnfoldOnlyProgressProvider(
+ foldProvider: FoldProvider,
+ @Main private val executor: Executor,
+ private val sourceProvider: UnfoldTransitionProgressProvider,
+ private val scopedProvider: ScopedUnfoldTransitionProgressProvider =
+ ScopedUnfoldTransitionProgressProvider(sourceProvider)
+) : UnfoldTransitionProgressProvider by scopedProvider {
+
+ private var isFolded = false
+
+ init {
+ foldProvider.registerCallback(FoldListener(), executor)
+ sourceProvider.addCallback(SourceTransitionListener())
+ }
+
+ private inner class SourceTransitionListener : TransitionProgressListener {
+ override fun onTransitionFinished() {
+ // Disable scoped progress provider after the first unfold animation, so fold animation
+ // will not be propagated. It will be re-enabled after folding so we can play
+ // the unfold animation again.
+ if (!isFolded) {
+ scopedProvider.setReadyToHandleTransition(false)
+ }
+ }
+ }
+
+ private inner class FoldListener : FoldCallback {
+ override fun onFoldUpdated(isFolded: Boolean) {
+ if (isFolded) {
+ scopedProvider.setReadyToHandleTransition(true)
+ }
+
+ this@UnfoldOnlyProgressProvider.isFolded = isFolded
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
index 4b021716f506..4211f55787d9 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -1226,15 +1226,16 @@ public class KeyguardSecurityContainer extends ConstraintLayout {
constraintSet.constrainHeight(mViewFlipper.getId(), MATCH_CONSTRAINT);
constraintSet.applyTo(mView);
} else {
- int leftElement = leftAlign ? mViewFlipper.getId() : mUserSwitcherViewGroup.getId();
- int rightElement =
+ int startElement =
+ leftAlign ? mViewFlipper.getId() : mUserSwitcherViewGroup.getId();
+ int endElement =
leftAlign ? mUserSwitcherViewGroup.getId() : mViewFlipper.getId();
ConstraintSet constraintSet = new ConstraintSet();
- constraintSet.connect(leftElement, LEFT, PARENT_ID, LEFT);
- constraintSet.connect(leftElement, RIGHT, rightElement, LEFT);
- constraintSet.connect(rightElement, LEFT, leftElement, RIGHT);
- constraintSet.connect(rightElement, RIGHT, PARENT_ID, RIGHT);
+ constraintSet.connect(startElement, START, PARENT_ID, START);
+ constraintSet.connect(startElement, END, endElement, START);
+ constraintSet.connect(endElement, START, startElement, END);
+ constraintSet.connect(endElement, END, PARENT_ID, END);
constraintSet.connect(mUserSwitcherViewGroup.getId(), TOP, PARENT_ID, TOP);
constraintSet.connect(mUserSwitcherViewGroup.getId(), BOTTOM, PARENT_ID, BOTTOM);
constraintSet.connect(mViewFlipper.getId(), TOP, PARENT_ID, TOP);
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java
index fb160f2a2f00..69ce78ce30a8 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java
@@ -109,6 +109,7 @@ public abstract class AuthBiometricView extends LinearLayout implements AuthBiom
int ACTION_ERROR = 5;
int ACTION_USE_DEVICE_CREDENTIAL = 6;
int ACTION_START_DELAYED_FINGERPRINT_SENSOR = 7;
+ int ACTION_AUTHENTICATED_AND_CONFIRMED = 8;
/**
* When an action has occurred. The caller will only invoke this when the callback should
@@ -509,7 +510,8 @@ public abstract class AuthBiometricView extends LinearLayout implements AuthBiom
}
public void updateState(@BiometricState int newState) {
- Log.v(TAG, "newState: " + newState);
+ Log.d(TAG, "newState: " + newState);
+
mIconController.updateState(mState, newState);
switch (newState) {
@@ -533,8 +535,14 @@ public abstract class AuthBiometricView extends LinearLayout implements AuthBiom
}
announceForAccessibility(getResources()
.getString(R.string.biometric_dialog_authenticated));
- mHandler.postDelayed(() -> mCallback.onAction(Callback.ACTION_AUTHENTICATED),
- getDelayAfterAuthenticatedDurationMs());
+ if (mState == STATE_PENDING_CONFIRMATION) {
+ mHandler.postDelayed(() -> mCallback.onAction(
+ Callback.ACTION_AUTHENTICATED_AND_CONFIRMED),
+ getDelayAfterAuthenticatedDurationMs());
+ } else {
+ mHandler.postDelayed(() -> mCallback.onAction(Callback.ACTION_AUTHENTICATED),
+ getDelayAfterAuthenticatedDurationMs());
+ }
break;
case STATE_PENDING_CONFIRMATION:
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
index 49ac26411d3e..43a3b9958ee5 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
@@ -213,6 +213,9 @@ public class AuthContainerView extends LinearLayout
case AuthBiometricView.Callback.ACTION_START_DELAYED_FINGERPRINT_SENSOR:
mConfig.mCallback.onStartFingerprintNow(getRequestId());
break;
+ case AuthBiometricView.Callback.ACTION_AUTHENTICATED_AND_CONFIRMED:
+ animateAway(AuthDialogCallback.DISMISSED_BUTTON_POSITIVE);
+ break;
default:
Log.e(TAG, "Unhandled action: " + action);
}
diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt
index e60063248fb0..fb19ac99d19e 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt
@@ -217,7 +217,6 @@ open class ControlsProviderSelectorActivity @Inject constructor(
)
}
startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(this).toBundle())
- animateExitAndFinish()
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/DetailDialog.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/DetailDialog.kt
index 7cbd1f53612b..be50a1468f07 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/DetailDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/DetailDialog.kt
@@ -162,7 +162,11 @@ class DetailDialog(
broadcastSender.closeSystemDialogs()
// not sent as interactive, lest the higher-importance activity launch
// be impacted
- pendingIntent.send()
+ val options = ActivityOptions.makeBasic()
+ .setPendingIntentBackgroundActivityStartMode(
+ ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED)
+ .toBundle()
+ pendingIntent.send(options)
false
}
if (keyguardStateController.isUnlocked()) {
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/StatusBehavior.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/StatusBehavior.kt
index 116f3ca898c0..84cda5a541e3 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/StatusBehavior.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/StatusBehavior.kt
@@ -16,6 +16,7 @@
package com.android.systemui.controls.ui
+import android.app.ActivityOptions
import android.app.AlertDialog
import android.app.PendingIntent
import android.content.DialogInterface
@@ -74,7 +75,11 @@ class StatusBehavior : Behavior {
R.string.controls_open_app,
DialogInterface.OnClickListener { dialog, _ ->
try {
- cws.control?.getAppIntent()?.send()
+ val options = ActivityOptions.makeBasic()
+ .setPendingIntentBackgroundActivityStartMode(
+ ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED)
+ .toBundle()
+ cws.control?.getAppIntent()?.send(options)
context.sendBroadcast(Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS))
} catch (e: PendingIntent.CanceledException) {
cvh.setErrorStatus()
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
index d6c082928168..e5fa2090bf0f 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
@@ -138,7 +138,7 @@ object Flags {
// TODO(b/275694445): Tracking Bug
@JvmField
- val LOCKSCREEN_WITHOUT_SECURE_LOCK_WHEN_DREAMING = unreleasedFlag(208,
+ val LOCKSCREEN_WITHOUT_SECURE_LOCK_WHEN_DREAMING = releasedFlag(208,
"lockscreen_without_secure_lock_when_dreaming")
/**
@@ -678,7 +678,7 @@ object Flags {
// TODO(b/283071711): Tracking bug
@JvmField
val TRIM_RESOURCES_WITH_BACKGROUND_TRIM_AT_LOCK =
- unreleasedFlag(2401, "trim_resources_with_background_trim_on_lock")
+ releasedFlag(2401, "trim_resources_with_background_trim_on_lock")
// TODO:(b/283203305): Tracking bug
@JvmField
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
index a8d22c48e709..5a8c2253b185 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
@@ -29,6 +29,7 @@ import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_OCCLUDE;
import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_OCCLUDE_BY_DREAM;
import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_UNOCCLUDE;
import static android.view.WindowManager.TRANSIT_OLD_NONE;
+import static android.view.WindowManager.TRANSIT_TO_BACK;
import static android.view.WindowManager.TransitionFlags;
import static android.view.WindowManager.TransitionOldType;
import static android.view.WindowManager.TransitionType;
@@ -49,6 +50,7 @@ import android.os.RemoteException;
import android.os.Trace;
import android.util.ArrayMap;
import android.util.Log;
+import android.util.RotationUtils;
import android.util.Slog;
import android.view.IRemoteAnimationFinishedCallback;
import android.view.IRemoteAnimationRunner;
@@ -73,6 +75,7 @@ import com.android.systemui.SystemUIApplication;
import com.android.systemui.settings.DisplayTracker;
import com.android.wm.shell.transition.ShellTransitions;
import com.android.wm.shell.transition.Transitions;
+import com.android.wm.shell.util.CounterRotator;
import com.android.wm.shell.util.TransitionUtil;
import java.util.ArrayList;
@@ -103,7 +106,8 @@ public class KeyguardService extends Service {
}
private static RemoteAnimationTarget[] wrap(TransitionInfo info, boolean wallpapers,
- SurfaceControl.Transaction t, ArrayMap<SurfaceControl, SurfaceControl> leashMap) {
+ SurfaceControl.Transaction t, ArrayMap<SurfaceControl, SurfaceControl> leashMap,
+ CounterRotator counterWallpaper) {
final ArrayList<RemoteAnimationTarget> out = new ArrayList<>();
for (int i = 0; i < info.getChanges().size(); i++) {
boolean changeIsWallpaper =
@@ -133,6 +137,25 @@ public class KeyguardService extends Service {
(change.getFlags() & TransitionInfo.FLAG_SHOW_WALLPAPER) != 0,
info, t, leashMap);
+ if (changeIsWallpaper) {
+ int rotateDelta = RotationUtils.deltaRotation(change.getStartRotation(),
+ change.getEndRotation());
+ if (rotateDelta != 0 && change.getParent() != null
+ && change.getMode() == TRANSIT_TO_BACK) {
+ final TransitionInfo.Change parent = info.getChange(change.getParent());
+ if (parent != null) {
+ float displayW = parent.getEndAbsBounds().width();
+ float displayH = parent.getEndAbsBounds().height();
+ counterWallpaper.setup(t, parent.getLeash(), rotateDelta, displayW,
+ displayH);
+ }
+ if (counterWallpaper.getSurface() != null) {
+ t.setLayer(counterWallpaper.getSurface(), -1);
+ counterWallpaper.addChild(t, leashMap.get(change.getLeash()));
+ }
+ }
+ }
+
out.add(target);
}
return out.toArray(new RemoteAnimationTarget[out.size()]);
@@ -163,6 +186,8 @@ public class KeyguardService extends Service {
return new IRemoteTransition.Stub() {
private final ArrayMap<SurfaceControl, SurfaceControl> mLeashMap = new ArrayMap<>();
+ private final CounterRotator mCounterRotator = new CounterRotator();
+
@GuardedBy("mLeashMap")
private IRemoteTransitionFinishedCallback mFinishCallback = null;
@@ -175,9 +200,9 @@ public class KeyguardService extends Service {
synchronized (mLeashMap) {
final RemoteAnimationTarget[] apps =
- wrap(info, false /* wallpapers */, t, mLeashMap);
+ wrap(info, false /* wallpapers */, t, mLeashMap, mCounterRotator);
final RemoteAnimationTarget[] wallpapers =
- wrap(info, true /* wallpapers */, t, mLeashMap);
+ wrap(info, true /* wallpapers */, t, mLeashMap, mCounterRotator);
final RemoteAnimationTarget[] nonApps = new RemoteAnimationTarget[0];
// Set alpha back to 1 for the independent changes because we will be animating
@@ -231,11 +256,19 @@ public class KeyguardService extends Service {
@GuardedBy("mLeashMap")
private void finish() throws RemoteException {
+ SurfaceControl.Transaction finishTransaction = null;
+ if (mCounterRotator.getSurface() != null
+ && mCounterRotator.getSurface().isValid()) {
+ finishTransaction = new SurfaceControl.Transaction();
+ mCounterRotator.cleanUp(finishTransaction);
+ }
mLeashMap.clear();
final IRemoteTransitionFinishedCallback finishCallback = mFinishCallback;
if (finishCallback != null) {
mFinishCallback = null;
- finishCallback.onTransitionFinished(null /* wct */, null /* t */);
+ finishCallback.onTransitionFinished(null /* wct */, finishTransaction);
+ } else if (finishTransaction != null) {
+ finishTransaction.apply();
}
}
};
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 45e4623c7e27..3b40d8602e6f 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -1602,9 +1602,9 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
final ContentResolver cr = mContext.getContentResolver();
// From SecuritySettings
- final long lockAfterTimeout = Settings.Secure.getInt(cr,
+ final long lockAfterTimeout = Settings.Secure.getIntForUser(cr,
Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT,
- KEYGUARD_LOCK_AFTER_DELAY_DEFAULT);
+ KEYGUARD_LOCK_AFTER_DELAY_DEFAULT, userId);
// From DevicePolicyAdmin
final long policyTimeout = mLockPatternUtils.getDevicePolicyManager()
@@ -1616,8 +1616,8 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
timeout = lockAfterTimeout;
} else {
// From DisplaySettings
- long displayTimeout = Settings.System.getInt(cr, SCREEN_OFF_TIMEOUT,
- KEYGUARD_DISPLAY_TIMEOUT_DELAY_DEFAULT);
+ long displayTimeout = Settings.System.getIntForUser(cr, SCREEN_OFF_TIMEOUT,
+ KEYGUARD_DISPLAY_TIMEOUT_DELAY_DEFAULT, userId);
// policy in effect. Make sure we don't go beyond policy limit.
displayTimeout = Math.max(displayTimeout, 0); // ignore negative values
@@ -2469,7 +2469,10 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
private void playSound(int soundId) {
if (soundId == 0) return;
final ContentResolver cr = mContext.getContentResolver();
- if (Settings.System.getInt(cr, Settings.System.LOCKSCREEN_SOUNDS_ENABLED, 1) == 1) {
+ int lockscreenSoundsEnabled = Settings.System.getIntForUser(cr,
+ Settings.System.LOCKSCREEN_SOUNDS_ENABLED, 1,
+ KeyguardUpdateMonitor.getCurrentUser());
+ if (lockscreenSoundsEnabled == 1) {
mLockSounds.stop(mLockSoundStreamId);
// Init mAudioManager
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/CameraQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/CameraQuickAffordanceConfig.kt
index c9f645dddd8d..af0abdff0c62 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/CameraQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/CameraQuickAffordanceConfig.kt
@@ -52,8 +52,7 @@ constructor(
override val key: String
get() = BuiltInKeyguardQuickAffordanceKeys.CAMERA
- override val pickerName: String
- get() = context.getString(R.string.accessibility_camera_button)
+ override fun pickerName(): String = context.getString(R.string.accessibility_camera_button)
override val pickerIconResourceId: Int
get() = R.drawable.ic_camera
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfig.kt
index ef0c9a175141..16385ec59aa7 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfig.kt
@@ -99,7 +99,7 @@ constructor(
override val key: String = BuiltInKeyguardQuickAffordanceKeys.DO_NOT_DISTURB
- override val pickerName: String = context.getString(R.string.quick_settings_dnd_label)
+ override fun pickerName(): String = context.getString(R.string.quick_settings_dnd_label)
override val pickerIconResourceId: Int = R.drawable.ic_do_not_disturb
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfig.kt
index 3412f35669e3..ed8823a53fe2 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfig.kt
@@ -75,8 +75,7 @@ constructor(
override val key: String
get() = BuiltInKeyguardQuickAffordanceKeys.FLASHLIGHT
- override val pickerName: String
- get() = context.getString(R.string.quick_settings_flashlight_label)
+ override fun pickerName(): String = context.getString(R.string.quick_settings_flashlight_label)
override val pickerIconResourceId: Int
get() = R.drawable.ic_flashlight_off
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfig.kt
index a1e9137d1764..abb63c4d34ce 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfig.kt
@@ -54,7 +54,7 @@ constructor(
override val key: String = BuiltInKeyguardQuickAffordanceKeys.HOME_CONTROLS
- override val pickerName: String by lazy { context.getString(component.getTileTitleId()) }
+ override fun pickerName(): String = context.getString(component.getTileTitleId())
override val pickerIconResourceId: Int by lazy { component.getTileImageId() }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceConfig.kt
index e32edcb010e8..28dc5bdcc45f 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceConfig.kt
@@ -31,8 +31,6 @@ interface KeyguardQuickAffordanceConfig {
/** Unique identifier for this quick affordance. It must be globally unique. */
val key: String
- val pickerName: String
-
val pickerIconResourceId: Int
/**
@@ -43,6 +41,12 @@ interface KeyguardQuickAffordanceConfig {
val lockScreenState: Flow<LockScreenState>
/**
+ * Returns a user-visible [String] that should be shown as the name for the option in the
+ * wallpaper picker / settings app to select this quick affordance.
+ */
+ fun pickerName(): String
+
+ /**
* Returns the [PickerScreenState] representing the affordance in the settings or selector
* experience.
*/
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceConfig.kt
index da91572894f3..250356819baf 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceConfig.kt
@@ -34,6 +34,7 @@ import com.android.systemui.keyguard.shared.quickaffordance.ActivationState
import com.android.systemui.settings.UserFileManager
import com.android.systemui.settings.UserTracker
import com.android.systemui.util.RingerModeTracker
+import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.channels.awaitClose
@@ -45,30 +46,32 @@ import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
-import javax.inject.Inject
@SysUISingleton
-class MuteQuickAffordanceConfig @Inject constructor(
- context: Context,
- private val userTracker: UserTracker,
- private val userFileManager: UserFileManager,
- private val ringerModeTracker: RingerModeTracker,
- private val audioManager: AudioManager,
- @Application private val coroutineScope: CoroutineScope,
- @Main private val mainDispatcher: CoroutineDispatcher,
- @Background private val backgroundDispatcher: CoroutineDispatcher,
+class MuteQuickAffordanceConfig
+@Inject
+constructor(
+ private val context: Context,
+ private val userTracker: UserTracker,
+ private val userFileManager: UserFileManager,
+ private val ringerModeTracker: RingerModeTracker,
+ private val audioManager: AudioManager,
+ @Application private val coroutineScope: CoroutineScope,
+ @Main private val mainDispatcher: CoroutineDispatcher,
+ @Background private val backgroundDispatcher: CoroutineDispatcher,
) : KeyguardQuickAffordanceConfig {
private var previousNonSilentMode: Int = DEFAULT_LAST_NON_SILENT_VALUE
override val key: String = BuiltInKeyguardQuickAffordanceKeys.MUTE
- override val pickerName: String = context.getString(R.string.volume_ringer_status_silent)
+ override fun pickerName(): String = context.getString(R.string.volume_ringer_status_silent)
override val pickerIconResourceId: Int = R.drawable.ic_notifications_silence
override val lockScreenState: Flow<KeyguardQuickAffordanceConfig.LockScreenState> =
- ringerModeTracker.ringerModeInternal.asFlow()
+ ringerModeTracker.ringerModeInternal
+ .asFlow()
.onStart { getLastNonSilentRingerMode() }
.distinctUntilChanged()
.onEach { mode ->
@@ -78,17 +81,14 @@ class MuteQuickAffordanceConfig @Inject constructor(
}
}
.map { mode ->
- val (activationState, contentDescriptionRes) = when {
- audioManager.isVolumeFixed ->
- ActivationState.NotSupported to
- R.string.volume_ringer_hint_mute
- mode == AudioManager.RINGER_MODE_SILENT ->
- ActivationState.Active to
- R.string.volume_ringer_hint_mute
- else ->
- ActivationState.Inactive to
- R.string.volume_ringer_hint_unmute
- }
+ val (activationState, contentDescriptionRes) =
+ when {
+ audioManager.isVolumeFixed ->
+ ActivationState.NotSupported to R.string.volume_ringer_hint_mute
+ mode == AudioManager.RINGER_MODE_SILENT ->
+ ActivationState.Active to R.string.volume_ringer_hint_mute
+ else -> ActivationState.Inactive to R.string.volume_ringer_hint_unmute
+ }
KeyguardQuickAffordanceConfig.LockScreenState.Visible(
Icon.Resource(
@@ -130,32 +130,35 @@ class MuteQuickAffordanceConfig @Inject constructor(
}
/**
- * Gets the last non-silent ringer mode from shared-preferences if it exists. This is
- * cached by [MuteQuickAffordanceCoreStartable] while this affordance is selected
+ * Gets the last non-silent ringer mode from shared-preferences if it exists. This is cached by
+ * [MuteQuickAffordanceCoreStartable] while this affordance is selected
*/
private suspend fun getLastNonSilentRingerMode(): Int =
withContext(backgroundDispatcher) {
- userFileManager.getSharedPreferences(
+ userFileManager
+ .getSharedPreferences(
MUTE_QUICK_AFFORDANCE_PREFS_FILE_NAME,
Context.MODE_PRIVATE,
userTracker.userId
- ).getInt(
+ )
+ .getInt(
LAST_NON_SILENT_RINGER_MODE_KEY,
ringerModeTracker.ringerModeInternal.value ?: DEFAULT_LAST_NON_SILENT_VALUE
- )
+ )
}
private fun <T> LiveData<T>.asFlow(): Flow<T?> =
conflatedCallbackFlow {
- val observer = Observer { value: T -> trySend(value) }
- observeForever(observer)
- send(value)
- awaitClose { removeObserver(observer) }
- }.flowOn(mainDispatcher)
+ val observer = Observer { value: T -> trySend(value) }
+ observeForever(observer)
+ send(value)
+ awaitClose { removeObserver(observer) }
+ }
+ .flowOn(mainDispatcher)
companion object {
const val LAST_NON_SILENT_RINGER_MODE_KEY = "key_last_non_silent_ringer_mode"
const val MUTE_QUICK_AFFORDANCE_PREFS_FILE_NAME = "quick_affordance_mute_ringer_mode_cache"
private const val DEFAULT_LAST_NON_SILENT_VALUE = AudioManager.RINGER_MODE_NORMAL
}
-} \ No newline at end of file
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfig.kt
index ea6c107cd161..0d54ab9adb4a 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfig.kt
@@ -42,7 +42,7 @@ constructor(
override val key: String = BuiltInKeyguardQuickAffordanceKeys.QR_CODE_SCANNER
- override val pickerName = context.getString(R.string.qr_code_scanner_title)
+ override fun pickerName(): String = context.getString(R.string.qr_code_scanner_title)
override val pickerIconResourceId = R.drawable.ic_qr_code_scanner
@@ -53,6 +53,7 @@ constructor(
override fun onQRCodeScannerActivityChanged() {
trySendWithFailureLogging(state(), TAG)
}
+
override fun onQRCodeScannerPreferenceChanged() {
trySendWithFailureLogging(state(), TAG)
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfig.kt
index 12270784adca..44e74e7e339b 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfig.kt
@@ -51,7 +51,7 @@ constructor(
override val key: String = BuiltInKeyguardQuickAffordanceKeys.QUICK_ACCESS_WALLET
- override val pickerName: String = context.getString(R.string.accessibility_wallet_button)
+ override fun pickerName(): String = context.getString(R.string.accessibility_wallet_button)
override val pickerIconResourceId = R.drawable.ic_wallet_lockscreen
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/VideoCameraQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/VideoCameraQuickAffordanceConfig.kt
index 6f821a2b5228..1ccc689da368 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/VideoCameraQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/VideoCameraQuickAffordanceConfig.kt
@@ -62,8 +62,7 @@ constructor(
override val key: String
get() = BuiltInKeyguardQuickAffordanceKeys.VIDEO_CAMERA
- override val pickerName: String
- get() = context.getString(R.string.video_camera)
+ override fun pickerName(): String = context.getString(R.string.video_camera)
override val pickerIconResourceId: Int
get() = R.drawable.ic_videocam
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepository.kt
index ab4abbf3d575..96c94d7d64b6 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepository.kt
@@ -170,7 +170,7 @@ constructor(
pickerState as? KeyguardQuickAffordanceConfig.PickerScreenState.Disabled
KeyguardQuickAffordancePickerRepresentation(
id = config.key,
- name = config.pickerName,
+ name = config.pickerName(),
iconResourceId = config.pickerIconResourceId,
isEnabled =
pickerState is KeyguardQuickAffordanceConfig.PickerScreenState.Default,
@@ -234,7 +234,9 @@ constructor(
pw.println(" $slotId$selectionText (capacity = $capacity)")
}
pw.println("Available affordances on device:")
- configs.forEach { config -> pw.println(" ${config.key} (\"${config.pickerName}\")") }
+ configs.forEach { config ->
+ pw.println(" ${config.key} (\"${config.pickerName()}\")")
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
index fe62bf4388e9..db231092d7a5 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
@@ -17,7 +17,7 @@
package com.android.systemui.keyguard.ui.preview
-import android.annotation.ColorInt
+import android.app.WallpaperColors
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
@@ -47,6 +47,7 @@ import com.android.systemui.keyguard.ui.binder.KeyguardPreviewSmartspaceViewBind
import com.android.systemui.keyguard.ui.viewmodel.KeyguardBottomAreaViewModel
import com.android.systemui.keyguard.ui.viewmodel.KeyguardPreviewClockViewModel
import com.android.systemui.keyguard.ui.viewmodel.KeyguardPreviewSmartspaceViewModel
+import com.android.systemui.monet.ColorScheme
import com.android.systemui.plugins.ClockController
import com.android.systemui.shared.clocks.ClockRegistry
import com.android.systemui.shared.clocks.DefaultClockController
@@ -91,6 +92,7 @@ constructor(
/** [shouldHideClock] here means that we never create and bind the clock views */
private val shouldHideClock: Boolean =
bundle.getBoolean(ClockPreviewConstants.KEY_HIDE_CLOCK, false)
+ private val wallpaperColors: WallpaperColors? = bundle.getParcelable(KEY_COLORS)
private var host: SurfaceControlViewHost
@@ -100,7 +102,6 @@ constructor(
private lateinit var largeClockHostView: FrameLayout
private lateinit var smallClockHostView: FrameLayout
private var smartSpaceView: View? = null
- private var colorOverride: Int? = null
private val disposables = mutableSetOf<DisposableHandle>()
private var isDestroyed = false
@@ -172,6 +173,10 @@ constructor(
rootView.translationX = (width - scale * rootView.width) / 2
rootView.translationY = (height - scale * rootView.height) / 2
+ if (isDestroyed) {
+ return@post
+ }
+
host.setView(rootView, rootView.measuredWidth, rootView.measuredHeight)
}
}
@@ -195,14 +200,6 @@ constructor(
mainHandler.post { smartSpaceView?.visibility = if (hide) View.INVISIBLE else View.VISIBLE }
}
- /** Sets the clock's color to the overridden seed color. */
- fun onColorOverridden(@ColorInt color: Int?) {
- mainHandler.post {
- colorOverride = color
- clockController.clock?.run { events.onSeedColorChanged(color) }
- }
- }
-
/**
* This sets up and shows a non-interactive smart space
*
@@ -395,7 +392,24 @@ constructor(
val clock = clockRegistry.createCurrentClock()
clockController.clock = clock
- colorOverride?.let { clock.events.onSeedColorChanged(it) }
+ if (clockRegistry.seedColor == null) {
+ // Seed color null means users do override any color on the clock. The default color
+ // will need to use wallpaper's extracted color and consider if the wallpaper's color
+ // is dark or a light.
+ // TODO(b/277832214) we can potentially simplify this code by checking for
+ // wallpaperColors being null in the if clause above and removing the many ?.
+ val wallpaperColorScheme =
+ wallpaperColors?.let { ColorScheme(it, /* darkTheme= */ false) }
+ val lightClockColor = wallpaperColorScheme?.accent1?.s100
+ val darkClockColor = wallpaperColorScheme?.accent2?.s600
+ /** Note that when [wallpaperColors] is null, isWallpaperDark is true. */
+ val isWallpaperDark: Boolean =
+ (wallpaperColors?.colorHints?.and(WallpaperColors.HINT_SUPPORTS_DARK_TEXT)) !=
+ WallpaperColors.HINT_SUPPORTS_DARK_TEXT
+ clock.events.onSeedColorChanged(
+ if (isWallpaperDark) lightClockColor else darkClockColor
+ )
+ }
updateLargeClock(clock)
updateSmallClock(clock)
@@ -428,6 +442,7 @@ constructor(
private const val KEY_VIEW_WIDTH = "width"
private const val KEY_VIEW_HEIGHT = "height"
private const val KEY_DISPLAY_ID = "display_id"
+ private const val KEY_COLORS = "wallpaper_colors"
private const val DIM_ALPHA = 0.3f
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardRemotePreviewManager.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardRemotePreviewManager.kt
index 79712f9c6be5..dafeacef60bb 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardRemotePreviewManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardRemotePreviewManager.kt
@@ -124,13 +124,6 @@ constructor(
message.data.getBoolean(KeyguardPreviewConstants.KEY_HIDE_SMART_SPACE)
)
}
- KeyguardPreviewConstants.MESSAGE_ID_COLOR_OVERRIDE -> {
- renderer.onColorOverridden(
- message.data
- .getString(KeyguardPreviewConstants.KEY_COLOR_OVERRIDE)
- ?.toIntOrNull()
- )
- }
else -> requestDestruction(this)
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
index 316c903eed5b..88ffa8da666b 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
@@ -28,6 +28,7 @@ import android.os.Build;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
+import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.CheckBox;
import android.widget.TextView;
@@ -151,6 +152,7 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {
mCurrentActivePosition = -1;
}
mStatusIcon.setVisibility(View.GONE);
+ enableFocusPropertyForView(mContainerLayout);
if (mController.isAnyDeviceTransferring()) {
if (device.getState() == MediaDeviceState.STATE_CONNECTING
@@ -250,7 +252,8 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {
mController.getColorItemContent());
updateGroupableCheckBox(true, isDeviceDeselectable, device);
updateEndClickArea(device, isDeviceDeselectable);
- setUpContentDescriptionForView(mContainerLayout, false, device);
+ disableFocusPropertyForView(mContainerLayout);
+ setUpContentDescriptionForView(mSeekBar, device);
setSingleLineLayout(getItemTitle(device), true /* showSeekBar */,
false /* showProgressBar */, true /* showCheckBox */,
true /* showEndTouchArea */);
@@ -274,7 +277,8 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {
mController.getDeselectableMediaDevice(), device);
updateGroupableCheckBox(true, isDeviceDeselectable, device);
updateEndClickArea(device, isDeviceDeselectable);
- setUpContentDescriptionForView(mContainerLayout, false, device);
+ disableFocusPropertyForView(mContainerLayout);
+ setUpContentDescriptionForView(mSeekBar, device);
setSingleLineLayout(getItemTitle(device), true /* showSeekBar */,
false /* showProgressBar */, true /* showCheckBox */,
true /* showEndTouchArea */);
@@ -282,7 +286,8 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {
} else {
updateTitleIcon(R.drawable.media_output_icon_volume,
mController.getColorItemContent());
- setUpContentDescriptionForView(mContainerLayout, false, device);
+ disableFocusPropertyForView(mContainerLayout);
+ setUpContentDescriptionForView(mSeekBar, device);
mCurrentActivePosition = position;
setSingleLineLayout(getItemTitle(device), true /* showSeekBar */,
false /* showProgressBar */, false /* showCheckBox */,
@@ -390,7 +395,7 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {
View.IMPORTANT_FOR_ACCESSIBILITY_YES);
mEndTouchArea.setBackgroundTintList(
ColorStateList.valueOf(mController.getColorItemBackground()));
- setUpContentDescriptionForView(mEndTouchArea, true, device);
+ setUpContentDescriptionForView(mEndTouchArea, device);
}
private void updateGroupableCheckBox(boolean isSelected, boolean isGroupable,
@@ -471,14 +476,29 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {
notifyDataSetChanged();
}
- private void setUpContentDescriptionForView(View view, boolean clickable,
- MediaDevice device) {
- view.setClickable(clickable);
+ private void disableFocusPropertyForView(View view) {
+ view.setFocusable(false);
+ view.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
+ }
+
+ private void enableFocusPropertyForView(View view) {
+ view.setFocusable(true);
+ view.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_AUTO);
+ }
+
+ private void setUpContentDescriptionForView(View view, MediaDevice device) {
view.setContentDescription(
mContext.getString(device.getDeviceType()
== MediaDevice.MediaDeviceType.TYPE_BLUETOOTH_DEVICE
? R.string.accessibility_bluetooth_name
: R.string.accessibility_cast_name, device.getName()));
+ view.setAccessibilityDelegate(new View.AccessibilityDelegate() {
+ public void onInitializeAccessibilityNodeInfo(View host,
+ AccessibilityNodeInfo info) {
+ super.onInitializeAccessibilityNodeInfo(host, info);
+ host.setOnClickListener(null);
+ }
+ });
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfig.kt
index 444407c2341a..0ce20cdbe63d 100644
--- a/packages/SystemUI/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfig.kt
@@ -73,7 +73,7 @@ constructor(
private val pickerNameResourceId = R.string.note_task_button_label
- override val pickerName: String = context.getString(pickerNameResourceId)
+ override fun pickerName(): String = context.getString(pickerNameResourceId)
override val pickerIconResourceId = R.drawable.ic_note_task_shortcut_keyguard
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialog.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialog.java
index 380b85cb5504..ad658458d330 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialog.java
@@ -20,7 +20,6 @@ import static com.android.systemui.qs.tiles.dialog.InternetDialogController.MAX_
import android.app.AlertDialog;
import android.content.Context;
-import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.net.Network;
import android.net.NetworkCapabilities;
@@ -58,7 +57,6 @@ import androidx.recyclerview.widget.RecyclerView;
import com.android.internal.logging.UiEvent;
import com.android.internal.logging.UiEventLogger;
-import com.android.settingslib.Utils;
import com.android.settingslib.wifi.WifiEnterpriseRestrictionUtils;
import com.android.systemui.Prefs;
import com.android.systemui.R;
@@ -419,14 +417,6 @@ public class InternetDialog extends SystemUIDialog implements
});
});
- TypedArray array = mContext.obtainStyledAttributes(
- R.style.InternetDialog_Divider_Active, new int[]{android.R.attr.background});
- int dividerColor = Utils.getColorAttrDefaultColor(mContext,
- android.R.attr.textColorSecondary);
- mMobileToggleDivider.setBackgroundColor(isNetworkConnected
- ? array.getColor(0, dividerColor) : dividerColor);
- array.recycle();
-
mMobileDataToggle.setVisibility(mCanConfigMobileData ? View.VISIBLE : View.INVISIBLE);
mMobileToggleDivider.setVisibility(
mCanConfigMobileData ? View.VISIBLE : View.INVISIBLE);
diff --git a/packages/SystemUI/src/com/android/systemui/smartspace/dagger/SmartspaceViewComponent.kt b/packages/SystemUI/src/com/android/systemui/smartspace/dagger/SmartspaceViewComponent.kt
index ba9d13d57a74..6d951bf4d83b 100644
--- a/packages/SystemUI/src/com/android/systemui/smartspace/dagger/SmartspaceViewComponent.kt
+++ b/packages/SystemUI/src/com/android/systemui/smartspace/dagger/SmartspaceViewComponent.kt
@@ -15,6 +15,7 @@
*/
package com.android.systemui.smartspace.dagger
+import android.app.ActivityOptions
import android.app.PendingIntent
import android.content.Intent
import android.view.View
@@ -81,7 +82,11 @@ interface SmartspaceViewComponent {
showOnLockscreen: Boolean
) {
if (showOnLockscreen) {
- pi.send()
+ val options = ActivityOptions.makeBasic()
+ .setPendingIntentBackgroundActivityStartMode(
+ ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED)
+ .toBundle()
+ pi.send(options)
} else {
activityStarter.startPendingIntentDismissingKeyguard(pi)
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt
index 7cc917f3b0b8..518825cea5e0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt
@@ -16,6 +16,7 @@
package com.android.systemui.statusbar.lockscreen
+import android.app.ActivityOptions
import android.app.PendingIntent
import android.app.smartspace.SmartspaceConfig
import android.app.smartspace.SmartspaceManager
@@ -358,7 +359,11 @@ constructor(
showOnLockscreen: Boolean
) {
if (showOnLockscreen) {
- pi.send()
+ val options = ActivityOptions.makeBasic()
+ .setPendingIntentBackgroundActivityStartMode(
+ ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED)
+ .toBundle()
+ pi.send(options)
} else {
activityStarter.postStartActivityDismissingKeyguard(pi)
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterImpl.kt
index df1a47abea98..1827a46958f8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterImpl.kt
@@ -572,6 +572,9 @@ constructor(
// TODO b/221255671: restrict this to only be set for
// notifications
options.isEligibleForLegacyPermissionPrompt = true
+ options.setPendingIntentBackgroundActivityStartMode(
+ ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED
+ )
return intent.sendAndReturnResult(
null,
0,
diff --git a/packages/SystemUI/src/com/android/systemui/theme/DynamicColors.kt b/packages/SystemUI/src/com/android/systemui/theme/DynamicColors.kt
index 57b9f914d4d6..ae4820837ce5 100644
--- a/packages/SystemUI/src/com/android/systemui/theme/DynamicColors.kt
+++ b/packages/SystemUI/src/com/android/systemui/theme/DynamicColors.kt
@@ -18,10 +18,11 @@ package com.android.systemui.theme
import android.util.Pair
import com.android.systemui.monet.dynamiccolor.DynamicColor
-import com.android.systemui.monet.dynamiccolor.MaterialDynamicColors as MDC
+import com.android.systemui.monet.dynamiccolor.MaterialDynamicColors
class DynamicColors {
companion object {
+ private val MDC = MaterialDynamicColors()
@JvmField
val ALL_DYNAMIC_COLORS_MAPPED: List<Pair<String, DynamicColor>> =
arrayListOf(
diff --git a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
index c1999b284553..b78329cfa5aa 100644
--- a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
+++ b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
@@ -659,6 +659,7 @@ public class ThemeOverlayController implements CoreStartable, Dumpable {
Resources res = userHandle.isSystem()
? mResources : mContext.createContextAsUser(userHandle, 0).getResources();
Resources.Theme theme = mContext.getTheme();
+ MaterialDynamicColors dynamicColors = new MaterialDynamicColors();
if (!(res.getColor(android.R.color.system_accent1_500, theme)
== mColorScheme.getAccent1().getS500()
&& res.getColor(android.R.color.system_accent2_500, theme)
@@ -670,15 +671,15 @@ public class ThemeOverlayController implements CoreStartable, Dumpable {
&& res.getColor(android.R.color.system_neutral2_500, theme)
== mColorScheme.getNeutral2().getS500()
&& res.getColor(android.R.color.system_outline_variant_dark, theme)
- == MaterialDynamicColors.outlineVariant().getArgb(mDynamicSchemeDark)
+ == dynamicColors.outlineVariant().getArgb(mDynamicSchemeDark)
&& res.getColor(android.R.color.system_outline_variant_light, theme)
- == MaterialDynamicColors.outlineVariant().getArgb(mDynamicSchemeLight)
+ == dynamicColors.outlineVariant().getArgb(mDynamicSchemeLight)
&& res.getColor(android.R.color.system_primary_container_dark, theme)
- == MaterialDynamicColors.primaryContainer().getArgb(mDynamicSchemeDark)
+ == dynamicColors.primaryContainer().getArgb(mDynamicSchemeDark)
&& res.getColor(android.R.color.system_primary_container_light, theme)
- == MaterialDynamicColors.primaryContainer().getArgb(mDynamicSchemeLight)
+ == dynamicColors.primaryContainer().getArgb(mDynamicSchemeLight)
&& res.getColor(android.R.color.system_primary_fixed, theme)
- == MaterialDynamicColors.primaryFixed().getArgb(mDynamicSchemeLight))) {
+ == dynamicColors.primaryFixed().getArgb(mDynamicSchemeLight))) {
return false;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/unfold/UnfoldTransitionModule.kt b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldTransitionModule.kt
index 2709da38a7d8..992b0221068c 100644
--- a/packages/SystemUI/src/com/android/systemui/unfold/UnfoldTransitionModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldTransitionModule.kt
@@ -18,16 +18,19 @@ package com.android.systemui.unfold
import android.content.Context
import android.hardware.devicestate.DeviceStateManager
+import android.os.SystemProperties
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.keyguard.LifecycleScreenStatusProvider
import com.android.systemui.unfold.config.UnfoldTransitionConfig
import com.android.systemui.unfold.system.SystemUnfoldSharedModule
+import com.android.systemui.unfold.updates.FoldProvider
import com.android.systemui.unfold.updates.FoldStateProvider
import com.android.systemui.unfold.updates.RotationChangeProvider
import com.android.systemui.unfold.updates.screen.ScreenStatusProvider
import com.android.systemui.unfold.util.NaturalRotationUnfoldProgressProvider
import com.android.systemui.unfold.util.ScopedUnfoldTransitionProgressProvider
+import com.android.systemui.unfold.util.UnfoldOnlyProgressProvider
import com.android.systemui.unfold.util.UnfoldTransitionATracePrefix
import com.android.systemui.util.time.SystemClockImpl
import com.android.wm.shell.unfold.ShellUnfoldProgressProvider
@@ -37,6 +40,7 @@ import dagger.Provides
import java.util.Optional
import java.util.concurrent.Executor
import javax.inject.Named
+import javax.inject.Provider
import javax.inject.Singleton
@Module(includes = [UnfoldSharedModule::class, SystemUnfoldSharedModule::class])
@@ -91,6 +95,18 @@ class UnfoldTransitionModule {
}
@Provides
+ @Singleton
+ @Named(UNFOLD_ONLY_PROVIDER)
+ fun provideUnfoldOnlyProvider(
+ foldProvider: FoldProvider,
+ @Main executor: Executor,
+ sourceProvider: Optional<UnfoldTransitionProgressProvider>
+ ): Optional<UnfoldTransitionProgressProvider> =
+ sourceProvider.map { provider ->
+ UnfoldOnlyProgressProvider(foldProvider, executor, provider)
+ }
+
+ @Provides
@Named(UNFOLD_STATUS_BAR)
@Singleton
fun provideStatusBarScopedTransitionProvider(
@@ -102,16 +118,35 @@ class UnfoldTransitionModule {
@Singleton
fun provideShellProgressProvider(
config: UnfoldTransitionConfig,
- provider: Optional<UnfoldTransitionProgressProvider>
- ): ShellUnfoldProgressProvider =
- if (config.isEnabled && provider.isPresent) {
- UnfoldProgressProvider(provider.get())
- } else {
- ShellUnfoldProgressProvider.NO_PROVIDER
- }
+ provider: Provider<Optional<UnfoldTransitionProgressProvider>>,
+ @Named(UNFOLD_ONLY_PROVIDER)
+ unfoldOnlyProvider: Provider<Optional<UnfoldTransitionProgressProvider>>
+ ): ShellUnfoldProgressProvider {
+ val resultingProvider =
+ if (config.isEnabled) {
+ // Return unfold only provider to the shell if we don't want to animate tasks during
+ // folding. Shell provider listeners are responsible for animating task bounds.
+ if (ENABLE_FOLD_TASK_ANIMATIONS) {
+ provider
+ } else {
+ unfoldOnlyProvider
+ }
+ } else {
+ null
+ }
+
+ return resultingProvider?.get()?.orElse(null)?.let(::UnfoldProgressProvider)
+ ?: ShellUnfoldProgressProvider.NO_PROVIDER
+ }
@Provides
fun screenStatusProvider(impl: LifecycleScreenStatusProvider): ScreenStatusProvider = impl
}
const val UNFOLD_STATUS_BAR = "unfold_status_bar"
+const val UNFOLD_ONLY_PROVIDER = "unfold_only_provider"
+
+// TODO: b/265764985 - tracking bug to clean-up the flag
+// FeatureFlags are not accessible here because it's a global submodule (see GlobalModule.java)
+private val ENABLE_FOLD_TASK_ANIMATIONS =
+ SystemProperties.getBoolean("persist.unfold.enable_fold_tasks_animation", false)
diff --git a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletView.java b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletView.java
index dfc6392404a4..cab47a3c4b4b 100644
--- a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletView.java
+++ b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletView.java
@@ -307,6 +307,8 @@ public class WalletView extends FrameLayout implements WalletCardCarousel.OnCard
BroadcastOptions options = BroadcastOptions.makeBasic();
options.setInteractive(true);
+ options.setPendingIntentBackgroundActivityStartMode(
+ BroadcastOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED);
walletCard.getPendingIntent().send(options.toBundle());
} catch (PendingIntent.CanceledException e) {
Log.w(TAG, "Error sending pending intent for wallet card.");
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java
index 565fc57e81b7..f6450a4fb563 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java
@@ -253,11 +253,11 @@ public class KeyguardSecurityContainerTest extends SysuiTestCase {
getViewConstraint(mSecurityViewFlipper.getId());
ConstraintSet.Constraint userSwitcherConstraint =
getViewConstraint(R.id.keyguard_bouncer_user_switcher);
- assertThat(viewFlipperConstraint.layout.rightToRight).isEqualTo(PARENT_ID);
- assertThat(viewFlipperConstraint.layout.leftToRight).isEqualTo(
+ assertThat(viewFlipperConstraint.layout.endToEnd).isEqualTo(PARENT_ID);
+ assertThat(viewFlipperConstraint.layout.startToEnd).isEqualTo(
R.id.keyguard_bouncer_user_switcher);
- assertThat(userSwitcherConstraint.layout.leftToLeft).isEqualTo(PARENT_ID);
- assertThat(userSwitcherConstraint.layout.rightToLeft).isEqualTo(
+ assertThat(userSwitcherConstraint.layout.startToStart).isEqualTo(PARENT_ID);
+ assertThat(userSwitcherConstraint.layout.endToStart).isEqualTo(
mSecurityViewFlipper.getId());
assertThat(viewFlipperConstraint.layout.topToTop).isEqualTo(PARENT_ID);
assertThat(viewFlipperConstraint.layout.bottomToBottom).isEqualTo(PARENT_ID);
@@ -377,7 +377,7 @@ public class KeyguardSecurityContainerTest extends SysuiTestCase {
ConstraintSet.Constraint viewFlipperConstraint = getViewConstraint(
mSecurityViewFlipper.getId());
- assertThat(viewFlipperConstraint.layout.leftToLeft).isEqualTo(PARENT_ID);
+ assertThat(viewFlipperConstraint.layout.startToStart).isEqualTo(PARENT_ID);
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFingerprintAndFaceViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFingerprintAndFaceViewTest.kt
index 2d1e8a830fc9..a93af7dd7450 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFingerprintAndFaceViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFingerprintAndFaceViewTest.kt
@@ -99,7 +99,7 @@ class AuthBiometricFingerprintAndFaceViewTest : SysuiTestCase() {
waitForIdleSync()
assertThat(biometricView.isAuthenticated).isTrue()
- verify(callback).onAction(AuthBiometricView.Callback.ACTION_AUTHENTICATED)
+ verify(callback).onAction(AuthBiometricView.Callback.ACTION_AUTHENTICATED_AND_CONFIRMED)
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsProviderSelectorActivityTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsProviderSelectorActivityTest.kt
index b2e37ccb045b..4ba67182c32c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsProviderSelectorActivityTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsProviderSelectorActivityTest.kt
@@ -145,7 +145,7 @@ class ControlsProviderSelectorActivityTest : SysuiTestCase() {
assertThat(activityRule.activity.lastStartedActivity?.component?.className)
.isEqualTo(ControlsFavoritingActivity::class.java.name)
- assertThat(activityRule.activity.triedToFinish).isTrue()
+ assertThat(activityRule.activity.triedToFinish).isFalse()
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/FakeKeyguardQuickAffordanceConfig.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/FakeKeyguardQuickAffordanceConfig.kt
index 13d1e6488d25..c85c7f678536 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/FakeKeyguardQuickAffordanceConfig.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/FakeKeyguardQuickAffordanceConfig.kt
@@ -28,7 +28,7 @@ import kotlinx.coroutines.yield
@RoboPilotTest
class FakeKeyguardQuickAffordanceConfig(
override val key: String,
- override val pickerName: String = key,
+ private val pickerName: String = key,
override val pickerIconResourceId: Int = 0,
) : KeyguardQuickAffordanceConfig {
@@ -41,6 +41,8 @@ class FakeKeyguardQuickAffordanceConfig(
override val lockScreenState: Flow<KeyguardQuickAffordanceConfig.LockScreenState> =
_lockScreenState
+ override fun pickerName(): String = pickerName
+
override fun onTriggered(
expandable: Expandable?,
): OnTriggeredResult {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt
index ca7c5db478a1..6b5be58b6d03 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt
@@ -189,12 +189,12 @@ class KeyguardQuickAffordanceRepositoryTest : SysuiTestCase() {
listOf(
KeyguardQuickAffordancePickerRepresentation(
id = config1.key,
- name = config1.pickerName,
+ name = config1.pickerName(),
iconResourceId = config1.pickerIconResourceId,
),
KeyguardQuickAffordancePickerRepresentation(
id = config2.key,
- name = config2.pickerName,
+ name = config2.pickerName(),
iconResourceId = config2.pickerIconResourceId,
),
)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt
index 895c1cd5a1a1..1d5971ce9adc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt
@@ -435,7 +435,7 @@ class KeyguardQuickAffordanceInteractorTest : SysuiTestCase() {
listOf(
KeyguardQuickAffordancePickerRepresentation(
id = homeControls.key,
- name = homeControls.pickerName,
+ name = homeControls.pickerName(),
iconResourceId = homeControls.pickerIconResourceId,
),
),
@@ -469,7 +469,7 @@ class KeyguardQuickAffordanceInteractorTest : SysuiTestCase() {
listOf(
KeyguardQuickAffordancePickerRepresentation(
id = quickAccessWallet.key,
- name = quickAccessWallet.pickerName,
+ name = quickAccessWallet.pickerName(),
iconResourceId = quickAccessWallet.pickerIconResourceId,
),
),
@@ -506,7 +506,7 @@ class KeyguardQuickAffordanceInteractorTest : SysuiTestCase() {
listOf(
KeyguardQuickAffordancePickerRepresentation(
id = quickAccessWallet.key,
- name = quickAccessWallet.pickerName,
+ name = quickAccessWallet.pickerName(),
iconResourceId = quickAccessWallet.pickerIconResourceId,
),
),
@@ -514,7 +514,7 @@ class KeyguardQuickAffordanceInteractorTest : SysuiTestCase() {
listOf(
KeyguardQuickAffordancePickerRepresentation(
id = qrCodeScanner.key,
- name = qrCodeScanner.pickerName,
+ name = qrCodeScanner.pickerName(),
iconResourceId = qrCodeScanner.pickerIconResourceId,
),
),
@@ -570,7 +570,7 @@ class KeyguardQuickAffordanceInteractorTest : SysuiTestCase() {
listOf(
KeyguardQuickAffordancePickerRepresentation(
id = quickAccessWallet.key,
- name = quickAccessWallet.pickerName,
+ name = quickAccessWallet.pickerName(),
iconResourceId = quickAccessWallet.pickerIconResourceId,
),
),
@@ -665,7 +665,7 @@ class KeyguardQuickAffordanceInteractorTest : SysuiTestCase() {
listOf(
KeyguardQuickAffordancePickerRepresentation(
id = quickAccessWallet.key,
- name = quickAccessWallet.pickerName,
+ name = quickAccessWallet.pickerName(),
iconResourceId = quickAccessWallet.pickerIconResourceId,
),
),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java
index c89897c0233c..6d8c9b106881 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java
@@ -247,6 +247,20 @@ public class MediaOutputAdapterTest extends SysuiTestCase {
}
@Test
+ public void onBindViewHolder_bindConnectedRemoteDevice_verifyContentDescriptionNotNull() {
+ when(mMediaOutputController.getSelectableMediaDevice()).thenReturn(
+ ImmutableList.of(mMediaDevice2));
+ when(mMediaOutputController.isCurrentConnectedDeviceRemote()).thenReturn(true);
+ mViewHolder = (MediaOutputAdapter.MediaDeviceViewHolder) mMediaOutputAdapter
+ .onCreateViewHolder(new LinearLayout(mContext), 0);
+ mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0);
+
+ assertThat(mViewHolder.mSeekBar.getContentDescription()).isNotNull();
+ assertThat(mViewHolder.mSeekBar.getAccessibilityDelegate()).isNotNull();
+ assertThat(mViewHolder.mContainerLayout.isFocusable()).isFalse();
+ }
+
+ @Test
public void onBindViewHolder_bindSingleConnectedRemoteDevice_verifyView() {
when(mMediaOutputController.getSelectableMediaDevice()).thenReturn(
ImmutableList.of());
@@ -334,6 +348,7 @@ public class MediaOutputAdapterTest extends SysuiTestCase {
assertThat(mViewHolder.mCheckBox.getVisibility()).isEqualTo(View.VISIBLE);
assertThat(mViewHolder.mTitleText.getVisibility()).isEqualTo(View.VISIBLE);
assertThat(mViewHolder.mTitleText.getText().toString()).isEqualTo(TEST_DEVICE_NAME_2);
+ assertThat(mViewHolder.mContainerLayout.isFocusable()).isTrue();
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/TestUnfoldTransitionProvider.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/TestUnfoldTransitionProvider.kt
index 4a28cd1de255..56c624565971 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/TestUnfoldTransitionProvider.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/TestUnfoldTransitionProvider.kt
@@ -4,7 +4,7 @@ import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionPr
class TestUnfoldTransitionProvider : UnfoldTransitionProgressProvider, TransitionProgressListener {
- private val listeners = arrayListOf<TransitionProgressListener>()
+ private val listeners = mutableListOf<TransitionProgressListener>()
override fun destroy() {
listeners.clear()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/UnfoldHapticsPlayerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/UnfoldHapticsPlayerTest.kt
index d3fdbd94a5ac..3dec45b4ff9f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/UnfoldHapticsPlayerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/UnfoldHapticsPlayerTest.kt
@@ -20,10 +20,9 @@ import android.os.Vibrator
import android.testing.AndroidTestingRunner
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
-import com.android.systemui.unfold.updates.FoldProvider
+import com.android.systemui.unfold.util.TestFoldProvider
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.mock
-import java.util.concurrent.Executor
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -115,20 +114,4 @@ class UnfoldHapticsPlayerTest : SysuiTestCase() {
verify(vibrator).vibrate(any<VibrationEffect>())
}
-
- private class TestFoldProvider : FoldProvider {
- private val listeners = arrayListOf<FoldProvider.FoldCallback>()
-
- override fun registerCallback(callback: FoldProvider.FoldCallback, executor: Executor) {
- listeners += callback
- }
-
- override fun unregisterCallback(callback: FoldProvider.FoldCallback) {
- listeners -= callback
- }
-
- fun onFoldUpdate(isFolded: Boolean) {
- listeners.forEach { it.onFoldUpdated(isFolded) }
- }
- }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/TestUnfoldProgressListener.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/TestUnfoldProgressListener.kt
index e2aef31b4f10..e461e3f7fb1a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/TestUnfoldProgressListener.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/TestUnfoldProgressListener.kt
@@ -74,6 +74,11 @@ class TestUnfoldProgressListener : UnfoldTransitionProgressProvider.TransitionPr
currentRecording?.assertLastProgress(progress) ?: error("unfold not in progress.")
}
+ fun clear() {
+ currentRecording = null
+ recordings.clear()
+ }
+
class UnfoldTransitionRecording {
private val progressHistory: MutableList<Float> = arrayListOf()
private var finishingInvocations: Int = 0
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/util/TestFoldProvider.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/util/TestFoldProvider.kt
new file mode 100644
index 000000000000..35df35ccfe9c
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/util/TestFoldProvider.kt
@@ -0,0 +1,34 @@
+/*
+ * 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.unfold.util
+
+import com.android.systemui.unfold.updates.FoldProvider
+import java.util.concurrent.Executor
+
+class TestFoldProvider : FoldProvider {
+ private val listeners = arrayListOf<FoldProvider.FoldCallback>()
+
+ override fun registerCallback(callback: FoldProvider.FoldCallback, executor: Executor) {
+ listeners += callback
+ }
+
+ override fun unregisterCallback(callback: FoldProvider.FoldCallback) {
+ listeners -= callback
+ }
+
+ fun onFoldUpdate(isFolded: Boolean) {
+ listeners.forEach { it.onFoldUpdated(isFolded) }
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/util/UnfoldOnlyProgressProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/util/UnfoldOnlyProgressProviderTest.kt
new file mode 100644
index 000000000000..4a38fc069d9f
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/util/UnfoldOnlyProgressProviderTest.kt
@@ -0,0 +1,128 @@
+/*
+ * 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.unfold.util
+
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.unfold.TestUnfoldTransitionProvider
+import com.android.systemui.unfold.progress.TestUnfoldProgressListener
+import com.google.common.util.concurrent.MoreExecutors
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+class UnfoldOnlyProgressProviderTest : SysuiTestCase() {
+
+ private val listener = TestUnfoldProgressListener()
+ private val sourceProvider = TestUnfoldTransitionProvider()
+
+ private val foldProvider = TestFoldProvider()
+
+ private lateinit var progressProvider: UnfoldOnlyProgressProvider
+
+ @Before
+ fun setUp() {
+ progressProvider =
+ UnfoldOnlyProgressProvider(foldProvider, MoreExecutors.directExecutor(), sourceProvider)
+
+ progressProvider.addCallback(listener)
+ }
+
+ @Test
+ fun unfolded_unfoldAnimationFinished_propagatesEvents() {
+ foldProvider.onFoldUpdate(isFolded = true)
+ foldProvider.onFoldUpdate(isFolded = false)
+
+ // Unfold animation
+ sourceProvider.onTransitionStarted()
+ sourceProvider.onTransitionProgress(0.5f)
+ sourceProvider.onTransitionFinished()
+
+ with(listener.ensureTransitionFinished()) {
+ assertLastProgress(0.5f)
+ }
+ }
+
+ @Test
+ fun unfoldedWithAnimation_foldAnimation_doesNotPropagateEvents() {
+ foldProvider.onFoldUpdate(isFolded = true)
+ foldProvider.onFoldUpdate(isFolded = false)
+ // Unfold animation
+ sourceProvider.onTransitionStarted()
+ sourceProvider.onTransitionProgress(0.5f)
+ sourceProvider.onTransitionFinished()
+ listener.clear()
+
+ // Fold animation
+ sourceProvider.onTransitionStarted()
+ sourceProvider.onTransitionProgress(0.2f)
+ sourceProvider.onTransitionFinished()
+
+ listener.assertNotStarted()
+ }
+
+ @Test
+ fun unfoldedWithAnimation_foldAnimationSeveralTimes_doesNotPropagateEvents() {
+ foldProvider.onFoldUpdate(isFolded = true)
+ foldProvider.onFoldUpdate(isFolded = false)
+ // Unfold animation
+ sourceProvider.onTransitionStarted()
+ sourceProvider.onTransitionProgress(0.5f)
+ sourceProvider.onTransitionFinished()
+ listener.clear()
+
+ // Start and stop fold animation several times
+ repeat(3) {
+ sourceProvider.onTransitionStarted()
+ sourceProvider.onTransitionProgress(0.2f)
+ sourceProvider.onTransitionFinished()
+ }
+
+ listener.assertNotStarted()
+ }
+
+ @Test
+ fun unfoldedAgainAfterFolding_propagatesEvents() {
+ foldProvider.onFoldUpdate(isFolded = true)
+ foldProvider.onFoldUpdate(isFolded = false)
+
+ // Unfold animation
+ sourceProvider.onTransitionStarted()
+ sourceProvider.onTransitionProgress(0.5f)
+ sourceProvider.onTransitionFinished()
+
+ // Fold animation
+ sourceProvider.onTransitionStarted()
+ sourceProvider.onTransitionProgress(0.2f)
+ sourceProvider.onTransitionFinished()
+ foldProvider.onFoldUpdate(isFolded = true)
+
+ listener.clear()
+
+ // Second unfold animation after folding
+ foldProvider.onFoldUpdate(isFolded = false)
+ sourceProvider.onTransitionStarted()
+ sourceProvider.onTransitionProgress(0.1f)
+ sourceProvider.onTransitionFinished()
+
+ with(listener.ensureTransitionFinished()) {
+ assertLastProgress(0.1f)
+ }
+ }
+}
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index ad038d1c0361..fdb28ba9103e 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -4006,17 +4006,14 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
@Override
public boolean registerProxyForDisplay(IAccessibilityServiceClient client, int displayId)
throws RemoteException {
- mSecurityPolicy.enforceCallingOrSelfPermission(Manifest.permission.MANAGE_ACCESSIBILITY);
mSecurityPolicy.enforceCallingOrSelfPermission(Manifest.permission.CREATE_VIRTUAL_DEVICE);
+ mSecurityPolicy.checkForAccessibilityPermissionOrRole();
if (client == null) {
return false;
}
if (displayId < 0) {
throw new IllegalArgumentException("The display id " + displayId + " is invalid.");
}
- if (displayId == Display.DEFAULT_DISPLAY) {
- throw new IllegalArgumentException("The default display cannot be proxy-ed.");
- }
if (!isTrackedDisplay(displayId)) {
throw new IllegalArgumentException("The display " + displayId + " does not exist or is"
+ " not tracked by accessibility.");
@@ -4025,6 +4022,10 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
throw new IllegalArgumentException("The display " + displayId + " is already being"
+ " proxy-ed");
}
+ if (!mProxyManager.displayBelongsToCaller(Binder.getCallingUid(), displayId)) {
+ throw new SecurityException("The display " + displayId + " does not belong to"
+ + " the caller.");
+ }
final long identity = Binder.clearCallingIdentity();
try {
@@ -4042,8 +4043,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
@Override
public boolean unregisterProxyForDisplay(int displayId) {
- mSecurityPolicy.enforceCallingOrSelfPermission(Manifest.permission.MANAGE_ACCESSIBILITY);
mSecurityPolicy.enforceCallingOrSelfPermission(Manifest.permission.CREATE_VIRTUAL_DEVICE);
+ mSecurityPolicy.checkForAccessibilityPermissionOrRole();
final long identity = Binder.clearCallingIdentity();
try {
return mProxyManager.unregisterProxy(displayId);
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilitySecurityPolicy.java b/services/accessibility/java/com/android/server/accessibility/AccessibilitySecurityPolicy.java
index 93356263b897..f45fa921c4a2 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilitySecurityPolicy.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilitySecurityPolicy.java
@@ -18,6 +18,7 @@ package com.android.server.accessibility;
import static android.accessibilityservice.AccessibilityService.SoftKeyboardController.ENABLE_IME_FAIL_BY_ADMIN;
import static android.accessibilityservice.AccessibilityService.SoftKeyboardController.ENABLE_IME_SUCCESS;
+import static android.companion.AssociationRequest.DEVICE_PROFILE_APP_STREAMING;
import android.Manifest;
import android.accessibilityservice.AccessibilityService;
@@ -25,6 +26,7 @@ import android.accessibilityservice.AccessibilityServiceInfo;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.AppOpsManager;
+import android.app.role.RoleManager;
import android.appwidget.AppWidgetManagerInternal;
import android.content.ComponentName;
import android.content.Context;
@@ -675,6 +677,42 @@ public class AccessibilitySecurityPolicy {
}
/**
+ * Throws a SecurityException if the caller has neither the MANAGE_ACCESSIBILITY permission nor
+ * the COMPANION_DEVICE_APP_STREAMING role.
+ */
+ public void checkForAccessibilityPermissionOrRole() {
+ final boolean canManageAccessibility =
+ mContext.checkCallingOrSelfPermission(Manifest.permission.MANAGE_ACCESSIBILITY)
+ == PackageManager.PERMISSION_GRANTED;
+ if (canManageAccessibility) {
+ return;
+ }
+ final int callingUid = Binder.getCallingUid();
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ final RoleManager roleManager = mContext.getSystemService(RoleManager.class);
+ if (roleManager != null) {
+ final List<String> holders = roleManager.getRoleHoldersAsUser(
+ DEVICE_PROFILE_APP_STREAMING, UserHandle.getUserHandleForUid(callingUid));
+ final String[] packageNames = mPackageManager.getPackagesForUid(callingUid);
+ if (packageNames != null) {
+ for (String packageName : packageNames) {
+ if (holders.contains(packageName)) {
+ return;
+ }
+ }
+ }
+ }
+ throw new SecurityException(
+ "Cannot register a proxy for a device without the "
+ + "android.app.role.COMPANION_DEVICE_APP_STREAMING role or the"
+ + " MANAGE_ACCESSIBILITY permission.");
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ /**
* Called after a service was bound or unbound. Checks the current bound accessibility
* services and updates alarms.
*
diff --git a/services/accessibility/java/com/android/server/accessibility/ProxyManager.java b/services/accessibility/java/com/android/server/accessibility/ProxyManager.java
index 6dc8fb347904..70882c6471de 100644
--- a/services/accessibility/java/com/android/server/accessibility/ProxyManager.java
+++ b/services/accessibility/java/com/android/server/accessibility/ProxyManager.java
@@ -24,6 +24,7 @@ import android.accessibilityservice.AccessibilityServiceInfo;
import android.accessibilityservice.AccessibilityTrace;
import android.accessibilityservice.IAccessibilityServiceClient;
import android.annotation.NonNull;
+import android.companion.virtual.VirtualDevice;
import android.companion.virtual.VirtualDeviceManager;
import android.content.ComponentName;
import android.content.Context;
@@ -319,6 +320,25 @@ public class ProxyManager {
return isTrackingDeviceId;
}
+ /** Returns true if the display belongs to one of the caller's virtual devices. */
+ public boolean displayBelongsToCaller(int callingUid, int proxyDisplayId) {
+ final VirtualDeviceManager vdm = mContext.getSystemService(VirtualDeviceManager.class);
+ final VirtualDeviceManagerInternal localVdm = getLocalVdm();
+ if (vdm == null || localVdm == null) {
+ return false;
+ }
+ final List<VirtualDevice> virtualDevices = vdm.getVirtualDevices();
+ for (VirtualDevice device : virtualDevices) {
+ if (localVdm.getDisplayIdsForDevice(device.getDeviceId()).contains(proxyDisplayId)) {
+ final int ownerUid = localVdm.getDeviceOwnerUid(device.getDeviceId());
+ if (callingUid == ownerUid) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
/**
* Sends AccessibilityEvents to a proxy given the event's displayId.
*/
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 00dbb97191fb..6db8ea7e536e 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -2156,7 +2156,6 @@ public final class ActiveServices {
}
}
- final boolean enableFgsWhileInUseFix = mAm.mConstants.mEnableFgsWhileInUseFix;
final boolean fgsTypeChangingFromShortFgs = r.isForeground && isOldTypeShortFgs;
if (fgsTypeChangingFromShortFgs) {
@@ -2214,19 +2213,7 @@ public final class ActiveServices {
}
}
- boolean resetNeededForLogging = false;
-
- // Re-evaluate mAllowWhileInUsePermissionInFgs and mAllowStartForeground
- // (i.e. while-in-use and BFSL flags) if needed.
- //
- // Consider the below if-else section to be in the else of the above
- // `if (fgsTypeChangingFromShortFgs)`.
- // Using an else would increase the indent further, so we don't use it here
- // and instead just add !fgsTypeChangingFromShortFgs to all if's.
- //
- // The first if's are for the original while-in-use logic.
- if (!fgsTypeChangingFromShortFgs && !enableFgsWhileInUseFix
- && r.mStartForegroundCount == 0) {
+ if (!fgsTypeChangingFromShortFgs && r.mStartForegroundCount == 0) {
/*
If the service was started with startService(), not
startForegroundService(), and if startForeground() isn't called within
@@ -2257,8 +2244,7 @@ public final class ActiveServices {
r.mLoggedInfoAllowStartForeground = false;
}
}
- } else if (!fgsTypeChangingFromShortFgs && !enableFgsWhileInUseFix
- && r.mStartForegroundCount >= 1) {
+ } else if (!fgsTypeChangingFromShortFgs && r.mStartForegroundCount >= 1) {
// We get here if startForeground() is called multiple times
// on the same service after it's created, regardless of whether
// stopForeground() has been called or not.
@@ -2269,100 +2255,6 @@ public final class ActiveServices {
r.appInfo.uid, r.intent.getIntent(), r, r.userId,
BackgroundStartPrivileges.NONE,
false /* isBindService */, false /* isStartService */);
- } else if (!fgsTypeChangingFromShortFgs && enableFgsWhileInUseFix) {
- // The new while-in-use logic.
- //
- // When startForeground() is called, we _always_ call
- // setFgsRestrictionLocked() to set the restrictions according to the
- // current state of the app.
- // (So if the app is now in TOP, for example, the service will now always
- // get while-in-use permissions.)
- //
- // Note, setFgsRestrictionLocked() will never disallow
- // mAllowWhileInUsePermissionInFgs nor mAllowStartForeground
- // (i.e. while-in-use and BFSL flags) once they're set to "allowed".
- //
- // HOWEVER, if these flags were set to "allowed" in Context.startService()
- // (as opposed to startForegroundService()), when the service wasn't yet
- // a foreground service, then we may not always
- // want to trust them -- for example, if the service has been running as a
- // BG service or a bound service for a long time when the app is not longer
- // in the foreground, then we shouldn't grant while-in-user nor BFSL.
- // So in that case, we need to reset it first.
-
- final long delayMs =
- (r.mLastUntrustedSetFgsRestrictionAllowedTime == 0) ? 0
- : (SystemClock.elapsedRealtime()
- - r.mLastUntrustedSetFgsRestrictionAllowedTime);
- final boolean resetNeeded =
- !r.isForeground
- && delayMs > mAm.mConstants.mFgsStartForegroundTimeoutMs;
- if (resetNeeded) {
- // We don't want to reset mDebugWhileInUseReasonInBindService here --
- // we'll instead reset it in the following code, using the simulated
- // legacy logic.
- resetFgsRestrictionLocked(r,
- /*resetDebugWhileInUseReasonInBindService=*/ false);
- }
-
- // Simulate the reset flow in the legacy logic to reset
- // mDebugWhileInUseReasonInBindService.
- // (Which is only used to compare to the old logic.)
- final long legacyDelayMs = SystemClock.elapsedRealtime() - r.createRealTime;
- if ((r.mStartForegroundCount == 0)
- && (legacyDelayMs > mAm.mConstants.mFgsStartForegroundTimeoutMs)) {
- r.mDebugWhileInUseReasonInBindService = REASON_DENIED;
- }
-
- setFgsRestrictionLocked(r.serviceInfo.packageName, r.app.getPid(),
- r.appInfo.uid, r.intent.getIntent(), r, r.userId,
- BackgroundStartPrivileges.NONE,
- false /* isBindService */, false /* isStartService */);
-
- final String temp = "startForegroundDelayMs:" + delayMs
- + "; started: " + r.startRequested
- + "; num_bindings: " + r.getConnections().size()
- + "; wasForeground: " + r.isForeground
- + "; resetNeeded:" + resetNeeded;
- if (r.mInfoAllowStartForeground != null) {
- r.mInfoAllowStartForeground += "; " + temp;
- } else {
- r.mInfoAllowStartForeground = temp;
- }
- r.mLoggedInfoAllowStartForeground = false;
-
- resetNeededForLogging = resetNeeded;
- }
-
- // If the service has any bindings and it's not yet a FGS
- // we compare the new and old while-in-use logics.
- // (If it's not the first startForeground() call, we already reset the
- // while-in-use and BFSL flags, so the logic change wouldn't matter.)
- //
- // Note, mDebugWhileInUseReasonInBindService does *not* fully simulate the
- // legacy logic, because we'll only set it in bindService(), but the actual
- // mAllowWhileInUsePermissionInFgsReason can change afterwards, in a subsequent
- // Service.startForeground(). This check will only provide "rough" check.
- // But if mDebugWhileInUseReasonInBindService is _not_ DENIED, and
- // mDebugWhileInUseReasonInStartForeground _is_ DENIED, then that means we'd
- // now detected a behavior change.
- // OTOH, if it's changing from non-DENIED to another non-DENIED, that may
- // not be a problem.
- if (enableFgsWhileInUseFix
- && !r.isForeground
- && (r.getConnections().size() > 0)
- && (r.mDebugWhileInUseReasonInBindService
- != r.mDebugWhileInUseReasonInStartForeground)) {
- logWhileInUseChangeWtf("FGS while-in-use changed (b/276963716): old="
- + reasonCodeToString(r.mDebugWhileInUseReasonInBindService)
- + " new="
- + reasonCodeToString(r.mDebugWhileInUseReasonInStartForeground)
- + " startForegroundCount=" + r.mStartForegroundCount
- + " started=" + r.startRequested
- + " num_bindings=" + r.getConnections().size()
- + " resetNeeded=" + resetNeededForLogging
- + " "
- + r.shortInstanceName);
}
// If the foreground service is not started from TOP process, do not allow it to
@@ -2471,10 +2363,6 @@ public final class ActiveServices {
}
r.isForeground = true;
- // Once the service becomes a foreground service,
- // the FGS restriction information always becomes "trustable".
- r.mLastUntrustedSetFgsRestrictionAllowedTime = 0;
-
// The logging of FOREGROUND_SERVICE_STATE_CHANGED__STATE__ENTER event could
// be deferred, make a copy of mAllowStartForeground and
// mAllowWhileInUsePermissionInFgs.
@@ -2620,13 +2508,6 @@ public final class ActiveServices {
}
}
- /**
- * It just does a wtf, but extracted to a method, so we can do a signature search on pitot.
- */
- private void logWhileInUseChangeWtf(String message) {
- Slog.wtf(TAG, message);
- }
-
private boolean withinFgsDeferRateLimit(ServiceRecord sr, final long now) {
// If we're still within the service's deferral period, then by definition
// deferral is not rate limited.
@@ -3839,25 +3720,9 @@ public final class ActiveServices {
return 0;
}
}
- if (!mAm.mConstants.mEnableFgsWhileInUseFix) {
- // Old while-in-use logic.
- setFgsRestrictionLocked(callingPackage, callingPid, callingUid, service, s, userId,
- BackgroundStartPrivileges.NONE, true /* isBindService */,
- false /* isStartService */);
- } else {
- // New logic will not call setFgsRestrictionLocked() here, but we still
- // keep track of the allow reason from the old logic here, so we can compare to
- // the new logic.
- // Once we're confident enough in the new logic, we should remove it.
- if (s.mDebugWhileInUseReasonInBindService == REASON_DENIED) {
- s.mDebugWhileInUseReasonInBindService =
- shouldAllowFgsWhileInUsePermissionLocked(
- callingPackage, callingPid, callingUid, s.app,
- BackgroundStartPrivileges.NONE,
- true /* isBindService */,
- false /* DO NOT enableFgsWhileInUseFix; use the old logic */);
- }
- }
+ setFgsRestrictionLocked(callingPackage, callingPid, callingUid, service, s, userId,
+ BackgroundStartPrivileges.NONE, true /* isBindService */,
+ false /* isStartService */);
if (s.app != null) {
ProcessServiceRecord servicePsr = s.app.mServices;
@@ -7554,15 +7419,13 @@ public final class ActiveServices {
* @param r the service to start.
* @param isStartService True if it's called from Context.startService().
* False if it's called from Context.startForegroundService() or
- * Service.startService().
+ * Service.startForeground().
* @return true if allow, false otherwise.
*/
private void setFgsRestrictionLocked(String callingPackage,
int callingPid, int callingUid, Intent intent, ServiceRecord r, int userId,
BackgroundStartPrivileges backgroundStartPrivileges, boolean isBindService,
boolean isStartService) {
- final long now = SystemClock.elapsedRealtime();
-
// Check DeviceConfig flag.
if (!mAm.mConstants.mFlagBackgroundFgsStartRestrictionEnabled) {
r.mAllowWhileInUsePermissionInFgs = true;
@@ -7580,60 +7443,30 @@ public final class ActiveServices {
isBindService);
// We store them to compare the old and new while-in-use logics to each other.
// (They're not used for any other purposes.)
- if (isBindService) {
- r.mDebugWhileInUseReasonInBindService = allowWhileInUse;
- } else {
- r.mDebugWhileInUseReasonInStartForeground = allowWhileInUse;
- }
if (!r.mAllowWhileInUsePermissionInFgs) {
r.mAllowWhileInUsePermissionInFgs = (allowWhileInUse != REASON_DENIED);
- newlyAllowed |= r.mAllowWhileInUsePermissionInFgs;
}
if (r.mAllowStartForeground == REASON_DENIED) {
r.mAllowStartForeground = shouldAllowFgsStartForegroundWithBindingCheckLocked(
allowWhileInUse, callingPackage, callingPid, callingUid, intent, r,
backgroundStartPrivileges, isBindService);
- newlyAllowed |= r.mAllowStartForeground != REASON_DENIED;
}
} else {
allowWhileInUse = REASON_UNKNOWN;
}
r.mAllowWhileInUsePermissionInFgsReason = allowWhileInUse;
-
- if (isStartService && !r.isForeground && newlyAllowed) {
- // If it's called by Context.startService() (not by startForegroundService()),
- // and we're setting "allowed", then we can't fully trust it yet -- we'll need to reset
- // the restrictions if startForeground() is called after the grace period.
- r.mLastUntrustedSetFgsRestrictionAllowedTime = now;
- }
}
/**
* Reset various while-in-use and BFSL related information.
*/
void resetFgsRestrictionLocked(ServiceRecord r) {
- resetFgsRestrictionLocked(r, /*resetDebugWhileInUseReasonInBindService=*/ true);
- }
-
- /**
- * Reset various while-in-use and BFSL related information.
- */
- void resetFgsRestrictionLocked(ServiceRecord r,
- boolean resetDebugWhileInUseReasonInBindService) {
r.mAllowWhileInUsePermissionInFgs = false;
r.mAllowWhileInUsePermissionInFgsReason = REASON_DENIED;
- r.mDebugWhileInUseReasonInStartForeground = REASON_DENIED;
-
- // In Service.startForeground(), we reset this field using a legacy logic,
- // so resetting this field is optional.
- if (resetDebugWhileInUseReasonInBindService) {
- r.mDebugWhileInUseReasonInBindService = REASON_DENIED;
- }
r.mAllowStartForeground = REASON_DENIED;
r.mInfoAllowStartForeground = null;
r.mInfoTempFgsAllowListReason = null;
r.mLoggedInfoAllowStartForeground = false;
- r.mLastUntrustedSetFgsRestrictionAllowedTime = 0;
r.updateAllowUiJobScheduling(r.mAllowWhileInUsePermissionInFgs);
}
@@ -7668,22 +7501,11 @@ public final class ActiveServices {
private @ReasonCode int shouldAllowFgsWhileInUsePermissionLocked(String callingPackage,
int callingPid, int callingUid, @Nullable ProcessRecord targetProcess,
BackgroundStartPrivileges backgroundStartPrivileges, boolean isBindService) {
- return shouldAllowFgsWhileInUsePermissionLocked(callingPackage,
- callingPid, callingUid, targetProcess, backgroundStartPrivileges, isBindService,
- /* enableFgsWhileInUseFix =*/ mAm.mConstants.mEnableFgsWhileInUseFix);
- }
-
- private @ReasonCode int shouldAllowFgsWhileInUsePermissionLocked(String callingPackage,
- int callingPid, int callingUid, @Nullable ProcessRecord targetProcess,
- BackgroundStartPrivileges backgroundStartPrivileges, boolean isBindService,
- boolean enableFgsWhileInUseFix) {
int ret = REASON_DENIED;
- // Define some local variables for better readability...
- final boolean useOldLogic = !enableFgsWhileInUseFix;
final boolean forStartForeground = !isBindService;
- if (useOldLogic || forStartForeground) {
+ if (forStartForeground) {
final int uidState = mAm.getUidStateLocked(callingUid);
if (ret == REASON_DENIED) {
// Allow FGS while-in-use if the caller's process state is PROCESS_STATE_PERSISTENT,
@@ -7733,10 +7555,6 @@ public final class ActiveServices {
}
}
- if (enableFgsWhileInUseFix && ret == REASON_DENIED) {
- ret = shouldAllowFgsWhileInUsePermissionByBindingsLocked(callingUid);
- }
-
if (ret == REASON_DENIED) {
// Allow FGS while-in-use if the WindowManager allows background activity start.
// This is mainly to get the 10 seconds grace period if any activity in the caller has
diff --git a/services/core/java/com/android/server/am/ActivityManagerConstants.java b/services/core/java/com/android/server/am/ActivityManagerConstants.java
index 3b446338298d..44e198b53761 100644
--- a/services/core/java/com/android/server/am/ActivityManagerConstants.java
+++ b/services/core/java/com/android/server/am/ActivityManagerConstants.java
@@ -1058,13 +1058,6 @@ final class ActivityManagerConstants extends ContentObserver {
/** @see #KEY_USE_MODERN_TRIM */
public boolean USE_MODERN_TRIM = DEFAULT_USE_MODERN_TRIM;
- private static final String KEY_ENABLE_FGS_WHILE_IN_USE_FIX =
- "key_enable_fgs_while_in_use_fix";
-
- private static final boolean DEFAULT_ENABLE_FGS_WHILE_IN_USE_FIX = false;
-
- public volatile boolean mEnableFgsWhileInUseFix = DEFAULT_ENABLE_FGS_WHILE_IN_USE_FIX;
-
private final OnPropertiesChangedListener mOnDeviceConfigChangedListener =
new OnPropertiesChangedListener() {
@Override
@@ -1233,9 +1226,6 @@ final class ActivityManagerConstants extends ContentObserver {
case KEY_ENABLE_WAIT_FOR_FINISH_ATTACH_APPLICATION:
updateEnableWaitForFinishAttachApplication();
break;
- case KEY_ENABLE_FGS_WHILE_IN_USE_FIX:
- updateEnableFgsWhileInUseFix();
- break;
case KEY_MAX_PREVIOUS_TIME:
updateMaxPreviousTime();
break;
@@ -2005,12 +1995,6 @@ final class ActivityManagerConstants extends ContentObserver {
DEFAULT_ENABLE_WAIT_FOR_FINISH_ATTACH_APPLICATION);
}
- private void updateEnableFgsWhileInUseFix() {
- mEnableFgsWhileInUseFix = DeviceConfig.getBoolean(
- DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
- KEY_ENABLE_FGS_WHILE_IN_USE_FIX,
- DEFAULT_ENABLE_FGS_WHILE_IN_USE_FIX);
- }
private void updateUseTieredCachedAdj() {
USE_TIERED_CACHED_ADJ = DeviceConfig.getBoolean(
DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
@@ -2211,9 +2195,6 @@ final class ActivityManagerConstants extends ContentObserver {
pw.print(" "); pw.print(KEY_SYSTEM_EXEMPT_POWER_RESTRICTIONS_ENABLED);
pw.print("="); pw.println(mFlagSystemExemptPowerRestrictionsEnabled);
- pw.print(" "); pw.print(KEY_ENABLE_FGS_WHILE_IN_USE_FIX);
- pw.print("="); pw.println(mEnableFgsWhileInUseFix);
-
pw.print(" "); pw.print(KEY_SHORT_FGS_TIMEOUT_DURATION);
pw.print("="); pw.println(mShortFgsTimeoutDuration);
pw.print(" "); pw.print(KEY_SHORT_FGS_PROC_STATE_EXTRA_WAIT_DURATION);
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 460ce4484a4b..5c1dad978095 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -1489,12 +1489,10 @@ public class ActivityManagerService extends IActivityManager.Stub
static final class ProcessChangeItem {
static final int CHANGE_ACTIVITIES = 1<<0;
static final int CHANGE_FOREGROUND_SERVICES = 1<<1;
- static final int CHANGE_CAPABILITY = 1<<2;
int changes;
int uid;
int pid;
int processState;
- int capability;
boolean foregroundActivities;
int foregroundServiceTypes;
}
@@ -4854,7 +4852,7 @@ public class ActivityManagerService extends IActivityManager.Stub
}
checkTime(startTime, "finishAttachApplicationInner: "
+ "after dispatching broadcasts");
- } catch (Exception e) {
+ } catch (BroadcastDeliveryFailedException e) {
// If the app died trying to launch the receiver we declare it 'bad'
Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
badApp = true;
diff --git a/services/core/java/com/android/server/am/BroadcastDeliveryFailedException.java b/services/core/java/com/android/server/am/BroadcastDeliveryFailedException.java
new file mode 100644
index 000000000000..9c9281635cf7
--- /dev/null
+++ b/services/core/java/com/android/server/am/BroadcastDeliveryFailedException.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.am;
+
+import android.util.AndroidException;
+
+/**
+ * Exception to represent that broadcast could not be delivered.
+ */
+public class BroadcastDeliveryFailedException extends AndroidException {
+ public BroadcastDeliveryFailedException(String name) {
+ super(name);
+ }
+
+ public BroadcastDeliveryFailedException(Exception cause) {
+ super(cause);
+ }
+}
diff --git a/services/core/java/com/android/server/am/BroadcastProcessQueue.java b/services/core/java/com/android/server/am/BroadcastProcessQueue.java
index 9b53af2e9b5c..0b5b1cb2902e 100644
--- a/services/core/java/com/android/server/am/BroadcastProcessQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastProcessQueue.java
@@ -280,6 +280,25 @@ class BroadcastProcessQueue {
}
/**
+ * Re-enqueue the active broadcast so that it can be made active and delivered again. In order
+ * to keep its previous position same to avoid issues with reordering, insert it at the head
+ * of the queue.
+ *
+ * Callers are responsible for clearing the active broadcast by calling
+ * {@link #makeActiveIdle()} after re-enqueuing it.
+ */
+ public void reEnqueueActiveBroadcast() {
+ final BroadcastRecord record = getActive();
+ final int recordIndex = getActiveIndex();
+
+ final SomeArgs broadcastArgs = SomeArgs.obtain();
+ broadcastArgs.arg1 = record;
+ broadcastArgs.argi1 = recordIndex;
+ getQueueForBroadcast(record).addFirst(broadcastArgs);
+ onBroadcastEnqueued(record, recordIndex);
+ }
+
+ /**
* Searches from newest to oldest in the pending broadcast queues, and at the first matching
* pending broadcast it finds, replaces it in-place and returns -- does not attempt to handle
* "duplicate" broadcasts in the queue.
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index 8e76e5b5cf48..e38a2eefcd92 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -148,7 +148,8 @@ public abstract class BroadcastQueue {
* dispatching a pending broadcast
*/
@GuardedBy("mService")
- public abstract boolean onApplicationAttachedLocked(@NonNull ProcessRecord app);
+ public abstract boolean onApplicationAttachedLocked(@NonNull ProcessRecord app)
+ throws BroadcastDeliveryFailedException;
/**
* Signal from OS internals that the given process has timed out during
diff --git a/services/core/java/com/android/server/am/BroadcastQueueImpl.java b/services/core/java/com/android/server/am/BroadcastQueueImpl.java
index e389821595a0..4eedfe259633 100644
--- a/services/core/java/com/android/server/am/BroadcastQueueImpl.java
+++ b/services/core/java/com/android/server/am/BroadcastQueueImpl.java
@@ -438,7 +438,8 @@ public class BroadcastQueueImpl extends BroadcastQueue {
scheduleBroadcastsLocked();
}
- public boolean onApplicationAttachedLocked(ProcessRecord app) {
+ public boolean onApplicationAttachedLocked(ProcessRecord app)
+ throws BroadcastDeliveryFailedException {
updateUidReadyForBootCompletedBroadcastLocked(app.uid);
if (mPendingBroadcast != null && mPendingBroadcast.curApp == app) {
@@ -460,7 +461,8 @@ public class BroadcastQueueImpl extends BroadcastQueue {
skipCurrentOrPendingReceiverLocked(app);
}
- public boolean sendPendingBroadcastsLocked(ProcessRecord app) {
+ public boolean sendPendingBroadcastsLocked(ProcessRecord app)
+ throws BroadcastDeliveryFailedException {
boolean didSomething = false;
final BroadcastRecord br = mPendingBroadcast;
if (br != null && br.curApp.getPid() > 0 && br.curApp.getPid() == app.getPid()) {
@@ -483,7 +485,7 @@ public class BroadcastQueueImpl extends BroadcastQueue {
scheduleBroadcastsLocked();
// We need to reset the state if we failed to start the receiver.
br.state = BroadcastRecord.IDLE;
- throw new RuntimeException(e.getMessage());
+ throw new BroadcastDeliveryFailedException(e);
}
}
return didSomething;
diff --git a/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java b/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java
index 22c0855ec54f..bb5fcbec7010 100644
--- a/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java
+++ b/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java
@@ -469,10 +469,15 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
if (DEBUG_BROADCAST) logv("Promoting " + queue
+ " from runnable to running; process is " + queue.app);
promoteToRunningLocked(queue);
- final boolean completed;
+ boolean completed;
if (processWarm) {
updateOomAdj |= queue.runningOomAdjusted;
- completed = scheduleReceiverWarmLocked(queue);
+ try {
+ completed = scheduleReceiverWarmLocked(queue);
+ } catch (BroadcastDeliveryFailedException e) {
+ reEnqueueActiveBroadcast(queue);
+ completed = true;
+ }
} else {
completed = scheduleReceiverColdLocked(queue);
}
@@ -513,7 +518,9 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
private void clearInvalidPendingColdStart() {
logw("Clearing invalid pending cold start: " + mRunningColdStart);
- onApplicationCleanupLocked(mRunningColdStart.app);
+ mRunningColdStart.reEnqueueActiveBroadcast();
+ demoteFromRunningLocked(mRunningColdStart);
+ clearRunningColdStart();
}
private void checkPendingColdStartValidity() {
@@ -535,8 +542,19 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
}
}
+ private void reEnqueueActiveBroadcast(@NonNull BroadcastProcessQueue queue) {
+ checkState(queue.isActive(), "isActive");
+
+ final BroadcastRecord record = queue.getActive();
+ final int index = queue.getActiveIndex();
+ setDeliveryState(queue, queue.app, record, index, record.receivers.get(index),
+ BroadcastRecord.DELIVERY_PENDING, "reEnqueueActiveBroadcast");
+ queue.reEnqueueActiveBroadcast();
+ }
+
@Override
- public boolean onApplicationAttachedLocked(@NonNull ProcessRecord app) {
+ public boolean onApplicationAttachedLocked(@NonNull ProcessRecord app)
+ throws BroadcastDeliveryFailedException {
// Process records can be recycled, so always start by looking up the
// relevant per-process queue
final BroadcastProcessQueue queue = getProcessQueue(app);
@@ -557,8 +575,14 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
queue.traceProcessEnd();
queue.traceProcessRunningBegin();
- if (scheduleReceiverWarmLocked(queue)) {
+ try {
+ if (scheduleReceiverWarmLocked(queue)) {
+ demoteFromRunningLocked(queue);
+ }
+ } catch (BroadcastDeliveryFailedException e) {
+ reEnqueueActiveBroadcast(queue);
demoteFromRunningLocked(queue);
+ throw e;
}
// We might be willing to kick off another cold start
@@ -588,14 +612,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
}
if ((mRunningColdStart != null) && (mRunningColdStart == queue)) {
- // We've been waiting for this app to cold start, and it had
- // trouble; clear the slot and fail delivery below
- mRunningColdStart = null;
-
- queue.traceProcessEnd();
-
- // We might be willing to kick off another cold start
- enqueueUpdateRunningList();
+ clearRunningColdStart();
}
if (queue != null) {
@@ -618,6 +635,17 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
}
}
+ private void clearRunningColdStart() {
+ mRunningColdStart.traceProcessEnd();
+
+ // We've been waiting for this app to cold start, and it had
+ // trouble; clear the slot and fail delivery below
+ mRunningColdStart = null;
+
+ // We might be willing to kick off another cold start
+ enqueueUpdateRunningList();
+ }
+
@Override
public int getPreferredSchedulingGroupLocked(@NonNull ProcessRecord app) {
final BroadcastProcessQueue queue = getProcessQueue(app);
@@ -836,7 +864,8 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
*/
@CheckResult
@GuardedBy("mService")
- private boolean scheduleReceiverWarmLocked(@NonNull BroadcastProcessQueue queue) {
+ private boolean scheduleReceiverWarmLocked(@NonNull BroadcastProcessQueue queue)
+ throws BroadcastDeliveryFailedException {
checkState(queue.isActive(), "isActive");
final int cookie = traceBegin("scheduleReceiverWarmLocked");
@@ -918,7 +947,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
*/
@CheckResult
private boolean dispatchReceivers(@NonNull BroadcastProcessQueue queue,
- @NonNull BroadcastRecord r, int index) {
+ @NonNull BroadcastRecord r, int index) throws BroadcastDeliveryFailedException {
final ProcessRecord app = queue.app;
final Object receiver = r.receivers.get(index);
@@ -1005,6 +1034,11 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
logw(msg);
app.killLocked("Can't deliver broadcast", ApplicationExitInfo.REASON_OTHER,
ApplicationExitInfo.SUBREASON_UNDELIVERED_BROADCAST, true);
+ // If we were trying to deliver a manifest broadcast, throw the error as we need
+ // to try redelivering the broadcast to this receiver.
+ if (receiver instanceof ResolveInfo) {
+ throw new BroadcastDeliveryFailedException(e);
+ }
finishReceiverActiveLocked(queue, BroadcastRecord.DELIVERY_FAILURE,
"remote app");
return false;
@@ -1092,7 +1126,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
boolean waitForServices) {
final BroadcastProcessQueue queue = getProcessQueue(app);
if ((queue == null) || !queue.isActive()) {
- logw("Ignoring finish; no active broadcast for " + queue);
+ logw("Ignoring finishReceiverLocked; no active broadcast for " + queue);
return false;
}
@@ -1129,7 +1163,13 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
// We're on a roll; move onto the next broadcast for this process
queue.makeActiveNextPending();
- if (scheduleReceiverWarmLocked(queue)) {
+ try {
+ if (scheduleReceiverWarmLocked(queue)) {
+ demoteFromRunningLocked(queue);
+ return true;
+ }
+ } catch (BroadcastDeliveryFailedException e) {
+ reEnqueueActiveBroadcast(queue);
demoteFromRunningLocked(queue);
return true;
}
@@ -1166,7 +1206,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
private void finishReceiverActiveLocked(@NonNull BroadcastProcessQueue queue,
@DeliveryState int deliveryState, @NonNull String reason) {
if (!queue.isActive()) {
- logw("Ignoring finish; no active broadcast for " + queue);
+ logw("Ignoring finishReceiverActiveLocked; no active broadcast for " + queue);
return;
}
diff --git a/services/core/java/com/android/server/am/BroadcastRecord.java b/services/core/java/com/android/server/am/BroadcastRecord.java
index 564b1fe8de34..863dd63a2922 100644
--- a/services/core/java/com/android/server/am/BroadcastRecord.java
+++ b/services/core/java/com/android/server/am/BroadcastRecord.java
@@ -699,6 +699,9 @@ final class BroadcastRecord extends Binder {
break;
}
switch (newDeliveryState) {
+ case DELIVERY_PENDING:
+ scheduledTime[index] = 0;
+ break;
case DELIVERY_SCHEDULED:
scheduledTime[index] = SystemClock.uptimeMillis();
break;
diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java
index 6c3f01e6cd3a..a86c2e362c54 100644
--- a/services/core/java/com/android/server/am/OomAdjuster.java
+++ b/services/core/java/com/android/server/am/OomAdjuster.java
@@ -3188,7 +3188,6 @@ public class OomAdjuster {
}
if (state.getCurCapability() != state.getSetCapability()) {
- changes |= ActivityManagerService.ProcessChangeItem.CHANGE_CAPABILITY;
state.setSetCapability(state.getCurCapability());
}
@@ -3212,13 +3211,12 @@ public class OomAdjuster {
mProcessList.enqueueProcessChangeItemLocked(app.getPid(), app.info.uid);
item.changes |= changes;
item.foregroundActivities = state.hasRepForegroundActivities();
- item.capability = state.getSetCapability();
if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
"Item " + Integer.toHexString(System.identityHashCode(item))
+ " " + app.toShortString() + ": changes=" + item.changes
+ " foreground=" + item.foregroundActivities
+ " type=" + state.getAdjType() + " source=" + state.getAdjSource()
- + " target=" + state.getAdjTarget() + " capability=" + item.capability);
+ + " target=" + state.getAdjTarget());
}
if (state.isCached() && !state.shouldNotKillOnBgRestrictedAndIdle()) {
diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java
index 1f39d1b5d7f8..dccbb0accadd 100644
--- a/services/core/java/com/android/server/am/ServiceRecord.java
+++ b/services/core/java/com/android/server/am/ServiceRecord.java
@@ -177,12 +177,6 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN
@PowerExemptionManager.ReasonCode
int mAllowWhileInUsePermissionInFgsReason = REASON_DENIED;
- // Integer version of mAllowWhileInUsePermissionInFgs that we keep track to compare
- // the old and new logics.
- // TODO: Remove them once we're confident in the new logic.
- int mDebugWhileInUseReasonInStartForeground = REASON_DENIED;
- int mDebugWhileInUseReasonInBindService = REASON_DENIED;
-
// A copy of mAllowWhileInUsePermissionInFgs's value when the service is entering FGS state.
boolean mAllowWhileInUsePermissionInFgsAtEntering;
/** Allow scheduling user-initiated jobs from the background. */
@@ -224,13 +218,6 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN
// is called.
int mStartForegroundCount;
- // Last time mAllowWhileInUsePermissionInFgs or mAllowStartForeground was set to "allowed"
- // from "disallowed" when the service was _not_ already a foreground service.
- // this means they're set in startService(). (not startForegroundService)
- // In startForeground(), if this timestamp is too old, we can't trust these flags, so
- // we need to reset them.
- long mLastUntrustedSetFgsRestrictionAllowedTime;
-
// This is a service record of a FGS delegate (not a service record of a real service)
boolean mIsFgsDelegate;
@Nullable ForegroundServiceDelegation mFgsDelegation;
@@ -624,12 +611,6 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN
pw.print(prefix); pw.print("mAllowWhileInUsePermissionInFgsReason=");
pw.println(PowerExemptionManager.reasonCodeToString(mAllowWhileInUsePermissionInFgsReason));
- pw.print(prefix); pw.print("debugWhileInUseReasonInStartForeground=");
- pw.println(PowerExemptionManager.reasonCodeToString(
- mDebugWhileInUseReasonInStartForeground));
- pw.print(prefix); pw.print("debugWhileInUseReasonInBindService=");
- pw.println(PowerExemptionManager.reasonCodeToString(mDebugWhileInUseReasonInBindService));
-
pw.print(prefix); pw.print("allowUiJobScheduling="); pw.println(mAllowUiJobScheduling);
pw.print(prefix); pw.print("recentCallingPackage=");
pw.println(mRecentCallingPackage);
@@ -642,10 +623,6 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN
pw.print(prefix); pw.print("infoAllowStartForeground=");
pw.println(mInfoAllowStartForeground);
- pw.print(prefix); pw.print("lastUntrustedSetFgsRestrictionAllowedTime=");
- TimeUtils.formatDuration(mLastUntrustedSetFgsRestrictionAllowedTime, now, pw);
- pw.println();
-
if (delayed) {
pw.print(prefix); pw.print("delayed="); pw.println(delayed);
}
diff --git a/services/core/java/com/android/server/biometrics/AuthSession.java b/services/core/java/com/android/server/biometrics/AuthSession.java
index 1989bc77583a..8ef2a1bd26c2 100644
--- a/services/core/java/com/android/server/biometrics/AuthSession.java
+++ b/services/core/java/com/android/server/biometrics/AuthSession.java
@@ -76,7 +76,7 @@ import java.util.function.Function;
*/
public final class AuthSession implements IBinder.DeathRecipient {
private static final String TAG = "BiometricService/AuthSession";
- private static final boolean DEBUG = false;
+ private static final boolean DEBUG = true;
/*
* Defined in biometrics.proto
@@ -118,6 +118,7 @@ public final class AuthSession implements IBinder.DeathRecipient {
@VisibleForTesting final IBinder mToken;
// Info to be shown on BiometricDialog when all cookies are returned.
@VisibleForTesting final PromptInfo mPromptInfo;
+ @VisibleForTesting final BiometricFrameworkStatsLogger mBiometricFrameworkStatsLogger;
private final long mRequestId;
private final long mOperationId;
private final int mUserId;
@@ -164,6 +165,32 @@ public final class AuthSession implements IBinder.DeathRecipient {
@NonNull PromptInfo promptInfo,
boolean debugEnabled,
@NonNull List<FingerprintSensorPropertiesInternal> fingerprintSensorProperties) {
+ this(context, biometricContext, statusBarService, sysuiReceiver, keystore, random,
+ clientDeathReceiver, preAuthInfo, token, requestId, operationId, userId,
+ sensorReceiver, clientReceiver, opPackageName, promptInfo, debugEnabled,
+ fingerprintSensorProperties, BiometricFrameworkStatsLogger.getInstance());
+ }
+
+ @VisibleForTesting
+ AuthSession(@NonNull Context context,
+ @NonNull BiometricContext biometricContext,
+ @NonNull IStatusBarService statusBarService,
+ @NonNull IBiometricSysuiReceiver sysuiReceiver,
+ @NonNull KeyStore keystore,
+ @NonNull Random random,
+ @NonNull ClientDeathReceiver clientDeathReceiver,
+ @NonNull PreAuthInfo preAuthInfo,
+ @NonNull IBinder token,
+ long requestId,
+ long operationId,
+ int userId,
+ @NonNull IBiometricSensorReceiver sensorReceiver,
+ @NonNull IBiometricServiceReceiver clientReceiver,
+ @NonNull String opPackageName,
+ @NonNull PromptInfo promptInfo,
+ boolean debugEnabled,
+ @NonNull List<FingerprintSensorPropertiesInternal> fingerprintSensorProperties,
+ @NonNull BiometricFrameworkStatsLogger logger) {
Slog.d(TAG, "Creating AuthSession with: " + preAuthInfo);
mContext = context;
mBiometricContext = biometricContext;
@@ -184,6 +211,7 @@ public final class AuthSession implements IBinder.DeathRecipient {
mDebugEnabled = debugEnabled;
mFingerprintSensorProperties = fingerprintSensorProperties;
mCancelled = false;
+ mBiometricFrameworkStatsLogger = logger;
try {
mClientReceiver.asBinder().linkToDeath(this, 0 /* flags */);
@@ -708,7 +736,7 @@ public final class AuthSession implements IBinder.DeathRecipient {
+ ", Latency: " + latency);
}
- BiometricFrameworkStatsLogger.getInstance().authenticate(
+ mBiometricFrameworkStatsLogger.authenticate(
mBiometricContext.updateContext(new OperationContextExt(true /* isBP */),
isCrypto()),
statsModality(),
@@ -723,11 +751,17 @@ public final class AuthSession implements IBinder.DeathRecipient {
} else {
final long latency = System.currentTimeMillis() - mStartTimeMs;
- int error = reason == BiometricPrompt.DISMISSED_REASON_NEGATIVE
- ? BiometricConstants.BIOMETRIC_ERROR_NEGATIVE_BUTTON
- : reason == BiometricPrompt.DISMISSED_REASON_USER_CANCEL
- ? BiometricConstants.BIOMETRIC_ERROR_USER_CANCELED
- : 0;
+ int error = 0;
+ switch(reason) {
+ case BiometricPrompt.DISMISSED_REASON_NEGATIVE:
+ error = BiometricConstants.BIOMETRIC_ERROR_NEGATIVE_BUTTON;
+ break;
+ case BiometricPrompt.DISMISSED_REASON_USER_CANCEL:
+ error = BiometricConstants.BIOMETRIC_ERROR_USER_CANCELED;
+ break;
+ default:
+ }
+
if (DEBUG) {
Slog.v(TAG, "Dismissed! Modality: " + statsModality()
+ ", User: " + mUserId
@@ -739,17 +773,19 @@ public final class AuthSession implements IBinder.DeathRecipient {
+ ", Latency: " + latency);
}
// Auth canceled
- BiometricFrameworkStatsLogger.getInstance().error(
- mBiometricContext.updateContext(new OperationContextExt(true /* isBP */),
- isCrypto()),
- statsModality(),
- BiometricsProtoEnums.ACTION_AUTHENTICATE,
- BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT,
- mDebugEnabled,
- latency,
- error,
- 0 /* vendorCode */,
- mUserId);
+ if (error != 0) {
+ mBiometricFrameworkStatsLogger.error(
+ mBiometricContext.updateContext(new OperationContextExt(true /* isBP */),
+ isCrypto()),
+ statsModality(),
+ BiometricsProtoEnums.ACTION_AUTHENTICATE,
+ BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT,
+ mDebugEnabled,
+ latency,
+ error,
+ 0 /* vendorCode */,
+ mUserId);
+ }
}
}
diff --git a/services/core/java/com/android/server/display/DisplayDeviceConfig.java b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
index ca482dc41ce5..7a797dd2250c 100644
--- a/services/core/java/com/android/server/display/DisplayDeviceConfig.java
+++ b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
@@ -889,6 +889,13 @@ public class DisplayDeviceConfig {
}
/**
+ * @return true if there is sdrHdrRatioMap, false otherwise.
+ */
+ public boolean hasSdrToHdrRatioSpline() {
+ return mSdrToHdrRatioSpline != null;
+ }
+
+ /**
* Calculate the HDR brightness for the specified SDR brightenss, restricted by the
* maxDesiredHdrSdrRatio (the ratio between the HDR luminance and SDR luminance)
*
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 38445295b0f1..da8eb23cbeae 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -238,6 +238,7 @@ public final class DisplayManagerService extends SystemService {
private static final int MSG_LOAD_BRIGHTNESS_CONFIGURATIONS = 6;
private static final int MSG_DELIVER_DISPLAY_EVENT_FRAME_RATE_OVERRIDE = 7;
private static final int MSG_DELIVER_DISPLAY_GROUP_EVENT = 8;
+ private static final int MSG_RECEIVED_DEVICE_STATE = 9;
private static final int[] EMPTY_ARRAY = new int[0];
private static final HdrConversionMode HDR_CONVERSION_MODE_UNSUPPORTED = new HdrConversionMode(
HDR_CONVERSION_UNSUPPORTED);
@@ -3213,6 +3214,10 @@ public final class DisplayManagerService extends SystemService {
mWindowManagerInternal.requestTraversalFromDisplayManager();
break;
+ case MSG_RECEIVED_DEVICE_STATE:
+ mWindowManagerInternal.onDisplayManagerReceivedDeviceState(msg.arg1);
+ break;
+
case MSG_UPDATE_VIEWPORT: {
final boolean changed;
synchronized (mSyncRoot) {
@@ -4680,6 +4685,14 @@ public final class DisplayManagerService extends SystemService {
public void onStateChanged(int deviceState) {
boolean isDeviceStateOverrideActive = deviceState != mBaseState;
synchronized (mSyncRoot) {
+ // Notify WindowManager that we are about to handle new device state, this should
+ // be sent before any work related to the device state in DisplayManager, so
+ // WindowManager could do implement that depends on the device state and display
+ // changes (serializes device state update and display change events)
+ Message msg = mHandler.obtainMessage(MSG_RECEIVED_DEVICE_STATE);
+ msg.arg1 = deviceState;
+ mHandler.sendMessage(msg);
+
mLogicalDisplayMapper
.setDeviceStateLocked(deviceState, isDeviceStateOverrideActive);
}
diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
index 79984c9b5355..c7c0fab6140d 100644
--- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
@@ -888,7 +888,9 @@ final class LocalDisplayAdapter extends DisplayAdapter {
BrightnessSynchronizer.brightnessFloatToInt(
sdrBrightnessState));
- handleHdrSdrNitsChanged(nits, sdrNits);
+ if (getDisplayDeviceConfig().hasSdrToHdrRatioSpline()) {
+ handleHdrSdrNitsChanged(nits, sdrNits);
+ }
} finally {
Trace.traceEnd(Trace.TRACE_TAG_POWER);
diff --git a/services/core/java/com/android/server/hdmi/HdmiEarcLocalDeviceTx.java b/services/core/java/com/android/server/hdmi/HdmiEarcLocalDeviceTx.java
index 873d5fc92601..4bc20a555dec 100644
--- a/services/core/java/com/android/server/hdmi/HdmiEarcLocalDeviceTx.java
+++ b/services/core/java/com/android/server/hdmi/HdmiEarcLocalDeviceTx.java
@@ -42,6 +42,12 @@ public class HdmiEarcLocalDeviceTx extends HdmiEarcLocalDevice {
// How long to wait for the audio system to report its capabilities after eARC was connected
static final long REPORT_CAPS_MAX_DELAY_MS = 2_000;
+ // Array containing the names of the eARC states. The integer value of the eARC state
+ // corresponds to the index in the array.
+ private static final String earcStatusNames[] = {"HDMI_EARC_STATUS_IDLE",
+ "HDMI_EARC_STATUS_EARC_PENDING", "HDMI_EARC_STATUS_ARC_PENDING",
+ "HDMI_EARC_STATUS_EARC_CONNECTED"};
+
// eARC Capability Data Structure parameters
private static final int EARC_CAPS_PAYLOAD_LENGTH = 0x02;
private static final int EARC_CAPS_DATA_START = 0x03;
@@ -75,11 +81,17 @@ public class HdmiEarcLocalDeviceTx extends HdmiEarcLocalDevice {
mReportCapsRunnable = new ReportCapsRunnable();
}
+ private String earcStatusToString(int status) {
+ return earcStatusNames[status];
+ }
+
protected void handleEarcStateChange(@Constants.EarcStatus int status) {
int oldEarcStatus;
+
synchronized (mLock) {
- HdmiLogger.debug("eARC state change [old:%b new %b]", mEarcStatus,
- status);
+ HdmiLogger.debug("eARC state change [old: %s(%d) new: %s(%d)]",
+ earcStatusToString(mEarcStatus), mEarcStatus,
+ earcStatusToString(status), status);
oldEarcStatus = mEarcStatus;
mEarcStatus = status;
}
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 9c780bb90b22..3e81f465a6c2 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -6012,12 +6012,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
@Override
- @WindowManagerFuncs.LidState
- public int getLidState() {
- return mDefaultDisplayPolicy.getLidState();
- }
-
- @Override
public void dumpDebug(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
proto.write(ROTATION_MODE, mDefaultDisplayRotation.getUserRotationMode());
diff --git a/services/core/java/com/android/server/policy/WindowManagerPolicy.java b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
index 3da78123016b..887f9461bdce 100644
--- a/services/core/java/com/android/server/policy/WindowManagerPolicy.java
+++ b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
@@ -218,14 +218,6 @@ public interface WindowManagerPolicy extends WindowManagerPolicyConstants {
* between it and the policy.
*/
public interface WindowManagerFuncs {
- @IntDef(prefix = { "LID_" }, value = {
- LID_ABSENT,
- LID_CLOSED,
- LID_OPEN,
- })
- @Retention(RetentionPolicy.SOURCE)
- @interface LidState{}
-
public static final int LID_ABSENT = -1;
public static final int LID_CLOSED = 0;
public static final int LID_OPEN = 1;
@@ -239,9 +231,8 @@ public interface WindowManagerPolicy extends WindowManagerPolicyConstants {
public static final int CAMERA_LENS_COVERED = 1;
/**
- * Returns a {@link LidState} that describes the current state of the lid switch.
+ * Returns a code that describes the current state of the lid switch.
*/
- @LidState
public int getLidState();
/**
@@ -291,7 +282,7 @@ public interface WindowManagerPolicy extends WindowManagerPolicyConstants {
/**
* Convert the lid state to a human readable format.
*/
- static String lidStateToString(@LidState int lid) {
+ static String lidStateToString(int lid) {
switch (lid) {
case LID_ABSENT:
return "LID_ABSENT";
@@ -1250,11 +1241,4 @@ public interface WindowManagerPolicy extends WindowManagerPolicyConstants {
* @return {@code true} if the key will be handled globally.
*/
boolean isGlobalKey(int keyCode);
-
- /**
- * Returns a {@link WindowManagerFuncs.LidState} that describes the current state of
- * the lid switch.
- */
- @WindowManagerFuncs.LidState
- int getLidState();
}
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 712be36e51c6..b8c5b3f5524a 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -33,7 +33,6 @@ import static android.os.PowerManagerInternal.isInteractive;
import static android.os.PowerManagerInternal.wakefulnessToString;
import static com.android.internal.util.LatencyTracker.ACTION_TURN_ON_SCREEN;
-import static com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs.LID_CLOSED;
import android.annotation.IntDef;
import android.annotation.NonNull;
@@ -5734,11 +5733,6 @@ public final class PowerManagerService extends SystemService
@Override // Binder call
public void wakeUp(long eventTime, @WakeReason int reason, String details,
String opPackageName) {
- if (mPolicy.getLidState() == LID_CLOSED) {
- Slog.d(TAG, "Ignoring wake up call due to the lid being closed");
- return;
- }
-
final long now = mClock.uptimeMillis();
if (eventTime > now) {
Slog.e(TAG, "Event time " + eventTime + " cannot be newer than " + now);
diff --git a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
index e82521584731..9128974fa9d3 100644
--- a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
+++ b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
@@ -1004,7 +1004,8 @@ public class StatsPullAtomService extends SystemService {
}
private void initAndRegisterDeferredPullers() {
- mUwbManager = mContext.getSystemService(UwbManager.class);
+ mUwbManager = mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_UWB)
+ ? mContext.getSystemService(UwbManager.class) : null;
registerUwbActivityInfo();
}
@@ -2172,6 +2173,9 @@ public class StatsPullAtomService extends SystemService {
}
private void registerUwbActivityInfo() {
+ if (mUwbManager == null) {
+ return;
+ }
int tagId = FrameworkStatsLog.UWB_ACTIVITY_INFO;
mStatsManager.setPullAtomCallback(
tagId,
diff --git a/services/core/java/com/android/server/wm/AnrController.java b/services/core/java/com/android/server/wm/AnrController.java
index 2df601fd1d3b..b9f6e177e637 100644
--- a/services/core/java/com/android/server/wm/AnrController.java
+++ b/services/core/java/com/android/server/wm/AnrController.java
@@ -68,7 +68,7 @@ class AnrController {
void notifyAppUnresponsive(InputApplicationHandle applicationHandle,
TimeoutRecord timeoutRecord) {
try {
- Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "notifyAppUnresponsive()");
+ timeoutRecord.mLatencyTracker.notifyAppUnresponsiveStarted();
timeoutRecord.mLatencyTracker.preDumpIfLockTooSlowStarted();
preDumpIfLockTooSlow();
timeoutRecord.mLatencyTracker.preDumpIfLockTooSlowEnded();
@@ -111,7 +111,6 @@ class AnrController {
if (!blamePendingFocusRequest) {
Slog.i(TAG_WM, "ANR in " + activity.getName() + ". Reason: "
+ timeoutRecord.mReason);
- dumpAnrStateAsync(activity, null /* windowState */, timeoutRecord.mReason);
mUnresponsiveAppByDisplay.put(activity.getDisplayId(), activity);
}
}
@@ -123,8 +122,13 @@ class AnrController {
} else {
activity.inputDispatchingTimedOut(timeoutRecord, INVALID_PID);
}
+
+ if (!blamePendingFocusRequest) {
+ dumpAnrStateAsync(activity, null /* windowState */, timeoutRecord.mReason);
+ }
+
} finally {
- Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
+ timeoutRecord.mLatencyTracker.notifyAppUnresponsiveEnded();
}
}
@@ -139,7 +143,7 @@ class AnrController {
void notifyWindowUnresponsive(@NonNull IBinder token, @NonNull OptionalInt pid,
@NonNull TimeoutRecord timeoutRecord) {
try {
- Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "notifyWindowUnresponsive()");
+ timeoutRecord.mLatencyTracker.notifyWindowUnresponsiveStarted();
if (notifyWindowUnresponsive(token, timeoutRecord)) {
return;
}
@@ -150,7 +154,7 @@ class AnrController {
}
notifyWindowUnresponsive(pid.getAsInt(), timeoutRecord);
} finally {
- Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
+ timeoutRecord.mLatencyTracker.notifyWindowUnresponsiveEnded();
}
}
@@ -168,6 +172,7 @@ class AnrController {
final int pid;
final boolean aboveSystem;
final ActivityRecord activity;
+ final WindowState windowState;
timeoutRecord.mLatencyTracker.waitingOnGlobalLockStarted();
synchronized (mService.mGlobalLock) {
timeoutRecord.mLatencyTracker.waitingOnGlobalLockEnded();
@@ -175,7 +180,7 @@ class AnrController {
if (target == null) {
return false;
}
- WindowState windowState = target.getWindowState();
+ windowState = target.getWindowState();
pid = target.getPid();
// Blame the activity if the input token belongs to the window. If the target is
// embedded, then we will blame the pid instead.
@@ -183,13 +188,13 @@ class AnrController {
? windowState.mActivityRecord : null;
Slog.i(TAG_WM, "ANR in " + target + ". Reason:" + timeoutRecord.mReason);
aboveSystem = isWindowAboveSystem(windowState);
- dumpAnrStateAsync(activity, windowState, timeoutRecord.mReason);
}
if (activity != null) {
activity.inputDispatchingTimedOut(timeoutRecord, pid);
} else {
mService.mAmInternal.inputDispatchingTimedOut(pid, aboveSystem, timeoutRecord);
}
+ dumpAnrStateAsync(activity, windowState, timeoutRecord.mReason);
return true;
}
@@ -199,15 +204,10 @@ class AnrController {
private void notifyWindowUnresponsive(int pid, TimeoutRecord timeoutRecord) {
Slog.i(TAG_WM,
"ANR in input window owned by pid=" + pid + ". Reason: " + timeoutRecord.mReason);
- timeoutRecord.mLatencyTracker.waitingOnGlobalLockStarted();
- synchronized (mService.mGlobalLock) {
- timeoutRecord.mLatencyTracker.waitingOnGlobalLockEnded();
- dumpAnrStateAsync(null /* activity */, null /* windowState */, timeoutRecord.mReason);
- }
-
// We cannot determine the z-order of the window, so place the anr dialog as high
// as possible.
mService.mAmInternal.inputDispatchingTimedOut(pid, true /*aboveSystem*/, timeoutRecord);
+ dumpAnrStateAsync(null /* activity */, null /* windowState */, timeoutRecord.mReason);
}
/**
diff --git a/services/core/java/com/android/server/wm/DeviceStateController.java b/services/core/java/com/android/server/wm/DeviceStateController.java
index 41c052d95053..31b1069dd022 100644
--- a/services/core/java/com/android/server/wm/DeviceStateController.java
+++ b/services/core/java/com/android/server/wm/DeviceStateController.java
@@ -19,9 +19,6 @@ package com.android.server.wm;
import android.annotation.CallbackExecutor;
import android.annotation.NonNull;
import android.content.Context;
-import android.hardware.devicestate.DeviceStateManager;
-import android.os.Handler;
-import android.os.HandlerExecutor;
import android.util.ArrayMap;
import com.android.internal.R;
@@ -36,17 +33,15 @@ import java.util.concurrent.Executor;
import java.util.function.Consumer;
/**
- * Class that registers callbacks with the {@link DeviceStateManager} and responds to device
+ * Class that listens for a callback from display manager and responds to device state
* changes.
*/
-final class DeviceStateController implements DeviceStateManager.DeviceStateCallback {
+final class DeviceStateController {
// Used to synchronize WindowManager services call paths with DeviceStateManager's callbacks.
@NonNull
private final WindowManagerGlobalLock mWmLock;
@NonNull
- private final DeviceStateManager mDeviceStateManager;
- @NonNull
private final int[] mOpenDeviceStates;
@NonNull
private final int[] mHalfFoldedDeviceStates;
@@ -77,10 +72,8 @@ final class DeviceStateController implements DeviceStateManager.DeviceStateCallb
CONCURRENT,
}
- DeviceStateController(@NonNull Context context, @NonNull Handler handler,
- @NonNull WindowManagerGlobalLock wmLock) {
+ DeviceStateController(@NonNull Context context, @NonNull WindowManagerGlobalLock wmLock) {
mWmLock = wmLock;
- mDeviceStateManager = context.getSystemService(DeviceStateManager.class);
mOpenDeviceStates = context.getResources()
.getIntArray(R.array.config_openDeviceStates);
@@ -97,10 +90,6 @@ final class DeviceStateController implements DeviceStateManager.DeviceStateCallb
mMatchBuiltInDisplayOrientationToDefaultDisplay = context.getResources()
.getBoolean(R.bool
.config_matchSecondaryInternalDisplaysOrientationToReverseDefaultDisplay);
-
- if (mDeviceStateManager != null) {
- mDeviceStateManager.registerCallback(new HandlerExecutor(handler), this);
- }
}
/**
@@ -137,8 +126,19 @@ final class DeviceStateController implements DeviceStateManager.DeviceStateCallb
return mMatchBuiltInDisplayOrientationToDefaultDisplay;
}
- @Override
- public void onStateChanged(int state) {
+ /**
+ * This event is sent from DisplayManager just before the device state is applied to
+ * the displays. This is needed to make sure that we first receive this callback before
+ * any device state related display updates from the DisplayManager.
+ *
+ * The flow for this event is the following:
+ * - {@link DeviceStateManager} sends event to {@link android.hardware.display.DisplayManager}
+ * - {@link android.hardware.display.DisplayManager} sends it to {@link WindowManagerInternal}
+ * - {@link WindowManagerInternal} eventually calls this method
+ *
+ * @param state device state as defined by {@link DeviceStateManager}
+ */
+ public void onDeviceStateReceivedByDisplayManager(int state) {
mCurrentState = state;
final DeviceState deviceState;
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index da102d0713ae..65771d1ce373 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -225,7 +225,6 @@ public class DisplayPolicy {
/** Currently it can only be non-null when physical display switch happens. */
private DecorInsets.Cache mCachedDecorInsets;
- @WindowManagerFuncs.LidState
private volatile int mLidState = LID_ABSENT;
private volatile int mDockMode = Intent.EXTRA_DOCK_STATE_UNDOCKED;
private volatile boolean mHdmiPlugged;
@@ -753,11 +752,10 @@ public class DisplayPolicy {
return mNavigationBarCanMove;
}
- public void setLidState(@WindowManagerFuncs.LidState int lidState) {
+ public void setLidState(int lidState) {
mLidState = lidState;
}
- @WindowManagerFuncs.LidState
public int getLidState() {
return mLidState;
}
diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java
index bc1ddf8f66bc..8be36f07a040 100644
--- a/services/core/java/com/android/server/wm/DisplayRotation.java
+++ b/services/core/java/com/android/server/wm/DisplayRotation.java
@@ -1730,7 +1730,9 @@ public class DisplayRotation {
}
/**
- * Called by the DeviceStateManager callback when the device state changes.
+ * Called by the display manager just before it applied the device state, it is guaranteed
+ * that in case of physical display change the {@link DisplayRotation#physicalDisplayChanged}
+ * method will be invoked *after* this one.
*/
void foldStateChanged(DeviceStateController.DeviceState deviceState) {
if (mFoldController != null) {
diff --git a/services/core/java/com/android/server/wm/PhysicalDisplaySwitchTransitionLauncher.java b/services/core/java/com/android/server/wm/PhysicalDisplaySwitchTransitionLauncher.java
index 78522498987c..f0757db76bda 100644
--- a/services/core/java/com/android/server/wm/PhysicalDisplaySwitchTransitionLauncher.java
+++ b/services/core/java/com/android/server/wm/PhysicalDisplaySwitchTransitionLauncher.java
@@ -71,7 +71,10 @@ public class PhysicalDisplaySwitchTransitionLauncher {
}
/**
- * Called by the DeviceStateManager callback when the state changes.
+ * Called by the display manager just before it applied the device state, it is guaranteed
+ * that in case of physical display change the
+ * {@link PhysicalDisplaySwitchTransitionLauncher#requestDisplaySwitchTransitionIfNeeded}
+ * method will be invoked *after* this one.
*/
void foldStateChanged(DeviceState newDeviceState) {
boolean isUnfolding = mDeviceState == FOLDED
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 7e839596c59b..4995236da1be 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -438,8 +438,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
mTaskSupervisor = mService.mTaskSupervisor;
mTaskSupervisor.mRootWindowContainer = this;
mDisplayOffTokenAcquirer = mService.new SleepTokenAcquirerImpl(DISPLAY_OFF_SLEEP_TOKEN_TAG);
- mDeviceStateController = new DeviceStateController(service.mContext, service.mH,
- service.mGlobalLock);
+ mDeviceStateController = new DeviceStateController(service.mContext, service.mGlobalLock);
mDisplayRotationCoordinator = new DisplayRotationCoordinator();
}
@@ -1283,6 +1282,15 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
false /* includingParents */);
}
+ /**
+ * Called just before display manager has applied the device state to the displays
+ * @param deviceState device state as defined by
+ * {@link android.hardware.devicestate.DeviceStateManager}
+ */
+ void onDisplayManagerReceivedDeviceState(int deviceState) {
+ mDeviceStateController.onDeviceStateReceivedByDisplayManager(deviceState);
+ }
+
// TODO(multi-display): Look at all callpoints to make sure they make sense in multi-display.
DisplayContent getDefaultDisplay() {
return mDefaultDisplay;
diff --git a/services/core/java/com/android/server/wm/WindowManagerInternal.java b/services/core/java/com/android/server/wm/WindowManagerInternal.java
index 92d4cec80cc9..9e7df004806b 100644
--- a/services/core/java/com/android/server/wm/WindowManagerInternal.java
+++ b/services/core/java/com/android/server/wm/WindowManagerInternal.java
@@ -370,6 +370,13 @@ public abstract class WindowManagerInternal {
public abstract void requestTraversalFromDisplayManager();
/**
+ * Called just before display manager has applied the device state to the displays
+ * @param deviceState device state as defined by
+ * {@link android.hardware.devicestate.DeviceStateManager}
+ */
+ public abstract void onDisplayManagerReceivedDeviceState(int deviceState);
+
+ /**
* Set by the accessibility layer to observe changes in the magnified region,
* rotation, and other window transformations related to display magnification
* as the window manager is responsible for doing the actual magnification
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index e33c6f03c720..d84c85c8e823 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -7674,6 +7674,15 @@ public class WindowManagerService extends IWindowManager.Stub
}
@Override
+ public void onDisplayManagerReceivedDeviceState(int deviceState) {
+ mH.post(() -> {
+ synchronized (mGlobalLock) {
+ mRoot.onDisplayManagerReceivedDeviceState(deviceState);
+ }
+ });
+ }
+
+ @Override
public void setMagnificationSpec(int displayId, MagnificationSpec spec) {
synchronized (mGlobalLock) {
if (mAccessibilityController.hasCallbacks()) {
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java
index 79c03497223a..5ba22830eec9 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java
@@ -454,8 +454,8 @@ final class DevicePolicyEngine {
onGlobalPolicyChanged(policyDefinition, enforcingAdmin);
}
- applyGlobalPolicyOnUsersWithLocalPoliciesLocked(
- policyDefinition, enforcingAdmin, /* value= */ null, /* enforcePolicy= */ true);
+ applyGlobalPolicyOnUsersWithLocalPoliciesLocked(policyDefinition, enforcingAdmin,
+ /* value= */ null, /* skipEnforcePolicy= */ false);
sendPolicyResultToAdmin(
enforcingAdmin,
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 7464045ad696..edb8e0c5aa64 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -14906,8 +14906,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
policy = new LockTaskPolicy(currentPolicy);
policy.setPackages(Set.of(packages));
}
- if (policy.getPackages().isEmpty()
- && policy.getFlags() == DevicePolicyManager.LOCK_TASK_FEATURE_NONE) {
+ if (policy.getPackages().isEmpty()) {
mDevicePolicyEngine.removeLocalPolicy(
PolicyDefinition.LOCK_TASK,
enforcingAdmin,
@@ -20689,7 +20688,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
private void addUserControlDisabledPackages(CallerIdentity caller,
EnforcingAdmin enforcingAdmin, Set<String> packages) {
- if (isCallerDeviceOwner(caller)) {
+ if (isDeviceOwner(caller)) {
mDevicePolicyEngine.setGlobalPolicy(
PolicyDefinition.USER_CONTROLLED_DISABLED_PACKAGES,
enforcingAdmin,
@@ -20705,7 +20704,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
private void removeUserControlDisabledPackages(CallerIdentity caller,
EnforcingAdmin enforcingAdmin) {
- if (isCallerDeviceOwner(caller)) {
+ if (isDeviceOwner(caller)) {
mDevicePolicyEngine.removeGlobalPolicy(
PolicyDefinition.USER_CONTROLLED_DISABLED_PACKAGES,
enforcingAdmin);
@@ -20717,12 +20716,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
}
- private boolean isCallerDeviceOwner(CallerIdentity caller) {
- synchronized (getLockObject()) {
- return getDeviceOwnerUserIdUncheckedLocked() == caller.getUserId();
- }
- }
-
@Override
public List<String> getUserControlDisabledPackages(ComponentName who,
String callerPackageName) {
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyEnforcerCallbacks.java b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyEnforcerCallbacks.java
index 454337fcf141..3b048b250075 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyEnforcerCallbacks.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyEnforcerCallbacks.java
@@ -167,7 +167,7 @@ final class PolicyEnforcerCallbacks {
packages == null ? null : packages.stream().toList());
LocalServices.getService(UsageStatsManagerInternal.class)
.setAdminProtectedPackages(
- packages == null ? null : new ArraySet(packages), userId);
+ packages == null ? null : new ArraySet<>(packages), userId);
});
return true;
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java
index 636576492362..4989f841a275 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java
@@ -276,7 +276,11 @@ public class BroadcastQueueTest {
switch (behavior) {
case SUCCESS:
case SUCCESS_PREDECESSOR:
- mQueue.onApplicationAttachedLocked(deliverRes);
+ try {
+ mQueue.onApplicationAttachedLocked(deliverRes);
+ } catch (BroadcastDeliveryFailedException e) {
+ Log.v(TAG, "Error while invoking onApplicationAttachedLocked", e);
+ }
break;
case FAIL_TIMEOUT:
case FAIL_TIMEOUT_PREDECESSOR:
@@ -1120,6 +1124,7 @@ public class BroadcastQueueTest {
final ProcessRecord restartedReceiverApp = mAms.getProcessRecordLocked(PACKAGE_GREEN,
getUidForPackage(PACKAGE_GREEN));
assertNotEquals(receiverApp, restartedReceiverApp);
+ verifyScheduleReceiver(restartedReceiverApp, airplane);
verifyScheduleReceiver(restartedReceiverApp, timezone);
}
@@ -1304,12 +1309,7 @@ public class BroadcastQueueTest {
final ProcessRecord receiverOrangeApp = mAms.getProcessRecordLocked(PACKAGE_ORANGE,
getUidForPackage(PACKAGE_ORANGE));
- if (mImpl == Impl.MODERN) {
- // Modern queue does not retry sending a broadcast once any broadcast delivery fails.
- assertNull(receiverGreenApp);
- } else {
- verifyScheduleReceiver(times(1), receiverGreenApp, airplane);
- }
+ verifyScheduleReceiver(times(1), receiverGreenApp, airplane);
verifyScheduleRegisteredReceiver(times(1), receiverBlueApp, airplane);
verifyScheduleReceiver(times(1), receiverYellowApp, airplane);
verifyScheduleReceiver(times(1), receiverOrangeApp, timezone);
diff --git a/services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java b/services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java
index 5f82ec1dde02..b7dbaf93b9e2 100644
--- a/services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java
@@ -27,6 +27,7 @@ import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeTrue;
import static org.mockito.ArgumentMatchers.anyFloat;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.mock;
@@ -981,6 +982,7 @@ public class LocalDisplayAdapterTest {
DisplayDevice displayDevice = mListener.addedDisplays.get(0);
// Turn on / initialize
+ assumeTrue(displayDevice.getDisplayDeviceConfig().hasSdrToHdrRatioSpline());
Runnable changeStateRunnable = displayDevice.requestDisplayStateLocked(Display.STATE_ON, 0,
0);
changeStateRunnable.run();
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
index 8cfc150afe56..7e638a869682 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
@@ -280,6 +280,7 @@ public class AccessibilityManagerServiceTest {
@SmallTest
@Test
public void testRegisterProxy() throws Exception {
+ when(mProxyManager.displayBelongsToCaller(anyInt(), anyInt())).thenReturn(true);
mA11yms.registerProxyForDisplay(mMockServiceClient, TEST_DISPLAY);
verify(mProxyManager).registerProxy(eq(mMockServiceClient), eq(TEST_DISPLAY), anyInt(),
eq(mMockSecurityPolicy),
@@ -289,9 +290,9 @@ public class AccessibilityManagerServiceTest {
@SmallTest
@Test
- public void testRegisterProxyWithoutA11yPermission() throws Exception {
+ public void testRegisterProxyWithoutA11yPermissionOrRole() throws Exception {
doThrow(SecurityException.class).when(mMockSecurityPolicy)
- .enforceCallingOrSelfPermission(Manifest.permission.MANAGE_ACCESSIBILITY);
+ .checkForAccessibilityPermissionOrRole();
assertThrows(SecurityException.class,
() -> mA11yms.registerProxyForDisplay(mMockServiceClient, TEST_DISPLAY));
@@ -314,7 +315,7 @@ public class AccessibilityManagerServiceTest {
@SmallTest
@Test
public void testRegisterProxyForDefaultDisplay() throws Exception {
- assertThrows(IllegalArgumentException.class,
+ assertThrows(SecurityException.class,
() -> mA11yms.registerProxyForDisplay(mMockServiceClient, Display.DEFAULT_DISPLAY));
verify(mProxyManager, never()).registerProxy(any(), anyInt(), anyInt(), any(),
any(), any(), any());
@@ -332,6 +333,7 @@ public class AccessibilityManagerServiceTest {
@SmallTest
@Test
public void testUnRegisterProxyWithPermission() throws Exception {
+ when(mProxyManager.displayBelongsToCaller(anyInt(), anyInt())).thenReturn(true);
mA11yms.registerProxyForDisplay(mMockServiceClient, TEST_DISPLAY);
mA11yms.unregisterProxyForDisplay(TEST_DISPLAY);
@@ -340,9 +342,9 @@ public class AccessibilityManagerServiceTest {
@SmallTest
@Test
- public void testUnRegisterProxyWithoutA11yPermission() {
+ public void testUnRegisterProxyWithoutA11yPermissionOrRole() {
doThrow(SecurityException.class).when(mMockSecurityPolicy)
- .enforceCallingOrSelfPermission(Manifest.permission.MANAGE_ACCESSIBILITY);
+ .checkForAccessibilityPermissionOrRole();
assertThrows(SecurityException.class,
() -> mA11yms.unregisterProxyForDisplay(TEST_DISPLAY));
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java b/services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java
index 4268eb924225..662477ddbbe9 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java
@@ -18,6 +18,9 @@ package com.android.server.biometrics;
import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE;
import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT;
+import static android.hardware.biometrics.BiometricConstants.BIOMETRIC_ERROR_NEGATIVE_BUTTON;
+import static android.hardware.biometrics.BiometricPrompt.DISMISSED_REASON_BIOMETRIC_CONFIRMED;
+import static android.hardware.biometrics.BiometricPrompt.DISMISSED_REASON_BIOMETRIC_CONFIRM_NOT_REQUIRED;
import static android.hardware.biometrics.BiometricPrompt.DISMISSED_REASON_NEGATIVE;
import static com.android.server.biometrics.BiometricServiceStateProto.STATE_AUTH_CALLED;
@@ -32,6 +35,7 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.anyObject;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
@@ -45,6 +49,7 @@ import android.app.trust.ITrustManager;
import android.content.Context;
import android.content.res.Resources;
import android.hardware.biometrics.BiometricManager.Authenticators;
+import android.hardware.biometrics.BiometricsProtoEnums;
import android.hardware.biometrics.ComponentInfoInternal;
import android.hardware.biometrics.IBiometricAuthenticator;
import android.hardware.biometrics.IBiometricSensorReceiver;
@@ -64,7 +69,10 @@ import android.security.KeyStore;
import androidx.test.filters.SmallTest;
import com.android.internal.statusbar.IStatusBarService;
+import com.android.internal.util.FrameworkStatsLog;
import com.android.server.biometrics.log.BiometricContext;
+import com.android.server.biometrics.log.BiometricFrameworkStatsLogger;
+import com.android.server.biometrics.log.OperationContextExt;
import org.junit.Before;
import org.junit.Test;
@@ -95,6 +103,7 @@ public class AuthSessionTest {
@Mock private IBiometricSysuiReceiver mSysuiReceiver;
@Mock private KeyStore mKeyStore;
@Mock private AuthSession.ClientDeathReceiver mClientDeathReceiver;
+ @Mock private BiometricFrameworkStatsLogger mBiometricFrameworkStatsLogger;
private Random mRandom;
private IBinder mToken;
@@ -395,6 +404,84 @@ public class AuthSessionTest {
eq(FingerprintManager.FINGERPRINT_ACQUIRED_VENDOR_BASE), eq(acquiredStrVendor));
}
+ @Test
+ public void testLogOnDialogDismissed_authenticatedWithConfirmation() throws RemoteException {
+ final IBiometricAuthenticator faceAuthenticator = mock(IBiometricAuthenticator.class);
+
+ setupFace(0 /* id */, false /* confirmationAlwaysRequired */, faceAuthenticator);
+ final AuthSession session = createAuthSession(mSensors,
+ false /* checkDevicePolicyManager */,
+ Authenticators.BIOMETRIC_STRONG,
+ TEST_REQUEST_ID,
+ 0 /* operationId */,
+ 0 /* userId */);
+ session.goToInitialState();
+ assertEquals(STATE_AUTH_CALLED, session.getState());
+
+ session.onDialogDismissed(DISMISSED_REASON_BIOMETRIC_CONFIRMED, null);
+ verify(mBiometricFrameworkStatsLogger, times(1)).authenticate(
+ (OperationContextExt) anyObject(),
+ eq(BiometricsProtoEnums.MODALITY_FACE),
+ eq(BiometricsProtoEnums.ACTION_UNKNOWN),
+ eq(BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT),
+ eq(false), /* debugEnabled */
+ anyLong(), /* latency */
+ eq(FrameworkStatsLog.BIOMETRIC_AUTHENTICATED__STATE__CONFIRMED),
+ eq(true), /* confirmationRequired */
+ eq(0) /* userId */,
+ eq(-1f) /* ambientLightLux */);
+ }
+
+ @Test
+ public void testLogOnDialogDismissed_authenticatedWithoutConfirmation() throws RemoteException {
+ final IBiometricAuthenticator faceAuthenticator = mock(IBiometricAuthenticator.class);
+
+ setupFace(0 /* id */, false /* confirmationAlwaysRequired */, faceAuthenticator);
+ final AuthSession session = createAuthSession(mSensors,
+ false /* checkDevicePolicyManager */,
+ Authenticators.BIOMETRIC_STRONG,
+ TEST_REQUEST_ID,
+ 0 /* operationId */,
+ 0 /* userId */);
+ session.goToInitialState();
+ assertEquals(STATE_AUTH_CALLED, session.getState());
+
+ session.onDialogDismissed(DISMISSED_REASON_BIOMETRIC_CONFIRM_NOT_REQUIRED, null);
+ verify(mBiometricFrameworkStatsLogger, never()).authenticate(
+ anyObject(), anyInt(), anyInt(), anyInt(), anyBoolean(), anyLong(), anyInt(),
+ anyBoolean(), anyInt(), eq(-1f));
+ verify(mBiometricFrameworkStatsLogger, never()).error(
+ anyObject(), anyInt(), anyInt(), anyInt(), anyBoolean(), anyLong(), anyInt(),
+ anyInt(), anyInt());
+ }
+
+ @Test
+ public void testLogOnDialogDismissed_error() throws RemoteException {
+ final IBiometricAuthenticator faceAuthenticator = mock(IBiometricAuthenticator.class);
+
+ setupFace(0 /* id */, false /* confirmationAlwaysRequired */, faceAuthenticator);
+ final AuthSession session = createAuthSession(mSensors,
+ false /* checkDevicePolicyManager */,
+ Authenticators.BIOMETRIC_STRONG,
+ TEST_REQUEST_ID,
+ 0 /* operationId */,
+ 0 /* userId */);
+ session.goToInitialState();
+ assertEquals(STATE_AUTH_CALLED, session.getState());
+
+ session.onDialogDismissed(DISMISSED_REASON_NEGATIVE, null);
+ verify(mBiometricFrameworkStatsLogger, times(1)).error(
+ (OperationContextExt) anyObject(),
+ eq(BiometricsProtoEnums.MODALITY_FACE),
+ eq(BiometricsProtoEnums.ACTION_AUTHENTICATE),
+ eq(BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT),
+ eq(false),
+ anyLong(),
+ eq(BIOMETRIC_ERROR_NEGATIVE_BUTTON),
+ eq(0) /* vendorCode */,
+ eq(0) /* userId */);
+ }
+
// TODO (b/208484275) : Enable these tests
// @Test
// public void testPreAuth_canAuthAndPrivacyDisabled() throws Exception {
@@ -498,7 +585,7 @@ public class AuthSessionTest {
return new AuthSession(mContext, mBiometricContext, mStatusBarService, mSysuiReceiver,
mKeyStore, mRandom, mClientDeathReceiver, preAuthInfo, mToken, requestId,
operationId, userId, mSensorReceiver, mClientReceiver, TEST_PACKAGE, promptInfo,
- false /* debugEnabled */, mFingerprintSensorProps);
+ false /* debugEnabled */, mFingerprintSensorProps, mBiometricFrameworkStatsLogger);
}
private PromptInfo createPromptInfo(@Authenticators.Types int authenticators) {
diff --git a/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
index a6c57371803b..0e775d57bbd7 100644
--- a/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
@@ -35,12 +35,14 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
@@ -72,6 +74,7 @@ import android.hardware.display.IVirtualDisplayCallback;
import android.hardware.display.VirtualDisplayConfig;
import android.media.projection.IMediaProjection;
import android.media.projection.IMediaProjectionManager;
+import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.MessageQueue;
@@ -96,17 +99,18 @@ import com.android.internal.R;
import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.companion.virtual.VirtualDeviceManagerInternal;
+import com.android.server.display.DisplayManagerService.DeviceStateListener;
import com.android.server.display.DisplayManagerService.SyncRoot;
import com.android.server.input.InputManagerInternal;
import com.android.server.lights.LightsManager;
import com.android.server.sensors.SensorManagerInternal;
import com.android.server.wm.WindowManagerInternal;
-import com.google.common.collect.ImmutableMap;
-
import libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges;
import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges;
+import com.google.common.collect.ImmutableMap;
+
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -114,6 +118,7 @@ import org.junit.rules.TestRule;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
+import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
@@ -547,6 +552,30 @@ public class DisplayManagerServiceTest {
}
/**
+ * Tests that we send the device state to window manager
+ */
+ @Test
+ public void testOnStateChanged_sendsStateChangedEventToWm() throws Exception {
+ DisplayManagerService displayManager =
+ new DisplayManagerService(mContext, mShortMockedInjector);
+ registerDefaultDisplays(displayManager);
+ displayManager.windowManagerAndInputReady();
+ displayManager.onBootPhase(SystemService.PHASE_BOOT_COMPLETED);
+ DeviceStateListener listener = displayManager.new DeviceStateListener();
+ Handler handler = displayManager.getDisplayHandler();
+ IDisplayManagerCallback displayChangesCallback = registerDisplayChangeCallback(
+ displayManager);
+
+ listener.onStateChanged(123);
+ waitForIdleHandler(handler);
+
+ InOrder inOrder = inOrder(mMockWindowManagerInternal, displayChangesCallback);
+ // Verify there are no display events before WM call
+ inOrder.verify(displayChangesCallback, never()).onDisplayEvent(anyInt(), anyInt());
+ inOrder.verify(mMockWindowManagerInternal).onDisplayManagerReceivedDeviceState(123);
+ }
+
+ /**
* Tests that there should be a display change notification to WindowManager to update its own
* internal state for things like display cutout when nonOverrideDisplayInfo is changed.
*/
@@ -2054,6 +2083,15 @@ public class DisplayManagerServiceTest {
updateDisplayDeviceInfo(displayManager, displayDevice, displayDeviceInfo);
}
+ private IDisplayManagerCallback registerDisplayChangeCallback(
+ DisplayManagerService displayManager) {
+ IDisplayManagerCallback displayChangesCallback = mock(IDisplayManagerCallback.class);
+ when(displayChangesCallback.asBinder()).thenReturn(new Binder());
+ DisplayManagerService.BinderService binderService = displayManager.new BinderService();
+ binderService.registerCallback(displayChangesCallback);
+ return displayChangesCallback;
+ }
+
private FakeDisplayManagerCallback registerDisplayListenerCallback(
DisplayManagerService displayManager,
DisplayManagerService.BinderService displayManagerBinderService,
diff --git a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
index 7aec04568e0f..933f00231313 100644
--- a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
@@ -26,9 +26,6 @@ import static android.os.PowerManagerInternal.WAKEFULNESS_AWAKE;
import static android.os.PowerManagerInternal.WAKEFULNESS_DOZING;
import static android.os.PowerManagerInternal.WAKEFULNESS_DREAMING;
-import static com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs.LID_ABSENT;
-import static com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs.LID_CLOSED;
-
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertFalse;
@@ -148,7 +145,6 @@ public class PowerManagerServiceTest {
@Mock private ActivityManagerInternal mActivityManagerInternalMock;
@Mock private AttentionManagerInternal mAttentionManagerInternalMock;
@Mock private DreamManagerInternal mDreamManagerInternalMock;
- @Mock private WindowManagerPolicy mPolicyMock;
@Mock private PowerManagerService.NativeWrapper mNativeWrapperMock;
@Mock private Notifier mNotifierMock;
@Mock private WirelessChargerDetector mWirelessChargerDetectorMock;
@@ -209,7 +205,6 @@ public class PowerManagerServiceTest {
.thenReturn(true);
when(mSystemPropertiesMock.get(eq(SYSTEM_PROPERTY_QUIESCENT), anyString())).thenReturn("");
when(mAmbientDisplayConfigurationMock.ambientDisplayAvailable()).thenReturn(true);
- when(mPolicyMock.getLidState()).thenReturn(LID_ABSENT);
addLocalServiceMock(LightsManager.class, mLightsManagerMock);
addLocalServiceMock(DisplayManagerInternal.class, mDisplayManagerInternalMock);
@@ -217,7 +212,6 @@ public class PowerManagerServiceTest {
addLocalServiceMock(ActivityManagerInternal.class, mActivityManagerInternalMock);
addLocalServiceMock(AttentionManagerInternal.class, mAttentionManagerInternalMock);
addLocalServiceMock(DreamManagerInternal.class, mDreamManagerInternalMock);
- addLocalServiceMock(WindowManagerPolicy.class, mPolicyMock);
mContextSpy = spy(new ContextWrapper(ApplicationProvider.getApplicationContext()));
mResourcesSpy = spy(mContextSpy.getResources());
@@ -684,20 +678,6 @@ public class PowerManagerServiceTest {
assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
}
- @Test
- public void testWakefulnessAwake_ShouldNotWakeUpWhenLidClosed() {
- when(mPolicyMock.getLidState()).thenReturn(LID_CLOSED);
- createService();
- startSystem();
- forceSleep();
-
- mService.getBinderServiceInstance().wakeUp(mClock.now(),
- PowerManager.WAKE_REASON_POWER_BUTTON,
- "testing IPowerManager.wakeUp()", "pkg.name");
-
- assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
- }
-
/**
* Tests a series of variants that control whether a device wakes-up when it is plugged in
* or docked.
diff --git a/services/tests/wmtests/src/com/android/server/wm/DeviceStateControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/DeviceStateControllerTests.java
index b515a9dc0d6b..07d8b8a0c8df 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DeviceStateControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DeviceStateControllerTests.java
@@ -27,7 +27,6 @@ import static org.mockito.ArgumentMatchers.any;
import android.content.Context;
import android.content.res.Resources;
import android.hardware.devicestate.DeviceStateManager;
-import android.os.Handler;
import android.platform.test.annotations.Presubmit;
import androidx.test.filters.SmallTest;
@@ -73,20 +72,19 @@ public class DeviceStateControllerTests {
};
mBuilder.setDelegate(mDelegate);
mBuilder.build();
- verify(mMockDeviceStateManager).registerCallback(any(), any());
}
@Test
public void testInitialization() {
initialize(true /* supportFold */, true /* supportHalfFolded */);
- mTarget.onStateChanged(mOpenDeviceStates[0]);
+ mTarget.onDeviceStateReceivedByDisplayManager(mOpenDeviceStates[0]);
assertEquals(DeviceStateController.DeviceState.OPEN, mCurrentState);
}
@Test
public void testInitializationWithNoFoldSupport() {
initialize(false /* supportFold */, false /* supportHalfFolded */);
- mTarget.onStateChanged(mFoldedStates[0]);
+ mTarget.onDeviceStateReceivedByDisplayManager(mFoldedStates[0]);
// Note that the folded state is ignored.
assertEquals(DeviceStateController.DeviceState.UNKNOWN, mCurrentState);
}
@@ -94,24 +92,24 @@ public class DeviceStateControllerTests {
@Test
public void testWithFoldSupported() {
initialize(true /* supportFold */, false /* supportHalfFolded */);
- mTarget.onStateChanged(mOpenDeviceStates[0]);
+ mTarget.onDeviceStateReceivedByDisplayManager(mOpenDeviceStates[0]);
assertEquals(DeviceStateController.DeviceState.OPEN, mCurrentState);
- mTarget.onStateChanged(mFoldedStates[0]);
+ mTarget.onDeviceStateReceivedByDisplayManager(mFoldedStates[0]);
assertEquals(DeviceStateController.DeviceState.FOLDED, mCurrentState);
- mTarget.onStateChanged(mHalfFoldedStates[0]);
+ mTarget.onDeviceStateReceivedByDisplayManager(mHalfFoldedStates[0]);
assertEquals(DeviceStateController.DeviceState.UNKNOWN, mCurrentState); // Ignored
}
@Test
public void testWithHalfFoldSupported() {
initialize(true /* supportFold */, true /* supportHalfFolded */);
- mTarget.onStateChanged(mOpenDeviceStates[0]);
+ mTarget.onDeviceStateReceivedByDisplayManager(mOpenDeviceStates[0]);
assertEquals(DeviceStateController.DeviceState.OPEN, mCurrentState);
- mTarget.onStateChanged(mFoldedStates[0]);
+ mTarget.onDeviceStateReceivedByDisplayManager(mFoldedStates[0]);
assertEquals(DeviceStateController.DeviceState.FOLDED, mCurrentState);
- mTarget.onStateChanged(mHalfFoldedStates[0]);
+ mTarget.onDeviceStateReceivedByDisplayManager(mHalfFoldedStates[0]);
assertEquals(DeviceStateController.DeviceState.HALF_FOLDED, mCurrentState);
- mTarget.onStateChanged(mConcurrentDisplayState);
+ mTarget.onDeviceStateReceivedByDisplayManager(mConcurrentDisplayState);
assertEquals(DeviceStateController.DeviceState.CONCURRENT, mCurrentState);
}
@@ -121,15 +119,15 @@ public class DeviceStateControllerTests {
assertEquals(1, mTarget.mDeviceStateCallbacks.size());
assertTrue(mTarget.mDeviceStateCallbacks.containsKey(mDelegate));
- mTarget.onStateChanged(mOpenDeviceStates[0]);
+ mTarget.onDeviceStateReceivedByDisplayManager(mOpenDeviceStates[0]);
assertEquals(DeviceStateController.DeviceState.OPEN, mCurrentState);
- mTarget.onStateChanged(mFoldedStates[0]);
+ mTarget.onDeviceStateReceivedByDisplayManager(mFoldedStates[0]);
assertEquals(DeviceStateController.DeviceState.FOLDED, mCurrentState);
// The callback should not receive state change when the it is unregistered.
mTarget.unregisterDeviceStateCallback(mDelegate);
assertTrue(mTarget.mDeviceStateCallbacks.isEmpty());
- mTarget.onStateChanged(mOpenDeviceStates[0]);
+ mTarget.onDeviceStateReceivedByDisplayManager(mOpenDeviceStates[0]);
assertEquals(DeviceStateController.DeviceState.FOLDED /* unchanged */, mCurrentState);
}
@@ -195,9 +193,7 @@ public class DeviceStateControllerTests {
Resources mockRes = mock(Resources.class);
when(mMockContext.getResources()).thenReturn((mockRes));
mockFold(mSupportFold, mSupportHalfFold);
- Handler mockHandler = mock(Handler.class);
- mTarget = new DeviceStateController(mMockContext, mockHandler,
- new WindowManagerGlobalLock());
+ mTarget = new DeviceStateController(mMockContext, new WindowManagerGlobalLock());
mTarget.registerDeviceStateCallback(mDelegate, MoreExecutors.directExecutor());
}
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java b/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
index 192632ce0277..adf3f3976f38 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
@@ -18,8 +18,6 @@ package com.android.server.wm;
import static android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE;
-import static com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs.LID_ABSENT;
-
import android.annotation.Nullable;
import android.content.Context;
import android.content.res.Configuration;
@@ -356,9 +354,4 @@ class TestWindowManagerPolicy implements WindowManagerPolicy {
public boolean isGlobalKey(int keyCode) {
return false;
}
-
- @Override
- public int getLidState() {
- return LID_ABSENT;
- }
}
diff --git a/tests/InputMethodStressTest/AndroidManifest.xml b/tests/InputMethodStressTest/AndroidManifest.xml
index 62eee0270cac..e890c9974882 100644
--- a/tests/InputMethodStressTest/AndroidManifest.xml
+++ b/tests/InputMethodStressTest/AndroidManifest.xml
@@ -19,8 +19,7 @@
package="com.android.inputmethod.stresstest">
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<application>
- <activity android:name=".ImeStressTestUtil$TestActivity"
- android:configChanges="orientation|screenSize"/>
+ <activity android:name=".ImeStressTestUtil$TestActivity"/>
</application>
<instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
diff --git a/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/ImeOpenCloseStressTest.java b/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/ImeOpenCloseStressTest.java
index 7632ab08b655..b76a4eb8c0e6 100644
--- a/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/ImeOpenCloseStressTest.java
+++ b/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/ImeOpenCloseStressTest.java
@@ -493,6 +493,7 @@ public final class ImeOpenCloseStressTest {
verifyShowBehavior(activity);
}
+ // TODO: Add tests for activities that don't handle the rotation.
@Test
public void testRotateScreenWithKeyboardOn() throws Exception {
Intent intent =
@@ -514,14 +515,14 @@ public final class ImeOpenCloseStressTest {
Thread.sleep(1000);
Log.i(TAG, "Rotate screen right");
assertThat(uiDevice.isNaturalOrientation()).isFalse();
- verifyShowBehavior(activity);
+ verifyRotateBehavior(activity);
uiDevice.setOrientationLeft();
uiDevice.waitForIdle();
Thread.sleep(1000);
Log.i(TAG, "Rotate screen left");
assertThat(uiDevice.isNaturalOrientation()).isFalse();
- verifyShowBehavior(activity);
+ verifyRotateBehavior(activity);
uiDevice.setOrientationNatural();
uiDevice.waitForIdle();
@@ -569,4 +570,36 @@ public final class ImeOpenCloseStressTest {
waitOnMainUntilImeIsShown(editText);
}
}
+
+ private static void verifyRotateBehavior(TestActivity activity) {
+ // Get the new TestActivity after recreation.
+ TestActivity newActivity = TestActivity.getLastCreatedInstance();
+ assertThat(newActivity).isNotNull();
+ assertThat(newActivity).isNotEqualTo(activity);
+
+ EditText newEditText = newActivity.getEditText();
+ int softInputMode = newActivity.getWindow().getAttributes().softInputMode;
+ int softInputVisibility = softInputMode & WindowManager.LayoutParams.SOFT_INPUT_MASK_STATE;
+
+ if (hasUnfocusableWindowFlags(newActivity)) {
+ verifyImeAlwaysHiddenWithWindowFlagSet(newActivity);
+ return;
+ }
+
+ if (softInputVisibility == WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN) {
+ // After rotation, the keyboard would be hidden only when the flag is
+ // SOFT_INPUT_STATE_ALWAYS_HIDDEN. However, SOFT_INPUT_STATE_HIDDEN is different because
+ // it requires appending SOFT_INPUT_IS_FORWARD_NAVIGATION flag, which won't be added
+ // when rotating the devices (rotating doesn't navigate forward to the next app window.)
+ verifyWindowAndViewFocus(newEditText, /*expectWindowFocus*/ true, /*expectViewFocus*/
+ true);
+ waitOnMainUntilImeIsHidden(newEditText);
+
+ } else {
+ // Other cases, keyboard would be shown.
+ verifyWindowAndViewFocus(newEditText, /*expectWindowFocus*/ true, /*expectViewFocus*/
+ true);
+ waitOnMainUntilImeIsShown(newEditText);
+ }
+ }
}
diff --git a/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/ImeStressTestUtil.java b/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/ImeStressTestUtil.java
index e16c9152df3e..f3c81942ae42 100644
--- a/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/ImeStressTestUtil.java
+++ b/tests/InputMethodStressTest/src/com/android/inputmethod/stresstest/ImeStressTestUtil.java
@@ -45,6 +45,7 @@ import androidx.test.platform.app.InstrumentationRegistry;
import com.android.compatibility.common.util.ThrowingRunnable;
+import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
@@ -296,6 +297,8 @@ public final class ImeStressTestUtil {
private static final String TAG = "ImeStressTestUtil.TestActivity";
private EditText mEditText;
private boolean mIsAnimating;
+ private static WeakReference<TestActivity> sLastCreatedInstance =
+ new WeakReference<>(null);
private final WindowInsetsAnimation.Callback mWindowInsetsAnimationCallback =
new WindowInsetsAnimation.Callback(DISPATCH_MODE_STOP) {
@@ -336,6 +339,7 @@ public final class ImeStressTestUtil {
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i(TAG, "onCreate()");
+ sLastCreatedInstance = new WeakReference<>(this);
boolean isUnfocusableView = getIntent().getBooleanExtra(UNFOCUSABLE_VIEW, false);
boolean requestFocus = getIntent().getBooleanExtra(REQUEST_FOCUS_ON_CREATE, false);
int softInputFlags = getIntent().getIntExtra(SOFT_INPUT_FLAGS, 0);
@@ -378,6 +382,12 @@ public final class ImeStressTestUtil {
}
}
+ /** Get the last created TestActivity instance. */
+ @Nullable
+ public static TestActivity getLastCreatedInstance() {
+ return sLastCreatedInstance.get();
+ }
+
/** Show IME with InputMethodManager. */
public boolean showImeWithInputMethodManager() {
boolean showResult =
diff --git a/wifi/tests/src/android/net/wifi/nl80211/OWNERS b/wifi/tests/src/android/net/wifi/nl80211/OWNERS
new file mode 100644
index 000000000000..8a75e25cb2f6
--- /dev/null
+++ b/wifi/tests/src/android/net/wifi/nl80211/OWNERS
@@ -0,0 +1 @@
+kumachang@google.com