summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apex/jobscheduler/framework/java/android/app/job/JobInfo.java21
-rw-r--r--apex/jobscheduler/framework/java/android/os/PowerWhitelistManager.java2
-rw-r--r--apex/jobscheduler/service/java/com/android/server/job/GrantedUriPermissions.java11
-rw-r--r--apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java184
-rw-r--r--apex/jobscheduler/service/java/com/android/server/job/JobPackageTracker.java66
-rw-r--r--apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java217
-rw-r--r--apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java87
-rw-r--r--apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java2
-rw-r--r--apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java150
-rw-r--r--apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java49
-rw-r--r--apex/jobscheduler/service/java/com/android/server/job/restrictions/ThermalStatusRestriction.java2
-rw-r--r--core/api/current.txt113
-rw-r--r--core/api/system-current.txt51
-rw-r--r--core/java/android/app/ITaskStackListener.aidl6
-rw-r--r--core/java/android/app/SystemServiceRegistry.java8
-rw-r--r--core/java/android/app/TaskStackListener.java4
-rw-r--r--core/java/android/content/Context.java8
-rw-r--r--core/java/android/net/vcn/VcnControlPlaneConfig.java2
-rw-r--r--core/java/android/net/vcn/VcnControlPlaneIkeConfig.java2
-rw-r--r--core/java/android/net/vcn/VcnGatewayConnectionConfig.java8
-rw-r--r--core/java/android/os/Trace.java6
-rw-r--r--core/java/android/os/incremental/IncrementalFileStorages.java10
-rw-r--r--core/java/android/service/displayhash/DisplayHasherService.java168
-rw-r--r--core/java/android/service/displayhash/IDisplayHasherService.aidl (renamed from core/java/android/service/screenshot/IScreenshotHasherService.aidl)34
-rw-r--r--core/java/android/service/displayhash/OWNERS (renamed from core/java/android/service/screenshot/OWNERS)0
-rw-r--r--core/java/android/service/screenshot/ScreenshotHash.java256
-rw-r--r--core/java/android/service/screenshot/ScreenshotHasherService.java160
-rw-r--r--core/java/android/speech/IRecognitionService.aidl5
-rw-r--r--core/java/android/speech/IRecognitionServiceManager.aidl10
-rw-r--r--core/java/android/speech/IRecognitionServiceManagerCallback.aidl2
-rw-r--r--core/java/android/speech/RecognitionService.java18
-rw-r--r--core/java/android/speech/SpeechRecognizer.java243
-rw-r--r--core/java/android/uwb/OWNERS1
-rw-r--r--core/java/android/uwb/TEST_MAPPING5
-rw-r--r--core/java/android/view/IWindowManager.aidl25
-rw-r--r--core/java/android/view/IWindowSession.aidl17
-rw-r--r--core/java/android/view/View.java78
-rw-r--r--core/java/android/view/WindowlessWindowManager.java7
-rw-r--r--core/java/android/view/displayhash/DisplayHash.aidl (renamed from core/java/android/service/screenshot/ScreenshotHash.aidl)6
-rw-r--r--core/java/android/view/displayhash/DisplayHash.java226
-rw-r--r--core/java/android/view/displayhash/DisplayHashManager.java97
-rw-r--r--core/java/android/view/displayhash/DisplayHashResultCallback.java98
-rw-r--r--core/java/android/view/displayhash/OWNERS1
-rw-r--r--core/java/android/view/displayhash/VerifiedDisplayHash.aidl (renamed from packages/SystemUI/src/com/android/keyguard/clock/ClockModule.java)18
-rw-r--r--core/java/android/view/displayhash/VerifiedDisplayHash.java242
-rw-r--r--core/jni/android_os_Trace.cpp2
-rw-r--r--core/res/AndroidManifest.xml4
-rw-r--r--core/res/res/values-af/strings.xml8
-rw-r--r--core/res/res/values-am/strings.xml8
-rw-r--r--core/res/res/values-ar/strings.xml11
-rw-r--r--core/res/res/values-as/strings.xml11
-rw-r--r--core/res/res/values-az/strings.xml16
-rw-r--r--core/res/res/values-b+sr+Latn/strings.xml8
-rw-r--r--core/res/res/values-be/strings.xml11
-rw-r--r--core/res/res/values-bg/strings.xml8
-rw-r--r--core/res/res/values-bn/strings.xml11
-rw-r--r--core/res/res/values-bs/strings.xml8
-rw-r--r--core/res/res/values-ca/strings.xml16
-rw-r--r--core/res/res/values-cs/strings.xml8
-rw-r--r--core/res/res/values-da/strings.xml10
-rw-r--r--core/res/res/values-de/strings.xml11
-rw-r--r--core/res/res/values-el/strings.xml8
-rw-r--r--core/res/res/values-en-rAU/strings.xml8
-rw-r--r--core/res/res/values-en-rCA/strings.xml8
-rw-r--r--core/res/res/values-en-rGB/strings.xml8
-rw-r--r--core/res/res/values-en-rIN/strings.xml8
-rw-r--r--core/res/res/values-en-rXC/strings.xml8
-rw-r--r--core/res/res/values-es-rUS/strings.xml8
-rw-r--r--core/res/res/values-es/strings.xml8
-rw-r--r--core/res/res/values-et/strings.xml8
-rw-r--r--core/res/res/values-eu/strings.xml23
-rw-r--r--core/res/res/values-fa/strings.xml10
-rw-r--r--core/res/res/values-fi/strings.xml8
-rw-r--r--core/res/res/values-fr-rCA/strings.xml11
-rw-r--r--core/res/res/values-fr/strings.xml11
-rw-r--r--core/res/res/values-gl/strings.xml8
-rw-r--r--core/res/res/values-gu/strings.xml11
-rw-r--r--core/res/res/values-hi/strings.xml10
-rw-r--r--core/res/res/values-hr/strings.xml8
-rw-r--r--core/res/res/values-hu/strings.xml8
-rw-r--r--core/res/res/values-hy/strings.xml10
-rw-r--r--core/res/res/values-in/strings.xml8
-rw-r--r--core/res/res/values-is/strings.xml8
-rw-r--r--core/res/res/values-it/strings.xml11
-rw-r--r--core/res/res/values-iw/strings.xml8
-rw-r--r--core/res/res/values-ja/strings.xml16
-rw-r--r--core/res/res/values-ka/strings.xml8
-rw-r--r--core/res/res/values-kk/strings.xml11
-rw-r--r--core/res/res/values-km/strings.xml10
-rw-r--r--core/res/res/values-kn/strings.xml8
-rw-r--r--core/res/res/values-ko/strings.xml8
-rw-r--r--core/res/res/values-ky/strings.xml18
-rw-r--r--core/res/res/values-lo/strings.xml11
-rw-r--r--core/res/res/values-lt/strings.xml8
-rw-r--r--core/res/res/values-lv/strings.xml8
-rw-r--r--core/res/res/values-mcc310-mnc950-si/strings.xml26
-rw-r--r--core/res/res/values-mk/strings.xml8
-rw-r--r--core/res/res/values-ml/strings.xml11
-rw-r--r--core/res/res/values-mn/strings.xml18
-rw-r--r--core/res/res/values-mr/strings.xml11
-rw-r--r--core/res/res/values-ms/strings.xml16
-rw-r--r--core/res/res/values-my/strings.xml8
-rw-r--r--core/res/res/values-nb/strings.xml8
-rw-r--r--core/res/res/values-ne/strings.xml11
-rw-r--r--core/res/res/values-nl/strings.xml18
-rw-r--r--core/res/res/values-or/strings.xml11
-rw-r--r--core/res/res/values-pa/strings.xml11
-rw-r--r--core/res/res/values-pl/strings.xml8
-rw-r--r--core/res/res/values-pt-rBR/strings.xml8
-rw-r--r--core/res/res/values-pt-rPT/strings.xml8
-rw-r--r--core/res/res/values-pt/strings.xml8
-rw-r--r--core/res/res/values-ro/strings.xml8
-rw-r--r--core/res/res/values-ru/strings.xml8
-rw-r--r--core/res/res/values-si/strings.xml8
-rw-r--r--core/res/res/values-sk/strings.xml8
-rw-r--r--core/res/res/values-sl/strings.xml11
-rw-r--r--core/res/res/values-sq/strings.xml8
-rw-r--r--core/res/res/values-sr/strings.xml8
-rw-r--r--core/res/res/values-sv/strings.xml8
-rw-r--r--core/res/res/values-sw/strings.xml8
-rw-r--r--core/res/res/values-ta/strings.xml8
-rw-r--r--core/res/res/values-te/strings.xml11
-rw-r--r--core/res/res/values-th/strings.xml8
-rw-r--r--core/res/res/values-tl/strings.xml8
-rw-r--r--core/res/res/values-tr/strings.xml8
-rw-r--r--core/res/res/values-uk/strings.xml8
-rw-r--r--core/res/res/values-ur/strings.xml11
-rw-r--r--core/res/res/values-uz/strings.xml8
-rw-r--r--core/res/res/values-vi/strings.xml8
-rw-r--r--core/res/res/values-zh-rCN/strings.xml8
-rw-r--r--core/res/res/values-zh-rHK/strings.xml10
-rw-r--r--core/res/res/values-zh-rTW/strings.xml8
-rw-r--r--core/res/res/values-zu/strings.xml8
-rw-r--r--core/res/res/values/config.xml4
-rw-r--r--core/res/res/values/symbols.xml2
-rw-r--r--core/tests/uwbtests/src/android/uwb/AngleMeasurementTest.java85
-rw-r--r--core/tests/uwbtests/src/android/uwb/AngleOfArrivalMeasurementTest.java89
-rw-r--r--core/tests/uwbtests/src/android/uwb/DistanceMeasurementTest.java87
-rw-r--r--core/tests/uwbtests/src/android/uwb/RangingMeasurementTest.java95
-rw-r--r--core/tests/uwbtests/src/android/uwb/RangingReportTest.java90
-rw-r--r--core/tests/uwbtests/src/android/uwb/RangingSessionTest.java378
-rw-r--r--core/tests/uwbtests/src/android/uwb/SessionHandleTest.java52
-rw-r--r--core/tests/uwbtests/src/android/uwb/UwbAddressTest.java79
-rw-r--r--core/tests/uwbtests/src/android/uwb/UwbManagerTest.java49
-rw-r--r--libs/WindowManager/Shell/res/drawable/pip_expand.xml6
-rw-r--r--libs/WindowManager/Shell/res/drawable/pip_ic_close_white.xml4
-rw-r--r--libs/WindowManager/Shell/res/drawable/pip_ic_pause_white.xml4
-rw-r--r--libs/WindowManager/Shell/res/drawable/pip_ic_play_arrow_white.xml4
-rw-r--r--libs/WindowManager/Shell/res/drawable/pip_ic_settings.xml4
-rw-r--r--libs/WindowManager/Shell/res/drawable/pip_ic_skip_next_white.xml6
-rw-r--r--libs/WindowManager/Shell/res/drawable/pip_ic_skip_previous_white.xml6
-rw-r--r--libs/WindowManager/Shell/res/layout/pip_menu.xml6
-rw-r--r--libs/WindowManager/Shell/res/layout/pip_menu_action.xml14
-rw-r--r--libs/WindowManager/Shell/res/values/dimen.xml10
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuActionView.java48
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java6
-rw-r--r--media/java/android/media/MediaCodec.java61
-rw-r--r--media/java/android/media/MediaDrm.java485
-rw-r--r--media/java/android/media/tv/TvInputManager.java8
-rw-r--r--media/jni/android_media_MediaDrm.cpp49
-rw-r--r--media/jni/android_media_MediaDrm.h40
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java19
-rw-r--r--packages/SystemUI/res/layout/pip_menu_activity.xml93
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/Task.java20
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java6
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java12
-rw-r--r--packages/SystemUI/src/com/android/keyguard/CarrierText.java65
-rw-r--r--packages/SystemUI/src/com/android/keyguard/CarrierTextController.java691
-rw-r--r--packages/SystemUI/src/com/android/keyguard/CarrierTextManager.java720
-rw-r--r--packages/SystemUI/src/com/android/keyguard/EmergencyButton.java140
-rw-r--r--packages/SystemUI/src/com/android/keyguard/EmergencyButtonController.java196
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputViewController.java14
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java8
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardInputViewController.java32
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java3
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java18
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputViewController.java3
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardPinViewController.java3
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardSecurityModel.java14
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewFlipperController.java13
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardSimPinViewController.java4
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardSimPukViewController.java8
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java35
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardSliceViewController.java4
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java19
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java18
-rw-r--r--packages/SystemUI/src/com/android/keyguard/clock/ClockOptionsProvider.java20
-rw-r--r--packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusBarViewComponent.java42
-rw-r--r--packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusBarViewModule.java34
-rw-r--r--packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusViewComponent.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/doze/DozeUi.java15
-rw-r--r--packages/SystemUI/src/com/android/systemui/flags/FeatureFlagReader.java41
-rw-r--r--packages/SystemUI/src/com/android/systemui/flags/SystemPropertiesHelper.kt (renamed from packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusBarViewScope.java)24
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/carrier/QSCarrierGroupController.java29
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt23
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java48
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java22
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java (renamed from packages/SystemUI/tests/src/com/android/keyguard/CarrierTextManagerTest.java)136
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardAbsKeyInputViewControllerTest.java5
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardDisplayManagerTest.java9
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt5
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinBasedInputViewControllerTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityViewFlipperControllerTest.java9
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/doze/DozeUiTest.java7
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagReaderTest.java46
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/carrier/QSCarrierGroupControllerTest.java54
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java12
-rw-r--r--packages/SystemUI/tools/lint/baseline.xml11
-rw-r--r--services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java9
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerSession.java13
-rw-r--r--services/core/java/com/android/server/speech/RemoteSpeechRecognitionService.java343
-rw-r--r--services/core/java/com/android/server/speech/SpeechRecognitionManagerService.java11
-rw-r--r--services/core/java/com/android/server/speech/SpeechRecognitionManagerServiceImpl.java204
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskManagerService.java3
-rw-r--r--services/core/java/com/android/server/wm/DisplayHashController.java (renamed from services/core/java/com/android/server/wm/ScreenshotHashController.java)111
-rw-r--r--services/core/java/com/android/server/wm/LockTaskController.java6
-rw-r--r--services/core/java/com/android/server/wm/Session.java8
-rw-r--r--services/core/java/com/android/server/wm/TaskChangeNotificationController.java15
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java59
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java17
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java4
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java92
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/LockTaskControllerTest.java3
-rw-r--r--tests/FlickerTests/OWNERS1
228 files changed, 5240 insertions, 3791 deletions
diff --git a/apex/jobscheduler/framework/java/android/app/job/JobInfo.java b/apex/jobscheduler/framework/java/android/app/job/JobInfo.java
index 930415fcd8fd..b7a3f1083176 100644
--- a/apex/jobscheduler/framework/java/android/app/job/JobInfo.java
+++ b/apex/jobscheduler/framework/java/android/app/job/JobInfo.java
@@ -59,6 +59,12 @@ import java.util.Objects;
* constraint on the JobInfo object that you are creating. Otherwise, the builder would throw an
* exception when building. From Android version {@link Build.VERSION_CODES#Q} and onwards, it is
* valid to schedule jobs with no constraints.
+ * <p> In Android version {@link Build.VERSION_CODES#LOLLIPOP}, jobs had a maximum execution time
+ * of one minute. Starting with Android version {@link Build.VERSION_CODES#M} and ending with
+ * Android version {@link Build.VERSION_CODES#R}, jobs had a maximum execution time of 10 minutes.
+ * Starting from Android version {@link Build.VERSION_CODES#S}, jobs will still be stopped after
+ * 10 minutes if the system is busy or needs the resources, but if not, jobs may continue running
+ * longer than 10 minutes.
*/
public class JobInfo implements Parcelable {
private static String TAG = "JobInfo";
@@ -1461,11 +1467,13 @@ public class JobInfo implements Parcelable {
* possible with stronger guarantees than regular jobs. These "expedited" jobs will:
* <ol>
* <li>Run as soon as possible</li>
- * <li>Be exempted from Doze and battery saver restrictions</li>
+ * <li>Be less restricted during Doze and battery saver</li>
* <li>Have network access</li>
- * <li>Less likely to be killed than regular jobs</li>
+ * <li>Be less likely to be killed than regular jobs</li>
+ * <li>Be subject to background location throttling</li>
* </ol>
*
+ * <p>
* Since these jobs have stronger guarantees than regular jobs, they will be subject to
* stricter quotas. As long as an app has available expedited quota, jobs scheduled with
* this set to true will run with these guarantees. If an app has run out of available
@@ -1475,9 +1483,18 @@ public class JobInfo implements Parcelable {
* will immediately return {@link JobScheduler#RESULT_FAILURE} if the app does not have
* available quota (and the job will not be successfully scheduled).
*
+ * <p>
* Expedited jobs may only set network, storage-not-low, and persistence constraints.
* No other constraints are allowed.
*
+ * <p>
+ * Assuming all constraints remain satisfied (including ideal system load conditions),
+ * expedited jobs are guaranteed to have a minimum allowed runtime of 1 minute. If your
+ * app has remaining expedited job quota, then the expedited job <i>may</i> potentially run
+ * longer until remaining quota is used up. Just like with regular jobs, quota is not
+ * consumed while the app is on top and visible to the user.
+ *
+ * <p>
* Note: Even though expedited jobs are meant to run as soon as possible, they may be
* deferred if the system is under heavy load or requested constraints are not satisfied.
*
diff --git a/apex/jobscheduler/framework/java/android/os/PowerWhitelistManager.java b/apex/jobscheduler/framework/java/android/os/PowerWhitelistManager.java
index 283e933e0fa9..df0e157abc6a 100644
--- a/apex/jobscheduler/framework/java/android/os/PowerWhitelistManager.java
+++ b/apex/jobscheduler/framework/java/android/os/PowerWhitelistManager.java
@@ -87,7 +87,7 @@ public class PowerWhitelistManager {
* The list of temp allowlist types.
* @hide
*/
- @IntDef(flag = true, prefix = { "TEMPORARY_ALLOW_TYPE_" }, value = {
+ @IntDef(flag = true, prefix = { "TEMPORARY_ALLOWLIST_TYPE_" }, value = {
TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED,
TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED,
})
diff --git a/apex/jobscheduler/service/java/com/android/server/job/GrantedUriPermissions.java b/apex/jobscheduler/service/java/com/android/server/job/GrantedUriPermissions.java
index b7e8cf6e3fc8..7f191d4a306a 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/GrantedUriPermissions.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/GrantedUriPermissions.java
@@ -26,6 +26,7 @@ import android.os.RemoteException;
import android.os.UserHandle;
import android.util.Slog;
import android.util.proto.ProtoOutputStream;
+
import com.android.server.LocalServices;
import com.android.server.uri.UriGrantsManagerInternal;
@@ -144,13 +145,13 @@ public final class GrantedUriPermissions {
}
// Dumpsys infrastructure
- public void dump(PrintWriter pw, String prefix) {
- pw.print(prefix); pw.print("mGrantFlags=0x"); pw.print(Integer.toHexString(mGrantFlags));
+ public void dump(PrintWriter pw) {
+ pw.print("mGrantFlags=0x"); pw.print(Integer.toHexString(mGrantFlags));
pw.print(" mSourceUserId="); pw.println(mSourceUserId);
- pw.print(prefix); pw.print("mTag="); pw.println(mTag);
- pw.print(prefix); pw.print("mPermissionOwner="); pw.println(mPermissionOwner);
+ pw.print("mTag="); pw.println(mTag);
+ pw.print("mPermissionOwner="); pw.println(mPermissionOwner);
for (int i = 0; i < mUris.size(); i++) {
- pw.print(prefix); pw.print("#"); pw.print(i); pw.print(": ");
+ pw.print("#"); pw.print(i); pw.print(": ");
pw.println(mUris.get(i));
}
}
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java b/apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java
index 164781a250b7..af9771553063 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java
@@ -20,6 +20,7 @@ import static com.android.server.job.JobSchedulerService.sElapsedRealtimeClock;
import android.annotation.IntDef;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.ActivityManagerInternal;
import android.app.UserSwitchObserver;
@@ -80,6 +81,8 @@ class JobConcurrencyManager {
static final int WORK_TYPE_BGUSER = 1 << 3;
@VisibleForTesting
static final int NUM_WORK_TYPES = 4;
+ private static final int ALL_WORK_TYPES =
+ WORK_TYPE_TOP | WORK_TYPE_EJ | WORK_TYPE_BG | WORK_TYPE_BGUSER;
@IntDef(prefix = {"WORK_TYPE_"}, flag = true, value = {
WORK_TYPE_NONE,
@@ -92,6 +95,23 @@ class JobConcurrencyManager {
public @interface WorkType {
}
+ private static String workTypeToString(@WorkType int workType) {
+ switch (workType) {
+ case WORK_TYPE_NONE:
+ return "NONE";
+ case WORK_TYPE_TOP:
+ return "TOP";
+ case WORK_TYPE_EJ:
+ return "EJ";
+ case WORK_TYPE_BG:
+ return "BG";
+ case WORK_TYPE_BGUSER:
+ return "BGUSER";
+ default:
+ return "WORK(" + workType + ")";
+ }
+ }
+
private final Object mLock;
private final JobSchedulerService mService;
private final Context mContext;
@@ -182,10 +202,16 @@ class JobConcurrencyManager {
int[] mRecycledWorkTypeForContext = new int[MAX_JOB_CONTEXTS_COUNT];
+ String[] mRecycledPreemptReasonForContext = new String[MAX_JOB_CONTEXTS_COUNT];
+
+ String[] mRecycledShouldStopJobReason = new String[MAX_JOB_CONTEXTS_COUNT];
+
private final ArraySet<JobStatus> mRunningJobs = new ArraySet<>();
private final WorkCountTracker mWorkCountTracker = new WorkCountTracker();
+ private WorkTypeConfig mWorkTypeConfig = CONFIG_LIMITS_SCREEN_OFF.normal;
+
/** Wait for this long after screen off before adjusting the job concurrency. */
private long mScreenOffAdjustmentDelayMs = DEFAULT_SCREEN_OFF_ADJUSTMENT_DELAY_MS;
@@ -353,23 +379,22 @@ class JobConcurrencyManager {
final WorkConfigLimitsPerMemoryTrimLevel workConfigs = mEffectiveInteractiveState
? CONFIG_LIMITS_SCREEN_ON : CONFIG_LIMITS_SCREEN_OFF;
- WorkTypeConfig workTypeConfig;
switch (mLastMemoryTrimLevel) {
case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
- workTypeConfig = workConfigs.moderate;
+ mWorkTypeConfig = workConfigs.moderate;
break;
case ProcessStats.ADJ_MEM_FACTOR_LOW:
- workTypeConfig = workConfigs.low;
+ mWorkTypeConfig = workConfigs.low;
break;
case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
- workTypeConfig = workConfigs.critical;
+ mWorkTypeConfig = workConfigs.critical;
break;
default:
- workTypeConfig = workConfigs.normal;
+ mWorkTypeConfig = workConfigs.normal;
break;
}
- mWorkCountTracker.setConfig(workTypeConfig);
+ mWorkCountTracker.setConfig(mWorkTypeConfig);
}
/**
@@ -401,13 +426,20 @@ class JobConcurrencyManager {
boolean[] slotChanged = mRecycledSlotChanged;
int[] preferredUidForContext = mRecycledPreferredUidForContext;
int[] workTypeForContext = mRecycledWorkTypeForContext;
+ String[] preemptReasonForContext = mRecycledPreemptReasonForContext;
+ String[] shouldStopJobReason = mRecycledShouldStopJobReason;
updateCounterConfigLocked();
// Reset everything since we'll re-evaluate the current state.
mWorkCountTracker.resetCounts();
+ // Update the priorities of jobs that aren't running, and also count the pending work types.
+ // Do this before the following loop to hopefully reduce the cost of
+ // shouldStopRunningJobLocked().
+ updateNonRunningPriorities(pendingJobs, true);
+
for (int i = 0; i < MAX_JOB_CONTEXTS_COUNT; i++) {
- final JobServiceContext js = mService.mActiveServices.get(i);
+ final JobServiceContext js = activeServices.get(i);
final JobStatus status = js.getRunningJobLocked();
if ((contextIdToJobMap[i] = status) != null) {
@@ -417,14 +449,13 @@ class JobConcurrencyManager {
slotChanged[i] = false;
preferredUidForContext[i] = js.getPreferredUid();
+ preemptReasonForContext[i] = null;
+ shouldStopJobReason[i] = shouldStopRunningJobLocked(js);
}
if (DEBUG) {
Slog.d(TAG, printContextIdToJobMap(contextIdToJobMap, "running jobs initial"));
}
- // Next, update the job priorities, and also count the pending FG / BG jobs.
- updateNonRunningPriorities(pendingJobs, true);
-
mWorkCountTracker.onCountDone();
for (int i = 0; i < pendingJobs.size(); i++) {
@@ -434,8 +465,6 @@ class JobConcurrencyManager {
continue;
}
- // TODO(171305774): make sure HPJs aren't pre-empted and add dedicated contexts for them
-
// Find an available slot for nextPending. The context should be available OR
// it should have lowest priority among all running jobs
// (sharing the same Uid as nextPending)
@@ -444,6 +473,9 @@ class JobConcurrencyManager {
int allWorkTypes = getJobWorkTypes(nextPending);
int workType = mWorkCountTracker.canJobStart(allWorkTypes);
boolean startingJob = false;
+ String preemptReason = null;
+ // TODO(141645789): rewrite this to look at empty contexts first so we don't
+ // unnecessarily preempt
for (int j = 0; j < MAX_JOB_CONTEXTS_COUNT; j++) {
JobStatus job = contextIdToJobMap[j];
int preferredUid = preferredUidForContext[j];
@@ -464,6 +496,15 @@ class JobConcurrencyManager {
continue;
}
if (job.getUid() != nextPending.getUid()) {
+ // Maybe stop the job if it has had its day in the sun.
+ final String reason = shouldStopJobReason[j];
+ if (reason != null && mWorkCountTracker.canJobStart(allWorkTypes,
+ activeServices.get(j).getRunningJobWorkType()) != WORK_TYPE_NONE) {
+ // Right now, the way the code is set up, we don't need to explicitly
+ // assign the new job to this context since we'll reassign when the
+ // preempted job finally stops.
+ preemptReason = reason;
+ }
continue;
}
@@ -477,6 +518,7 @@ class JobConcurrencyManager {
// the lowest-priority running job
minPriorityForPreemption = jobPriority;
selectedContextId = j;
+ preemptReason = "higher priority job found";
// In this case, we're just going to preempt a low priority job, we're not
// actually starting a job, so don't set startingJob.
}
@@ -484,6 +526,7 @@ class JobConcurrencyManager {
if (selectedContextId != -1) {
contextIdToJobMap[selectedContextId] = nextPending;
slotChanged[selectedContextId] = true;
+ preemptReasonForContext[selectedContextId] = preemptReason;
}
if (startingJob) {
// Increase the counters when we're going to start a job.
@@ -509,7 +552,7 @@ class JobConcurrencyManager {
+ activeServices.get(i).getRunningJobLocked());
}
// preferredUid will be set to uid of currently running job.
- activeServices.get(i).preemptExecutingJobLocked();
+ activeServices.get(i).preemptExecutingJobLocked(preemptReasonForContext[i]);
preservePreferredUid = true;
} else {
final JobStatus pendingJob = contextIdToJobMap[i];
@@ -692,6 +735,91 @@ class JobConcurrencyManager {
noteConcurrency();
}
+ /**
+ * Returns {@code null} if the job can continue running and a non-null String if the job should
+ * be stopped. The non-null String details the reason for stopping the job. A job will generally
+ * be stopped if there similar job types waiting to be run and stopping this job would allow
+ * another job to run, or if system state suggests the job should stop.
+ */
+ @Nullable
+ String shouldStopRunningJobLocked(@NonNull JobServiceContext context) {
+ final JobStatus js = context.getRunningJobLocked();
+ if (js == null) {
+ // This can happen when we try to assign newly found pending jobs to contexts.
+ return null;
+ }
+
+ if (context.isWithinExecutionGuaranteeTime()) {
+ return null;
+ }
+
+ // Update config in case memory usage has changed significantly.
+ updateCounterConfigLocked();
+
+ @WorkType final int workType = context.getRunningJobWorkType();
+
+ // We're over the minimum guaranteed runtime. Stop the job if we're over config limits or
+ // there are pending jobs that could replace this one.
+ if (mRunningJobs.size() > mWorkTypeConfig.getMaxTotal()
+ || mWorkCountTracker.isOverTypeLimit(workType)) {
+ return "too many jobs running";
+ }
+
+ final List<JobStatus> pendingJobs = mService.mPendingJobs;
+ final int numPending = pendingJobs.size();
+ if (numPending == 0) {
+ // All quiet. We can let this job run to completion.
+ return null;
+ }
+
+ // Only expedited jobs can replace expedited jobs.
+ if (js.shouldTreatAsExpeditedJob()) {
+ // Keep fg/bg user distinction.
+ if (workType == WORK_TYPE_BGUSER) {
+ // For now, let any bg user job replace a bg user expedited job.
+ // TODO: limit to ej once we have dedicated bg user ej slots.
+ if (mWorkCountTracker.getPendingJobCount(WORK_TYPE_BGUSER) > 0) {
+ return "blocking " + workTypeToString(workType) + " queue";
+ }
+ } else {
+ if (mWorkCountTracker.getPendingJobCount(WORK_TYPE_EJ) > 0) {
+ return "blocking " + workTypeToString(workType) + " queue";
+ }
+ }
+
+ if (mPowerManager.isPowerSaveMode()) {
+ return "battery saver";
+ }
+ if (mPowerManager.isDeviceIdleMode()) {
+ return "deep doze";
+ }
+ }
+
+ // Easy check. If there are pending jobs of the same work type, then we know that
+ // something will replace this.
+ if (mWorkCountTracker.getPendingJobCount(workType) > 0) {
+ return "blocking " + workTypeToString(workType) + " queue";
+ }
+
+ // Harder check. We need to see if a different work type can replace this job.
+ int remainingWorkTypes = ALL_WORK_TYPES;
+ for (int i = 0; i < numPending; ++i) {
+ final JobStatus pending = pendingJobs.get(i);
+ final int workTypes = getJobWorkTypes(pending);
+ if ((workTypes & remainingWorkTypes) > 0
+ && mWorkCountTracker.canJobStart(workTypes, workType) != WORK_TYPE_NONE) {
+ return "blocking other pending jobs";
+ }
+
+ remainingWorkTypes = remainingWorkTypes & ~workTypes;
+ if (remainingWorkTypes == 0) {
+ break;
+ }
+ }
+
+ return null;
+ }
+
@GuardedBy("mLock")
private String printPendingQueueLocked() {
StringBuilder s = new StringBuilder("Pending queue: ");
@@ -1362,10 +1490,40 @@ class JobConcurrencyManager {
return WORK_TYPE_NONE;
}
+ int canJobStart(int workTypes, @WorkType int replacingWorkType) {
+ final boolean changedNums;
+ int oldNumRunning = mNumRunningJobs.get(replacingWorkType);
+ if (replacingWorkType != WORK_TYPE_NONE && oldNumRunning > 0) {
+ mNumRunningJobs.put(replacingWorkType, oldNumRunning - 1);
+ // Lazy implementation to avoid lots of processing. Best way would be to go
+ // through the whole process of adjusting reservations, but the processing cost
+ // is likely not worth it.
+ mNumUnspecializedRemaining++;
+ changedNums = true;
+ } else {
+ changedNums = false;
+ }
+
+ final int ret = canJobStart(workTypes);
+ if (changedNums) {
+ mNumRunningJobs.put(replacingWorkType, oldNumRunning);
+ mNumUnspecializedRemaining--;
+ }
+ return ret;
+ }
+
+ int getPendingJobCount(@WorkType final int workType) {
+ return mNumPendingJobs.get(workType, 0);
+ }
+
int getRunningJobCount(@WorkType final int workType) {
return mNumRunningJobs.get(workType, 0);
}
+ boolean isOverTypeLimit(@WorkType final int workType) {
+ return getRunningJobCount(workType) > mConfigAbsoluteMaxSlots.get(workType);
+ }
+
public String toString() {
StringBuilder sb = new StringBuilder();
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobPackageTracker.java b/apex/jobscheduler/service/java/com/android/server/job/JobPackageTracker.java
index d05034797f3d..6ffac91d7098 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobPackageTracker.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobPackageTracker.java
@@ -25,6 +25,7 @@ import android.app.job.JobParameters;
import android.os.UserHandle;
import android.text.format.DateFormat;
import android.util.ArrayMap;
+import android.util.IndentingPrintWriter;
import android.util.SparseArray;
import android.util.SparseIntArray;
import android.util.TimeUtils;
@@ -33,8 +34,6 @@ import android.util.proto.ProtoOutputStream;
import com.android.internal.util.RingBufferIndices;
import com.android.server.job.controllers.JobStatus;
-import java.io.PrintWriter;
-
public final class JobPackageTracker {
// We batch every 30 minutes.
static final long BATCHING_TIME = 30*60*1000;
@@ -294,53 +293,69 @@ public final class JobPackageTracker {
}
}
- void printDuration(PrintWriter pw, long period, long duration, int count, String suffix) {
+ /** Return {@code true} if text was printed. */
+ boolean printDuration(IndentingPrintWriter pw, long period, long duration, int count,
+ String suffix) {
float fraction = duration / (float) period;
int percent = (int) ((fraction * 100) + .5f);
if (percent > 0) {
- pw.print(" ");
pw.print(percent);
pw.print("% ");
pw.print(count);
pw.print("x ");
pw.print(suffix);
+ return true;
} else if (count > 0) {
- pw.print(" ");
pw.print(count);
pw.print("x ");
pw.print(suffix);
+ return true;
}
+
+ return false;
}
- void dump(PrintWriter pw, String header, String prefix, long now, long nowElapsed,
- int filterUid) {
+ void dump(IndentingPrintWriter pw, String header, long now, long nowElapsed,
+ int filterAppId) {
final long period = getTotalTime(now);
- pw.print(prefix); pw.print(header); pw.print(" at ");
+ pw.print(header); pw.print(" at ");
pw.print(DateFormat.format("yyyy-MM-dd-HH-mm-ss", mStartClockTime).toString());
pw.print(" (");
TimeUtils.formatDuration(mStartElapsedTime, nowElapsed, pw);
pw.print(") over ");
TimeUtils.formatDuration(period, pw);
pw.println(":");
+ pw.increaseIndent();
+ pw.print("Max concurrency: ");
+ pw.print(mMaxTotalActive); pw.print(" total, ");
+ pw.print(mMaxFgActive); pw.println(" foreground");
+
+ pw.println();
final int NE = mEntries.size();
for (int i = 0; i < NE; i++) {
int uid = mEntries.keyAt(i);
- if (filterUid != -1 && filterUid != UserHandle.getAppId(uid)) {
+ if (filterAppId != -1 && filterAppId != UserHandle.getAppId(uid)) {
continue;
}
ArrayMap<String, PackageEntry> uidMap = mEntries.valueAt(i);
final int NP = uidMap.size();
for (int j = 0; j < NP; j++) {
PackageEntry pe = uidMap.valueAt(j);
- pw.print(prefix); pw.print(" ");
UserHandle.formatUid(pw, uid);
pw.print(" / "); pw.print(uidMap.keyAt(j));
pw.println(":");
- pw.print(prefix); pw.print(" ");
- printDuration(pw, period, pe.getPendingTime(now), pe.pendingCount, "pending");
- printDuration(pw, period, pe.getActiveTime(now), pe.activeCount, "active");
- printDuration(pw, period, pe.getActiveTopTime(now), pe.activeTopCount,
- "active-top");
+
+ pw.increaseIndent();
+ if (printDuration(pw, period,
+ pe.getPendingTime(now), pe.pendingCount, "pending")) {
+ pw.print(" ");
+ }
+ if (printDuration(pw, period,
+ pe.getActiveTime(now), pe.activeCount, "active")) {
+ pw.print(" ");
+ }
+ printDuration(pw, period,
+ pe.getActiveTopTime(now), pe.activeTopCount, "active-top");
if (pe.pendingNesting > 0 || pe.hadPending) {
pw.print(" (pending)");
}
@@ -352,7 +367,6 @@ public final class JobPackageTracker {
}
pw.println();
if (pe.stopReasons.size() > 0) {
- pw.print(prefix); pw.print(" ");
for (int k = 0; k < pe.stopReasons.size(); k++) {
if (k > 0) {
pw.print(", ");
@@ -364,11 +378,10 @@ public final class JobPackageTracker {
}
pw.println();
}
+ pw.decreaseIndent();
}
}
- pw.print(prefix); pw.print(" Max concurrency: ");
- pw.print(mMaxTotalActive); pw.print(" total, ");
- pw.print(mMaxFgActive); pw.println(" foreground");
+ pw.decreaseIndent();
}
private void printPackageEntryState(ProtoOutputStream proto, long fieldId,
@@ -520,7 +533,7 @@ public final class JobPackageTracker {
return time / (float)period;
}
- public void dump(PrintWriter pw, String prefix, int filterUid) {
+ void dump(IndentingPrintWriter pw, int filterAppId) {
final long now = sUptimeMillisClock.millis();
final long nowElapsed = sElapsedRealtimeClock.millis();
final DataSet total;
@@ -533,11 +546,11 @@ public final class JobPackageTracker {
mCurDataSet.addTo(total, now);
for (int i = 1; i < mLastDataSets.length; i++) {
if (mLastDataSets[i] != null) {
- mLastDataSets[i].dump(pw, "Historical stats", prefix, now, nowElapsed, filterUid);
+ mLastDataSets[i].dump(pw, "Historical stats", now, nowElapsed, filterAppId);
pw.println();
}
}
- total.dump(pw, "Current stats", prefix, now, nowElapsed, filterUid);
+ total.dump(pw, "Current stats", now, nowElapsed, filterAppId);
}
public void dump(ProtoOutputStream proto, long fieldId, int filterUid) {
@@ -566,17 +579,19 @@ public final class JobPackageTracker {
proto.end(token);
}
- public boolean dumpHistory(PrintWriter pw, String prefix, int filterUid) {
+ boolean dumpHistory(IndentingPrintWriter pw, int filterAppId) {
final int size = mEventIndices.size();
if (size <= 0) {
return false;
}
- pw.println(" Job history:");
+ pw.increaseIndent();
+ pw.println("Job history:");
+ pw.decreaseIndent();
final long now = sElapsedRealtimeClock.millis();
for (int i=0; i<size; i++) {
final int index = mEventIndices.indexOf(i);
final int uid = mEventUids[index];
- if (filterUid != -1 && filterUid != UserHandle.getAppId(uid)) {
+ if (filterAppId != -1 && filterAppId != UserHandle.getAppId(uid)) {
continue;
}
final int cmd = mEventCmds[index] & EVENT_CMD_MASK;
@@ -591,7 +606,6 @@ public final class JobPackageTracker {
case EVENT_STOP_PERIODIC_JOB: label = " STOP-P"; break;
default: label = " ??"; break;
}
- pw.print(prefix);
TimeUtils.formatDuration(mEventTimes[index]-now, pw, TimeUtils.HUNDRED_DAY_FIELD_LEN);
pw.print(" ");
pw.print(label);
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 fdbc0864a59d..ac6eb3229a25 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
@@ -339,6 +339,7 @@ public class JobSchedulerService extends com.android.server.SystemService
public void onPropertiesChanged(DeviceConfig.Properties properties) {
boolean apiQuotaScheduleUpdated = false;
boolean concurrencyUpdated = false;
+ boolean runtimeUpdated = false;
for (int controller = 0; controller < mControllers.size(); controller++) {
final StateController sc = mControllers.get(controller);
sc.prepareForUpdatedConstantsLocked();
@@ -377,6 +378,14 @@ public class JobSchedulerService extends com.android.server.SystemService
case Constants.KEY_CONN_PREFETCH_RELAX_FRAC:
mConstants.updateConnectivityConstantsLocked();
break;
+ case Constants.KEY_RUNTIME_FREE_QUOTA_MAX_LIMIT_MS:
+ case Constants.KEY_RUNTIME_MIN_GUARANTEE_MS:
+ case Constants.KEY_RUNTIME_MIN_EJ_GUARANTEE_MS:
+ if (!runtimeUpdated) {
+ mConstants.updateRuntimeConstantsLocked();
+ runtimeUpdated = true;
+ }
+ break;
default:
if (name.startsWith(JobConcurrencyManager.CONFIG_KEY_PREFIX_CONCURRENCY)
&& !concurrencyUpdated) {
@@ -432,6 +441,11 @@ public class JobSchedulerService extends com.android.server.SystemService
private static final String KEY_API_QUOTA_SCHEDULE_RETURN_FAILURE_RESULT =
"aq_schedule_return_failure";
+ private static final String KEY_RUNTIME_FREE_QUOTA_MAX_LIMIT_MS =
+ "runtime_free_quota_max_limit_ms";
+ private static final String KEY_RUNTIME_MIN_GUARANTEE_MS = "runtime_min_guarantee_ms";
+ private static final String KEY_RUNTIME_MIN_EJ_GUARANTEE_MS = "runtime_min_ej_guarantee_ms";
+
private static final int DEFAULT_MIN_READY_NON_ACTIVE_JOBS_COUNT = 5;
private static final long DEFAULT_MAX_NON_ACTIVE_JOB_BATCH_DELAY_MS = 31 * MINUTE_IN_MILLIS;
private static final float DEFAULT_HEAVY_USE_FACTOR = .9f;
@@ -445,6 +459,12 @@ public class JobSchedulerService extends com.android.server.SystemService
private static final long DEFAULT_API_QUOTA_SCHEDULE_WINDOW_MS = MINUTE_IN_MILLIS;
private static final boolean DEFAULT_API_QUOTA_SCHEDULE_THROW_EXCEPTION = true;
private static final boolean DEFAULT_API_QUOTA_SCHEDULE_RETURN_FAILURE_RESULT = false;
+ @VisibleForTesting
+ public static final long DEFAULT_RUNTIME_FREE_QUOTA_MAX_LIMIT_MS = 30 * MINUTE_IN_MILLIS;
+ @VisibleForTesting
+ public static final long DEFAULT_RUNTIME_MIN_GUARANTEE_MS = 10 * MINUTE_IN_MILLIS;
+ @VisibleForTesting
+ public static final long DEFAULT_RUNTIME_MIN_EJ_GUARANTEE_MS = 3 * MINUTE_IN_MILLIS;
/**
* Minimum # of non-ACTIVE jobs for which the JMS will be happy running some work early.
@@ -509,6 +529,19 @@ public class JobSchedulerService extends com.android.server.SystemService
public boolean API_QUOTA_SCHEDULE_RETURN_FAILURE_RESULT =
DEFAULT_API_QUOTA_SCHEDULE_RETURN_FAILURE_RESULT;
+ /** The maximum amount of time we will let a job run for when quota is "free". */
+ public long RUNTIME_FREE_QUOTA_MAX_LIMIT_MS = DEFAULT_RUNTIME_FREE_QUOTA_MAX_LIMIT_MS;
+
+ /**
+ * The minimum amount of time we try to guarantee regular jobs will run for.
+ */
+ public long RUNTIME_MIN_GUARANTEE_MS = DEFAULT_RUNTIME_MIN_GUARANTEE_MS;
+
+ /**
+ * The minimum amount of time we try to guarantee EJs will run for.
+ */
+ public long RUNTIME_MIN_EJ_GUARANTEE_MS = DEFAULT_RUNTIME_MIN_EJ_GUARANTEE_MS;
+
private void updateBatchingConstantsLocked() {
MIN_READY_NON_ACTIVE_JOBS_COUNT = DeviceConfig.getInt(
DeviceConfig.NAMESPACE_JOB_SCHEDULER,
@@ -568,6 +601,25 @@ public class JobSchedulerService extends com.android.server.SystemService
DEFAULT_API_QUOTA_SCHEDULE_RETURN_FAILURE_RESULT);
}
+ private void updateRuntimeConstantsLocked() {
+ DeviceConfig.Properties properties = DeviceConfig.getProperties(
+ DeviceConfig.NAMESPACE_JOB_SCHEDULER,
+ KEY_RUNTIME_FREE_QUOTA_MAX_LIMIT_MS,
+ KEY_RUNTIME_MIN_GUARANTEE_MS, KEY_RUNTIME_MIN_EJ_GUARANTEE_MS);
+
+ // Make sure min runtime for regular jobs is at least 10 minutes.
+ RUNTIME_MIN_GUARANTEE_MS = Math.max(10 * MINUTE_IN_MILLIS,
+ properties.getLong(
+ KEY_RUNTIME_MIN_GUARANTEE_MS, DEFAULT_RUNTIME_MIN_GUARANTEE_MS));
+ // Make sure min runtime for expedited jobs is at least one minute.
+ RUNTIME_MIN_EJ_GUARANTEE_MS = Math.max(MINUTE_IN_MILLIS,
+ properties.getLong(
+ KEY_RUNTIME_MIN_EJ_GUARANTEE_MS, DEFAULT_RUNTIME_MIN_EJ_GUARANTEE_MS));
+ RUNTIME_FREE_QUOTA_MAX_LIMIT_MS = Math.max(RUNTIME_MIN_GUARANTEE_MS,
+ properties.getLong(KEY_RUNTIME_FREE_QUOTA_MAX_LIMIT_MS,
+ DEFAULT_RUNTIME_FREE_QUOTA_MAX_LIMIT_MS));
+ }
+
void dump(IndentingPrintWriter pw) {
pw.println("Settings:");
pw.increaseIndent();
@@ -591,6 +643,11 @@ public class JobSchedulerService extends com.android.server.SystemService
pw.print(KEY_API_QUOTA_SCHEDULE_RETURN_FAILURE_RESULT,
API_QUOTA_SCHEDULE_RETURN_FAILURE_RESULT).println();
+ pw.print(KEY_RUNTIME_MIN_GUARANTEE_MS, RUNTIME_MIN_GUARANTEE_MS).println();
+ pw.print(KEY_RUNTIME_MIN_EJ_GUARANTEE_MS, RUNTIME_MIN_EJ_GUARANTEE_MS).println();
+ pw.print(KEY_RUNTIME_FREE_QUOTA_MAX_LIMIT_MS, RUNTIME_FREE_QUOTA_MAX_LIMIT_MS)
+ .println();
+
pw.decreaseIndent();
}
@@ -1602,7 +1659,7 @@ public class JobSchedulerService extends com.android.server.SystemService
* time of the job to be the time of completion (i.e. the time at which this function is
* called).
* <p>This could be inaccurate b/c the job can run for as long as
- * {@link com.android.server.job.JobServiceContext#DEFAULT_EXECUTING_TIMESLICE_MILLIS}, but
+ * {@link Constants#DEFAULT_RUNTIME_FREE_QUOTA_MAX_LIMIT_MS}, but
* will lead to underscheduling at least, rather than if we had taken the last execution time
* to be the start of the execution.
*
@@ -2213,11 +2270,24 @@ public class JobSchedulerService extends com.android.server.SystemService
return isComponentUsable(job);
}
+ /** Returns the minimum amount of time we should let this job run before timing out. */
+ public long getMinJobExecutionGuaranteeMs(JobStatus job) {
+ synchronized (mLock) {
+ if (job.shouldTreatAsExpeditedJob()) {
+ // Don't guarantee RESTRICTED jobs more than 5 minutes.
+ return job.getEffectiveStandbyBucket() != RESTRICTED_INDEX
+ ? mConstants.RUNTIME_MIN_EJ_GUARANTEE_MS
+ : Math.min(mConstants.RUNTIME_MIN_EJ_GUARANTEE_MS, 5 * MINUTE_IN_MILLIS);
+ } else {
+ return mConstants.RUNTIME_MIN_GUARANTEE_MS;
+ }
+ }
+ }
+
/** Returns the maximum amount of time this job could run for. */
public long getMaxJobExecutionTimeMs(JobStatus job) {
synchronized (mLock) {
- return Math.min(mQuotaController.getMaxJobExecutionTimeMsLocked(job),
- JobServiceContext.DEFAULT_EXECUTING_TIMESLICE_MILLIS);
+ return mQuotaController.getMaxJobExecutionTimeMsLocked(job);
}
}
@@ -3021,14 +3091,14 @@ public class JobSchedulerService extends com.android.server.SystemService
}
void dumpInternal(final IndentingPrintWriter pw, int filterUid) {
- final int filterUidFinal = UserHandle.getAppId(filterUid);
+ final int filterAppId = UserHandle.getAppId(filterUid);
final long now = sSystemClock.millis();
final long nowElapsed = sElapsedRealtimeClock.millis();
final long nowUptime = sUptimeMillisClock.millis();
final Predicate<JobStatus> predicate = (js) -> {
- return filterUidFinal == -1 || UserHandle.getAppId(js.getUid()) == filterUidFinal
- || UserHandle.getAppId(js.getSourceUid()) == filterUidFinal;
+ return filterAppId == -1 || UserHandle.getAppId(js.getUid()) == filterAppId
+ || UserHandle.getAppId(js.getSourceUid()) == filterAppId;
};
synchronized (mLock) {
mConstants.dump(pw);
@@ -3041,7 +3111,6 @@ public class JobSchedulerService extends com.android.server.SystemService
for (int i = mJobRestrictions.size() - 1; i >= 0; i--) {
mJobRestrictions.get(i).dumpConstants(pw);
- pw.println();
}
pw.println();
@@ -3052,21 +3121,25 @@ public class JobSchedulerService extends com.android.server.SystemService
pw.print("Registered ");
pw.print(mJobs.size());
pw.println(" jobs:");
+ pw.increaseIndent();
+ boolean jobPrinted = false;
if (mJobs.size() > 0) {
final List<JobStatus> jobs = mJobs.mJobSet.getAllJobs();
sortJobs(jobs);
for (JobStatus job : jobs) {
- pw.print(" JOB #"); job.printUniqueId(pw); pw.print(": ");
- pw.println(job.toShortStringExceptUniqueId());
-
// Skip printing details if the caller requested a filter
if (!predicate.test(job)) {
continue;
}
+ jobPrinted = true;
+
+ pw.print("JOB #"); job.printUniqueId(pw); pw.print(": ");
+ pw.println(job.toShortStringExceptUniqueId());
- job.dump(pw, " ", true, nowElapsed);
+ pw.increaseIndent();
+ job.dump(pw, true, nowElapsed);
- pw.print(" Restricted due to:");
+ pw.print("Restricted due to:");
final boolean isRestricted = checkIfRestricted(job) != null;
if (isRestricted) {
for (int i = mJobRestrictions.size() - 1; i >= 0; i--) {
@@ -3081,7 +3154,7 @@ public class JobSchedulerService extends com.android.server.SystemService
}
pw.println(".");
- pw.print(" Ready: ");
+ pw.print("Ready: ");
pw.print(isReadyToBeExecutedLocked(job));
pw.print(" (job=");
pw.print(job.isReady());
@@ -3098,10 +3171,15 @@ public class JobSchedulerService extends com.android.server.SystemService
pw.print(" comp=");
pw.print(isComponentUsable(job));
pw.println(")");
+
+ pw.decreaseIndent();
}
- } else {
- pw.println(" None.");
}
+ if (!jobPrinted) {
+ pw.println("None.");
+ }
+ pw.decreaseIndent();
+
for (int i=0; i<mControllers.size(); i++) {
pw.println();
pw.println(mControllers.get(i).getClass().getSimpleName() + ":");
@@ -3109,66 +3187,105 @@ public class JobSchedulerService extends com.android.server.SystemService
mControllers.get(i).dumpControllerStateLocked(pw, predicate);
pw.decreaseIndent();
}
- pw.println();
- pw.println("Uid priority overrides:");
+
+ boolean overridePrinted = false;
for (int i=0; i< mUidPriorityOverride.size(); i++) {
int uid = mUidPriorityOverride.keyAt(i);
- if (filterUidFinal == -1 || filterUidFinal == UserHandle.getAppId(uid)) {
- pw.print(" "); pw.print(UserHandle.formatUid(uid));
+ if (filterAppId == -1 || filterAppId == UserHandle.getAppId(uid)) {
+ if (!overridePrinted) {
+ overridePrinted = true;
+ pw.println();
+ pw.println("Uid priority overrides:");
+ pw.increaseIndent();
+ }
+ pw.print(UserHandle.formatUid(uid));
pw.print(": "); pw.println(mUidPriorityOverride.valueAt(i));
}
}
- if (mBackingUpUids.size() > 0) {
- pw.println();
- pw.println("Backing up uids:");
- boolean first = true;
- for (int i = 0; i < mBackingUpUids.size(); i++) {
- int uid = mBackingUpUids.keyAt(i);
- if (filterUidFinal == -1 || filterUidFinal == UserHandle.getAppId(uid)) {
- if (first) {
- pw.print(" ");
- first = false;
- } else {
- pw.print(", ");
- }
- pw.print(UserHandle.formatUid(uid));
+ if (overridePrinted) {
+ pw.decreaseIndent();
+ }
+
+ boolean backingPrinted = false;
+ for (int i = 0; i < mBackingUpUids.size(); i++) {
+ int uid = mBackingUpUids.keyAt(i);
+ if (filterAppId == -1 || filterAppId == UserHandle.getAppId(uid)) {
+ if (!backingPrinted) {
+ pw.println();
+ pw.println("Backing up uids:");
+ pw.increaseIndent();
+ backingPrinted = true;
+ } else {
+ pw.print(", ");
}
+ pw.print(UserHandle.formatUid(uid));
}
+ }
+ if (backingPrinted) {
+ pw.decreaseIndent();
pw.println();
}
+
pw.println();
- mJobPackageTracker.dump(pw, "", filterUidFinal);
+ mJobPackageTracker.dump(pw, filterAppId);
pw.println();
- if (mJobPackageTracker.dumpHistory(pw, "", filterUidFinal)) {
+ if (mJobPackageTracker.dumpHistory(pw, filterAppId)) {
pw.println();
}
+
+ boolean pendingPrinted = false;
pw.println("Pending queue:");
+ pw.increaseIndent();
for (int i=0; i<mPendingJobs.size(); i++) {
JobStatus job = mPendingJobs.get(i);
- pw.print(" Pending #"); pw.print(i); pw.print(": ");
+ if (!predicate.test(job)) {
+ continue;
+ }
+ if (!pendingPrinted) {
+ pendingPrinted = true;
+ }
+
+ pw.print("Pending #"); pw.print(i); pw.print(": ");
pw.println(job.toShortString());
- job.dump(pw, " ", false, nowElapsed);
+
+ pw.increaseIndent();
+ job.dump(pw, false, nowElapsed);
int priority = evaluateJobPriorityLocked(job);
- pw.print(" Evaluated priority: ");
+ pw.print("Evaluated priority: ");
pw.println(JobInfo.getPriorityString(priority));
- pw.print(" Tag: "); pw.println(job.getTag());
- pw.print(" Enq: ");
+ pw.print("Tag: "); pw.println(job.getTag());
+ pw.print("Enq: ");
TimeUtils.formatDuration(job.madePending - nowUptime, pw);
+ pw.decreaseIndent();
pw.println();
}
+ if (!pendingPrinted) {
+ pw.println("None");
+ }
+ pw.decreaseIndent();
+
pw.println();
pw.println("Active jobs:");
pw.increaseIndent();
for (int i=0; i<mActiveServices.size(); i++) {
JobServiceContext jsc = mActiveServices.get(i);
+ final JobStatus job = jsc.getRunningJobLocked();
+
+ if (job != null && !predicate.test(job)) {
+ continue;
+ }
+
pw.print("Slot #"); pw.print(i); pw.print(": ");
jsc.dumpLocked(pw, nowElapsed);
- final JobStatus job = jsc.getRunningJobLocked();
if (job != null) {
pw.increaseIndent();
- job.dump(pw, " ", false, nowElapsed);
+
+ pw.increaseIndent();
+ job.dump(pw, false, nowElapsed);
+ pw.decreaseIndent();
+
pw.print("Evaluated priority: ");
pw.println(JobInfo.getPriorityString(job.lastEvaluatedPriority));
@@ -3176,8 +3293,8 @@ public class JobSchedulerService extends com.android.server.SystemService
TimeUtils.formatDuration(job.madeActive - nowUptime, pw);
pw.print(", pending for ");
TimeUtils.formatDuration(job.madeActive - job.madePending, pw);
- pw.println();
pw.decreaseIndent();
+ pw.println();
}
}
pw.decreaseIndent();
@@ -3199,13 +3316,13 @@ public class JobSchedulerService extends com.android.server.SystemService
void dumpInternalProto(final FileDescriptor fd, int filterUid) {
ProtoOutputStream proto = new ProtoOutputStream(fd);
- final int filterUidFinal = UserHandle.getAppId(filterUid);
+ final int filterAppId = UserHandle.getAppId(filterUid);
final long now = sSystemClock.millis();
final long nowElapsed = sElapsedRealtimeClock.millis();
final long nowUptime = sUptimeMillisClock.millis();
final Predicate<JobStatus> predicate = (js) -> {
- return filterUidFinal == -1 || UserHandle.getAppId(js.getUid()) == filterUidFinal
- || UserHandle.getAppId(js.getSourceUid()) == filterUidFinal;
+ return filterAppId == -1 || UserHandle.getAppId(js.getUid()) == filterAppId
+ || UserHandle.getAppId(js.getSourceUid()) == filterAppId;
};
synchronized (mLock) {
@@ -3278,7 +3395,7 @@ public class JobSchedulerService extends com.android.server.SystemService
}
for (int i=0; i< mUidPriorityOverride.size(); i++) {
int uid = mUidPriorityOverride.keyAt(i);
- if (filterUidFinal == -1 || filterUidFinal == UserHandle.getAppId(uid)) {
+ if (filterAppId == -1 || filterAppId == UserHandle.getAppId(uid)) {
long pToken = proto.start(JobSchedulerServiceDumpProto.PRIORITY_OVERRIDES);
proto.write(JobSchedulerServiceDumpProto.PriorityOverride.UID, uid);
proto.write(JobSchedulerServiceDumpProto.PriorityOverride.OVERRIDE_VALUE,
@@ -3288,15 +3405,15 @@ public class JobSchedulerService extends com.android.server.SystemService
}
for (int i = 0; i < mBackingUpUids.size(); i++) {
int uid = mBackingUpUids.keyAt(i);
- if (filterUidFinal == -1 || filterUidFinal == UserHandle.getAppId(uid)) {
+ if (filterAppId == -1 || filterAppId == UserHandle.getAppId(uid)) {
proto.write(JobSchedulerServiceDumpProto.BACKING_UP_UIDS, uid);
}
}
mJobPackageTracker.dump(proto, JobSchedulerServiceDumpProto.PACKAGE_TRACKER,
- filterUidFinal);
+ filterAppId);
mJobPackageTracker.dumpHistory(proto, JobSchedulerServiceDumpProto.HISTORY,
- filterUidFinal);
+ filterAppId);
for (JobStatus job : mPendingJobs) {
final long pjToken = proto.start(JobSchedulerServiceDumpProto.PENDING_JOBS);
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 0aca2461b41c..be91947b0445 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java
@@ -17,9 +17,9 @@
package com.android.server.job;
import static com.android.server.job.JobConcurrencyManager.WORK_TYPE_NONE;
-import static com.android.server.job.JobSchedulerService.RESTRICTED_INDEX;
import static com.android.server.job.JobSchedulerService.sElapsedRealtimeClock;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.job.IJobCallback;
import android.app.job.IJobService;
@@ -76,14 +76,6 @@ public final class JobServiceContext implements ServiceConnection {
private static final boolean DEBUG_STANDBY = JobSchedulerService.DEBUG_STANDBY;
private static final String TAG = "JobServiceContext";
- /** Amount of time a job is allowed to execute for before being considered timed-out. */
- public static final long DEFAULT_EXECUTING_TIMESLICE_MILLIS = 10 * 60 * 1000; // 10mins.
- /**
- * Amount of time a RESTRICTED expedited job is allowed to execute for before being considered
- * timed-out.
- */
- public static final long DEFAULT_RESTRICTED_EXPEDITED_JOB_EXECUTING_TIMESLICE_MILLIS =
- DEFAULT_EXECUTING_TIMESLICE_MILLIS / 2;
/** Amount of time the JobScheduler waits for the initial service launch+bind. */
private static final long OP_BIND_TIMEOUT_MILLIS = 18 * 1000;
/** Amount of time the JobScheduler will wait for a response from an app for a message. */
@@ -110,6 +102,7 @@ public final class JobServiceContext implements ServiceConnection {
/** Make callbacks to {@link JobSchedulerService} to inform on job completion status. */
private final JobCompletedListener mCompletedListener;
private final JobConcurrencyManager mJobConcurrencyManager;
+ private final JobSchedulerService mService;
/** Used for service binding, etc. */
private final Context mContext;
private final Object mLock;
@@ -149,6 +142,13 @@ public final class JobServiceContext implements ServiceConnection {
private long mExecutionStartTimeElapsed;
/** Track when job will timeout. */
private long mTimeoutElapsed;
+ /**
+ * The minimum amount of time the context will allow the job to run before checking whether to
+ * stop it or not.
+ */
+ private long mMinExecutionGuaranteeMillis;
+ /** The absolute maximum amount of time the job can run */
+ private long mMaxExecutionTimeMillis;
// Debugging: reason this job was last stopped.
public String mStoppedReason;
@@ -190,6 +190,7 @@ public final class JobServiceContext implements ServiceConnection {
IBatteryStats batteryStats, JobPackageTracker tracker, Looper looper) {
mContext = service.getContext();
mLock = service.getLock();
+ mService = service;
mBatteryStats = batteryStats;
mJobPackageTracker = tracker;
mCallbackHandler = new JobServiceHandler(looper);
@@ -239,6 +240,9 @@ public final class JobServiceContext implements ServiceConnection {
isDeadlineExpired, job.shouldTreatAsExpeditedJob(),
triggeredUris, triggeredAuthorities, job.network);
mExecutionStartTimeElapsed = sElapsedRealtimeClock.millis();
+ mMinExecutionGuaranteeMillis = mService.getMinJobExecutionGuaranteeMs(job);
+ mMaxExecutionTimeMillis =
+ Math.max(mService.getMaxJobExecutionTimeMs(job), mMinExecutionGuaranteeMillis);
final long whenDeferred = job.getWhenStandbyDeferred();
if (whenDeferred > 0) {
@@ -352,8 +356,8 @@ public final class JobServiceContext implements ServiceConnection {
}
@GuardedBy("mLock")
- void preemptExecutingJobLocked() {
- doCancelLocked(JobParameters.REASON_PREEMPT, "cancelled due to preemption");
+ void preemptExecutingJobLocked(@NonNull String reason) {
+ doCancelLocked(JobParameters.REASON_PREEMPT, reason);
}
int getPreferredUid() {
@@ -372,6 +376,11 @@ public final class JobServiceContext implements ServiceConnection {
return mTimeoutElapsed;
}
+ boolean isWithinExecutionGuaranteeTime() {
+ return mExecutionStartTimeElapsed + mMinExecutionGuaranteeMillis
+ < sElapsedRealtimeClock.millis();
+ }
+
@GuardedBy("mLock")
boolean timeoutIfExecutingLocked(String pkgName, int userId, boolean matchJobId, int jobId,
String reason) {
@@ -607,7 +616,7 @@ public final class JobServiceContext implements ServiceConnection {
}
@GuardedBy("mLock")
- void doCancelLocked(int arg1, String debugReason) {
+ private void doCancelLocked(int stopReasonCode, String debugReason) {
if (mVerb == VERB_FINISHED) {
if (DEBUG) {
Slog.d(TAG,
@@ -615,8 +624,8 @@ public final class JobServiceContext implements ServiceConnection {
}
return;
}
- mParams.setStopReason(arg1, debugReason);
- if (arg1 == JobParameters.REASON_PREEMPT) {
+ mParams.setStopReason(stopReasonCode, debugReason);
+ if (stopReasonCode == JobParameters.REASON_PREEMPT) {
mPreferredUid = mRunningJob != null ? mRunningJob.getUid() :
NO_PREFERRED_UID;
}
@@ -767,11 +776,30 @@ public final class JobServiceContext implements ServiceConnection {
closeAndCleanupJobLocked(true /* needsReschedule */, "timed out while stopping");
break;
case VERB_EXECUTING:
- // Not an error - client ran out of time.
- Slog.i(TAG, "Client timed out while executing (no jobFinished received), " +
- "sending onStop: " + getRunningJobNameLocked());
- mParams.setStopReason(JobParameters.REASON_TIMEOUT, "client timed out");
- sendStopMessageLocked("timeout while executing");
+ final long latestStopTimeElapsed =
+ mExecutionStartTimeElapsed + mMaxExecutionTimeMillis;
+ final long nowElapsed = sElapsedRealtimeClock.millis();
+ if (nowElapsed >= latestStopTimeElapsed) {
+ // Not an error - client ran out of time.
+ Slog.i(TAG, "Client timed out while executing (no jobFinished received)."
+ + " Sending onStop: " + getRunningJobNameLocked());
+ mParams.setStopReason(JobParameters.REASON_TIMEOUT, "client timed out");
+ sendStopMessageLocked("timeout while executing");
+ } else {
+ // We've given the app the minimum execution time. See if we should stop it or
+ // let it continue running
+ final String reason = mJobConcurrencyManager.shouldStopRunningJobLocked(this);
+ if (reason != null) {
+ Slog.i(TAG, "Stopping client after min execution time: "
+ + getRunningJobNameLocked() + " because " + reason);
+ mParams.setStopReason(JobParameters.REASON_TIMEOUT, reason);
+ sendStopMessageLocked(reason);
+ } else {
+ Slog.i(TAG, "Letting " + getRunningJobNameLocked()
+ + " continue to run past min execution time");
+ scheduleOpTimeOutLocked();
+ }
+ }
break;
default:
Slog.e(TAG, "Handling timeout for an invalid job state: "
@@ -878,10 +906,16 @@ public final class JobServiceContext implements ServiceConnection {
final long timeoutMillis;
switch (mVerb) {
case VERB_EXECUTING:
- timeoutMillis = mRunningJob.shouldTreatAsExpeditedJob()
- && mRunningJob.getStandbyBucket() == RESTRICTED_INDEX
- ? DEFAULT_RESTRICTED_EXPEDITED_JOB_EXECUTING_TIMESLICE_MILLIS
- : DEFAULT_EXECUTING_TIMESLICE_MILLIS;
+ final long earliestStopTimeElapsed =
+ mExecutionStartTimeElapsed + mMinExecutionGuaranteeMillis;
+ final long latestStopTimeElapsed =
+ mExecutionStartTimeElapsed + mMaxExecutionTimeMillis;
+ final long nowElapsed = sElapsedRealtimeClock.millis();
+ if (nowElapsed < earliestStopTimeElapsed) {
+ timeoutMillis = earliestStopTimeElapsed - nowElapsed;
+ } else {
+ timeoutMillis = latestStopTimeElapsed - nowElapsed;
+ }
break;
case VERB_BINDING:
@@ -925,6 +959,13 @@ public final class JobServiceContext implements ServiceConnection {
pw.print(", timeout at: ");
TimeUtils.formatDuration(mTimeoutElapsed - nowElapsed, pw);
pw.println();
+ pw.print("Remaining execution limits: [");
+ TimeUtils.formatDuration(
+ (mExecutionStartTimeElapsed + mMinExecutionGuaranteeMillis) - nowElapsed, pw);
+ pw.print(", ");
+ TimeUtils.formatDuration(
+ (mExecutionStartTimeElapsed + mMaxExecutionTimeMillis) - nowElapsed, pw);
+ pw.println("]");
pw.decreaseIndent();
}
}
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java
index d249f2ae813c..14484ff441ca 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java
@@ -325,6 +325,8 @@ public final class ConnectivityController extends RestrictingController implemen
*/
private boolean isInsane(JobStatus jobStatus, Network network,
NetworkCapabilities capabilities, Constants constants) {
+ // Use the maximum possible time since it gives us an upper bound, even though the job
+ // could end up stopping earlier.
final long maxJobExecutionTimeMs = mService.getMaxJobExecutionTimeMs(jobStatus);
final long downloadBytes = jobStatus.getEstimatedNetworkDownloadBytes();
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 539c3c960f2e..6917fb531ac4 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
@@ -35,6 +35,7 @@ import android.os.UserHandle;
import android.provider.MediaStore;
import android.text.format.DateFormat;
import android.util.ArraySet;
+import android.util.IndentingPrintWriter;
import android.util.Pair;
import android.util.Slog;
import android.util.TimeUtils;
@@ -1644,14 +1645,18 @@ public final class JobStatus {
}
}
- private void dumpJobWorkItem(PrintWriter pw, String prefix, JobWorkItem work, int index) {
- pw.print(prefix); pw.print(" #"); pw.print(index); pw.print(": #");
+ private void dumpJobWorkItem(IndentingPrintWriter pw, JobWorkItem work, int index) {
+ pw.increaseIndent();
+ pw.print("#"); pw.print(index); pw.print(": #");
pw.print(work.getWorkId()); pw.print(" "); pw.print(work.getDeliveryCount());
pw.print("x "); pw.println(work.getIntent());
if (work.getGrants() != null) {
- pw.print(prefix); pw.println(" URI grants:");
- ((GrantedUriPermissions)work.getGrants()).dump(pw, prefix + " ");
+ pw.println("URI grants:");
+ pw.increaseIndent();
+ ((GrantedUriPermissions) work.getGrants()).dump(pw);
+ pw.decreaseIndent();
}
+ pw.decreaseIndent();
}
private void dumpJobWorkItem(ProtoOutputStream proto, long fieldId, JobWorkItem work) {
@@ -1695,36 +1700,38 @@ public final class JobStatus {
}
// Dumpsys infrastructure
- public void dump(PrintWriter pw, String prefix, boolean full, long elapsedRealtimeMillis) {
- pw.print(prefix); UserHandle.formatUid(pw, callingUid);
+ public void dump(IndentingPrintWriter pw, boolean full, long elapsedRealtimeMillis) {
+ UserHandle.formatUid(pw, callingUid);
pw.print(" tag="); pw.println(tag);
- pw.print(prefix);
+
pw.print("Source: uid="); UserHandle.formatUid(pw, getSourceUid());
pw.print(" user="); pw.print(getSourceUserId());
pw.print(" pkg="); pw.println(getSourcePackageName());
if (full) {
- pw.print(prefix); pw.println("JobInfo:");
- pw.print(prefix); pw.print(" Service: ");
+ pw.println("JobInfo:");
+ pw.increaseIndent();
+
+ pw.print("Service: ");
pw.println(job.getService().flattenToShortString());
if (job.isPeriodic()) {
- pw.print(prefix); pw.print(" PERIODIC: interval=");
+ pw.print("PERIODIC: interval=");
TimeUtils.formatDuration(job.getIntervalMillis(), pw);
pw.print(" flex="); TimeUtils.formatDuration(job.getFlexMillis(), pw);
pw.println();
}
if (job.isPersisted()) {
- pw.print(prefix); pw.println(" PERSISTED");
+ pw.println("PERSISTED");
}
if (job.getPriority() != 0) {
- pw.print(prefix); pw.print(" Priority: ");
+ pw.print("Priority: ");
pw.println(JobInfo.getPriorityString(job.getPriority()));
}
if (job.getFlags() != 0) {
- pw.print(prefix); pw.print(" Flags: ");
+ pw.print("Flags: ");
pw.println(Integer.toHexString(job.getFlags()));
}
if (getInternalFlags() != 0) {
- pw.print(prefix); pw.print(" Internal flags: ");
+ pw.print("Internal flags: ");
pw.print(Integer.toHexString(getInternalFlags()));
if ((getInternalFlags()&INTERNAL_FLAG_HAS_FOREGROUND_EXEMPTION) != 0) {
@@ -1732,106 +1739,109 @@ public final class JobStatus {
}
pw.println();
}
- pw.print(prefix); pw.print(" Requires: charging=");
+ pw.print("Requires: charging=");
pw.print(job.isRequireCharging()); pw.print(" batteryNotLow=");
pw.print(job.isRequireBatteryNotLow()); pw.print(" deviceIdle=");
pw.println(job.isRequireDeviceIdle());
if (job.getTriggerContentUris() != null) {
- pw.print(prefix); pw.println(" Trigger content URIs:");
+ pw.println("Trigger content URIs:");
+ pw.increaseIndent();
for (int i = 0; i < job.getTriggerContentUris().length; i++) {
JobInfo.TriggerContentUri trig = job.getTriggerContentUris()[i];
- pw.print(prefix); pw.print(" ");
pw.print(Integer.toHexString(trig.getFlags()));
pw.print(' '); pw.println(trig.getUri());
}
+ pw.decreaseIndent();
if (job.getTriggerContentUpdateDelay() >= 0) {
- pw.print(prefix); pw.print(" Trigger update delay: ");
+ pw.print("Trigger update delay: ");
TimeUtils.formatDuration(job.getTriggerContentUpdateDelay(), pw);
pw.println();
}
if (job.getTriggerContentMaxDelay() >= 0) {
- pw.print(prefix); pw.print(" Trigger max delay: ");
+ pw.print("Trigger max delay: ");
TimeUtils.formatDuration(job.getTriggerContentMaxDelay(), pw);
pw.println();
}
}
if (job.getExtras() != null && !job.getExtras().isDefinitelyEmpty()) {
- pw.print(prefix); pw.print(" Extras: ");
+ pw.print("Extras: ");
pw.println(job.getExtras().toShortString());
}
if (job.getTransientExtras() != null && !job.getTransientExtras().isDefinitelyEmpty()) {
- pw.print(prefix); pw.print(" Transient extras: ");
+ pw.print("Transient extras: ");
pw.println(job.getTransientExtras().toShortString());
}
if (job.getClipData() != null) {
- pw.print(prefix); pw.print(" Clip data: ");
+ pw.print("Clip data: ");
StringBuilder b = new StringBuilder(128);
b.append(job.getClipData());
pw.println(b);
}
if (uriPerms != null) {
- pw.print(prefix); pw.println(" Granted URI permissions:");
- uriPerms.dump(pw, prefix + " ");
+ pw.println("Granted URI permissions:");
+ uriPerms.dump(pw);
}
if (job.getRequiredNetwork() != null) {
- pw.print(prefix); pw.print(" Network type: ");
+ pw.print("Network type: ");
pw.println(job.getRequiredNetwork());
}
if (mTotalNetworkDownloadBytes != JobInfo.NETWORK_BYTES_UNKNOWN) {
- pw.print(prefix); pw.print(" Network download bytes: ");
+ pw.print("Network download bytes: ");
pw.println(mTotalNetworkDownloadBytes);
}
if (mTotalNetworkUploadBytes != JobInfo.NETWORK_BYTES_UNKNOWN) {
- pw.print(prefix); pw.print(" Network upload bytes: ");
+ pw.print("Network upload bytes: ");
pw.println(mTotalNetworkUploadBytes);
}
if (job.getMinLatencyMillis() != 0) {
- pw.print(prefix); pw.print(" Minimum latency: ");
+ pw.print("Minimum latency: ");
TimeUtils.formatDuration(job.getMinLatencyMillis(), pw);
pw.println();
}
if (job.getMaxExecutionDelayMillis() != 0) {
- pw.print(prefix); pw.print(" Max execution delay: ");
+ pw.print("Max execution delay: ");
TimeUtils.formatDuration(job.getMaxExecutionDelayMillis(), pw);
pw.println();
}
- pw.print(prefix); pw.print(" Backoff: policy="); pw.print(job.getBackoffPolicy());
+ pw.print("Backoff: policy="); pw.print(job.getBackoffPolicy());
pw.print(" initial="); TimeUtils.formatDuration(job.getInitialBackoffMillis(), pw);
pw.println();
if (job.hasEarlyConstraint()) {
- pw.print(prefix); pw.println(" Has early constraint");
+ pw.println("Has early constraint");
}
if (job.hasLateConstraint()) {
- pw.print(prefix); pw.println(" Has late constraint");
+ pw.println("Has late constraint");
}
+
+ pw.decreaseIndent();
}
- pw.print(prefix); pw.print("Required constraints:");
+
+ pw.print("Required constraints:");
dumpConstraints(pw, requiredConstraints);
pw.println();
- pw.print(prefix);
pw.print("Dynamic constraints:");
dumpConstraints(pw, mDynamicConstraints);
pw.println();
if (full) {
- pw.print(prefix); pw.print("Satisfied constraints:");
+ pw.print("Satisfied constraints:");
dumpConstraints(pw, satisfiedConstraints);
pw.println();
- pw.print(prefix); pw.print("Unsatisfied constraints:");
+ pw.print("Unsatisfied constraints:");
dumpConstraints(pw,
((requiredConstraints | CONSTRAINT_WITHIN_QUOTA) & ~satisfiedConstraints));
pw.println();
if (dozeWhitelisted) {
- pw.print(prefix); pw.println("Doze whitelisted: true");
+ pw.println("Doze whitelisted: true");
}
if (uidActive) {
- pw.print(prefix); pw.println("Uid: active");
+ pw.println("Uid: active");
}
if (job.isExemptedFromAppStandby()) {
- pw.print(prefix); pw.println("Is exempted from app standby");
+ pw.println("Is exempted from app standby");
}
}
if (trackingControllers != 0) {
- pw.print(prefix); pw.print("Tracking:");
+ pw.print("Tracking:");
if ((trackingControllers&TRACKING_BATTERY) != 0) pw.print(" BATTERY");
if ((trackingControllers&TRACKING_CONNECTIVITY) != 0) pw.print(" CONNECTIVITY");
if ((trackingControllers&TRACKING_CONTENT) != 0) pw.print(" CONTENT");
@@ -1842,76 +1852,78 @@ public final class JobStatus {
pw.println();
}
- pw.print(prefix); pw.println("Implicit constraints:");
- pw.print(prefix); pw.print(" readyNotDozing: ");
+ pw.println("Implicit constraints:");
+ pw.increaseIndent();
+ pw.print("readyNotDozing: ");
pw.println(mReadyNotDozing);
- pw.print(prefix); pw.print(" readyNotRestrictedInBg: ");
+ pw.print("readyNotRestrictedInBg: ");
pw.println(mReadyNotRestrictedInBg);
if (!job.isPeriodic() && hasDeadlineConstraint()) {
- pw.print(prefix); pw.print(" readyDeadlineSatisfied: ");
+ pw.print("readyDeadlineSatisfied: ");
pw.println(mReadyDeadlineSatisfied);
}
if (mDynamicConstraints != 0) {
- pw.print(prefix);
- pw.print(" readyDynamicSatisfied: ");
+ pw.print("readyDynamicSatisfied: ");
pw.println(mReadyDynamicSatisfied);
}
- pw.print(prefix);
- pw.print(" readyComponentEnabled: ");
+ pw.print("readyComponentEnabled: ");
pw.println(serviceInfo != null);
if ((getFlags() & JobInfo.FLAG_EXPEDITED) != 0) {
- pw.print(prefix);
- pw.print(" mReadyWithinExpeditedQuota: ");
+ pw.print("readyWithinExpeditedQuota: ");
pw.println(mReadyWithinExpeditedQuota);
}
+ pw.decreaseIndent();
if (changedAuthorities != null) {
- pw.print(prefix); pw.println("Changed authorities:");
+ pw.println("Changed authorities:");
+ pw.increaseIndent();
for (int i=0; i<changedAuthorities.size(); i++) {
- pw.print(prefix); pw.print(" "); pw.println(changedAuthorities.valueAt(i));
+ pw.println(changedAuthorities.valueAt(i));
}
+ pw.decreaseIndent();
}
if (changedUris != null) {
- pw.print(prefix);
pw.println("Changed URIs:");
+ pw.increaseIndent();
for (int i = 0; i < changedUris.size(); i++) {
- pw.print(prefix);
- pw.print(" ");
pw.println(changedUris.valueAt(i));
}
+ pw.decreaseIndent();
}
if (network != null) {
- pw.print(prefix); pw.print("Network: "); pw.println(network);
+ pw.print("Network: "); pw.println(network);
}
if (pendingWork != null && pendingWork.size() > 0) {
- pw.print(prefix); pw.println("Pending work:");
+ pw.println("Pending work:");
for (int i = 0; i < pendingWork.size(); i++) {
- dumpJobWorkItem(pw, prefix, pendingWork.get(i), i);
+ dumpJobWorkItem(pw, pendingWork.get(i), i);
}
}
if (executingWork != null && executingWork.size() > 0) {
- pw.print(prefix); pw.println("Executing work:");
+ pw.println("Executing work:");
for (int i = 0; i < executingWork.size(); i++) {
- dumpJobWorkItem(pw, prefix, executingWork.get(i), i);
+ dumpJobWorkItem(pw, executingWork.get(i), i);
}
}
- pw.print(prefix); pw.print("Standby bucket: ");
+ pw.print("Standby bucket: ");
pw.println(getBucketName());
+ pw.increaseIndent();
if (whenStandbyDeferred != 0) {
- pw.print(prefix); pw.print(" Deferred since: ");
+ pw.print("Deferred since: ");
TimeUtils.formatDuration(whenStandbyDeferred, elapsedRealtimeMillis, pw);
pw.println();
}
if (mFirstForceBatchedTimeElapsed != 0) {
- pw.print(prefix);
- pw.print(" Time since first force batch attempt: ");
+ pw.print("Time since first force batch attempt: ");
TimeUtils.formatDuration(mFirstForceBatchedTimeElapsed, elapsedRealtimeMillis, pw);
pw.println();
}
- pw.print(prefix); pw.print("Enqueue time: ");
+ pw.decreaseIndent();
+
+ pw.print("Enqueue time: ");
TimeUtils.formatDuration(enqueueTime, elapsedRealtimeMillis, pw);
pw.println();
- pw.print(prefix); pw.print("Run time: earliest=");
+ pw.print("Run time: earliest=");
formatRunTime(pw, earliestRunTimeElapsedMillis, NO_EARLIEST_RUNTIME, elapsedRealtimeMillis);
pw.print(", latest=");
formatRunTime(pw, latestRunTimeElapsedMillis, NO_LATEST_RUNTIME, elapsedRealtimeMillis);
@@ -1920,14 +1932,14 @@ public final class JobStatus {
NO_LATEST_RUNTIME, elapsedRealtimeMillis);
pw.println();
if (numFailures != 0) {
- pw.print(prefix); pw.print("Num failures: "); pw.println(numFailures);
+ pw.print("Num failures: "); pw.println(numFailures);
}
if (mLastSuccessfulRunTime != 0) {
- pw.print(prefix); pw.print("Last successful run: ");
+ pw.print("Last successful run: ");
pw.println(formatTime(mLastSuccessfulRunTime));
}
if (mLastFailedRunTime != 0) {
- pw.print(prefix); pw.print("Last failed run: ");
+ pw.print("Last failed run: ");
pw.println(formatTime(mLastFailedRunTime));
}
}
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 f2d10ac0f7d7..2196b16e0846 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
@@ -72,7 +72,6 @@ import com.android.server.LocalServices;
import com.android.server.PowerAllowlistInternal;
import com.android.server.job.ConstantsProto;
import com.android.server.job.JobSchedulerService;
-import com.android.server.job.JobServiceContext;
import com.android.server.job.StateControllerProto;
import com.android.server.usage.AppStandbyInternal;
import com.android.server.usage.AppStandbyInternal.AppIdleStateChangeListener;
@@ -770,18 +769,38 @@ public final class QuotaController extends StateController {
/** Returns the maximum amount of time this job could run for. */
public long getMaxJobExecutionTimeMsLocked(@NonNull final JobStatus jobStatus) {
- // If quota is currently "free", then the job can run for the full amount of time.
- if (mChargeTracker.isCharging()
- || isTopStartedJobLocked(jobStatus)
- || isUidInForeground(jobStatus.getSourceUid())) {
- return JobServiceContext.DEFAULT_EXECUTING_TIMESLICE_MILLIS;
- }
- if (jobStatus.shouldTreatAsExpeditedJob()) {
- return jobStatus.getStandbyBucket() == RESTRICTED_INDEX
- ? JobServiceContext.DEFAULT_RESTRICTED_EXPEDITED_JOB_EXECUTING_TIMESLICE_MILLIS
- : JobServiceContext.DEFAULT_EXECUTING_TIMESLICE_MILLIS;
- }
- return getRemainingExecutionTimeLocked(jobStatus);
+ // Need to look at current proc state as well in the case where the job hasn't started yet.
+ final boolean isTop = mActivityManagerInternal
+ .getUidProcessState(jobStatus.getSourceUid()) <= ActivityManager.PROCESS_STATE_TOP;
+
+ if (!jobStatus.shouldTreatAsExpeditedJob()) {
+ // If quota is currently "free", then the job can run for the full amount of time.
+ if (mChargeTracker.isCharging()
+ || isTop
+ || isTopStartedJobLocked(jobStatus)
+ || isUidInForeground(jobStatus.getSourceUid())) {
+ return mConstants.RUNTIME_FREE_QUOTA_MAX_LIMIT_MS;
+ }
+ return getTimeUntilQuotaConsumedLocked(
+ jobStatus.getSourceUserId(), jobStatus.getSourcePackageName());
+ }
+
+ // Expedited job.
+ if (mChargeTracker.isCharging()) {
+ return mConstants.RUNTIME_FREE_QUOTA_MAX_LIMIT_MS;
+ }
+ if (isTop || isTopStartedJobLocked(jobStatus)) {
+ return Math.max(mEJLimitsMs[ACTIVE_INDEX] / 2,
+ getTimeUntilEJQuotaConsumedLocked(
+ jobStatus.getSourceUserId(), jobStatus.getSourcePackageName()));
+ }
+ if (isUidInForeground(jobStatus.getSourceUid())) {
+ return Math.max(mEJLimitsMs[WORKING_INDEX] / 2,
+ getTimeUntilEJQuotaConsumedLocked(
+ jobStatus.getSourceUserId(), jobStatus.getSourcePackageName()));
+ }
+ return getTimeUntilEJQuotaConsumedLocked(
+ jobStatus.getSourceUserId(), jobStatus.getSourcePackageName());
}
/** @return true if the job is within expedited job quota. */
@@ -3577,8 +3596,8 @@ public final class QuotaController extends StateController {
mEJLimitsMs[RARE_INDEX] = newRareLimitMs;
mShouldReevaluateConstraints = true;
}
- // The limit must be in the range [0 minutes, rare limit].
- long newRestrictedLimitMs = Math.max(0,
+ // The limit must be in the range [5 minutes, rare limit].
+ long newRestrictedLimitMs = Math.max(5 * MINUTE_IN_MILLIS,
Math.min(newRareLimitMs, EJ_LIMIT_RESTRICTED_MS));
if (mEJLimitsMs[RESTRICTED_INDEX] != newRestrictedLimitMs) {
mEJLimitsMs[RESTRICTED_INDEX] = newRestrictedLimitMs;
diff --git a/apex/jobscheduler/service/java/com/android/server/job/restrictions/ThermalStatusRestriction.java b/apex/jobscheduler/service/java/com/android/server/job/restrictions/ThermalStatusRestriction.java
index 40c8ce0d5c89..954a5b8bdaa8 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/restrictions/ThermalStatusRestriction.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/restrictions/ThermalStatusRestriction.java
@@ -64,7 +64,7 @@ public class ThermalStatusRestriction extends JobRestriction {
@Override
public void dumpConstants(IndentingPrintWriter pw) {
pw.print("In thermal throttling?: ");
- pw.print(mIsThermalRestricted);
+ pw.println(mIsThermalRestricted);
}
@Override
diff --git a/core/api/current.txt b/core/api/current.txt
index d3d754c0d8a5..742004b24541 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -10444,6 +10444,7 @@ package android.content {
field public static final int CONTEXT_RESTRICTED = 4; // 0x4
field public static final String CROSS_PROFILE_APPS_SERVICE = "crossprofileapps";
field public static final String DEVICE_POLICY_SERVICE = "device_policy";
+ field public static final String DISPLAY_HASH_SERVICE = "display_hash";
field public static final String DISPLAY_SERVICE = "display";
field public static final String DOWNLOAD_SERVICE = "download";
field public static final String DROPBOX_SERVICE = "dropbox";
@@ -21117,15 +21118,15 @@ package android.media {
public static final class MediaCodec.CryptoException extends java.lang.RuntimeException {
ctor public MediaCodec.CryptoException(int, @Nullable String);
method public int getErrorCode();
- field public static final int ERROR_FRAME_TOO_LARGE = 8; // 0x8
- field public static final int ERROR_INSUFFICIENT_OUTPUT_PROTECTION = 4; // 0x4
- field public static final int ERROR_INSUFFICIENT_SECURITY = 7; // 0x7
- field public static final int ERROR_KEY_EXPIRED = 2; // 0x2
- field public static final int ERROR_LOST_STATE = 9; // 0x9
- field public static final int ERROR_NO_KEY = 1; // 0x1
- field public static final int ERROR_RESOURCE_BUSY = 3; // 0x3
- field public static final int ERROR_SESSION_NOT_OPENED = 5; // 0x5
- field public static final int ERROR_UNSUPPORTED_OPERATION = 6; // 0x6
+ field @Deprecated public static final int ERROR_FRAME_TOO_LARGE = 8; // 0x8
+ field @Deprecated public static final int ERROR_INSUFFICIENT_OUTPUT_PROTECTION = 4; // 0x4
+ field @Deprecated public static final int ERROR_INSUFFICIENT_SECURITY = 7; // 0x7
+ field @Deprecated public static final int ERROR_KEY_EXPIRED = 2; // 0x2
+ field @Deprecated public static final int ERROR_LOST_STATE = 9; // 0x9
+ field @Deprecated public static final int ERROR_NO_KEY = 1; // 0x1
+ field @Deprecated public static final int ERROR_RESOURCE_BUSY = 3; // 0x3
+ field @Deprecated public static final int ERROR_SESSION_NOT_OPENED = 5; // 0x5
+ field @Deprecated public static final int ERROR_UNSUPPORTED_OPERATION = 6; // 0x6
}
public static final class MediaCodec.CryptoInfo {
@@ -21744,6 +21745,42 @@ package android.media {
method public boolean verify(@NonNull byte[], @NonNull byte[], @NonNull byte[]);
}
+ public static final class MediaDrm.ErrorCodes {
+ field public static final int ERROR_CERTIFICATE_MALFORMED = 10; // 0xa
+ field public static final int ERROR_CERTIFICATE_MISSING = 11; // 0xb
+ field public static final int ERROR_CRYPTO_LIBRARY = 12; // 0xc
+ field public static final int ERROR_FRAME_TOO_LARGE = 8; // 0x8
+ field public static final int ERROR_GENERIC_OEM = 13; // 0xd
+ field public static final int ERROR_GENERIC_PLUGIN = 14; // 0xe
+ field public static final int ERROR_INIT_DATA = 15; // 0xf
+ field public static final int ERROR_INSUFFICIENT_OUTPUT_PROTECTION = 4; // 0x4
+ field public static final int ERROR_INSUFFICIENT_SECURITY = 7; // 0x7
+ field public static final int ERROR_KEY_EXPIRED = 2; // 0x2
+ field public static final int ERROR_KEY_NOT_LOADED = 16; // 0x10
+ field public static final int ERROR_LICENSE_PARSE = 17; // 0x11
+ field public static final int ERROR_LICENSE_POLICY = 18; // 0x12
+ field public static final int ERROR_LICENSE_RELEASE = 19; // 0x13
+ field public static final int ERROR_LICENSE_REQUEST_REJECTED = 20; // 0x14
+ field public static final int ERROR_LICENSE_RESTORE = 21; // 0x15
+ field public static final int ERROR_LICENSE_STATE = 22; // 0x16
+ field public static final int ERROR_LOST_STATE = 9; // 0x9
+ field public static final int ERROR_MEDIA_FRAMEWORK = 23; // 0x17
+ field public static final int ERROR_NO_KEY = 1; // 0x1
+ field public static final int ERROR_PROVISIONING_CERTIFICATE = 24; // 0x18
+ field public static final int ERROR_PROVISIONING_CONFIG = 25; // 0x19
+ field public static final int ERROR_PROVISIONING_PARSE = 26; // 0x1a
+ field public static final int ERROR_PROVISIONING_RETRY = 27; // 0x1b
+ field public static final int ERROR_RESOURCE_BUSY = 3; // 0x3
+ field public static final int ERROR_RESOURCE_CONTENTION = 28; // 0x1c
+ field public static final int ERROR_SECURE_STOP_RELEASE = 29; // 0x1d
+ field public static final int ERROR_SESSION_NOT_OPENED = 5; // 0x5
+ field public static final int ERROR_STORAGE_READ = 30; // 0x1e
+ field public static final int ERROR_STORAGE_WRITE = 31; // 0x1f
+ field public static final int ERROR_UNKNOWN = 0; // 0x0
+ field public static final int ERROR_UNSUPPORTED_OPERATION = 6; // 0x6
+ field public static final int ERROR_ZERO_SUBSAMPLES = 32; // 0x20
+ }
+
@Deprecated @IntDef({android.media.MediaDrm.HDCP_LEVEL_UNKNOWN, android.media.MediaDrm.HDCP_NONE, android.media.MediaDrm.HDCP_V1, android.media.MediaDrm.HDCP_V2, android.media.MediaDrm.HDCP_V2_1, android.media.MediaDrm.HDCP_V2_2, android.media.MediaDrm.HDCP_V2_3, android.media.MediaDrm.HDCP_NO_DIGITAL_OUTPUT}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface MediaDrm.HdcpLevel {
}
@@ -21777,6 +21814,8 @@ package android.media {
public static final class MediaDrm.MediaDrmStateException extends java.lang.IllegalStateException {
method @NonNull public String getDiagnosticInfo();
+ method public int getErrorCode();
+ method public boolean isTransient();
}
public static final class MediaDrm.MetricsConstants {
@@ -21843,9 +21882,10 @@ package android.media {
public static final class MediaDrm.SessionException extends java.lang.RuntimeException {
ctor public MediaDrm.SessionException(int, @Nullable String);
- method public int getErrorCode();
- field public static final int ERROR_RESOURCE_CONTENTION = 1; // 0x1
- field public static final int ERROR_UNKNOWN = 0; // 0x0
+ method @Deprecated public int getErrorCode();
+ method public boolean isTransient();
+ field @Deprecated public static final int ERROR_RESOURCE_CONTENTION = 1; // 0x1
+ field @Deprecated public static final int ERROR_UNKNOWN = 0; // 0x0
}
public class MediaDrmException extends java.lang.Exception {
@@ -26985,6 +27025,15 @@ package android.net.vcn {
method @NonNull public android.net.vcn.VcnConfig build();
}
+ public abstract class VcnControlPlaneConfig {
+ }
+
+ public final class VcnControlPlaneIkeConfig extends android.net.vcn.VcnControlPlaneConfig {
+ ctor public VcnControlPlaneIkeConfig(@NonNull android.net.ipsec.ike.IkeSessionParams, @NonNull android.net.ipsec.ike.TunnelModeChildSessionParams);
+ method @NonNull public android.net.ipsec.ike.TunnelModeChildSessionParams getChildSessionParams();
+ method @NonNull public android.net.ipsec.ike.IkeSessionParams getIkeSessionParams();
+ }
+
public final class VcnGatewayConnectionConfig {
method @NonNull public int[] getExposedCapabilities();
method @IntRange(from=android.net.vcn.VcnGatewayConnectionConfig.MIN_MTU_V6) public int getMaxMtu();
@@ -26993,7 +27042,7 @@ package android.net.vcn {
}
public static final class VcnGatewayConnectionConfig.Builder {
- ctor public VcnGatewayConnectionConfig.Builder();
+ ctor public VcnGatewayConnectionConfig.Builder(@NonNull android.net.vcn.VcnControlPlaneConfig);
method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder addExposedCapability(int);
method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder addRequiredUnderlyingCapability(int);
method @NonNull public android.net.vcn.VcnGatewayConnectionConfig build();
@@ -39026,7 +39075,9 @@ package android.speech {
field public static final int ERROR_NO_MATCH = 7; // 0x7
field public static final int ERROR_RECOGNIZER_BUSY = 8; // 0x8
field public static final int ERROR_SERVER = 4; // 0x4
+ field public static final int ERROR_SERVER_DISCONNECTED = 11; // 0xb
field public static final int ERROR_SPEECH_TIMEOUT = 6; // 0x6
+ field public static final int ERROR_TOO_MANY_REQUESTS = 10; // 0xa
field public static final String RESULTS_RECOGNITION = "results_recognition";
}
@@ -48233,6 +48284,7 @@ package android.view {
method public android.view.View focusSearch(int);
method public void forceHasOverlappingRendering(boolean);
method public void forceLayout();
+ method @Nullable public void generateDisplayHash(@NonNull String, @Nullable android.graphics.Rect, @NonNull java.util.concurrent.Executor, @NonNull android.view.displayhash.DisplayHashResultCallback);
method public static int generateViewId();
method public CharSequence getAccessibilityClassName();
method public android.view.View.AccessibilityDelegate getAccessibilityDelegate();
@@ -51188,6 +51240,41 @@ package android.view.contentcapture {
}
+package android.view.displayhash {
+
+ public final class DisplayHash implements android.os.Parcelable {
+ method public int describeContents();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.view.displayhash.DisplayHash> CREATOR;
+ }
+
+ public final class DisplayHashManager {
+ method @NonNull public java.util.Set<java.lang.String> getSupportedHashAlgorithms();
+ method @Nullable public android.view.displayhash.VerifiedDisplayHash verifyDisplayHash(@NonNull android.view.displayhash.DisplayHash);
+ }
+
+ public interface DisplayHashResultCallback {
+ method public void onDisplayHashError(int);
+ method public void onDisplayHashResult(@NonNull android.view.displayhash.DisplayHash);
+ field public static final int DISPLAY_HASH_ERROR_INVALID_BOUNDS = -2; // 0xfffffffe
+ field public static final int DISPLAY_HASH_ERROR_MISSING_WINDOW = -3; // 0xfffffffd
+ field public static final int DISPLAY_HASH_ERROR_NOT_VISIBLE_ON_SCREEN = -4; // 0xfffffffc
+ field public static final int DISPLAY_HASH_ERROR_UNKNOWN = -1; // 0xffffffff
+ }
+
+ public final class VerifiedDisplayHash implements android.os.Parcelable {
+ ctor public VerifiedDisplayHash(long, @NonNull android.graphics.Rect, @NonNull String, @NonNull byte[]);
+ method public int describeContents();
+ method @NonNull public android.graphics.Rect getBoundsInWindow();
+ method @NonNull public String getHashAlgorithm();
+ method @NonNull public byte[] getImageHash();
+ method public long getTimeMillis();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.view.displayhash.VerifiedDisplayHash> CREATOR;
+ }
+
+}
+
package android.view.inputmethod {
public class BaseInputConnection implements android.view.inputmethod.InputConnection {
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index deff7b38ea2a..7e83426dc7cd 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -9984,6 +9984,18 @@ package android.service.dataloader {
}
+package android.service.displayhash {
+
+ public abstract class DisplayHasherService extends android.app.Service {
+ ctor public DisplayHasherService();
+ method @NonNull public final android.os.IBinder onBind(@NonNull android.content.Intent);
+ method @Nullable public abstract void onGenerateDisplayHash(@NonNull byte[], @NonNull android.hardware.HardwareBuffer, @NonNull android.graphics.Rect, @NonNull String, @NonNull android.view.displayhash.DisplayHashResultCallback);
+ method @Nullable public abstract android.view.displayhash.VerifiedDisplayHash onVerifyDisplayHash(@NonNull byte[], @NonNull android.view.displayhash.DisplayHash);
+ field public static final String SERVICE_INTERFACE = "android.service.displayhash.DisplayHasherService";
+ }
+
+}
+
package android.service.euicc {
public final class DownloadSubscriptionResult implements android.os.Parcelable {
@@ -10344,30 +10356,6 @@ package android.service.rotationresolver {
}
-package android.service.screenshot {
-
- public final class ScreenshotHash implements android.os.Parcelable {
- ctor public ScreenshotHash(long, @NonNull android.graphics.Rect, @NonNull String, @NonNull byte[], @NonNull byte[]);
- method public int describeContents();
- method @NonNull public android.graphics.Rect getBoundsInWindow();
- method @NonNull public String getHashingAlgorithm();
- method @NonNull public byte[] getHmac();
- method @NonNull public byte[] getImageHash();
- method public long getScreenshotTimeMillis();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.service.screenshot.ScreenshotHash> CREATOR;
- }
-
- public abstract class ScreenshotHasherService extends android.app.Service {
- ctor public ScreenshotHasherService();
- method @NonNull public final android.os.IBinder onBind(@NonNull android.content.Intent);
- method @Nullable public abstract android.service.screenshot.ScreenshotHash onGenerateScreenshotHash(@NonNull byte[], @NonNull android.hardware.HardwareBuffer, @NonNull android.graphics.Rect, @NonNull String);
- method public abstract boolean onVerifyScreenshotHash(@NonNull byte[], @NonNull android.service.screenshot.ScreenshotHash);
- field public static final String SERVICE_INTERFACE = "android.service.screenshot.ScreenshotHasherService";
- }
-
-}
-
package android.service.search {
public abstract class SearchUiService extends android.app.Service {
@@ -14399,6 +14387,21 @@ package android.view.contentcapture {
}
+package android.view.displayhash {
+
+ public final class DisplayHash implements android.os.Parcelable {
+ ctor public DisplayHash(long, @NonNull android.graphics.Rect, @NonNull String, @NonNull byte[], @NonNull byte[]);
+ method public int describeContents();
+ method @NonNull public android.graphics.Rect getBoundsInWindow();
+ method @NonNull public String getHashAlgorithm();
+ method @NonNull public byte[] getHmac();
+ method @NonNull public byte[] getImageHash();
+ method public long getTimeMillis();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ }
+
+}
+
package android.view.translation {
public final class UiTranslationManager {
diff --git a/core/java/android/app/ITaskStackListener.aidl b/core/java/android/app/ITaskStackListener.aidl
index a9e28bb635be..b1c39d39d414 100644
--- a/core/java/android/app/ITaskStackListener.aidl
+++ b/core/java/android/app/ITaskStackListener.aidl
@@ -209,4 +209,10 @@ oneway interface ITaskStackListener {
* @param taskInfo info about the task which moved
*/
void onTaskMovedToBack(in ActivityManager.RunningTaskInfo taskInfo);
+
+ /**
+ * Called when the lock task mode changes. See ActivityManager#LOCK_TASK_MODE_* and
+ * LockTaskController.
+ */
+ void onLockTaskModeChanged(int mode);
}
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index c47b546653b9..ffaaa578cdd2 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -211,6 +211,7 @@ import android.view.autofill.AutofillManager;
import android.view.autofill.IAutoFillManager;
import android.view.contentcapture.ContentCaptureManager;
import android.view.contentcapture.IContentCaptureManager;
+import android.view.displayhash.DisplayHashManager;
import android.view.inputmethod.InputMethodManager;
import android.view.textclassifier.TextClassificationManager;
import android.view.textservice.TextServicesManager;
@@ -1426,6 +1427,13 @@ public final class SystemServiceRegistry {
}
});
+ registerService(Context.DISPLAY_HASH_SERVICE, DisplayHashManager.class,
+ new CachedServiceFetcher<DisplayHashManager>() {
+ @Override
+ public DisplayHashManager createService(ContextImpl ctx) {
+ return new DisplayHashManager();
+ }});
+
sInitializing = true;
try {
// Note: the following functions need to be @SystemApis, once they become mainline
diff --git a/core/java/android/app/TaskStackListener.java b/core/java/android/app/TaskStackListener.java
index 517ae24b75a6..1e382307a1a3 100644
--- a/core/java/android/app/TaskStackListener.java
+++ b/core/java/android/app/TaskStackListener.java
@@ -193,4 +193,8 @@ public abstract class TaskStackListener extends ITaskStackListener.Stub {
@Override
public void onTaskMovedToBack(RunningTaskInfo taskInfo) {
}
+
+ @Override
+ public void onLockTaskModeChanged(int mode) {
+ }
}
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 51669432e377..0093b6342da6 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -5491,6 +5491,14 @@ public abstract class Context {
public static final String DOMAIN_VERIFICATION_SERVICE = "domain_verification";
/**
+ * Use with {@link #getSystemService(String)} to access
+ * {@link android.view.displayhash.DisplayHashManager} to handle display hashes.
+ *
+ * @see #getSystemService(String)
+ */
+ public static final String DISPLAY_HASH_SERVICE = "display_hash";
+
+ /**
* Determine whether the given permission is allowed for a particular
* process and user ID running in the system.
*
diff --git a/core/java/android/net/vcn/VcnControlPlaneConfig.java b/core/java/android/net/vcn/VcnControlPlaneConfig.java
index 0c6ccfee5d5d..92f6c4440377 100644
--- a/core/java/android/net/vcn/VcnControlPlaneConfig.java
+++ b/core/java/android/net/vcn/VcnControlPlaneConfig.java
@@ -35,8 +35,6 @@ import java.util.Objects;
*
* @see VcnManager
* @see VcnGatewayConnectionConfig
- *
- * @hide
*/
public abstract class VcnControlPlaneConfig {
/** @hide */
diff --git a/core/java/android/net/vcn/VcnControlPlaneIkeConfig.java b/core/java/android/net/vcn/VcnControlPlaneIkeConfig.java
index 2f6e1f63b960..de086f63b14d 100644
--- a/core/java/android/net/vcn/VcnControlPlaneIkeConfig.java
+++ b/core/java/android/net/vcn/VcnControlPlaneIkeConfig.java
@@ -34,8 +34,6 @@ import java.util.Objects;
* configuration, authentication and authorization parameters.
*
* @see VcnControlPlaneConfig
- *
- * @hide
*/
public final class VcnControlPlaneIkeConfig extends VcnControlPlaneConfig {
private static final String TAG = VcnControlPlaneIkeConfig.class.getSimpleName();
diff --git a/core/java/android/net/vcn/VcnGatewayConnectionConfig.java b/core/java/android/net/vcn/VcnGatewayConnectionConfig.java
index 94dff9159bd9..9f83b21f0d0c 100644
--- a/core/java/android/net/vcn/VcnGatewayConnectionConfig.java
+++ b/core/java/android/net/vcn/VcnGatewayConnectionConfig.java
@@ -420,7 +420,6 @@ public final class VcnGatewayConnectionConfig {
*
* @param ctrlPlaneConfig the control plane configuration
* @see VcnControlPlaneConfig
- * @hide
*/
public Builder(@NonNull VcnControlPlaneConfig ctrlPlaneConfig) {
Objects.requireNonNull(ctrlPlaneConfig, "ctrlPlaneConfig was null");
@@ -428,13 +427,6 @@ public final class VcnGatewayConnectionConfig {
mCtrlPlaneConfig = ctrlPlaneConfig;
}
- /** Construct a Builder object. */
- // TODO: Remove this constructor when #Builder(ctrlPlaneConfig) is exposed as public API.
- // This constructor is created to avoid changing API shape in this CL
- public Builder() {
- mCtrlPlaneConfig = null;
- }
-
/**
* Add a capability that this VCN Gateway Connection will support.
*
diff --git a/core/java/android/os/Trace.java b/core/java/android/os/Trace.java
index 9c9e4995d673..c8cbc517b226 100644
--- a/core/java/android/os/Trace.java
+++ b/core/java/android/os/Trace.java
@@ -168,8 +168,10 @@ public final class Trace {
}
/**
- * Set whether application tracing is allowed for this process. This is intended to be set
- * once at application start-up time based on whether the application is debuggable.
+ * From Android S, this is no-op.
+ *
+ * Before, set whether application tracing is allowed for this process. This is intended to be
+ * set once at application start-up time based on whether the application is debuggable.
*
* @hide
*/
diff --git a/core/java/android/os/incremental/IncrementalFileStorages.java b/core/java/android/os/incremental/IncrementalFileStorages.java
index f2fe71913bb1..a078e0434867 100644
--- a/core/java/android/os/incremental/IncrementalFileStorages.java
+++ b/core/java/android/os/incremental/IncrementalFileStorages.java
@@ -36,6 +36,7 @@ import android.annotation.Nullable;
import android.content.Context;
import android.content.pm.DataLoaderParams;
import android.content.pm.IDataLoaderStatusListener;
+import android.content.pm.IPackageLoadingProgressCallback;
import android.content.pm.InstallationFileParcel;
import java.io.File;
@@ -71,7 +72,8 @@ public final class IncrementalFileStorages {
@Nullable StorageHealthCheckParams healthCheckParams,
@Nullable IStorageHealthListener healthListener,
@NonNull List<InstallationFileParcel> addedFiles,
- @NonNull PerUidReadTimeouts[] perUidReadTimeouts) throws IOException {
+ @NonNull PerUidReadTimeouts[] perUidReadTimeouts,
+ IPackageLoadingProgressCallback progressCallback) throws IOException {
// TODO(b/136132412): validity check if session should not be incremental
IncrementalManager incrementalManager = (IncrementalManager) context.getSystemService(
Context.INCREMENTAL_SERVICE);
@@ -95,6 +97,11 @@ public final class IncrementalFileStorages {
throw new IOException("Unknown file location: " + file.location);
}
}
+ // Register progress loading callback after files have been added
+ if (progressCallback != null) {
+ incrementalManager.registerLoadingProgressCallback(stageDir.getAbsolutePath(),
+ progressCallback);
+ }
result.startLoading(dataLoaderParams, statusListener, healthCheckParams, healthListener,
perUidReadTimeouts);
@@ -205,6 +212,7 @@ public final class IncrementalFileStorages {
try {
mDefaultStorage.unBind(mStageDir.getAbsolutePath());
+ mDefaultStorage.unregisterLoadingProgressListener();
} catch (IOException ignored) {
}
mDefaultStorage = null;
diff --git a/core/java/android/service/displayhash/DisplayHasherService.java b/core/java/android/service/displayhash/DisplayHasherService.java
new file mode 100644
index 000000000000..331dbe91f6c7
--- /dev/null
+++ b/core/java/android/service/displayhash/DisplayHasherService.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.service.displayhash;
+
+import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.app.Service;
+import android.content.Intent;
+import android.graphics.Rect;
+import android.hardware.HardwareBuffer;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.RemoteCallback;
+import android.view.displayhash.DisplayHash;
+import android.view.displayhash.DisplayHashResultCallback;
+import android.view.displayhash.VerifiedDisplayHash;
+
+/**
+ * A service that handles generating and verify {@link DisplayHash}.
+ *
+ * The service will generate a DisplayHash based on arguments passed in. Then later that
+ * same DisplayHash can be verified to determine that it was created by the system.
+ *
+ * @hide
+ */
+@SystemApi
+public abstract class DisplayHasherService extends Service {
+
+ /** @hide **/
+ public static final String EXTRA_VERIFIED_DISPLAY_HASH =
+ "android.service.displayhash.extra.VERIFIED_DISPLAY_HASH";
+
+ /**
+ * Manifest metadata key for the resource string array containing the names of all hashing
+ * algorithms provided by the service.
+ *
+ * @hide
+ */
+ public static final String SERVICE_META_DATA_KEY_AVAILABLE_ALGORITHMS =
+ "android.displayhash.available_algorithms";
+
+ /**
+ * The {@link Intent} action that must be declared as handled by a service in its manifest
+ * for the system to recognize it as a DisplayHash providing service.
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final String SERVICE_INTERFACE =
+ "android.service.displayhash.DisplayHasherService";
+
+ private DisplayHasherServiceWrapper mWrapper;
+ private Handler mHandler;
+
+ public DisplayHasherService() {
+ }
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ mWrapper = new DisplayHasherServiceWrapper();
+ mHandler = new Handler(Looper.getMainLooper(), null, true);
+ }
+
+ @NonNull
+ @Override
+ public final IBinder onBind(@NonNull Intent intent) {
+ return mWrapper;
+ }
+
+ /**
+ * Generates the DisplayHash that can be used to validate that the system generated the
+ * token.
+ *
+ * @param salt The salt to use when generating the hmac. This should be unique to the
+ * caller so the token cannot be verified by any other process.
+ * @param buffer The buffer for the content to generate the hash for.
+ * @param bounds The size and position of the content in window space.
+ * @param hashAlgorithm The String for the hashing algorithm to use based values in
+ * {@link #SERVICE_META_DATA_KEY_AVAILABLE_ALGORITHMS)}.
+ * @param callback The callback to invoke
+ * {@link DisplayHashResultCallback#onDisplayHashResult(DisplayHash)}
+ * if successfully generated a DisplayHash or {@link
+ * DisplayHashResultCallback#onDisplayHashError(int)} if failed.
+ */
+ @Nullable
+ public abstract void onGenerateDisplayHash(@NonNull byte[] salt,
+ @NonNull HardwareBuffer buffer, @NonNull Rect bounds,
+ @NonNull String hashAlgorithm, @NonNull DisplayHashResultCallback callback);
+
+ /**
+ * Call to verify that the DisplayHash passed in was generated by the system.
+ *
+ * @param salt The salt value to use when verifying the hmac. This should be the
+ * same value that was passed to
+ * {@link #onGenerateDisplayHash(byte[],
+ * HardwareBuffer, Rect, String, DisplayHashResultCallback)} to
+ * generate the token.
+ * @param displayHash The token to verify that it was generated by the system.
+ * @return a {@link VerifiedDisplayHash} if the token was generated by the system or null
+ * if the token cannot be verified.
+ */
+ @Nullable
+ public abstract VerifiedDisplayHash onVerifyDisplayHash(@NonNull byte[] salt,
+ @NonNull DisplayHash displayHash);
+
+ private void verifyDisplayHash(byte[] salt, DisplayHash displayHash,
+ RemoteCallback callback) {
+ VerifiedDisplayHash verifiedDisplayHash = onVerifyDisplayHash(salt,
+ displayHash);
+ final Bundle data = new Bundle();
+ data.putParcelable(EXTRA_VERIFIED_DISPLAY_HASH, verifiedDisplayHash);
+ callback.sendResult(data);
+ }
+
+ private final class DisplayHasherServiceWrapper extends IDisplayHasherService.Stub {
+ @Override
+ public void generateDisplayHash(byte[] salt, HardwareBuffer buffer, Rect bounds,
+ String hashAlgorithm, RemoteCallback callback) {
+ mHandler.sendMessage(
+ obtainMessage(DisplayHasherService::onGenerateDisplayHash,
+ DisplayHasherService.this, salt, buffer, bounds,
+ hashAlgorithm, new DisplayHashResultCallback() {
+ @Override
+ public void onDisplayHashResult(
+ @NonNull DisplayHash displayHash) {
+ Bundle result = new Bundle();
+ result.putParcelable(EXTRA_DISPLAY_HASH, displayHash);
+ callback.sendResult(result);
+ }
+
+ @Override
+ public void onDisplayHashError(int errorCode) {
+ Bundle result = new Bundle();
+ result.putInt(EXTRA_DISPLAY_HASH_ERROR_CODE, errorCode);
+ callback.sendResult(result);
+ }
+ }));
+ }
+
+ @Override
+ public void verifyDisplayHash(byte[] salt, DisplayHash displayHash,
+ RemoteCallback callback) {
+ mHandler.sendMessage(
+ obtainMessage(DisplayHasherService::verifyDisplayHash,
+ DisplayHasherService.this, salt, displayHash, callback));
+ }
+ }
+}
diff --git a/core/java/android/service/screenshot/IScreenshotHasherService.aidl b/core/java/android/service/displayhash/IDisplayHasherService.aidl
index d14d147e096c..236bc28c74c8 100644
--- a/core/java/android/service/screenshot/IScreenshotHasherService.aidl
+++ b/core/java/android/service/displayhash/IDisplayHasherService.aidl
@@ -14,43 +14,41 @@
* limitations under the License.
*/
-package android.service.screenshot;
+package android.service.displayhash;
import android.graphics.Rect;
import android.hardware.HardwareBuffer;
import android.os.RemoteCallback;
-import android.service.screenshot.ScreenshotHash;
+import android.view.displayhash.DisplayHash;
/**
- * Service used to handle ScreenshotHash requests.
+ * Service used to handle DisplayHash requests.
*
* @hide
*/
-oneway interface IScreenshotHasherService {
+oneway interface IDisplayHasherService {
/**
- * Generates the ScreenshotHash token that can be used to validate that the system generated the
- * token.
+ * Generates the DisplayHash that can be used to validate that the system generated the token.
*
* @param salt The salt to use when generating the hmac. This should be unique to the caller so
* the token cannot be verified by any other process.
- * @param screenshot The screenshot to generate the hash and add to the token.
- * @param bounds The size and position of the content being screenshot in the window.
- * @param hashAlgorithm The String for the hashing algorithm to use based on values in
+ * @param buffer The buffer to generate the hash for.
+ * @param bounds The size and position of the content being hashed in window space.
+ * @param hashAlgorithm The String for the hash algorithm to use based on values in
* {@link #SERVICE_META_DATA_KEY_AVAILABLE_ALGORITHMS}.
- * @param Callback The callback invoked to send back the ScreenshotHash token.
+ * @param Callback The callback invoked to send back the DisplayHash.
*/
- void generateScreenshotHash(in byte[] salt, in HardwareBuffer screenshot, in Rect bounds,
+ void generateDisplayHash(in byte[] salt, in HardwareBuffer buffer, in Rect bounds,
in String hashAlgorithm, in RemoteCallback callback);
/**
- * Call to verify that the ScreenshotHash passed in was generated by the system. The result
- * will be sent in the callback as a boolean with the key {@link #EXTRA_VERIFICATION_STATUS}.
+ * Call to verify that the DisplayHash passed in was generated by the system. The result
+ * will be sent in the callback as a boolean with the key {@link #EXTRA_VERIFIED_DISPLAY_HASH}.
*
* @param salt The salt value to use when verifying the hmac. This should be the same value that
- * was passed to {@link generateScreenshotHash()} to generate the token.
- * @param screenshotHash The hash to verify that it was generated by the system.
- * @param callback The callback invoked to send back the verification status.
+ * was passed to {@link generateDisplayHash()} to generate the DisplayHash.
+ * @param displayHash The hash to verify that it was generated by the system.
+ * @param callback The callback invoked to send back the VerifiedDisplayHash.
*/
- void verifyScreenshotHash(in byte[] salt, in ScreenshotHash screenshotHash,
- in RemoteCallback callback);
+ void verifyDisplayHash(in byte[] salt, in DisplayHash displayHash, in RemoteCallback callback);
}
diff --git a/core/java/android/service/screenshot/OWNERS b/core/java/android/service/displayhash/OWNERS
index 0862c05e0ee4..0862c05e0ee4 100644
--- a/core/java/android/service/screenshot/OWNERS
+++ b/core/java/android/service/displayhash/OWNERS
diff --git a/core/java/android/service/screenshot/ScreenshotHash.java b/core/java/android/service/screenshot/ScreenshotHash.java
deleted file mode 100644
index 9ae4192bb676..000000000000
--- a/core/java/android/service/screenshot/ScreenshotHash.java
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.service.screenshot;
-
-import android.annotation.NonNull;
-import android.annotation.SystemApi;
-import android.graphics.Rect;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import com.android.internal.util.DataClass;
-
-/**
- * The screenshot hash used to validate information about what was present on screen.
- * @hide
- *
- * TODO: Remove hide and SystemAPI since this will be a public class
- */
-@SystemApi
-@DataClass(genToString = true, genAidl = true)
-public final class ScreenshotHash implements Parcelable {
- /**
- * The timestamp when the screenshot was generated.
- */
- private final long mScreenshotTimeMillis;
-
- /**
- * The bounds of the requested area to take the screenshot. This is in window space passed in
- * by the client.
- */
- @NonNull
- private final Rect mBoundsInWindow;
-
- /**
- * The selected hashing algorithm that generated the image hash.
- */
- @NonNull
- private final String mHashingAlgorithm;
-
- /**
- * The image hash generated when creating the ScreenshotHash from the screenshot taken.
- */
- @NonNull
- private final byte[] mImageHash;
-
- /**
- * The hmac generated by the system and used to verify whether this token was generated by
- * the system. This should only be accessed by a system process.
- */
- @NonNull
- private final byte[] mHmac;
-
- /**
- * The hmac generated by the system and used to verify whether this token was generated by
- * the system. This should only be accessed by a system process.
- *
- * @hide
- */
- @SystemApi
- @NonNull
- public byte[] getHmac() {
- return mHmac;
- }
-
-
-
- // Code below generated by codegen v1.0.22.
- //
- // DO NOT MODIFY!
- // CHECKSTYLE:OFF Generated code
- //
- // To regenerate run:
- // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/service/screenshot
- // /ScreenshotHash.java
- //
- // To exclude the generated code from IntelliJ auto-formatting enable (one-time):
- // Settings > Editor > Code Style > Formatter Control
- //@formatter:off
-
-
- /**
- * Creates a new ScreenshotHash.
- *
- * @param screenshotTimeMillis
- * The timestamp when the screenshot was generated.
- * @param boundsInWindow
- * The bounds of the requested area to take the screenshot. This is in window space passed in
- * by the client.
- * @param hashingAlgorithm
- * The selected hashing algorithm that generated the image hash.
- * @param imageHash
- * The image hash generated when creating the ScreenshotHash from the screenshot taken.
- * @param hmac
- * The hmac generated by the system and used to verify whether this token was generated by
- * the system. This should only be accessed by a system process.
- */
- @DataClass.Generated.Member
- public ScreenshotHash(
- long screenshotTimeMillis,
- @NonNull Rect boundsInWindow,
- @NonNull String hashingAlgorithm,
- @NonNull byte[] imageHash,
- @NonNull byte[] hmac) {
- this.mScreenshotTimeMillis = screenshotTimeMillis;
- this.mBoundsInWindow = boundsInWindow;
- com.android.internal.util.AnnotationValidations.validate(
- NonNull.class, null, mBoundsInWindow);
- this.mHashingAlgorithm = hashingAlgorithm;
- com.android.internal.util.AnnotationValidations.validate(
- NonNull.class, null, mHashingAlgorithm);
- this.mImageHash = imageHash;
- com.android.internal.util.AnnotationValidations.validate(
- NonNull.class, null, mImageHash);
- this.mHmac = hmac;
- com.android.internal.util.AnnotationValidations.validate(
- NonNull.class, null, mHmac);
-
- // onConstructed(); // You can define this method to get a callback
- }
-
- /**
- * The timestamp when the screenshot was generated.
- */
- @DataClass.Generated.Member
- public long getScreenshotTimeMillis() {
- return mScreenshotTimeMillis;
- }
-
- /**
- * The bounds of the requested area to take the screenshot. This is in window space passed in
- * by the client.
- */
- @DataClass.Generated.Member
- public @NonNull Rect getBoundsInWindow() {
- return mBoundsInWindow;
- }
-
- /**
- * The selected hashing algorithm that generated the image hash.
- */
- @DataClass.Generated.Member
- public @NonNull String getHashingAlgorithm() {
- return mHashingAlgorithm;
- }
-
- /**
- * The image hash generated when creating the ScreenshotHash from the screenshot taken.
- */
- @DataClass.Generated.Member
- public @NonNull byte[] getImageHash() {
- return mImageHash;
- }
-
- @Override
- @DataClass.Generated.Member
- public String toString() {
- // You can override field toString logic by defining methods like:
- // String fieldNameToString() { ... }
-
- return "ScreenshotHash { " +
- "screenshotTimeMillis = " + mScreenshotTimeMillis + ", " +
- "boundsInWindow = " + mBoundsInWindow + ", " +
- "hashingAlgorithm = " + mHashingAlgorithm + ", " +
- "imageHash = " + java.util.Arrays.toString(mImageHash) + ", " +
- "hmac = " + java.util.Arrays.toString(mHmac) +
- " }";
- }
-
- @Override
- @DataClass.Generated.Member
- public void writeToParcel(@NonNull Parcel dest, int flags) {
- // You can override field parcelling by defining methods like:
- // void parcelFieldName(Parcel dest, int flags) { ... }
-
- dest.writeLong(mScreenshotTimeMillis);
- dest.writeTypedObject(mBoundsInWindow, flags);
- dest.writeString(mHashingAlgorithm);
- dest.writeByteArray(mImageHash);
- dest.writeByteArray(mHmac);
- }
-
- @Override
- @DataClass.Generated.Member
- public int describeContents() { return 0; }
-
- /** @hide */
- @SuppressWarnings({"unchecked", "RedundantCast"})
- @DataClass.Generated.Member
- /* package-private */ ScreenshotHash(@NonNull Parcel in) {
- // You can override field unparcelling by defining methods like:
- // static FieldType unparcelFieldName(Parcel in) { ... }
-
- long screenshotTimeMillis = in.readLong();
- Rect boundsInWindow = (Rect) in.readTypedObject(Rect.CREATOR);
- String hashingAlgorithm = in.readString();
- byte[] imageHash = in.createByteArray();
- byte[] hmac = in.createByteArray();
-
- this.mScreenshotTimeMillis = screenshotTimeMillis;
- this.mBoundsInWindow = boundsInWindow;
- com.android.internal.util.AnnotationValidations.validate(
- NonNull.class, null, mBoundsInWindow);
- this.mHashingAlgorithm = hashingAlgorithm;
- com.android.internal.util.AnnotationValidations.validate(
- NonNull.class, null, mHashingAlgorithm);
- this.mImageHash = imageHash;
- com.android.internal.util.AnnotationValidations.validate(
- NonNull.class, null, mImageHash);
- this.mHmac = hmac;
- com.android.internal.util.AnnotationValidations.validate(
- NonNull.class, null, mHmac);
-
- // onConstructed(); // You can define this method to get a callback
- }
-
- @DataClass.Generated.Member
- public static final @NonNull Parcelable.Creator<ScreenshotHash> CREATOR
- = new Parcelable.Creator<ScreenshotHash>() {
- @Override
- public ScreenshotHash[] newArray(int size) {
- return new ScreenshotHash[size];
- }
-
- @Override
- public ScreenshotHash createFromParcel(@NonNull Parcel in) {
- return new ScreenshotHash(in);
- }
- };
-
- @DataClass.Generated(
- time = 1612383172822L,
- codegenVersion = "1.0.22",
- sourceFile = "frameworks/base/core/java/android/service/screenshot/ScreenshotHash.java",
- inputSignatures = "private final long mScreenshotTimeMillis\nprivate final @android.annotation.NonNull android.graphics.Rect mBoundsInWindow\nprivate final @android.annotation.NonNull java.lang.String mHashingAlgorithm\nprivate final @android.annotation.NonNull byte[] mImageHash\nprivate final @android.annotation.NonNull byte[] mHmac\npublic @android.annotation.SystemApi @android.annotation.NonNull byte[] getHmac()\nclass ScreenshotHash extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genToString=true, genAidl=true)")
- @Deprecated
- private void __metadata() {}
-
-
- //@formatter:on
- // End of generated code
-
-}
diff --git a/core/java/android/service/screenshot/ScreenshotHasherService.java b/core/java/android/service/screenshot/ScreenshotHasherService.java
deleted file mode 100644
index d96cc7eaba7a..000000000000
--- a/core/java/android/service/screenshot/ScreenshotHasherService.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.service.screenshot;
-
-import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.app.Service;
-import android.content.Intent;
-import android.graphics.Rect;
-import android.hardware.HardwareBuffer;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.RemoteCallback;
-
-/**
- * A service that handles generating and verify {@link ScreenshotHash}.
- *
- * The service will generate a ScreenshotHash based on arguments passed in. Then later that
- * same ScreenshotHash can be verified to determine that it was created by the system.
- *
- * @hide
- */
-@SystemApi
-public abstract class ScreenshotHasherService extends Service {
- /** @hide **/
- public static final String EXTRA_SCREENSHOT_HASH =
- "android.service.screenshot.extra.SCREENSHOT_HASH";
-
- /** @hide **/
- public static final String EXTRA_VERIFICATION_STATUS =
- "android.service.screenshot.extra.VERIFICATION_STATUS";
-
- /**
- * Manifest metadata key for the resource string array containing the names of all hashing
- * algorithms provided by the service.
- *
- * @hide
- */
- public static final String SERVICE_META_DATA_KEY_AVAILABLE_ALGORITHMS =
- "android.screenshot.available_algorithms";
-
- /**
- * The {@link Intent} action that must be declared as handled by a service in its manifest
- * for the system to recognize it as a ScreenshotHash providing service.
- *
- * @hide
- */
- @SystemApi
- public static final String SERVICE_INTERFACE =
- "android.service.screenshot.ScreenshotHasherService";
-
- private ScreenshotHasherServiceWrapper mWrapper;
- private Handler mHandler;
-
- public ScreenshotHasherService() {
- }
-
- @Override
- public void onCreate() {
- super.onCreate();
- mWrapper = new ScreenshotHasherServiceWrapper();
- mHandler = new Handler(Looper.getMainLooper(), null, true);
- }
-
- @NonNull
- @Override
- public final IBinder onBind(@NonNull Intent intent) {
- return mWrapper;
- }
-
- /**
- * Generates the ScreenshotHash that can be used to validate that the system generated the
- * token.
- *
- * @param salt The salt to use when generating the hmac. This should be unique to the
- * caller so the token cannot be verified by any other process.
- * @param screenshot The screenshot buffer for the content.
- * @param bounds The size and position of the content being screenshot in the window.
- * @param hashAlgorithm The String for the hashing algorithm to use based values in
- * {@link #SERVICE_META_DATA_KEY_AVAILABLE_ALGORITHMS)}.
- * @return A ScreenshotHash that can be used to validate information about the content.
- * Returns null when the arguments sent are invalid.
- */
- @Nullable
- public abstract ScreenshotHash onGenerateScreenshotHash(@NonNull byte[] salt,
- @NonNull HardwareBuffer screenshot, @NonNull Rect bounds,
- @NonNull String hashAlgorithm);
-
- /**
- * Call to verify that the ScreenshotHash passed in was generated by the system.
- *
- * @param salt The salt value to use when verifying the hmac. This should be the
- * same value that was passed to
- * {@link #onGenerateScreenshotHash(byte[],
- * HardwareBuffer, Rect, String)} to
- * generate the token.
- * @param screenshotHash The token to verify that it was generated by the system.
- * @return true if the token can be verified that it was generated by the system.
- */
- public abstract boolean onVerifyScreenshotHash(@NonNull byte[] salt,
- @NonNull ScreenshotHash screenshotHash);
-
- private void generateScreenshotHash(byte[] salt, HardwareBuffer screenshot, Rect bounds,
- String hashAlgorithm, RemoteCallback callback) {
- ScreenshotHash screenshotHash = onGenerateScreenshotHash(salt, screenshot,
- bounds,
- hashAlgorithm);
- final Bundle data = new Bundle();
- data.putParcelable(EXTRA_SCREENSHOT_HASH, screenshotHash);
- callback.sendResult(data);
- }
-
- private void verifyScreenshotHash(byte[] salt, ScreenshotHash screenshotHash,
- RemoteCallback callback) {
- boolean verificationStatus = onVerifyScreenshotHash(salt, screenshotHash);
- final Bundle data = new Bundle();
- data.putBoolean(EXTRA_VERIFICATION_STATUS, verificationStatus);
- callback.sendResult(data);
- }
-
- private final class ScreenshotHasherServiceWrapper extends
- IScreenshotHasherService.Stub {
- @Override
- public void generateScreenshotHash(byte[] salt, HardwareBuffer screenshot, Rect bounds,
- String hashAlgorithm, RemoteCallback callback) {
- mHandler.sendMessage(
- obtainMessage(ScreenshotHasherService::generateScreenshotHash,
- ScreenshotHasherService.this, salt, screenshot, bounds,
- hashAlgorithm, callback));
- }
-
- @Override
- public void verifyScreenshotHash(byte[] salt, ScreenshotHash screenshotHash,
- RemoteCallback callback) {
- mHandler.sendMessage(
- obtainMessage(ScreenshotHasherService::verifyScreenshotHash,
- ScreenshotHasherService.this, salt, screenshotHash,
- callback));
- }
- }
-}
diff --git a/core/java/android/speech/IRecognitionService.aidl b/core/java/android/speech/IRecognitionService.aidl
index f91e122ea9cb..cc1cdedd0f96 100644
--- a/core/java/android/speech/IRecognitionService.aidl
+++ b/core/java/android/speech/IRecognitionService.aidl
@@ -43,7 +43,7 @@ oneway interface IRecognitionService {
* @param featureId The feature in the package
*/
void startListening(in Intent recognizerIntent, in IRecognitionListener listener,
- String packageName, String featureId);
+ String packageName, String featureId, int callingUid);
/**
* Stops listening for speech. Speech captured so far will be recognized as
@@ -62,6 +62,7 @@ oneway interface IRecognitionService {
* @param listener to receive callbacks, note that this must be non-null
* @param packageName the package name calling this API
* @param featureId The feature in the package
+ * @param isShutdown Whether the cancellation is caused by a client calling #shutdown
*/
- void cancel(in IRecognitionListener listener, String packageName, String featureId);
+ void cancel(in IRecognitionListener listener, String packageName, String featureId, boolean isShutdown);
}
diff --git a/core/java/android/speech/IRecognitionServiceManager.aidl b/core/java/android/speech/IRecognitionServiceManager.aidl
index 7158ba2f9f63..8e5292d1ddf1 100644
--- a/core/java/android/speech/IRecognitionServiceManager.aidl
+++ b/core/java/android/speech/IRecognitionServiceManager.aidl
@@ -16,6 +16,8 @@
package android.speech;
+import android.content.ComponentName;
+
import android.speech.IRecognitionServiceManagerCallback;
/**
@@ -23,6 +25,10 @@ import android.speech.IRecognitionServiceManagerCallback;
*
* {@hide}
*/
-interface IRecognitionServiceManager {
- void createSession(in IRecognitionServiceManagerCallback callback);
+oneway interface IRecognitionServiceManager {
+ void createSession(
+ in ComponentName componentName,
+ in IBinder clientToken,
+ boolean onDevice,
+ in IRecognitionServiceManagerCallback callback);
}
diff --git a/core/java/android/speech/IRecognitionServiceManagerCallback.aidl b/core/java/android/speech/IRecognitionServiceManagerCallback.aidl
index d760810deda8..26afdaafd919 100644
--- a/core/java/android/speech/IRecognitionServiceManagerCallback.aidl
+++ b/core/java/android/speech/IRecognitionServiceManagerCallback.aidl
@@ -25,5 +25,5 @@ import android.speech.IRecognitionService;
*/
oneway interface IRecognitionServiceManagerCallback {
void onSuccess(in IRecognitionService service);
- void onError();
+ void onError(int errorCode);
}
diff --git a/core/java/android/speech/RecognitionService.java b/core/java/android/speech/RecognitionService.java
index c97dbfe38ead..fd584f191743 100644
--- a/core/java/android/speech/RecognitionService.java
+++ b/core/java/android/speech/RecognitionService.java
@@ -105,17 +105,6 @@ public abstract class RecognitionService extends Service {
int callingUid) {
if (mCurrentCallback == null) {
if (DBG) Log.d(TAG, "created new mCurrentCallback, listener = " + listener.asBinder());
- try {
- listener.asBinder().linkToDeath(new IBinder.DeathRecipient() {
- @Override
- public void binderDied() {
- mHandler.sendMessage(mHandler.obtainMessage(MSG_CANCEL, listener));
- }
- }, 0);
- } catch (RemoteException re) {
- Log.e(TAG, "dead listener on startListening");
- return;
- }
mCurrentCallback = new Callback(listener, callingUid);
RecognitionService.this.onStartListening(intent, mCurrentCallback);
} else {
@@ -352,7 +341,6 @@ public abstract class RecognitionService extends Service {
* Return the Linux uid assigned to the process that sent you the current transaction that
* is being processed. This is obtained from {@link Binder#getCallingUid()}.
*/
- // TODO(b/176578753): need to make sure this is fixed when proxied through system.
public int getCallingUid() {
return mCallingUid;
}
@@ -368,7 +356,7 @@ public abstract class RecognitionService extends Service {
@Override
public void startListening(Intent recognizerIntent, IRecognitionListener listener,
- String packageName, String featureId) {
+ String packageName, String featureId, int callingUid) {
Preconditions.checkNotNull(packageName);
if (DBG) Log.d(TAG, "startListening called by:" + listener.asBinder());
@@ -377,7 +365,7 @@ public abstract class RecognitionService extends Service {
packageName, featureId)) {
service.mHandler.sendMessage(Message.obtain(service.mHandler,
MSG_START_LISTENING, service.new StartListeningArgs(
- recognizerIntent, listener, Binder.getCallingUid())));
+ recognizerIntent, listener, callingUid)));
}
}
@@ -397,7 +385,7 @@ public abstract class RecognitionService extends Service {
@Override
public void cancel(IRecognitionListener listener, String packageName,
- String featureId) {
+ String featureId, boolean isShutdown) {
Preconditions.checkNotNull(packageName);
if (DBG) Log.d(TAG, "cancel called by:" + listener.asBinder());
diff --git a/core/java/android/speech/SpeechRecognizer.java b/core/java/android/speech/SpeechRecognizer.java
index de879c63a1a6..850f997a2d2f 100644
--- a/core/java/android/speech/SpeechRecognizer.java
+++ b/core/java/android/speech/SpeechRecognizer.java
@@ -20,8 +20,8 @@ import android.annotation.NonNull;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
-import android.content.ServiceConnection;
import android.content.pm.ResolveInfo;
+import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
@@ -32,10 +32,9 @@ import android.os.ServiceManager;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;
+import android.util.Slog;
-import java.util.LinkedList;
import java.util.List;
-import java.util.Queue;
/**
* This class provides access to the speech recognition service. This service allows access to the
@@ -107,6 +106,12 @@ public class SpeechRecognizer {
/** Insufficient permissions */
public static final int ERROR_INSUFFICIENT_PERMISSIONS = 9;
+ /** Too many requests from the same client. */
+ public static final int ERROR_TOO_MANY_REQUESTS = 10;
+
+ /** Server has been disconnected, e.g. because the app has crashed. */
+ public static final int ERROR_SERVER_DISCONNECTED = 11;
+
/** action codes */
private final static int MSG_START = 1;
private final static int MSG_STOP = 2;
@@ -116,9 +121,6 @@ public class SpeechRecognizer {
/** The actual RecognitionService endpoint */
private IRecognitionService mService;
- /** The connection to the actual service */
- private Connection mConnection;
-
/** Context with which the manager was created */
private final Context mContext;
@@ -151,15 +153,11 @@ public class SpeechRecognizer {
}
};
- /**
- * Temporary queue, saving the messages until the connection will be established, afterwards,
- * only mHandler will receive the messages
- */
- private final Queue<Message> mPendingTasks = new LinkedList<Message>();
-
/** The Listener that will receive all the callbacks */
private final InternalListener mListener = new InternalListener();
+ private final IBinder mClientToken = new Binder();
+
/**
* The right way to create a {@code SpeechRecognizer} is by using
* {@link #createSpeechRecognizer} static factory method
@@ -181,30 +179,6 @@ public class SpeechRecognizer {
}
/**
- * Basic ServiceConnection that records the mService variable. Additionally, on creation it
- * invokes the {@link IRecognitionService#startListening(Intent, IRecognitionListener)}.
- */
- private class Connection implements ServiceConnection {
-
- public void onServiceConnected(final ComponentName name, final IBinder service) {
- // always done on the application main thread, so no need to send message to mHandler
- mService = IRecognitionService.Stub.asInterface(service);
- if (DBG) Log.d(TAG, "onServiceConnected - Success");
- while (!mPendingTasks.isEmpty()) {
- mHandler.sendMessage(mPendingTasks.poll());
- }
- }
-
- public void onServiceDisconnected(final ComponentName name) {
- // always done on the application main thread, so no need to send message to mHandler
- mService = null;
- mConnection = null;
- mPendingTasks.clear();
- if (DBG) Log.d(TAG, "onServiceDisconnected - Success");
- }
- }
-
- /**
* Checks whether a speech recognition service is available on the system. If this method
* returns {@code false}, {@link SpeechRecognizer#createSpeechRecognizer(Context)} will
* fail.
@@ -303,87 +277,52 @@ public class SpeechRecognizer {
throw new IllegalArgumentException("intent must not be null");
}
checkIsCalledFromMainThread();
- if (mConnection == null) { // first time connection
- // TODO(b/176578753): both flows should go through system service.
- if (mOnDevice) {
- connectToSystemService();
- } else {
- connectToService();
- }
- }
- putMessage(Message.obtain(mHandler, MSG_START, recognizerIntent));
- }
- private void connectToSystemService() {
- mManagerService = IRecognitionServiceManager.Stub.asInterface(
- ServiceManager.getService(Context.SPEECH_RECOGNITION_SERVICE));
-
- if (mManagerService == null) {
- mListener.onError(ERROR_CLIENT);
- return;
- }
-
- try {
- // TODO(b/176578753): this has to supply information on whether to use on-device impl.
- mManagerService.createSession(new IRecognitionServiceManagerCallback.Stub(){
- @Override
- public void onSuccess(IRecognitionService service) throws RemoteException {
- mService = service;
- }
-
- @Override
- public void onError() throws RemoteException {
- Log.e(TAG, "Bind to system recognition service failed");
- mListener.onError(ERROR_CLIENT);
- }
- });
- } catch (RemoteException e) {
- e.rethrowFromSystemServer();
- }
- }
-
- private void connectToService() {
- mConnection = new Connection();
-
- Intent serviceIntent = new Intent(RecognitionService.SERVICE_INTERFACE);
-
- if (mServiceComponent == null) {
- String serviceComponent = Settings.Secure.getString(mContext.getContentResolver(),
- Settings.Secure.VOICE_RECOGNITION_SERVICE);
-
- if (TextUtils.isEmpty(serviceComponent)) {
- Log.e(TAG, "no selected voice recognition service");
- mListener.onError(ERROR_CLIENT);
- return;
+ if (DBG) {
+ Slog.i(TAG, "#startListening called");
+ if (mService == null) {
+ Slog.i(TAG, "Connection is not established yet");
}
+ }
- serviceIntent.setComponent(
- ComponentName.unflattenFromString(serviceComponent));
+ if (mService == null) {
+ // First time connection: first establish a connection, then dispatch #startListening.
+ connectToSystemService(
+ () -> putMessage(Message.obtain(mHandler, MSG_START, recognizerIntent)));
} else {
- serviceIntent.setComponent(mServiceComponent);
- }
- if (!mContext.bindService(serviceIntent, mConnection,
- Context.BIND_AUTO_CREATE | Context.BIND_INCLUDE_CAPABILITIES)) {
- Log.e(TAG, "bind to recognition service failed");
- mConnection = null;
- mService = null;
- mListener.onError(ERROR_CLIENT);
- return;
+ putMessage(Message.obtain(mHandler, MSG_START, recognizerIntent));
}
}
/**
* Stops listening for speech. Speech captured so far will be recognized as if the user had
- * stopped speaking at this point. Note that in the default case, this does not need to be
- * called, as the speech endpointer will automatically stop the recognizer listening when it
- * determines speech has completed. However, you can manipulate endpointer parameters directly
- * using the intent extras defined in {@link RecognizerIntent}, in which case you may sometimes
- * want to manually call this method to stop listening sooner. Please note that
+ * stopped speaking at this point.
+ *
+ * <p>Note that in the default case, this does not need to be called, as the speech endpointer
+ * will automatically stop the recognizer listening when it determines speech has completed.
+ * However, you can manipulate endpointer parameters directly using the intent extras defined in
+ * {@link RecognizerIntent}, in which case you may sometimes want to manually call this method
+ * to stop listening sooner.
+ *
+ * <p>Upon invocation clients must wait until {@link RecognitionListener#onResults} or
+ * {@link RecognitionListener#onError} are invoked before calling
+ * {@link SpeechRecognizer#startListening} again. Otherwise such an attempt would be rejected by
+ * recognition service.
+ *
+ * <p>Please note that
* {@link #setRecognitionListener(RecognitionListener)} should be called beforehand, otherwise
* no notifications will be received.
*/
public void stopListening() {
checkIsCalledFromMainThread();
+
+ if (DBG) {
+ Slog.i(TAG, "#stopListening called");
+ if (mService == null) {
+ Slog.i(TAG, "Connection is not established yet");
+ }
+ }
+
putMessage(Message.obtain(mHandler, MSG_STOP));
}
@@ -405,11 +344,7 @@ public class SpeechRecognizer {
}
private void putMessage(Message msg) {
- if (mService == null) {
- mPendingTasks.offer(msg);
- } else {
- mHandler.sendMessage(msg);
- }
+ mHandler.sendMessage(msg);
}
/** sends the actual message to the service */
@@ -419,7 +354,7 @@ public class SpeechRecognizer {
}
try {
mService.startListening(recognizerIntent, mListener, mContext.getOpPackageName(),
- mContext.getAttributionTag());
+ mContext.getAttributionTag(), android.os.Process.myUid());
if (DBG) Log.d(TAG, "service start listening command succeded");
} catch (final RemoteException e) {
Log.e(TAG, "startListening() failed", e);
@@ -448,7 +383,11 @@ public class SpeechRecognizer {
return;
}
try {
- mService.cancel(mListener, mContext.getOpPackageName(), mContext.getAttributionTag());
+ mService.cancel(
+ mListener,
+ mContext.getOpPackageName(),
+ mContext.getAttributionTag(),
+ false /* isShutdown */);
if (DBG) Log.d(TAG, "service cancel command succeded");
} catch (final RemoteException e) {
Log.e(TAG, "cancel() failed", e);
@@ -471,28 +410,94 @@ public class SpeechRecognizer {
mListener.mInternalListener = listener;
}
- /**
- * Destroys the {@code SpeechRecognizer} object.
- */
+ /** Destroys the {@code SpeechRecognizer} object. */
public void destroy() {
if (mService != null) {
try {
mService.cancel(mListener, mContext.getOpPackageName(),
- mContext.getAttributionTag());
+ mContext.getAttributionTag(), true /* isShutdown */);
} catch (final RemoteException e) {
// Not important
}
}
- if (mConnection != null) {
- mContext.unbindService(mConnection);
- }
- mPendingTasks.clear();
mService = null;
- mConnection = null;
mListener.mInternalListener = null;
}
+ /** Establishes a connection to system server proxy and initializes the session. */
+ private void connectToSystemService(Runnable onSuccess) {
+ mManagerService = IRecognitionServiceManager.Stub.asInterface(
+ ServiceManager.getService(Context.SPEECH_RECOGNITION_SERVICE));
+
+ if (mManagerService == null) {
+ mListener.onError(ERROR_CLIENT);
+ return;
+ }
+
+ ComponentName componentName = getSpeechRecognizerComponentName();
+
+ if (!mOnDevice && componentName == null) {
+ mListener.onError(ERROR_CLIENT);
+ return;
+ }
+
+ try {
+ mManagerService.createSession(
+ componentName,
+ mClientToken,
+ mOnDevice,
+ new IRecognitionServiceManagerCallback.Stub(){
+ @Override
+ public void onSuccess(IRecognitionService service) throws RemoteException {
+ mService = service;
+ onSuccess.run();
+ }
+
+ @Override
+ public void onError(int errorCode) throws RemoteException {
+ Log.e(TAG, "Bind to system recognition service failed");
+ mListener.onError(errorCode);
+ }
+ });
+ } catch (RemoteException e) {
+ e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Returns the component name to be used for establishing a connection, based on the parameters
+ * used during initialization.
+ *
+ * <p>Note the 3 different scenarios:
+ * <ol>
+ * <li>On-device speech recognizer which is determined by the manufacturer and not
+ * changeable by the user
+ * <li>Default user-selected speech recognizer as specified by
+ * {@code Settings.Secure.VOICE_RECOGNITION_SERVICE}
+ * <li>Custom speech recognizer supplied by the client.
+ */
+ private ComponentName getSpeechRecognizerComponentName() {
+ if (mOnDevice) {
+ return null;
+ }
+
+ if (mServiceComponent != null) {
+ return mServiceComponent;
+ }
+
+ String serviceComponent = Settings.Secure.getString(mContext.getContentResolver(),
+ Settings.Secure.VOICE_RECOGNITION_SERVICE);
+
+ if (TextUtils.isEmpty(serviceComponent)) {
+ Log.e(TAG, "no selected voice recognition service");
+ mListener.onError(ERROR_CLIENT);
+ return null;
+ }
+
+ return ComponentName.unflattenFromString(serviceComponent);
+ }
+
/**
* Internal wrapper of IRecognitionListener which will propagate the results to
* RecognitionListener
diff --git a/core/java/android/uwb/OWNERS b/core/java/android/uwb/OWNERS
index ea41c3984dfd..17936ae7bb73 100644
--- a/core/java/android/uwb/OWNERS
+++ b/core/java/android/uwb/OWNERS
@@ -1,5 +1,6 @@
bstack@google.com
eliptus@google.com
jsolnit@google.com
+matbev@google.com
siyuanh@google.com
zachoverflow@google.com
diff --git a/core/java/android/uwb/TEST_MAPPING b/core/java/android/uwb/TEST_MAPPING
index 9e50bd64d089..08ed2c7b71d9 100644
--- a/core/java/android/uwb/TEST_MAPPING
+++ b/core/java/android/uwb/TEST_MAPPING
@@ -2,6 +2,9 @@
"presubmit": [
{
"name": "UwbManagerTests"
+ },
+ {
+ "name": "CtsUwbTestCases"
}
]
-} \ No newline at end of file
+}
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 62f4b864c7a8..4e4ba3fad246 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -32,7 +32,6 @@ import android.graphics.Region;
import android.os.Bundle;
import android.os.IRemoteCallback;
import android.os.ParcelFileDescriptor;
-import android.service.screenshot.ScreenshotHash;
import android.view.DisplayCutout;
import android.view.IApplicationToken;
import android.view.IAppTransitionAnimationSpecsFuture;
@@ -63,6 +62,8 @@ import android.view.AppTransitionAnimationSpec;
import android.view.WindowContentFrameStats;
import android.view.WindowManager;
import android.view.SurfaceControl;
+import android.view.displayhash.DisplayHash;
+import android.view.displayhash.VerifiedDisplayHash;
/**
* System private interface to the window manager.
@@ -757,23 +758,23 @@ interface IWindowManager
void holdLock(in IBinder token, in int durationMs);
/**
- * Gets an array of support hashing algorithms that can be used to generate the hash of the
- * screenshot. The String value of one algorithm should be used when requesting to generate
- * the ScreenshotHash.
+ * Gets an array of support hash algorithms that can be used to generate a DisplayHash. The
+ * String value of one algorithm should be used when requesting to generate
+ * the DisplayHash.
*
- * @return a String array of supported hashing algorithms.
+ * @return a String array of supported hash algorithms.
*/
- String[] getSupportedScreenshotHashingAlgorithms();
+ String[] getSupportedDisplayHashAlgorithms();
/**
- * Validate the ScreenshotHash was generated by the system. The ScreenshotHash passed in
- * should be the token generated when calling {@link IWindowSession#generateScreenshotHash}
+ * Validate the DisplayHash was generated by the system. The DisplayHash passed in should be
+ * the object generated when calling {@link IWindowSession#generateDisplayHash}
*
- * @param ScreenshotHash The token to verify that it was generated by the system.
- * @return true if the token was generated by the system or false if the token cannot be
- * verified.
+ * @param DisplayHash The hash to verify that it was generated by the system.
+ * @return a {@link VerifiedDisplayHash} if the hash was generated by the system or null
+ * if the token cannot be verified.
*/
- boolean verifyScreenshotHash(in ScreenshotHash screenshotHash);
+ VerifiedDisplayHash verifyDisplayHash(in DisplayHash displayHash);
/**
* Registers a listener for a {@link android.app.WindowContext} to handle configuration changes
diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl
index dad932c2ee19..ce649cc7c2b2 100644
--- a/core/java/android/view/IWindowSession.aidl
+++ b/core/java/android/view/IWindowSession.aidl
@@ -22,7 +22,7 @@ import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.Region;
import android.os.Bundle;
-import android.service.screenshot.ScreenshotHash;
+import android.os.RemoteCallback;
import android.util.MergedConfiguration;
import android.view.DisplayCutout;
import android.view.InputChannel;
@@ -337,14 +337,15 @@ interface IWindowSession {
void grantEmbeddedWindowFocus(IWindow window, in IBinder inputToken, boolean grantFocus);
/**
- * Generates an ScreenshotHash that can be used to validate whether specific content was on
+ * Generates an DisplayHash that can be used to validate whether specific content was on
* screen.
*
- * @param window The token for the window where the view to screenshot is shown.
- * @param boundsInWindow The size and position of the ads view in the window
- * @param hashAlgorithm The String for the hashing algorithm to use based on values returned
- * from {@link IWindowManager#getSupportedHashingAlgorithms()}
+ * @param window The token for the window to generate the hash of.
+ * @param boundsInWindow The size and position in the window of where to generate the hash.
+ * @param hashAlgorithm The String for the hash algorithm to use based on values returned
+ * from {@link IWindowManager#getSupportedDisplayHashAlgorithms()}
+ * @param callback The callback invoked to get the results of generateDisplayHash
*/
- ScreenshotHash generateScreenshotHash(IWindow window, in Rect boundsInWindow,
- in String hashAlgorithm);
+ oneway void generateDisplayHash(IWindow window, in Rect boundsInWindow,
+ in String hashAlgorithm, in RemoteCallback callback);
}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 44d4d6b24f58..c46fbc7fb4c4 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -18,6 +18,12 @@ package android.view;
import static android.content.res.Resources.ID_NULL;
import static android.view.accessibility.AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED;
+import static android.view.displayhash.DisplayHashResultCallback.DISPLAY_HASH_ERROR_INVALID_BOUNDS;
+import static android.view.displayhash.DisplayHashResultCallback.DISPLAY_HASH_ERROR_MISSING_WINDOW;
+import static android.view.displayhash.DisplayHashResultCallback.DISPLAY_HASH_ERROR_NOT_VISIBLE_ON_SCREEN;
+import static android.view.displayhash.DisplayHashResultCallback.DISPLAY_HASH_ERROR_UNKNOWN;
+import static android.view.displayhash.DisplayHashResultCallback.EXTRA_DISPLAY_HASH;
+import static android.view.displayhash.DisplayHashResultCallback.EXTRA_DISPLAY_HASH_ERROR_CODE;
import static com.android.internal.util.FrameworkStatsLog.TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__DEEP_PRESS;
import static com.android.internal.util.FrameworkStatsLog.TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__LONG_PRESS;
@@ -89,6 +95,7 @@ import android.os.IBinder;
import android.os.Message;
import android.os.Parcel;
import android.os.Parcelable;
+import android.os.RemoteCallback;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.Trace;
@@ -135,6 +142,9 @@ import android.view.autofill.AutofillValue;
import android.view.contentcapture.ContentCaptureContext;
import android.view.contentcapture.ContentCaptureManager;
import android.view.contentcapture.ContentCaptureSession;
+import android.view.displayhash.DisplayHash;
+import android.view.displayhash.DisplayHashManager;
+import android.view.displayhash.DisplayHashResultCallback;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.view.inspector.InspectableProperty;
@@ -176,6 +186,7 @@ import java.util.Locale;
import java.util.Map;
import java.util.Queue;
import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Predicate;
@@ -30707,4 +30718,71 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
public void onTranslationComplete(@NonNull TranslationRequest request) {
// no-op
}
+
+ /**
+ * Called to generate a {@link DisplayHash} for this view.
+ *
+ * @param hashAlgorithm The hash algorithm to use when hashing the display. Must be one of
+ * the values returned from
+ * {@link DisplayHashManager#getSupportedHashAlgorithms()}
+ * @param bounds The bounds for the content within the View to generate the hash for. If
+ * bounds are null, the entire View's bounds will be used. If empty, it will
+ * invoke the callback
+ * {@link DisplayHashResultCallback#onDisplayHashError} with error
+ * {@link DisplayHashResultCallback#DISPLAY_HASH_ERROR_INVALID_BOUNDS}
+ * @param executor The executor that the callback should be invoked on.
+ * @param callback The callback to handle the results of generating the display hash
+ */
+ @Nullable
+ public void generateDisplayHash(@NonNull String hashAlgorithm,
+ @Nullable Rect bounds, @NonNull Executor executor,
+ @NonNull DisplayHashResultCallback callback) {
+ IWindowSession session = getWindowSession();
+ if (session == null) {
+ callback.onDisplayHashError(DISPLAY_HASH_ERROR_MISSING_WINDOW);
+ return;
+ }
+ IWindow window = getWindow();
+ if (window == null) {
+ callback.onDisplayHashError(DISPLAY_HASH_ERROR_MISSING_WINDOW);
+ return;
+ }
+
+ Rect visibleBounds = new Rect();
+ getGlobalVisibleRect(visibleBounds);
+
+ if (bounds != null && bounds.isEmpty()) {
+ callback.onDisplayHashError(DISPLAY_HASH_ERROR_INVALID_BOUNDS);
+ return;
+ }
+
+ if (bounds != null) {
+ bounds.offset(visibleBounds.left, visibleBounds.top);
+ visibleBounds.intersectUnchecked(bounds);
+ }
+
+ if (visibleBounds.isEmpty()) {
+ callback.onDisplayHashError(DISPLAY_HASH_ERROR_NOT_VISIBLE_ON_SCREEN);
+ return;
+ }
+
+ RemoteCallback remoteCallback = new RemoteCallback(result ->
+ executor.execute(() -> {
+ DisplayHash displayHash = result.getParcelable(EXTRA_DISPLAY_HASH);
+ int errorCode = result.getInt(EXTRA_DISPLAY_HASH_ERROR_CODE,
+ DISPLAY_HASH_ERROR_UNKNOWN);
+ if (displayHash != null) {
+ callback.onDisplayHashResult(displayHash);
+ } else {
+ callback.onDisplayHashError(errorCode);
+ }
+ }));
+
+ try {
+ session.generateDisplayHash(window, visibleBounds, hashAlgorithm, remoteCallback);
+ } catch (RemoteException e) {
+ Log.e(VIEW_LOG_TAG, "Failed to call generateDisplayHash");
+ callback.onDisplayHashError(DISPLAY_HASH_ERROR_UNKNOWN);
+ }
+ }
}
diff --git a/core/java/android/view/WindowlessWindowManager.java b/core/java/android/view/WindowlessWindowManager.java
index 39d3c01dd409..7cc2db1c0dab 100644
--- a/core/java/android/view/WindowlessWindowManager.java
+++ b/core/java/android/view/WindowlessWindowManager.java
@@ -23,8 +23,8 @@ import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.Region;
import android.os.IBinder;
+import android.os.RemoteCallback;
import android.os.RemoteException;
-import android.service.screenshot.ScreenshotHash;
import android.util.Log;
import android.util.MergedConfiguration;
import android.window.ClientWindowFrames;
@@ -487,8 +487,7 @@ public class WindowlessWindowManager implements IWindowSession {
}
@Override
- public ScreenshotHash generateScreenshotHash(IWindow window, Rect boundsInWindow,
- String hashAlgorithm) {
- return null;
+ public void generateDisplayHash(IWindow window, Rect boundsInWindow, String hashAlgorithm,
+ RemoteCallback callback) {
}
}
diff --git a/core/java/android/service/screenshot/ScreenshotHash.aidl b/core/java/android/view/displayhash/DisplayHash.aidl
index a7c50db171a2..cabf57573fa0 100644
--- a/core/java/android/service/screenshot/ScreenshotHash.aidl
+++ b/core/java/android/view/displayhash/DisplayHash.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2020 The Android Open Source Project
+ * Copyright (C) 2021 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.
@@ -14,6 +14,6 @@
* limitations under the License.
*/
-package android.service.screenshot;
+package android.view.displayhash;
-parcelable ScreenshotHash;
+parcelable DisplayHash;
diff --git a/core/java/android/view/displayhash/DisplayHash.java b/core/java/android/view/displayhash/DisplayHash.java
new file mode 100644
index 000000000000..41484865b98e
--- /dev/null
+++ b/core/java/android/view/displayhash/DisplayHash.java
@@ -0,0 +1,226 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view.displayhash;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.graphics.Rect;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.AnnotationValidations;
+
+/**
+ * The DisplayHash used to validate information about what was present on screen.
+ */
+public final class DisplayHash implements Parcelable {
+ /**
+ * The timestamp when the hash was generated.
+ */
+ private final long mTimeMillis;
+
+ /**
+ * The bounds of the requested area to generate the hash. This is in window space passed in
+ * by the client.
+ */
+ @NonNull
+ private final Rect mBoundsInWindow;
+
+ /**
+ * The selected hash algorithm that generated the image hash.
+ */
+ @NonNull
+ private final String mHashAlgorithm;
+
+ /**
+ * The image hash generated when creating the DisplayHash.
+ */
+ @NonNull
+ private final byte[] mImageHash;
+
+ /**
+ * The hmac generated by the system and used to verify whether this token was generated by
+ * the system.
+ */
+ @NonNull
+ private final byte[] mHmac;
+
+ /**
+ * Creates a new DisplayHash.
+ *
+ * @param timeMillis The timestamp when the hash was generated.
+ * @param boundsInWindow The bounds of the requested area to generate the hash. This is
+ * in window space passed in by the client.
+ * @param hashAlgorithm The selected hash algorithm that generated the image hash.
+ * @param imageHash The image hash generated when creating the DisplayHash.
+ * @param hmac The hmac generated by the system and used to verify whether this
+ * token was generated by
+ * the system. This should only be accessed by a system process.
+ * @hide
+ */
+ @SystemApi
+ public DisplayHash(long timeMillis, @NonNull Rect boundsInWindow,
+ @NonNull String hashAlgorithm, @NonNull byte[] imageHash, @NonNull byte[] hmac) {
+ mTimeMillis = timeMillis;
+ mBoundsInWindow = boundsInWindow;
+ AnnotationValidations.validate(NonNull.class, null, mBoundsInWindow);
+ mHashAlgorithm = hashAlgorithm;
+ AnnotationValidations.validate(NonNull.class, null, mHashAlgorithm);
+ mImageHash = imageHash;
+ AnnotationValidations.validate(NonNull.class, null, mImageHash);
+ mHmac = hmac;
+ AnnotationValidations.validate(NonNull.class, null, mHmac);
+ }
+
+ /**
+ * The timestamp when the hash was generated.
+ *
+ * @hide
+ */
+ @SystemApi
+ public long getTimeMillis() {
+ return mTimeMillis;
+ }
+
+ /**
+ * The bounds of the requested area to to generate the hash. This is in window space passed in
+ * by the client.
+ *
+ * @hide
+ */
+ @SystemApi
+ @NonNull
+ public Rect getBoundsInWindow() {
+ return mBoundsInWindow;
+ }
+
+ /**
+ * The selected hash algorithm that generated the image hash.
+ *
+ * @hide
+ */
+ @SystemApi
+ @NonNull
+ public String getHashAlgorithm() {
+ return mHashAlgorithm;
+ }
+
+ /**
+ * The image hash generated when creating the DisplayHash.
+ *
+ * @hide
+ */
+ @SystemApi
+ @NonNull
+ public byte[] getImageHash() {
+ return mImageHash;
+ }
+
+ /**
+ * The hmac generated by the system and used to verify whether this token was generated by
+ * the system. This should only be accessed by a system process.
+ *
+ * @hide
+ */
+ @SystemApi
+ @NonNull
+ public byte[] getHmac() {
+ return mHmac;
+ }
+
+ /** @hide **/
+ @Override
+ public String toString() {
+ return "DisplayHash { "
+ + "timeMillis = " + mTimeMillis + ", "
+ + "boundsInWindow = " + mBoundsInWindow + ", "
+ + "hashAlgorithm = " + mHashAlgorithm + ", "
+ + "imageHash = " + byteArrayToString(mImageHash) + ", "
+ + "hmac = " + byteArrayToString(mHmac)
+ + " }";
+ }
+
+ private String byteArrayToString(byte[] byteArray) {
+ if (byteArray == null) {
+ return "null";
+ }
+ int iMax = byteArray.length - 1;
+ if (iMax == -1) {
+ return "[]";
+ }
+
+ StringBuilder b = new StringBuilder();
+ b.append('[');
+ for (int i = 0; ; i++) {
+ String formatted = String.format("%02X", byteArray[i] & 0xFF);
+ b.append(formatted);
+ if (i == iMax) {
+ return b.append(']').toString();
+ }
+ b.append(", ");
+ }
+ }
+
+ /** @hide **/
+ @SystemApi
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeLong(mTimeMillis);
+ dest.writeTypedObject(mBoundsInWindow, flags);
+ dest.writeString(mHashAlgorithm);
+ dest.writeByteArray(mImageHash);
+ dest.writeByteArray(mHmac);
+ }
+
+ /** @hide **/
+ @SystemApi
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ private DisplayHash(@NonNull Parcel in) {
+ mTimeMillis = in.readLong();
+ Rect boundsInWindow = in.readTypedObject(Rect.CREATOR);
+ String hashAlgorithm = in.readString();
+ byte[] imageHash = in.createByteArray();
+ byte[] hmac = in.createByteArray();
+
+ mBoundsInWindow = boundsInWindow;
+ AnnotationValidations.validate(NonNull.class, null, mBoundsInWindow);
+ mHashAlgorithm = hashAlgorithm;
+ AnnotationValidations.validate(NonNull.class, null, mHashAlgorithm);
+ mImageHash = imageHash;
+ AnnotationValidations.validate(NonNull.class, null, mImageHash);
+ mHmac = hmac;
+ AnnotationValidations.validate(NonNull.class, null, mHmac);
+ }
+
+ @NonNull
+ public static final Parcelable.Creator<DisplayHash> CREATOR =
+ new Parcelable.Creator<DisplayHash>() {
+ @Override
+ public DisplayHash[] newArray(int size) {
+ return new DisplayHash[size];
+ }
+
+ @Override
+ public DisplayHash createFromParcel(@NonNull Parcel in) {
+ return new DisplayHash(in);
+ }
+ };
+}
diff --git a/core/java/android/view/displayhash/DisplayHashManager.java b/core/java/android/view/displayhash/DisplayHashManager.java
new file mode 100644
index 000000000000..6b0c1a6d7633
--- /dev/null
+++ b/core/java/android/view/displayhash/DisplayHashManager.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view.displayhash;
+
+
+import static android.content.Context.DISPLAY_HASH_SERVICE;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemService;
+import android.os.RemoteException;
+import android.util.ArraySet;
+import android.util.Log;
+import android.view.WindowManagerGlobal;
+
+import com.android.internal.annotations.GuardedBy;
+
+import java.util.Collections;
+import java.util.Set;
+
+/**
+ * Utility class for DisplayHash requests.
+ */
+@SystemService(DISPLAY_HASH_SERVICE)
+public final class DisplayHashManager {
+ private static final String TAG = "DisplayHashManager";
+
+ private final Object mSupportedHashingAlgorithmLock = new Object();
+
+ @GuardedBy("mSupportedAlgorithmLock")
+ private static Set<String> sSupportedHashAlgorithms;
+
+ /**
+ * @hide
+ */
+ public DisplayHashManager() {
+ }
+
+ /**
+ * Get a Set of DisplayHash algorithms that the device supports.
+ *
+ * @return a String Set of supported hashing algorithms. The String value of one
+ * algorithm should be used when requesting to generate the DisplayHash.
+ */
+ @NonNull
+ public Set<String> getSupportedHashAlgorithms() {
+ synchronized (mSupportedHashingAlgorithmLock) {
+ if (sSupportedHashAlgorithms != null) {
+ return sSupportedHashAlgorithms;
+ }
+
+ try {
+ String[] supportedAlgorithms = WindowManagerGlobal.getWindowManagerService()
+ .getSupportedDisplayHashAlgorithms();
+ if (supportedAlgorithms == null) {
+ return Collections.emptySet();
+ }
+ sSupportedHashAlgorithms = new ArraySet<>(supportedAlgorithms);
+ return sSupportedHashAlgorithms;
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to send request getSupportedHashingAlgorithms", e);
+ return Collections.emptySet();
+ }
+ }
+ }
+
+ /**
+ * Call to verify that the DisplayHash passed in was generated by the system.
+ *
+ * @param displayHash The hash to verify that it was generated by the system.
+ * @return a {@link VerifiedDisplayHash} if the hash was generated by the system or null
+ * if the hash cannot be verified.
+ */
+ @Nullable
+ public VerifiedDisplayHash verifyDisplayHash(@NonNull DisplayHash displayHash) {
+ try {
+ return WindowManagerGlobal.getWindowManagerService().verifyDisplayHash(displayHash);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to send request verifyImpressionToken", e);
+ return null;
+ }
+ }
+}
diff --git a/core/java/android/view/displayhash/DisplayHashResultCallback.java b/core/java/android/view/displayhash/DisplayHashResultCallback.java
new file mode 100644
index 000000000000..15b29adafddd
--- /dev/null
+++ b/core/java/android/view/displayhash/DisplayHashResultCallback.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view.displayhash;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.graphics.Rect;
+import android.view.View;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.concurrent.Executor;
+
+/**
+ * Use when calling {@link View#generateDisplayHash(String, Rect, Executor,
+ * DisplayHashResultCallback)}.
+ *
+ * The callback will only invoke either {@link #onDisplayHashResult} when the system successfully
+ * generated the {@link DisplayHash} or {@link #onDisplayHashError(int)} when it failed.
+ */
+public interface DisplayHashResultCallback {
+ /**
+ * @hide
+ */
+ String EXTRA_DISPLAY_HASH = "DISPLAY_HASH";
+
+ /**
+ * @hide
+ */
+ String EXTRA_DISPLAY_HASH_ERROR_CODE = "DISPLAY_HASH_ERROR_CODE";
+
+ /**
+ * An unknown error occurred.
+ */
+ int DISPLAY_HASH_ERROR_UNKNOWN = -1;
+
+ /**
+ * The bounds used when requesting the hash hash were invalid or empty.
+ */
+ int DISPLAY_HASH_ERROR_INVALID_BOUNDS = -2;
+
+ /**
+ * The window for the view that requested the hash is no longer around. This can happen if the
+ * window is getting torn down.
+ */
+ int DISPLAY_HASH_ERROR_MISSING_WINDOW = -3;
+
+ /**
+ * The view that requested the hash is not visible on screen. This could either mean
+ * that the view bounds are offscreen, window bounds are offscreen, view is not visible, or
+ * window is not visible.
+ */
+ int DISPLAY_HASH_ERROR_NOT_VISIBLE_ON_SCREEN = -4;
+
+ /** @hide */
+ @IntDef(prefix = {"DISPLAY_HASH_ERROR_"}, value = {
+ DISPLAY_HASH_ERROR_UNKNOWN,
+ DISPLAY_HASH_ERROR_INVALID_BOUNDS,
+ DISPLAY_HASH_ERROR_MISSING_WINDOW,
+ DISPLAY_HASH_ERROR_NOT_VISIBLE_ON_SCREEN
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ @interface DisplayHashErrorCode {
+ }
+
+ /**
+ * Callback invoked when calling
+ * {@link android.view.View#generateDisplayHash(String, Rect, Executor,
+ * DisplayHashResultCallback)}
+ *
+ * @param displayHash The DisplayHash generated. If the hash cannot be generated,
+ * {@link #onDisplayHashError(int)} will be called instead
+ */
+ void onDisplayHashResult(@NonNull DisplayHash displayHash);
+
+ /**
+ * Callback invoked when
+ * {@link android.view.View#generateDisplayHash(String, Rect, Executor,
+ * DisplayHashResultCallback)} results in an error and cannot generate a display hash.
+ *
+ * @param errorCode One of the values in {@link DisplayHashErrorCode}
+ */
+ void onDisplayHashError(@DisplayHashErrorCode int errorCode);
+}
diff --git a/core/java/android/view/displayhash/OWNERS b/core/java/android/view/displayhash/OWNERS
new file mode 100644
index 000000000000..0862c05e0ee4
--- /dev/null
+++ b/core/java/android/view/displayhash/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/wm/OWNERS
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/ClockModule.java b/core/java/android/view/displayhash/VerifiedDisplayHash.aidl
index c4be1ba53503..9e7ebefa7ca1 100644
--- a/packages/SystemUI/src/com/android/keyguard/clock/ClockModule.java
+++ b/core/java/android/view/displayhash/VerifiedDisplayHash.aidl
@@ -14,20 +14,6 @@
* limitations under the License.
*/
-package com.android.keyguard.clock;
+package android.view.displayhash;
-import java.util.List;
-
-import dagger.Module;
-import dagger.Provides;
-
-/** Dagger Module for clock package. */
-@Module
-public abstract class ClockModule {
-
- /** */
- @Provides
- public static List<ClockInfo> provideClockInfoList(ClockManager clockManager) {
- return clockManager.getClockInfos();
- }
-}
+parcelable VerifiedDisplayHash;
diff --git a/core/java/android/view/displayhash/VerifiedDisplayHash.java b/core/java/android/view/displayhash/VerifiedDisplayHash.java
new file mode 100644
index 000000000000..16a428e73005
--- /dev/null
+++ b/core/java/android/view/displayhash/VerifiedDisplayHash.java
@@ -0,0 +1,242 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view.displayhash;
+
+import android.annotation.NonNull;
+import android.graphics.Rect;
+import android.os.Parcelable;
+
+import com.android.internal.util.DataClass;
+
+/**
+ * The verified display hash used to validate information about what was present on screen.
+ */
+@DataClass(genToString = true, genAidl = true)
+public final class VerifiedDisplayHash implements Parcelable {
+ /**
+ * The timestamp when the hash was generated.
+ */
+ private final long mTimeMillis;
+
+ /**
+ * The bounds of the requested area to generate the hash. This is in window space passed in
+ * by the client.
+ */
+ @NonNull
+ private final Rect mBoundsInWindow;
+
+ /**
+ * The selected hash algorithm that generated the image hash.
+ */
+ @NonNull
+ private final String mHashAlgorithm;
+
+ /**
+ * The image hash generated when creating the DisplayHash.
+ */
+ @NonNull
+ private final byte[] mImageHash;
+
+ private String imageHashToString() {
+ return byteArrayToString(mImageHash);
+ }
+
+ private String byteArrayToString(byte[] byteArray) {
+ if (byteArray == null) {
+ return "null";
+ }
+ int iMax = byteArray.length - 1;
+ if (iMax == -1) {
+ return "[]";
+ }
+
+ StringBuilder b = new StringBuilder();
+ b.append('[');
+ for (int i = 0; ; i++) {
+ String formatted = String.format("%02X", byteArray[i] & 0xFF);
+ b.append(formatted);
+ if (i == iMax) {
+ return b.append(']').toString();
+ }
+ b.append(", ");
+ }
+ }
+
+
+
+ // Code below generated by codegen v1.0.22.
+ //
+ // DO NOT MODIFY!
+ // CHECKSTYLE:OFF Generated code
+ //
+ // To regenerate run:
+ // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/view/displayhash/VerifiedDisplayHash.java
+ //
+ // To exclude the generated code from IntelliJ auto-formatting enable (one-time):
+ // Settings > Editor > Code Style > Formatter Control
+ //@formatter:off
+
+
+ /**
+ * Creates a new VerifiedDisplayHash.
+ *
+ * @param timeMillis
+ * The timestamp when the hash was generated.
+ * @param boundsInWindow
+ * The bounds of the requested area to generate the hash. This is in window space passed in
+ * by the client.
+ * @param hashAlgorithm
+ * The selected hash algorithm that generated the image hash.
+ * @param imageHash
+ * The image hash generated when creating the DisplayHash.
+ */
+ @DataClass.Generated.Member
+ public VerifiedDisplayHash(
+ long timeMillis,
+ @NonNull Rect boundsInWindow,
+ @NonNull String hashAlgorithm,
+ @NonNull byte[] imageHash) {
+ this.mTimeMillis = timeMillis;
+ this.mBoundsInWindow = boundsInWindow;
+ com.android.internal.util.AnnotationValidations.validate(
+ NonNull.class, null, mBoundsInWindow);
+ this.mHashAlgorithm = hashAlgorithm;
+ com.android.internal.util.AnnotationValidations.validate(
+ NonNull.class, null, mHashAlgorithm);
+ this.mImageHash = imageHash;
+ com.android.internal.util.AnnotationValidations.validate(
+ NonNull.class, null, mImageHash);
+
+ // onConstructed(); // You can define this method to get a callback
+ }
+
+ /**
+ * The timestamp when the hash was generated.
+ */
+ @DataClass.Generated.Member
+ public long getTimeMillis() {
+ return mTimeMillis;
+ }
+
+ /**
+ * The bounds of the requested area to generate the hash. This is in window space passed in
+ * by the client.
+ */
+ @DataClass.Generated.Member
+ public @NonNull Rect getBoundsInWindow() {
+ return mBoundsInWindow;
+ }
+
+ /**
+ * The selected hash algorithm that generated the image hash.
+ */
+ @DataClass.Generated.Member
+ public @NonNull String getHashAlgorithm() {
+ return mHashAlgorithm;
+ }
+
+ /**
+ * The image hash generated when creating the DisplayHash.
+ */
+ @DataClass.Generated.Member
+ public @NonNull byte[] getImageHash() {
+ return mImageHash;
+ }
+
+ @Override
+ @DataClass.Generated.Member
+ public String toString() {
+ // You can override field toString logic by defining methods like:
+ // String fieldNameToString() { ... }
+
+ return "VerifiedDisplayHash { " +
+ "timeMillis = " + mTimeMillis + ", " +
+ "boundsInWindow = " + mBoundsInWindow + ", " +
+ "hashAlgorithm = " + mHashAlgorithm + ", " +
+ "imageHash = " + imageHashToString() +
+ " }";
+ }
+
+ @Override
+ @DataClass.Generated.Member
+ public void writeToParcel(@NonNull android.os.Parcel dest, int flags) {
+ // You can override field parcelling by defining methods like:
+ // void parcelFieldName(Parcel dest, int flags) { ... }
+
+ dest.writeLong(mTimeMillis);
+ dest.writeTypedObject(mBoundsInWindow, flags);
+ dest.writeString(mHashAlgorithm);
+ dest.writeByteArray(mImageHash);
+ }
+
+ @Override
+ @DataClass.Generated.Member
+ public int describeContents() { return 0; }
+
+ /** @hide */
+ @SuppressWarnings({"unchecked", "RedundantCast"})
+ @DataClass.Generated.Member
+ /* package-private */ VerifiedDisplayHash(@NonNull android.os.Parcel in) {
+ // You can override field unparcelling by defining methods like:
+ // static FieldType unparcelFieldName(Parcel in) { ... }
+
+ long timeMillis = in.readLong();
+ Rect boundsInWindow = (Rect) in.readTypedObject(Rect.CREATOR);
+ String hashAlgorithm = in.readString();
+ byte[] imageHash = in.createByteArray();
+
+ this.mTimeMillis = timeMillis;
+ this.mBoundsInWindow = boundsInWindow;
+ com.android.internal.util.AnnotationValidations.validate(
+ NonNull.class, null, mBoundsInWindow);
+ this.mHashAlgorithm = hashAlgorithm;
+ com.android.internal.util.AnnotationValidations.validate(
+ NonNull.class, null, mHashAlgorithm);
+ this.mImageHash = imageHash;
+ com.android.internal.util.AnnotationValidations.validate(
+ NonNull.class, null, mImageHash);
+
+ // onConstructed(); // You can define this method to get a callback
+ }
+
+ @DataClass.Generated.Member
+ public static final @NonNull Parcelable.Creator<VerifiedDisplayHash> CREATOR
+ = new Parcelable.Creator<VerifiedDisplayHash>() {
+ @Override
+ public VerifiedDisplayHash[] newArray(int size) {
+ return new VerifiedDisplayHash[size];
+ }
+
+ @Override
+ public VerifiedDisplayHash createFromParcel(@NonNull android.os.Parcel in) {
+ return new VerifiedDisplayHash(in);
+ }
+ };
+
+ @DataClass.Generated(
+ time = 1613168749684L,
+ codegenVersion = "1.0.22",
+ sourceFile = "frameworks/base/core/java/android/view/displayhash/VerifiedDisplayHash.java",
+ inputSignatures = "private final long mTimeMillis\nprivate final @android.annotation.NonNull android.graphics.Rect mBoundsInWindow\nprivate final @android.annotation.NonNull java.lang.String mHashAlgorithm\nprivate final @android.annotation.NonNull byte[] mImageHash\nprivate java.lang.String imageHashToString()\nprivate java.lang.String byteArrayToString(byte[])\nclass VerifiedDisplayHash extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genToString=true, genAidl=true)")
+ @Deprecated
+ private void __metadata() {}
+
+
+ //@formatter:on
+ // End of generated code
+
+}
diff --git a/core/jni/android_os_Trace.cpp b/core/jni/android_os_Trace.cpp
index 0f7611a8ead1..f67007cda209 100644
--- a/core/jni/android_os_Trace.cpp
+++ b/core/jni/android_os_Trace.cpp
@@ -83,7 +83,7 @@ static void android_os_Trace_nativeAsyncTraceEnd(JNIEnv* env, jclass,
}
static void android_os_Trace_nativeSetAppTracingAllowed(JNIEnv*, jclass, jboolean allowed) {
- atrace_set_debuggable(allowed);
+ atrace_update_tags();
}
static void android_os_Trace_nativeSetTracingEnabled(JNIEnv*, jclass, jboolean enabled) {
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index c61802d54e04..a4da22280bf1 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -5498,11 +5498,11 @@
android:protectionLevel="signature" />
<!-- Must be required by a
- {@link android.service.screenshot.ScreenshotHasherService}
+ {@link android.service.displayhash.DisplayHasherService}
to ensure that only the system can bind to it.
@hide This is not a third-party API (intended for OEMs and system apps).
-->
- <permission android:name="android.permission.BIND_SCREENSHOT_HASHER_SERVICE"
+ <permission android:name="android.permission.BIND_DISPLAY_HASHER_SERVICE"
android:protectionLevel="signature" />
<!-- @hide @TestApi Allows an application to enable/disable toast rate limiting.
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 55eaaf648f84..8aa297ec66e5 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -579,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Hierdie toetstel het nie \'n vingerafdruksensor nie."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor is tydelik gedeaktiveer."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Vinger <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Gebruik jou vingerafdruk om voort te gaan"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Vingerafdrukikoon"</string>
@@ -1664,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Gebruik kortpad"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Kleuromkering"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Kleurkorreksie"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Verminder helderheid"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Het volumesleutels ingehou. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> aangeskakel."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Het volumesleutels ingehou. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> is afgeskakel"</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Druk en hou albei volumesleutels drie sekondes lank om <xliff:g id="SERVICE_NAME">%1$s</xliff:g> te gebruik"</string>
@@ -1880,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"Maksimeer"</string>
<string name="close_button_text" msgid="10603510034455258">"Maak toe"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"Antwoord"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"Wys af"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Lui af"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"Inkomende oproep"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Oproep aan die gang"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"Keur tans \'n inkomende oproep"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> gekies</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> gekies</item>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 316122669352..16c8404ce1bd 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -579,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ይህ መሣሪያ የጣት አሻራ ዳሳሽ የለውም።"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ዳሳሽ ለጊዜው ተሰናክሏል።"</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"ጣት <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"ለመቀጠል የእርስዎን የጣት አሻራ ይጠቀሙ"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"የጣት አሻራ አዶ"</string>
@@ -1664,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"አቋራጭ ይጠቀሙ"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"ተቃራኒ ቀለም"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"የቀለም ማስተካከያ"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"ብሩህነትን ይቀንሱ"</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="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>ን ለመጠቀም ለሦስት ሰከንዶች ሁለቱንም የድምፅ ቁልፎች ተጭነው ይያዙ"</string>
@@ -1880,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"አስፋ"</string>
<string name="close_button_text" msgid="10603510034455258">"ዝጋ"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>፦ <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"መልስ"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"አትቀበል"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"ስልኩን ዝጋ"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"ገቢ ጥሪ"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"እየተካሄደ ያለ ጥሪ"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"ገቢ ጥሪ ማጣራት"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ተመርጧል</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ተመርጠዋል</item>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index a2d3671d667c..a291a89b62f8 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -152,8 +152,7 @@
<string name="wfc_mode_wifi_only_summary" msgid="104951993894678665">"‏Wi-Fi فقط"</string>
<!-- no translation found for crossSimFormat_spn (9125246077491634262) -->
<skip />
- <!-- no translation found for crossSimFormat_spn_cross_sim_calling (5620807020002879057) -->
- <skip />
+ <string name="crossSimFormat_spn_cross_sim_calling" msgid="5620807020002879057">"<xliff:g id="SPN">%s</xliff:g> الاتصال الاحتياطي"</string>
<string name="cfTemplateNotForwarded" msgid="862202427794270501">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: لم تتم إعادة التوجيه"</string>
<string name="cfTemplateForwarded" msgid="9132506315842157860">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
<string name="cfTemplateForwardedTime" msgid="735042369233323609">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g> بعد <xliff:g id="TIME_DELAY">{2}</xliff:g> ثانية"</string>
@@ -592,6 +591,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"لا يحتوي هذا الجهاز على مستشعِر بصمات إصبع."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"تم إيقاف جهاز الاستشعار مؤقتًا."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"الإصبع <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"يمكنك استخدام بصمة الإصبع للمتابعة."</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"رمز بصمة الإصبع"</string>
@@ -1753,6 +1753,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"استخدام الاختصار"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"قلب الألوان"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"تصحيح الألوان"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"تقليل السطوع"</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="4228997042855695090">"اضغط مع الاستمرار على مفتاحي مستوى الصوت لمدة 3 ثوانٍ لاستخدام <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
@@ -2005,6 +2006,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"تكبير"</string>
<string name="close_button_text" msgid="10603510034455258">"إغلاق"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"ردّ"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"رفض"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"قطع الاتصال"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"مكالمة واردة"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"مكالمة جارية"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"رصد مكالمة واردة"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="zero">تم اختيار <xliff:g id="COUNT_1">%1$d</xliff:g> عنصر</item>
<item quantity="two">تم اختيار عنصرين (<xliff:g id="COUNT_1">%1$d</xliff:g>)</item>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index 0a9ef97c2ad8..3c052d74878b 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -148,8 +148,7 @@
<string name="wfc_mode_wifi_only_summary" msgid="104951993894678665">"কোৱল ৱাই-ফাই"</string>
<!-- no translation found for crossSimFormat_spn (9125246077491634262) -->
<skip />
- <!-- no translation found for crossSimFormat_spn_cross_sim_calling (5620807020002879057) -->
- <skip />
+ <string name="crossSimFormat_spn_cross_sim_calling" msgid="5620807020002879057">"<xliff:g id="SPN">%s</xliff:g> বেকআপ কলিং"</string>
<string name="cfTemplateNotForwarded" msgid="862202427794270501">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: ফৰৱাৰ্ড কৰা নহ\'ল"</string>
<string name="cfTemplateForwarded" msgid="9132506315842157860">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
<string name="cfTemplateForwardedTime" msgid="735042369233323609">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g> <xliff:g id="TIME_DELAY">{2}</xliff:g> ছেকেণ্ডৰ পাছত"</string>
@@ -580,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"এই ডিভাইচটোত ফিংগাৰপ্ৰিণ্ট ছেন্সৰ নাই।"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ছেন্সৰটো সাময়িকভাৱে অক্ষম হৈ আছে।"</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g> আঙুলি"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"অব্যাহত ৰাখিবলৈ আপোনাৰ ফিংগাৰপ্ৰিণ্ট ব্যৱহাৰ কৰক"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"ফিংগাৰপ্ৰিণ্ট আইকন"</string>
@@ -1665,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"শ্বৰ্টকাট ব্যৱহাৰ কৰক"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"ৰং বিপৰীতকৰণ"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"ৰং শুধৰণী"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"উজ্জ্বলতা কমাওক"</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="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> ব্যৱহাৰ কৰিবলৈ দুয়োটা ভলিউম বুটাম তিনি ছেকেণ্ডৰ বাবে হেঁচি ৰাখক"</string>
@@ -1881,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"সৰ্বাধিক মাত্ৰালৈ বঢ়াওক"</string>
<string name="close_button_text" msgid="10603510034455258">"বন্ধ কৰক"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"উত্তৰ দিয়ক"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"প্ৰত্যাখ্যান কৰক"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"কল কাটি দিয়ক"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"অন্তৰ্গামী কল"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"চলি থকা কল"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"এটা অন্তৰ্গামী কলৰ পৰীক্ষা কৰি থকা হৈছে"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g>টা বাছনি কৰা হ’ল</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>টা বাছনি কৰা হ’ল</item>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index e91e2b740543..70b57a99be1d 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -325,7 +325,7 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"Həyati əlamətlər haqqında sensor dataya daxil olun"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Pəncərənin məzmununu əldə edin"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Əlaqədə olduğunuz pəncərənin məzmununu nəzərdən keçirin."</string>
- <string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Toxunaraq Kəşf et funksiyasını yandırın"</string>
+ <string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Toxunuşla öyrənmə funksiyasını aktiv edin"</string>
<string name="capability_desc_canRequestTouchExploration" msgid="4394677060796752976">"Tıklanan hissələr səsləndiriləcək və ekran jestlərlə idarə oluna biləcək."</string>
<string name="capability_title_canRequestFilterKeyEvents" msgid="2772371671541753254">"Yazdığınız mətni izləyin"</string>
<string name="capability_desc_canRequestFilterKeyEvents" msgid="2381315802405773092">"Kredit kartı nömrələri və parollar kimi şəxsi məlumatlar daxildir."</string>
@@ -579,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Bu cihazda barmaq izi sensoru yoxdur."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor müvəqqəti deaktivdir."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Barmaq <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Davam etmək üçün barmaq izinizi istifadə edin"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Barmaq izi ikonası"</string>
@@ -1629,7 +1630,7 @@
<string name="kg_failed_attempts_now_wiping" product="tv" msgid="5045460916106267585">"Android TV cihazını kiliddən çıxarmaq üçün <xliff:g id="NUMBER">%d</xliff:g> dəfə yanlış cəhd etdiniz. Android TV cihazınız defolt fabrik dəyərlərinə sıfırlanacaq."</string>
<string name="kg_failed_attempts_now_wiping" product="default" msgid="5043730590446071189">"Siz telefonun kilidini açmaq üçün <xliff:g id="NUMBER">%d</xliff:g> yanlış cəhd etmisiniz. Telefon artıq defolt zavod halına sıfırlanacaq."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="7086799295109717623">"Siz kilidi açmaq üçün şablonu <xliff:g id="NUMBER_0">%1$d</xliff:g> dəfə səhv çəkdiniz. <xliff:g id="NUMBER_1">%2$d</xliff:g> daha uğursuz cəhddən sonra planşetinizin kilidini e-poçt hesabınızla açmaq tələb olunacaq.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> saniyə ərzində bir daha yoxlayın."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4670840383567106114">"Kiliddən çıxarma modelini <xliff:g id="NUMBER_0">%1$d</xliff:g> dəfə yanlış çəkdiniz. Daha <xliff:g id="NUMBER_1">%2$d</xliff:g> yanlış cəhddən sonra Android TV cihazını e-poçt hesabınızla kiliddən çıxarmağınız tələb olunacaq.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> saniyə sonra yenidən cəhd edin."</string>
+ <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4670840383567106114">"Kiliddən çıxarma modelini <xliff:g id="NUMBER_0">%1$d</xliff:g> dəfə yanlış çəkdiniz. Daha <xliff:g id="NUMBER_1">%2$d</xliff:g> yanlış cəhddən sonra Android TV cihazını e-poçt hesabınızla kiliddən çıxarmağınız tələb olunacaq.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> saniyə sonra cəhd edin."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="5270861875006378092">"Siz artıq modeli <xliff:g id="NUMBER_0">%1$d</xliff:g> dəfə yanlış daxil etmisiniz.<xliff:g id="NUMBER_1">%2$d</xliff:g> dəfə də yanlış daxil etsəniz, telefonun kilidinin açılması üçün elektron poçt ünvanınız tələb olunacaq.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> saniyə ərzində yenidən cəhd edin."</string>
<string name="kg_text_message_separator" product="default" msgid="4503708889934976866">" - "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="2034358143731750914">"Yığışdır"</string>
@@ -1637,10 +1638,10 @@
<string name="accessibility_shortcut_warning_dialog_title" msgid="4017995837692622933">"Əlçatımlılıq Qısayolu istifadə edilsin?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="4161716521310929544">"Qısayol aktiv olduqda, hər iki səs düyməsinə 3 saniyə basıb saxlamaqla əlçatımlılıq funksiyası başladılacaq."</string>
<string name="accessibility_shortcut_multiple_service_warning_title" msgid="3135860819356676426">"Əlçatımlılıq funksiyaları üçün qısayol aktiv edilsin?"</string>
- <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"Hər iki səs səviyyəsi düyməsinə bir neçə saniyə basıb saxladıqda əlçatımlılıq funksiyaları aktiv olur. Bu, cihazınızın işləmə qaydasını dəyişə bilər.\n\nCari funksiyalar:\n<xliff:g id="SERVICE">%1$s</xliff:g>\nAyarlar və Əlçatımlılıq bölməsində seçilmiş funksiyaları dəyişə bilərsiniz."</string>
+ <string name="accessibility_shortcut_multiple_service_warning" msgid="3740723309483706911">"Hər iki səs səviyyəsi düyməsinə bir neçə saniyə basıb saxladıqda əlçatımlılıq funksiyaları aktiv olur. Cihazınızın işləmə qaydasını dəyişə bilər.\n\nCari funksiyalar:\n<xliff:g id="SERVICE">%1$s</xliff:g>\nAyarlar və Əlçatımlılıq bölməsində seçilmiş funksiyaları dəyişə bilərsiniz."</string>
<string name="accessibility_shortcut_multiple_service_list" msgid="6935581470716541531">" • <xliff:g id="SERVICE">%1$s</xliff:g>\n"</string>
<string name="accessibility_shortcut_single_service_warning_title" msgid="1909518473488345266">"<xliff:g id="SERVICE">%1$s</xliff:g> qısayolu aktiv edilsin?"</string>
- <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Hər iki səs səviyyəsi düyməsinə bir neçə saniyə basıb saxladıqda əlçatımlılıq funksiyası olan <xliff:g id="SERVICE">%1$s</xliff:g> aktiv olur. Bu, cihazınızın işləmə qaydasını dəyişə bilər.\n\nAyarlar və Əlçatımlılıq bölməsində bu qısayolu başqa bir funksiyata dəyişə bilərsiniz."</string>
+ <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"Hər iki səs səviyyəsi düyməsinə bir neçə saniyə basıb saxladıqda əlçatımlılıq funksiyası olan <xliff:g id="SERVICE">%1$s</xliff:g> aktiv olur. Cihazınızın işləmə qaydasını dəyişə bilər.\n\nAyarlar və Əlçatımlılıq bölməsində bu qısayolu başqa bir funksiyaya dəyişə bilərsiniz."</string>
<string name="accessibility_shortcut_on" msgid="5463618449556111344">"Aktiv edin"</string>
<string name="accessibility_shortcut_off" msgid="3651336255403648739">"Aktiv etməyin"</string>
<string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"AKTİV"</string>
@@ -1664,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Qısayol İstifadə edin"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Rəng İnversiyası"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Rəng korreksiyası"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Parlaqlığı Azaldın"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Səs səviyyəsi düymələrinə basıb saxlayın. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> aktiv edildi."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Səs səviyyəsi düymələrinə basılaraq saxlanıb. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> deaktiv edilib."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> istifadə etmək üçün hər iki səs düyməsini üç saniyə basıb saxlayın"</string>
@@ -1880,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"Böyüdün"</string>
<string name="close_button_text" msgid="10603510034455258">"Qapadın"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"Cavab verin"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"İmtina edin"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Dəstəyi asın"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"Gələn zəng"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Davam edən zəng"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"Gələn zəng göstərilir"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> seçilib</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> seçilib</item>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index a490a6ce2b7d..c96264ead6dd 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -582,6 +582,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Ovaj uređaj nema senzor za otisak prsta."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Senzor je privremeno onemogućen."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Nastavite pomoću otiska prsta"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ikona otiska prsta"</string>
@@ -1686,6 +1687,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Koristi prečicu"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Inverzija boja"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Korekcija boja"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Smanjite osvetljenost"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Držali ste tastere za jačinu zvuka. Usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je uključena."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Držali ste tastere za jačinu zvuka. Usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je isključena."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Pritisnite i zadržite oba tastera za jačinu zvuka tri sekunde da biste koristili <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -1911,6 +1913,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"Uvećaj"</string>
<string name="close_button_text" msgid="10603510034455258">"Zatvori"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"Odgovori"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"Odbij"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Prekini vezu"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"Dolazni poziv"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Poziv je u toku"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"Proverava se dolazni poziv"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="one">Izabrana je <xliff:g id="COUNT_1">%1$d</xliff:g> stavka</item>
<item quantity="few">Izabrane su <xliff:g id="COUNT_1">%1$d</xliff:g> stavke</item>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index 80f67d07a0d2..06b7372665d0 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -150,8 +150,7 @@
<string name="wfc_mode_wifi_only_summary" msgid="104951993894678665">"Толькі Wi-Fi"</string>
<!-- no translation found for crossSimFormat_spn (9125246077491634262) -->
<skip />
- <!-- no translation found for crossSimFormat_spn_cross_sim_calling (5620807020002879057) -->
- <skip />
+ <string name="crossSimFormat_spn_cross_sim_calling" msgid="5620807020002879057">"Рэзервовае капіраванне выклікаў праз аператара \"<xliff:g id="SPN">%s</xliff:g>\""</string>
<string name="cfTemplateNotForwarded" msgid="862202427794270501">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: не пераадрасоўваецца"</string>
<string name="cfTemplateForwarded" msgid="9132506315842157860">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
<string name="cfTemplateForwardedTime" msgid="735042369233323609">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g> праз <xliff:g id="TIME_DELAY">{2}</xliff:g> с."</string>
@@ -586,6 +585,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"На гэтай прыладзе няма сканера адбіткаў пальцаў."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Датчык часова выключаны."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Палец <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Каб працягнуць, выкарыстоўвайце свой адбітак пальца"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Значок адбіткаў пальцаў"</string>
@@ -1709,6 +1709,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Выкарыстоўваць камбінацыю хуткага доступу"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Інверсія колеру"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Карэкцыя колеру"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Паменшыць яркасць"</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="4228997042855695090">"Каб карыстацца сэрвісам \"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\", націсніце і ўтрымлівайце на працягу трох секунд абедзве клавішы гучнасці"</string>
@@ -1943,6 +1944,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"Разгарнуць"</string>
<string name="close_button_text" msgid="10603510034455258">"Закрыць"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"Адказаць"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"Адхіліць"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Завяршыць"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"Уваходны выклік"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Бягучы выклік"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"Фільтраванне ўваходнага выкліку"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> выбраны</item>
<item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> выбрана</item>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 20342e07953d..3a86bea53b9b 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -579,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Това устройство няма сензор за отпечатъци."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Сензорът е временно деактивиран."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Пръст <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Използвайте отпечатъка си, за да продължите"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Икона за отпечатък"</string>
@@ -1664,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Използване на пряк път"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Инвертиране на цветовете"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Коригиране на цветовете"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Намаляване на яркостта"</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="4228997042855695090">"За да използвате <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, натиснете двата бутона за силата на звука и ги задръжте за 3 секунди"</string>
@@ -1880,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"Увеличаване"</string>
<string name="close_button_text" msgid="10603510034455258">"Затваряне"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"„<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>“: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"Отговор"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"Отхвърляне"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Затваряне"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"Входящо обаждане"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Текущо обаждане"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"Преглежда се входящо обаждане"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="other">Избрахте <xliff:g id="COUNT_1">%1$d</xliff:g></item>
<item quantity="one">Избрахте <xliff:g id="COUNT_0">%1$d</xliff:g></item>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index 51d09b27afe6..2cb7bf544bab 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -148,8 +148,7 @@
<string name="wfc_mode_wifi_only_summary" msgid="104951993894678665">"শুধুমাত্র ওয়াই-ফাই"</string>
<!-- no translation found for crossSimFormat_spn (9125246077491634262) -->
<skip />
- <!-- no translation found for crossSimFormat_spn_cross_sim_calling (5620807020002879057) -->
- <skip />
+ <string name="crossSimFormat_spn_cross_sim_calling" msgid="5620807020002879057">"<xliff:g id="SPN">%s</xliff:g> ব্যাক-আপ কলিং"</string>
<string name="cfTemplateNotForwarded" msgid="862202427794270501">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: ফরওয়ার্ড করা হয়নি"</string>
<string name="cfTemplateForwarded" msgid="9132506315842157860">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
<string name="cfTemplateForwardedTime" msgid="735042369233323609">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g> <xliff:g id="TIME_DELAY">{2}</xliff:g> সেকেন্ড পরে"</string>
@@ -580,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"এই ডিভাইসে আঙ্গুলের ছাপ নেওয়ার সেন্সর নেই।"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"সেন্সর অস্থায়ীভাবে বন্ধ করা আছে।"</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"আঙ্গুল <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"চালিয়ে যেতে আঙ্গুলের ছাপ ব্যবহার করুন"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"আঙ্গুলের ছাপ আইকন"</string>
@@ -1665,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"শর্টকাট ব্যবহার করুন"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"রঙ উল্টানো"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"রঙ সংশোধন"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"উজ্জ্বলতা কমান"</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="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> ব্যবহার করতে ভলিউম কী বোতাম ৩ সেকেন্ডের জন্য চেপে ধরে রাখুন"</string>
@@ -1881,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"বড় করুন"</string>
<string name="close_button_text" msgid="10603510034455258">"বন্ধ করুন"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"উত্তর"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"বাতিল করুন"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"কল কেটে দেওয়া"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"ইনকামিং কল"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"চালু থাকা কল"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"ইনকামিং কল স্ক্রিনিং করা হচ্ছে"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g>টি নির্বাচন করা হয়েছে</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>টি নির্বাচন করা হয়েছে</item>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index 989e2bb7b598..b738b0d907a5 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -582,6 +582,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Ovaj uređaj nema senzor za otisak prsta."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Senzor je privremeno onemogućen."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Nastavite pomoću otiska prsta"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ikona za otisak prsta"</string>
@@ -1686,6 +1687,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Koristi prečicu"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Inverzija boja"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Ispravka boja"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Smanjenje osvjetljenja"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Držali ste tipke za jačinu zvuka. Usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je uključena."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Držali ste tipke za jačinu zvuka. Usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je isključena."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Pritisnite obje tipke za podešavanje jačine zvuka i držite ih pritisnutim tri sekunde da koristite uslugu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -1911,6 +1913,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"Povećaj maksimalno"</string>
<string name="close_button_text" msgid="10603510034455258">"Zatvori"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"Odgovori"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"Odbaci"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Prekini vezu"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"Dolazni poziv"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Poziv u toku"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"Filtriranje dolaznog poziva"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> stavka je odabrana</item>
<item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> stavke su odabrane</item>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index e9c55d76c6ac..ead0988d9b8d 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -538,10 +538,10 @@
<string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Permet que l\'aplicació conegui el nivell de complexitat del bloqueig de pantalla (alt, mitjà, baix o cap), que indica la llargària i el tipus de bloqueig de pantalla possibles. L\'aplicació també pot suggerir que els usuaris actualitzin el bloqueig de pantalla a un nivell determinat, però els usuaris poden ignorar aquestes recomanacions. Tingues en compte que el bloqueig de pantalla no s\'emmagatzema com a text sense format, de manera que l\'aplicació no coneix la contrasenya exacta."</string>
<string name="permlab_useBiometric" msgid="6314741124749633786">"utilitza maquinari biomètric"</string>
<string name="permdesc_useBiometric" msgid="7502858732677143410">"Permet que l\'aplicació faci servir maquinari biomètric per a l\'autenticació"</string>
- <string name="permlab_manageFingerprint" msgid="7432667156322821178">"Gestionar el maquinari d\'empremtes dactilars"</string>
+ <string name="permlab_manageFingerprint" msgid="7432667156322821178">"Gestionar el maquinari d\'empremtes digitals"</string>
<string name="permdesc_manageFingerprint" msgid="2025616816437339865">"Permet que l\'aplicació invoqui mètodes per afegir i suprimir plantilles d\'empremtes dactilars que es puguin fer servir."</string>
- <string name="permlab_useFingerprint" msgid="1001421069766751922">"Utilitzar el maquinari d\'empremtes dactilars"</string>
- <string name="permdesc_useFingerprint" msgid="412463055059323742">"Permet que l\'aplicació faci servir maquinari d\'empremtes dactilars per a l\'autenticació"</string>
+ <string name="permlab_useFingerprint" msgid="1001421069766751922">"Utilitzar el maquinari d\'empremtes digitals"</string>
+ <string name="permdesc_useFingerprint" msgid="412463055059323742">"Permet que l\'aplicació faci servir maquinari d\'empremtes digitals per a l\'autenticació"</string>
<string name="permlab_audioWrite" msgid="8501705294265669405">"modificar la teva col·lecció de música"</string>
<string name="permdesc_audioWrite" msgid="8057399517013412431">"Permet que l\'aplicació modifiqui la teva col·lecció de música."</string>
<string name="permlab_videoWrite" msgid="5940738769586451318">"modificar la teva col·lecció de vídeos"</string>
@@ -567,7 +567,7 @@
<string name="fingerprint_authenticated" msgid="2024862866860283100">"L\'empremta digital s\'ha autenticat"</string>
<string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Cara autenticada"</string>
<string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Cara autenticada; prem el botó per confirmar"</string>
- <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"El maquinari per a empremtes dactilars no està disponible."</string>
+ <string name="fingerprint_error_hw_not_available" msgid="4571700896929561202">"El maquinari d\'empremtes digitals no està disponible."</string>
<string name="fingerprint_error_no_space" msgid="6126456006769817485">"L\'empremta digital no es pot desar. Suprimeix-ne una."</string>
<string name="fingerprint_error_timeout" msgid="2946635815726054226">"S\'ha esgotat el temps d\'espera per a l\'empremta digital. Torna-ho a provar."</string>
<string name="fingerprint_error_canceled" msgid="540026881380070750">"S\'ha cancel·lat l\'operació d\'empremta digital."</string>
@@ -579,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Aquest dispositiu no té sensor d\'empremtes dactilars."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"El sensor està desactivat temporalment."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Dit <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Fes servir l\'empremta digital per continuar"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Icona d\'empremta digital"</string>
@@ -1664,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Utilitza la drecera"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Inversió de colors"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Correcció de color"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Reducció de la brillantor"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"S\'han mantingut premudes les tecles de volum. S\'ha activat <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"S\'han mantingut premudes les tecles de volum. S\'ha desactivat <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Mantén premudes les dues tecles de volum durant 3 segons per fer servir <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -1880,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"Maximitza"</string>
<string name="close_button_text" msgid="10603510034455258">"Tanca"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"Respon"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"Rebutja"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Penja"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"Trucada entrant"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Trucada en curs"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"S\'està filtrant una trucada entrant"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="other">Seleccionats: <xliff:g id="COUNT_1">%1$d</xliff:g></item>
<item quantity="one">Seleccionats: <xliff:g id="COUNT_0">%1$d</xliff:g></item>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 071bbfd69ce5..a9975b5a4fd0 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -585,6 +585,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Toto zařízení nemá snímač otisků prstů."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Senzor je dočasně deaktivován."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Pokračujte přiložením prstu"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ikona otisku prstů"</string>
@@ -1708,6 +1709,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Použít zkratku"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Převrácení barev"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Oprava barev"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Snížit jas"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Byla podržena tlačítka hlasitosti. Služba <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je zapnutá."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Byla podržena tlačítka hlasitosti. Služba <xliff:g id="SERVICE_NAME">%1$s</xliff:g> byla vypnuta."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Chcete-li používat službu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, tři sekundy podržte stisknutá obě tlačítka hlasitosti"</string>
@@ -1942,6 +1944,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"Maximalizovat"</string>
<string name="close_button_text" msgid="10603510034455258">"Zavřít"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"Přijmout"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"Odmítnout"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Zavěsit"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"Příchozí hovor"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Probíhající hovor"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"Prověřování příchozího hovoru"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> položky</item>
<item quantity="many"><xliff:g id="COUNT_1">%1$d</xliff:g> položky</item>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index b760f5b1c16e..187e098b869f 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -148,7 +148,7 @@
<string name="wfc_mode_wifi_only_summary" msgid="104951993894678665">"Kun Wi-Fi"</string>
<!-- no translation found for crossSimFormat_spn (9125246077491634262) -->
<skip />
- <string name="crossSimFormat_spn_cross_sim_calling" msgid="5620807020002879057">"Alternativ løsning til opkald leveret af <xliff:g id="SPN">%s</xliff:g>"</string>
+ <string name="crossSimFormat_spn_cross_sim_calling" msgid="5620807020002879057">"<xliff:g id="SPN">%s</xliff:g>-opkald via alternativt SIM"</string>
<string name="cfTemplateNotForwarded" msgid="862202427794270501">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Ikke viderestillet"</string>
<string name="cfTemplateForwarded" msgid="9132506315842157860">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
<string name="cfTemplateForwardedTime" msgid="735042369233323609">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g> efter <xliff:g id="TIME_DELAY">{2}</xliff:g> sekunder"</string>
@@ -581,6 +581,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Denne enhed har ingen fingeraftrykslæser."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensoren er midlertidigt deaktiveret."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Fingeraftryk <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Brug dit fingeraftryk for at fortsætte"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ikon for fingeraftryk"</string>
@@ -1666,6 +1667,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Brug genvej"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Ombytning af farver"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Korriger farve"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Reducer lysstyrken"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Lydstyrkeknapperne blev holdt nede. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> er aktiveret."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Lydstyrkeknapperne blev holdt nede. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> er deaktiveret."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Hold begge lydstyrkeknapper nede i tre sekunder for at bruge <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -1882,6 +1884,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"Maksimér"</string>
<string name="close_button_text" msgid="10603510034455258">"Luk"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"Besvar"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"Afvis"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Læg på"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"Indgående opkald"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Igangværende opkald"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"Et indgående opkald screenes"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g>valgt</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> valgt</item>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index f8066e2bfedf..f8e874dd3d61 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -148,8 +148,7 @@
<string name="wfc_mode_wifi_only_summary" msgid="104951993894678665">"Nur WLAN"</string>
<!-- no translation found for crossSimFormat_spn (9125246077491634262) -->
<skip />
- <!-- no translation found for crossSimFormat_spn_cross_sim_calling (5620807020002879057) -->
- <skip />
+ <string name="crossSimFormat_spn_cross_sim_calling" msgid="5620807020002879057">"<xliff:g id="SPN">%s</xliff:g>-Anruf über Ersatz-SIM"</string>
<string name="cfTemplateNotForwarded" msgid="862202427794270501">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Nicht weitergeleitet"</string>
<string name="cfTemplateForwarded" msgid="9132506315842157860">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
<string name="cfTemplateForwardedTime" msgid="735042369233323609">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g><xliff:g id="DIALING_NUMBER">{1}</xliff:g> nach <xliff:g id="TIME_DELAY">{2}</xliff:g> Sekunden."</string>
@@ -580,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Dieses Gerät hat keinen Fingerabdrucksensor."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Der Sensor ist vorübergehend deaktiviert."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Mithilfe deines Fingerabdrucks fortfahren"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Fingerabdruck-Symbol"</string>
@@ -1665,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Verknüpfung verwenden"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Farbumkehr"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Farbkorrektur"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Helligkeit verringern"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Lautstärketasten wurden gedrückt gehalten. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ist aktiviert."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Lautstärketasten wurden gedrückt gehalten. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ist deaktiviert."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Halten Sie beide Lautstärketasten drei Sekunden lang gedrückt, um <xliff:g id="SERVICE_NAME">%1$s</xliff:g> zu verwenden"</string>
@@ -1881,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"Maximieren"</string>
<string name="close_button_text" msgid="10603510034455258">"Schließen"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"Annehmen"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"Ablehnen"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Auflegen"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"Eingehender Anruf"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Aktueller Anruf"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"Screening für eingehenden Anruf"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ausgewählt</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ausgewählt</item>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 4f3c8a95a469..14d0271578c8 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -579,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Αυτή η συσκευή δεν διαθέτει αισθητήρα δακτυλικού αποτυπώματος."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Ο αισθητήρας απενεργοποιήθηκε προσωρινά."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Δάχτυλο <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Χρησιμοποιήστε το δακτυλικό αποτύπωμά σας για να συνεχίσετε"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Εικονίδιο δακτυλικών αποτυπωμάτων"</string>
@@ -1664,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Χρήση συντόμευσης"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Αντιστροφή χρωμάτων"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Διόρθωση χρωμάτων"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Μείωση φωτεινότητας"</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="4228997042855695090">"Πατήστε παρατεταμένα και τα δύο κουμπιά έντασης ήχου για τρία δευτερόλεπτα, ώστε να χρησιμοποιήσετε την υπηρεσία <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -1880,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"Μεγιστοποίηση"</string>
<string name="close_button_text" msgid="10603510034455258">"Κλείσιμο"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"Απάντηση"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"Απόρριψη"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Τερματισμός"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"Εισερχόμενη κλήση"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Κλήση σε εξέλιξη"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"Διαλογή εισερχόμενης κλήσης"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="other">Επιλέχτηκαν <xliff:g id="COUNT_1">%1$d</xliff:g></item>
<item quantity="one">Επιλέχτηκε <xliff:g id="COUNT_0">%1$d</xliff:g></item>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index 9f3bc7de2385..6c850a6ded1b 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -579,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"This device does not have a fingerprint sensor."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor temporarily disabled."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Use your fingerprint to continue"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Fingerprint icon"</string>
@@ -1664,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Use Shortcut"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Colour Inversion"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Colour correction"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Reduce Brightness"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned on."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned off."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Press and hold both volume keys for three seconds to use <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -1880,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"Maximise"</string>
<string name="close_button_text" msgid="10603510034455258">"Close"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"Answer"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"Decline"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Hang up"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"Incoming call"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"On-going call"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"Screening an incoming call"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> selected</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> selected</item>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index 766e372927d6..dd37df765aa5 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -579,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"This device does not have a fingerprint sensor."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor temporarily disabled."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Use your fingerprint to continue"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Fingerprint icon"</string>
@@ -1664,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Use Shortcut"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Colour inversion"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Colour correction"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Reduce Brightness"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned on."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned off."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Press and hold both volume keys for three seconds to use <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -1880,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"Maximise"</string>
<string name="close_button_text" msgid="10603510034455258">"Close"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"Answer"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"Decline"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Hang up"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"Incoming call"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"On-going call"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"Screening an incoming call"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> selected</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> selected</item>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 16da2116ed40..17dbd45f2395 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -579,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"This device does not have a fingerprint sensor."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor temporarily disabled."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Use your fingerprint to continue"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Fingerprint icon"</string>
@@ -1664,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Use Shortcut"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Colour Inversion"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Colour correction"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Reduce Brightness"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned on."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned off."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Press and hold both volume keys for three seconds to use <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -1880,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"Maximise"</string>
<string name="close_button_text" msgid="10603510034455258">"Close"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"Answer"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"Decline"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Hang up"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"Incoming call"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"On-going call"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"Screening an incoming call"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> selected</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> selected</item>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 150830ef027d..fb57bbcd5a2e 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -579,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"This device does not have a fingerprint sensor."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor temporarily disabled."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Use your fingerprint to continue"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Fingerprint icon"</string>
@@ -1664,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Use Shortcut"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Colour Inversion"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Color correction"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Reduce Brightness"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned on."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned off."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Press and hold both volume keys for three seconds to use <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -1880,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"Maximise"</string>
<string name="close_button_text" msgid="10603510034455258">"Close"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"Answer"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"Decline"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Hang up"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"Incoming call"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"On-going call"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"Screening an incoming call"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> selected</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> selected</item>
diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml
index e952cac93ca6..8fbeedeb8fea 100644
--- a/core/res/res/values-en-rXC/strings.xml
+++ b/core/res/res/values-en-rXC/strings.xml
@@ -579,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‎‎‎‎‎‏‎‎‎‏‎‏‏‎‏‏‏‏‎‎‎‏‎‎‎‏‏‏‏‎‏‎‎‏‏‎‎‏‎‏‎‎‎‎‎‎‎‎‏‏‎‎‏‎‏‏‎‎This device does not have a fingerprint sensor.‎‏‎‎‏‎"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‎‎‎‏‏‏‎‎‎‏‏‎‎‏‎‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎‏‏‎‎‎‏‎‎‎‏‏‏‎‎‎‎‏‎‏‏‏‎‎‎‏‎Sensor temporarily disabled.‎‏‎‎‏‎"</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‏‏‏‎‎‏‎‏‎‏‎‎‏‎‎‏‎‏‏‎‏‎‏‎‎‏‎‎‏‎‏‏‏‏‏‎‎‏‎‎‎‏‏‏‏‏‏‎‎‏‎‎Finger ‎‏‎‎‏‏‎<xliff:g id="FINGERID">%d</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‏‏‏‎‏‎‏‏‏‏‏‏‎‏‏‏‏‎‏‏‎‏‎‏‎‏‎‏‎‏‏‏‏‎‎‏‎‎‎‏‎‏‏‎‎‏‎‎‎‏‏‎‎‎‎‎‏‎Use your fingerprint to continue‎‏‎‎‏‎"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‏‎‎‏‎‏‏‏‎‏‎‏‎‎‎‏‎‏‎‎‏‎‏‏‏‏‎‎‎‏‏‎‏‏‎‎‎‎‎‎‏‎‎‏‏‏‎‏‎‎‏‎‎‎‏‎Fingerprint icon‎‏‎‎‏‎"</string>
@@ -1664,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‏‎‎‏‏‏‎‏‎‏‏‎‎‎‏‎‎‏‎‎‎‎‎‏‎‏‎‎‎‏‎‎‏‎‏‏‏‎‏‎‎‎‏‏‏‏‎‎‏‎‏‏‏‏‎‎Use Shortcut‎‏‎‎‏‎"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‎‎‏‎‎‎‎‏‏‎‎‏‎‏‏‏‎‎‏‏‎‎‏‎‏‎‏‏‎‎‎‎‎‏‎‏‎‏‎‏‏‎‏‏‏‎‏‏‏‏‏‏‎‏‎‏‎‎‎Color Inversion‎‏‎‎‏‎"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‎‏‎‏‏‏‎‎‏‎‏‏‏‎‎‎‏‎‏‏‎‎‎‎‏‏‏‏‎‎‎‏‎‎‎‎‎‎‎‏‎‎‎‎‏‏‎‎‎‎‎‎‎‎‏‎‏‎Color Correction‎‏‎‎‏‎"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‎‎‏‎‏‏‏‎‎‎‏‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‏‎‎‏‏‏‏‏‎‎‎‎‎‎‎‏‏‏‎‏‏‎‏‏‎‏‏‎‏‎‎Reduce Brightness‎‏‎‎‏‎"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‏‏‏‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‎‎‎‏‏‎‏‎‏‎‎‏‏‏‏‏‎‏‎‎‎‏‏‏‏‏‎‎‏‎‎‎‎‎‏‏‏‎Held volume keys. ‎‏‎‎‏‏‎<xliff:g id="SERVICE_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ turned on.‎‏‎‎‏‎"</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‎‎‏‎‎‏‎‏‎‏‎‎‎‏‎‎‏‏‎‏‎‏‏‎‎‏‏‏‎‎‏‎‏‎‏‏‏‏‎‏‎‏‏‏‎‎‏‎‎‏‎‏‏‎Held volume keys. ‎‏‎‎‏‏‎<xliff:g id="SERVICE_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ turned off.‎‏‎‎‏‎"</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‎‏‎‏‏‎‎‎‎‎‏‏‎‏‎‏‎‎‏‏‎‎‏‏‏‎‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‎‏‎‏‎‎‏‎‏‏‏‏‎‎‏‎‎Press and hold both volume keys for three seconds to use ‎‏‎‎‏‏‎<xliff:g id="SERVICE_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
@@ -1880,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‏‎‎‎‏‏‎‏‎‏‎‏‏‏‎‏‏‎‏‏‏‎‏‏‏‏‎‎‏‎‏‎‏‎‏‏‎‏‏‎‏‏‏‎‏‏‏‎‎‎‏‏‎‎‏‎‏‎Maximize‎‏‎‎‏‎"</string>
<string name="close_button_text" msgid="10603510034455258">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‎‏‏‎‏‎‎‏‎‏‏‎‏‎‏‎‏‏‏‏‎‏‎‏‏‎‎‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‏‏‎‏‎‏‏‎‏‏‎‏‎‎Close‎‏‎‎‏‎"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‎‏‎‏‏‏‎‎‏‏‎‏‏‏‏‎‏‏‏‎‏‎‎‏‏‎‏‏‎‏‎‎‏‎‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‏‏‎‏‎‏‎‏‎‎‏‎‎‏‏‎<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>‎‏‎‎‏‏‏‎: ‎‏‎‎‏‏‎<xliff:g id="SENDER_NAME">%2$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‏‎‏‎‎‎‎‎‏‏‎‎‏‏‎‏‏‎‎‏‏‎‏‏‎‎‏‎‏‎‎‏‎‎‏‏‎‎‏‎‏‎‏‏‏‏‎‏‏‎‎‎‎‏‎‎‏‎Answer‎‏‎‎‏‎"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‏‎‏‎‏‏‎‏‎‎‏‎‎‎‏‎‏‎‎‎‎‏‎‎‎‎‎‏‎‏‎‏‎‏‎‎‎‏‎‎‏‏‎‎‏‏‏‏‎‎‏‎‏‎‏‏‎‎Decline‎‏‎‎‏‎"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‏‎‏‏‎‏‎‏‏‎‎‎‎‎‎‎‎‎‎‎‎‎‎‏‏‏‏‏‎‎‏‎‎‎‏‎‎‏‎‎‎‎‏‎‏‎‎‎‏‏‎Hang Up‎‏‎‎‏‎"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‏‎‏‎‎‎‎‎‎‏‎‏‏‎‏‎‏‏‏‎‏‎‏‏‎‏‎‏‎‏‏‏‏‏‎‎‏‎‎‏‏‎‎‎‏‏‎‎‎‎‏‏‏‏‎‎‏‎Incoming call‎‏‎‎‏‎"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‏‏‏‎‏‏‎‏‏‎‏‏‏‏‏‎‎‏‏‏‏‏‏‎‏‏‏‏‎‏‎‏‏‏‎‏‏‎‏‏‎‏‏‏‏‎‏‏‎‏‏‎‎‏‎‏‏‎Ongoing call‎‏‎‎‏‎"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‎‏‎‎‏‎‏‎‎‎‎‎‏‎‎‎‎‎‎‏‎‎‏‏‎‎‎‎‏‏‎‏‎‎‏‏‏‎‏‏‎‎‎‎‎Screening an incoming call‎‏‎‎‏‎"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‎‏‏‎‎‎‎‏‏‏‏‎‎‎‎‏‏‎‎‎‎‏‏‏‏‏‏‎‎‏‏‎‎‎‏‏‎‏‎‏‏‎‏‎‏‏‏‎‏‎‎‏‎‏‎‏‏‎‎‏‎‎‏‏‎<xliff:g id="COUNT_1">%1$d</xliff:g>‎‏‎‎‏‏‏‎ selected‎‏‎‎‏‎</item>
<item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‎‏‏‎‎‎‎‏‏‏‏‎‎‎‎‏‏‎‎‎‎‏‏‏‏‏‏‎‎‏‏‎‎‎‏‏‎‏‎‏‏‎‏‎‏‏‏‎‏‎‎‏‎‏‎‏‏‎‎‏‎‎‏‏‎<xliff:g id="COUNT_0">%1$d</xliff:g>‎‏‎‎‏‏‏‎ selected‎‏‎‎‏‎</item>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index c5ff193bc6a2..3e995c6e6d34 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -579,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Este dispositivo no tiene sensor de huellas digitales."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Se inhabilitó temporalmente el sensor."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Utiliza tu huella digital para continuar"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ícono de huella digital"</string>
@@ -1664,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Usar acceso directo"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Inversión de color"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Corrección de color"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Reducir el brillo"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Como mantuviste presionadas las teclas de volumen, se activó <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Se presionaron las teclas de volumen. Se desactivó <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Mantén presionadas ambas teclas de volumen durante tres segundos para usar <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -1880,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"Maximizar"</string>
<string name="close_button_text" msgid="10603510034455258">"Cerrar"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"Responder"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"Rechazar"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Colgar"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"Llamada entrante"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Llamada en curso"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"Filtrando una llamada entrante"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> elementos seleccionados</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> elemento seleccionado</item>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 108c3dbeb954..8b1c3271e7f5 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -579,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Este dispositivo no tiene sensor de huellas digitales."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"El sensor está inhabilitado en estos momentos."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Usa tu huella digital para continuar"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Icono de huella digital"</string>
@@ -1664,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Utilizar acceso directo"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Inversión de color"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Corrección de color"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Reducir brillo"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Al mantener pulsadas las teclas de volumen, se ha activado <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Se han mantenido pulsadas las teclas de volumen. Se ha desactivado <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Para utilizar <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, mantén pulsadas ambas teclas de volumen durante 3 segundos"</string>
@@ -1880,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"Maximizar"</string>
<string name="close_button_text" msgid="10603510034455258">"Cerrar"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"Responder"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"Rechazar"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Colgar"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"Llamada entrante"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Llamada en curso"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"Filtrando una llamada entrante"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> seleccionados</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> seleccionado</item>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index 70862d481b65..33f8e526828a 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -579,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Selles seadmes pole sõrmejäljeandurit."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Andur on ajutiselt keelatud."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Sõrmejälg <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Jätkamiseks kasutage sõrmejälge"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Sõrmejälje ikoon"</string>
@@ -1664,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Kasuta otseteed"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Värvide ümberpööramine"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Värvide korrigeerimine"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Ereduse vähendamine"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Helitugevuse klahve hoiti all. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> lülitati sisse."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Helitugevuse klahve hoiti all. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> lülitati välja."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Teenuse <xliff:g id="SERVICE_NAME">%1$s</xliff:g> kasutamiseks hoidke kolm sekundit all mõlemat helitugevuse klahvi"</string>
@@ -1880,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"Maksimeeri"</string>
<string name="close_button_text" msgid="10603510034455258">"Sule"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"Vasta"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"Keeldu"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Lõpeta kõne"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"Sissetulev kõne"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Käimasolev kõne"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"Sissetuleva kõne filtreerimine"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> on valitud</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> on valitud</item>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index bc691a5c37e2..8328c86df751 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -93,7 +93,7 @@
<string name="notification_channel_mobile_data_status" msgid="1941911162076442474">"Datu-konexioaren egoera"</string>
<string name="notification_channel_sms" msgid="1243384981025535724">"SMS mezuak"</string>
<string name="notification_channel_voice_mail" msgid="8457433203106654172">"Erantzungailuko mezuak"</string>
- <string name="notification_channel_wfc" msgid="9048240466765169038">"Wi-Fi bidezko deiak"</string>
+ <string name="notification_channel_wfc" msgid="9048240466765169038">"Wifi bidezko deiak"</string>
<string name="notification_channel_sim" msgid="5098802350325677490">"SIMaren egoera"</string>
<string name="notification_channel_sim_high_prio" msgid="642361929452850928">"SIM txartelaren lehentasun handiko jakinarazpenak"</string>
<string name="peerTtyModeFull" msgid="337553730440832160">"Beste gailuak TTY osagarria FULL moduan erabiltzea eskatu du"</string>
@@ -122,23 +122,23 @@
<string name="roamingText11" msgid="5245687407203281407">"Ibiltaritzari buruzko jakinarazpena aktibatuta"</string>
<string name="roamingText12" msgid="673537506362152640">"Ibiltaritzari buruzko jakinarazpena desaktibatuta"</string>
<string name="roamingTextSearching" msgid="5323235489657753486">"Zerbitzu bila"</string>
- <string name="wfcRegErrorTitle" msgid="3193072971584858020">"Ezin izan dira konfiguratu Wi‑Fi bidezko deiak"</string>
+ <string name="wfcRegErrorTitle" msgid="3193072971584858020">"Ezin izan dira konfiguratu wifi bidezko deiak"</string>
<string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="468830943567116703">"Wi-Fi bidez deiak egiteko eta mezuak bidaltzeko, eskatu operadoreari zerbitzu hori gaitzeko. Ondoren, aktibatu Wi-Fi bidezko deiak Ezarpenak atalean. (Errore-kodea: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
+ <item msgid="468830943567116703">"Wifi bidez deiak egiteko eta mezuak bidaltzeko, eskatu operadoreari zerbitzu hori gaitzeko. Ondoren, aktibatu Wifi bidezko deiak Ezarpenak atalean. (Errore-kodea: <xliff:g id="CODE">%1$s</xliff:g>)"</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
- <item msgid="4795145070505729156">"Arazo bat izan da Wi‑Fi bidezko deiak zure operadorearekin erregistratzean: <xliff:g id="CODE">%1$s</xliff:g>"</item>
+ <item msgid="4795145070505729156">"Arazo bat izan da wifi bidezko deiak zure operadorearekin erregistratzean: <xliff:g id="CODE">%1$s</xliff:g>"</item>
</string-array>
<!-- no translation found for wfcSpnFormat_spn (2982505428519096311) -->
<skip />
- <string name="wfcSpnFormat_spn_wifi_calling" msgid="3165949348000906194">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi bidezko deiak"</string>
+ <string name="wfcSpnFormat_spn_wifi_calling" msgid="3165949348000906194">"<xliff:g id="SPN">%s</xliff:g> operadorearen wifi bidezko deiak"</string>
<string name="wfcSpnFormat_spn_wifi_calling_vo_hyphen" msgid="3836827895369365298">"<xliff:g id="SPN">%s</xliff:g> operadorearen wifi bidezko deiak"</string>
<string name="wfcSpnFormat_wlan_call" msgid="4895315549916165700">"WLAN bidezko deia"</string>
<string name="wfcSpnFormat_spn_wlan_call" msgid="255919245825481510">"<xliff:g id="SPN">%s</xliff:g> WLAN bidezko deia"</string>
<string name="wfcSpnFormat_spn_wifi" msgid="7232899594327126970">"<xliff:g id="SPN">%s</xliff:g> wifia"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="8383917598312067365">"Wi-Fi bidezko deiak | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="6865214948822061486">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
- <string name="wfcSpnFormat_wifi_calling" msgid="6178935388378661755">"Wi-Fi bidezko deiak"</string>
+ <string name="wfcSpnFormat_wifi_calling" msgid="6178935388378661755">"Wifi bidezko deiak"</string>
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wifia"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Wi-Fi bidezko deiak"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
@@ -148,8 +148,7 @@
<string name="wfc_mode_wifi_only_summary" msgid="104951993894678665">"Wifi-sarea soilik"</string>
<!-- no translation found for crossSimFormat_spn (9125246077491634262) -->
<skip />
- <!-- no translation found for crossSimFormat_spn_cross_sim_calling (5620807020002879057) -->
- <skip />
+ <string name="crossSimFormat_spn_cross_sim_calling" msgid="5620807020002879057">"<xliff:g id="SPN">%s</xliff:g> operadorearen deietarako ordezko aukera"</string>
<string name="cfTemplateNotForwarded" msgid="862202427794270501">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: ez da desbideratu"</string>
<string name="cfTemplateForwarded" msgid="9132506315842157860">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
<string name="cfTemplateForwardedTime" msgid="735042369233323609">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g> zenbakira <xliff:g id="TIME_DELAY">{2}</xliff:g> segundotan"</string>
@@ -580,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Gailu honek ez du hatz-marken sentsorerik."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sentsorea aldi baterako desgaitu da."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g> hatza"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Aurrera egiteko, erabili hatz-marka"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Hatz-markaren ikonoa"</string>
@@ -1665,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Erabili lasterbidea"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Koloreen alderantzikatzea"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Koloreen zuzenketa"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Murriztu distira"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Bolumen-botoiak sakatuta eduki direnez, <xliff:g id="SERVICE_NAME">%1$s</xliff:g> aktibatu egin da."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Bolumen-botoiak sakatuta eduki direnez, <xliff:g id="SERVICE_NAME">%1$s</xliff:g> desaktibatu egin da."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> erabiltzeko, eduki sakatuta bi bolumen-botoiak hiru segundoz"</string>
@@ -1881,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"Maximizatu"</string>
<string name="close_button_text" msgid="10603510034455258">"Itxi"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"Erantzun"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"Baztertu"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Amaitu deia"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"Jasotako deia"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Deia abian da"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"Jasotako dei bat bistaratzen"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> hautatuta</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> hautatuta</item>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 6a0e45446341..75081e5e5787 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -579,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"این دستگاه حسگر اثر انگشت ندارد."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"حسگر به‌طور موقت غیرفعال است."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"انگشت <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"برای ادامه، از اثر انگشتتان استفاده کنید"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"نماد اثر انگشت"</string>
@@ -1440,7 +1441,7 @@
<string name="notification_listener_binding_label" msgid="2702165274471499713">"شنونده اعلان"</string>
<string name="vr_listener_binding_label" msgid="8013112996671206429">"‏شنونده VR"</string>
<string name="condition_provider_service_binding_label" msgid="8490641013951857673">"ارائه‌دهنده وضعیت"</string>
- <string name="notification_ranker_binding_label" msgid="432708245635563763">"سرویس رتبه‌بندی اعلان"</string>
+ <string name="notification_ranker_binding_label" msgid="432708245635563763">"سرویس رده‌بندی اعلان"</string>
<string name="vpn_title" msgid="5906991595291514182">"‏VPN فعال شد"</string>
<string name="vpn_title_long" msgid="6834144390504619998">"‏VPN را <xliff:g id="APP">%s</xliff:g> فعال کرده است"</string>
<string name="vpn_text" msgid="2275388920267251078">"برای مدیریت شبکه ضربه بزنید."</string>
@@ -1664,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"استفاده از میان‌بر"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"وارونگی رنگ"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"تصحیح رنگ"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"کاهش روشنایی"</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="4228997042855695090">"برای استفاده از <xliff:g id="SERVICE_NAME">%1$s</xliff:g>، هر دو کلید صدا را فشار دهید و سه ثانیه نگه دارید"</string>
@@ -1880,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"بزرگ کردن"</string>
<string name="close_button_text" msgid="10603510034455258">"بستن"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>:‏ <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"پاسخ"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"رد کردن"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"قطع تماس"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"تماس ورودی"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"تماس درحال انجام"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"درحال غربال کردن تماس ورودی"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="one">‏<xliff:g id="COUNT_1">%1$d</xliff:g> انتخاب شد</item>
<item quantity="other">‏<xliff:g id="COUNT_1">%1$d</xliff:g> انتخاب شد</item>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 8e5d9b44759a..42c220dfcf92 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -579,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Laitteessa ei ole sormenjälkitunnistinta."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Tunnistin poistettu väliaikaisesti käytöstä."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Sormi <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Jatka sormenjäljen avulla"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Sormenjälkikuvake"</string>
@@ -1664,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Käytä pikanäppäintä"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Käänteiset värit"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Värinkorjaus"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Vähennä kirkkautta"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Äänenvoimakkuuspainikkeita painettiin pitkään. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> laitettiin päälle."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Äänenvoimakkuuspainikkeita painettiin pitkään. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> laitettiin pois päältä."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Voit käyttää palvelua <xliff:g id="SERVICE_NAME">%1$s</xliff:g> painamalla molempia äänenvoimakkuuspainikkeita kolmen sekunnin ajan"</string>
@@ -1880,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"Suurenna"</string>
<string name="close_button_text" msgid="10603510034455258">"Sulje"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"Vastaa"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"Hylkää"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Lopeta puhelu"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"Saapuva puhelu"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Käynnissä oleva puhelu"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"Seulotaan saapuvaa puhelua"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> valittu</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> valittu</item>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 849f9594729f..b4a22f46e4fa 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -148,8 +148,7 @@
<string name="wfc_mode_wifi_only_summary" msgid="104951993894678665">"Wi-Fi seulement"</string>
<!-- no translation found for crossSimFormat_spn (9125246077491634262) -->
<skip />
- <!-- no translation found for crossSimFormat_spn_cross_sim_calling (5620807020002879057) -->
- <skip />
+ <string name="crossSimFormat_spn_cross_sim_calling" msgid="5620807020002879057">"Méthode d\'appel secondaire avec <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="cfTemplateNotForwarded" msgid="862202427794270501">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g> : non transféré"</string>
<string name="cfTemplateForwarded" msgid="9132506315842157860">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g> : <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
<string name="cfTemplateForwardedTime" msgid="735042369233323609">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g> : <xliff:g id="DIALING_NUMBER">{1}</xliff:g> au bout de <xliff:g id="TIME_DELAY">{2}</xliff:g> secondes"</string>
@@ -580,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Cet appareil ne possède pas de capteur d\'empreintes digitales."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Le capteur a été désactivé temporairement."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Doigt <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Utilisez votre empreinte digitale pour continuer"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Icône d\'empreinte digitale"</string>
@@ -1665,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Utiliser le raccourci"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Inversion des couleurs"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Correction des couleurs"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Réduire la luminosité"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Touches de volume maintenues enfoncées. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> activé."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Touches de volume maintenues enfoncées. Service <xliff:g id="SERVICE_NAME">%1$s</xliff:g> désactivé."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Maintenez enfoncées les deux touches de volume pendant trois secondes pour utiliser <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -1881,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"Agrandir"</string>
<string name="close_button_text" msgid="10603510034455258">"Fermer"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g> : <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"Répondre"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"Refuser"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Raccrocher"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"Appel entrant"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Appel en cours"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"Filtrer un appel entrant"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> élément sélectionné</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> éléments sélectionnés</item>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 60138c47d40e..8133f97dd0c1 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -148,8 +148,7 @@
<string name="wfc_mode_wifi_only_summary" msgid="104951993894678665">"Wi-Fi uniquement"</string>
<!-- no translation found for crossSimFormat_spn (9125246077491634262) -->
<skip />
- <!-- no translation found for crossSimFormat_spn_cross_sim_calling (5620807020002879057) -->
- <skip />
+ <string name="crossSimFormat_spn_cross_sim_calling" msgid="5620807020002879057">"Appels de secours via <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="cfTemplateNotForwarded" msgid="862202427794270501">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g> : non transféré"</string>
<string name="cfTemplateForwarded" msgid="9132506315842157860">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g> : <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
<string name="cfTemplateForwardedTime" msgid="735042369233323609">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g> : <xliff:g id="DIALING_NUMBER">{1}</xliff:g> au bout de <xliff:g id="TIME_DELAY">{2}</xliff:g> secondes"</string>
@@ -580,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Aucun lecteur d\'empreinte digitale n\'est installé sur cet appareil."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Capteur temporairement désactivé."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Doigt <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Utilisez votre empreinte digitale pour continuer"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Icône d\'empreinte digitale"</string>
@@ -1665,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Utiliser le raccourci"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Inversion des couleurs"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Correction des couleurs"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Réduire la luminosité"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Touches de volume appuyées de manière prolongée. Service <xliff:g id="SERVICE_NAME">%1$s</xliff:g> activé."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Touches de volume appuyées de manière prolongée. Service <xliff:g id="SERVICE_NAME">%1$s</xliff:g> désactivé."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Appuyez de manière prolongée sur les deux touches de volume pendant trois secondes pour utiliser <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -1881,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"Agrandir"</string>
<string name="close_button_text" msgid="10603510034455258">"Fermer"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g> : <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"Répondre"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"Refuser"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Raccrocher"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"Appel entrant"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Appel en cours"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"Filtrer un appel entrant"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> élément sélectionné</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> éléments sélectionnés</item>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index eadac9edad74..526c74607fd4 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -579,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Este dispositivo non ten sensor de impresión dixital."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Desactivouse o sensor temporalmente."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Utiliza a túa impresión dixital para continuar"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Icona de impresión dixital"</string>
@@ -1664,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Utilizar atallo"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Inversión de cor"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Corrección de cor"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Reducir brillo"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Teclas de volume premidas. Activouse o servizo <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Teclas de volume premidas. Desactivouse <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Mantén premidas as teclas do volume durante tres segudos para usar <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -1880,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"Maximizar"</string>
<string name="close_button_text" msgid="10603510034455258">"Pechar"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"Resposta"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"Rexeitar"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Colgar"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"Chamada entrante"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Chamada en curso"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"Filtrando chamada entrante"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="other">Seleccionáronse <xliff:g id="COUNT_1">%1$d</xliff:g></item>
<item quantity="one">Seleccionouse <xliff:g id="COUNT_0">%1$d</xliff:g></item>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index 86416bce3f48..e0e20af38496 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -148,8 +148,7 @@
<string name="wfc_mode_wifi_only_summary" msgid="104951993894678665">"ફક્ત વાઇ-ફાઇ"</string>
<!-- no translation found for crossSimFormat_spn (9125246077491634262) -->
<skip />
- <!-- no translation found for crossSimFormat_spn_cross_sim_calling (5620807020002879057) -->
- <skip />
+ <string name="crossSimFormat_spn_cross_sim_calling" msgid="5620807020002879057">"<xliff:g id="SPN">%s</xliff:g> બૅકઅપ કૉલિંગ"</string>
<string name="cfTemplateNotForwarded" msgid="862202427794270501">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: ફોરવર્ડ કર્યો નથી"</string>
<string name="cfTemplateForwarded" msgid="9132506315842157860">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
<string name="cfTemplateForwardedTime" msgid="735042369233323609">"<xliff:g id="TIME_DELAY">{2}</xliff:g> સેકન્ડ પછી <xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -580,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"આ ડિવાઇસમાં કોઈ ફિંગરપ્રિન્ટ સેન્સર નથી."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"સેન્સર હંગામી રૂપે બંધ કર્યું છે."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"આંગળી <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"ચાલુ રાખવા માટે તમારી ફિંગરપ્રિન્ટનો ઉપયોગ કરો"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"ફિંગરપ્રિન્ટ આયકન"</string>
@@ -1665,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"શૉર્ટકટનો ઉપયોગ કરો"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"વિપરીત રંગમાં બદલવું"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"રંગ સુધારણા"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"બ્રાઇટનેસ ઘટાડો"</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="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>નો ઉપયોગ કરવા માટે બન્ને વૉલ્યૂમ કીને ત્રણ સેકન્ડ સુધી દબાવી રાખો"</string>
@@ -1881,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"મહત્તમ કરો"</string>
<string name="close_button_text" msgid="10603510034455258">"બંધ કરો"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"જવાબ"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"નકારો"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"સમાપ્ત કરો"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"ઇનકમિંગ કૉલ"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"ચાલુ કૉલ"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"ઇનકમિંગ કૉલનું સ્ક્રીનિંગ થાય છે"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> પસંદ કરી</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> પસંદ કરી</item>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 5f0a8f89b926..df97a1259fd8 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -303,7 +303,7 @@
<string name="managed_profile_label" msgid="7316778766973512382">"प्रोफ़ाइल बदलकर वर्क प्रोफ़ाइल पर जाएं"</string>
<string name="permgrouplab_contacts" msgid="4254143639307316920">"संपर्क"</string>
<string name="permgroupdesc_contacts" msgid="9163927941244182567">"अपने संपर्कों को ऐक्सेस करने की"</string>
- <string name="permgrouplab_location" msgid="1858277002233964394">"जगह"</string>
+ <string name="permgrouplab_location" msgid="1858277002233964394">"जगह की जानकारी"</string>
<string name="permgroupdesc_location" msgid="1995955142118450685">"इस डिवाइस की जगह तक पहुंचने दें"</string>
<string name="permgrouplab_calendar" msgid="6426860926123033230">"कैलेंडर"</string>
<string name="permgroupdesc_calendar" msgid="6762751063361489379">"अपने कैलेंडर को ऐक्सेस करने"</string>
@@ -579,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"इस डिवाइस में फ़िंगरप्रिंट सेंसर नहीं है."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"सेंसर कुछ समय के लिए बंद कर दिया गया है."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"फ़िंगरप्रिंट <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"जारी रखने के लिए फ़िंगरप्रिंट का इस्तेमाल करें"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"फ़िंगरप्रिंट आइकॉन"</string>
@@ -1664,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"शॉर्टकट का उपयोग करें"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"रंग बदलने की सुविधा"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"रंग में सुधार करने की सुविधा"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"स्क्रीन की चमक कम करें"</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="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> इस्तेमाल करने के लिए आवाज़ वाले दोनों बटन तीन सेकंड तक दबाकर रखें"</string>
@@ -1880,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"बड़ा करें"</string>
<string name="close_button_text" msgid="10603510034455258">"बंद करें"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"जवाब दें"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"अस्वीकार करें"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"कॉल काटें"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"आने वाला (इनकमिंग) कॉल"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"जारी कॉल"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"इनकमिंग कॉल को स्क्रीन किया जा रहा है"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> चयनित</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> चयनित</item>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index e1ae1e24e0a1..fdadb5e170e4 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -582,6 +582,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Ovaj uređaj nema senzor otiska prsta."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Senzor je privremeno onemogućen."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Nastavite pomoću otiska prsta"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ikona otiska prsta"</string>
@@ -1686,6 +1687,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Upotrijebi prečac"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Inverzija boja"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Korekcija boje"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Smanjenje svjetline"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Držali ste tipke za glasnoću. Uključila se usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Držali ste tipke za glasnoću. Isključila se usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Pritisnite i zadržite tipke za glasnoću na tri sekunde da biste koristili uslugu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -1911,6 +1913,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"Maksimiziraj"</string>
<string name="close_button_text" msgid="10603510034455258">"Zatvori"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"Odgovori"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"Odbij"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Prekini"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"Dolazni poziv"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Poziv u tijeku"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"Filtriranje dolaznog poziva"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> odabrana</item>
<item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> odabrane</item>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 3c04bec04151..dce975cf0080 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -579,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Ez az eszköz nem rendelkezik ujjlenyomat-érzékelővel."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Az érzékelő átmenetileg le van tiltva."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g>. ujj"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"A folytatáshoz használja ujjlenyomatát"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ujjlenyomat ikon"</string>
@@ -1664,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Billentyűparancs használata"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Színek invertálása"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Színkorrekció"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Fényerő csökkentése"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Nyomva tartotta a hangerőgombokat. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> bekapcsolva."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Nyomva tartotta a hangerőgombokat. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> kikapcsolva."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"A(z) <xliff:g id="SERVICE_NAME">%1$s</xliff:g> használatához tartsa lenyomva három másodpercig a két hangerőgombot"</string>
@@ -1880,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"Teljes méret"</string>
<string name="close_button_text" msgid="10603510034455258">"Bezárás"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"Fogadás"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"Elutasítás"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Befejezés"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"Bejövő hívás"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Hívás folyamatban"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"Bejövő hívás szűrése"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> kiválasztva</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> kiválasztva</item>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index bdd238757bfb..ca4e9b8be535 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -579,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Այս սարքը չունի մատնահետքերի սկաներ։"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Տվիչը ժամանակավորապես անջատված է:"</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Մատնահետք <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Շարունակելու համար անհրաժեշտ է ձեր մատնահետքը"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Մատնահետքի պատկերակ"</string>
@@ -1438,7 +1439,7 @@
<string name="wallpaper_binding_label" msgid="1197440498000786738">"Պաստառ"</string>
<string name="chooser_wallpaper" msgid="3082405680079923708">"Փոխել պաստառը"</string>
<string name="notification_listener_binding_label" msgid="2702165274471499713">"Ծանուցման ունկնդիր"</string>
- <string name="vr_listener_binding_label" msgid="8013112996671206429">"VR ունկնդրիչ"</string>
+ <string name="vr_listener_binding_label" msgid="8013112996671206429">"VR ունկնիր"</string>
<string name="condition_provider_service_binding_label" msgid="8490641013951857673">"Պայմանների մատակարար"</string>
<string name="notification_ranker_binding_label" msgid="432708245635563763">"Ծանուցումների դասակարգման ծառայություն"</string>
<string name="vpn_title" msgid="5906991595291514182">"VPN-ը ակտիվացված է"</string>
@@ -1664,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Օգտագործել դյուրանցումը"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Գունաշրջում"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Գունաշտկում"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Նվազեցնել պայծառությունը"</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="4228997042855695090">"«<xliff:g id="SERVICE_NAME">%1$s</xliff:g>» ծառայությունն օգտագործելու համար սեղմեք և 3 վայրկյան պահեք ձայնի ուժգնության երկու կոճակները"</string>
@@ -1880,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"Մեծացնել"</string>
<string name="close_button_text" msgid="10603510034455258">"Փակել"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>՝ <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"Պատասխանել"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"Մերժել"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Ավարտել"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"Մուտքային զանգ"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Ընթացիկ զանգ"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"Մուտքային զանգի զտում"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="one">Ընտրված է՝ <xliff:g id="COUNT_1">%1$d</xliff:g></item>
<item quantity="other">Ընտրված է՝ <xliff:g id="COUNT_1">%1$d</xliff:g></item>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index c84bc1318caf..e68812db464f 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -579,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Perangkat ini tidak memiliki sensor sidik jari."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor dinonaktifkan untuk sementara."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Jari <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Gunakan sidik jari untuk melanjutkan"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ikon sidik jari"</string>
@@ -1664,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Gunakan Pintasan"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Inversi Warna"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Koreksi Warna"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Kurangi Kecerahan"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Tombol volume ditahan. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> diaktifkan."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Tombol volume ditahan. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> dinonaktifkan."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Tekan dan tahan kedua tombol volume selama tiga detik untuk menggunakan <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -1880,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"Maksimalkan"</string>
<string name="close_button_text" msgid="10603510034455258">"Tutup"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"Jawab"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"Tolak"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Tutup"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"Panggilan masuk"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Panggilan sedang berlangsung"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"Menyaring panggilan masuk"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> dipilih</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> dipilih</item>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index 84611a2d44a9..2076363a19fd 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -579,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Þetta tæki er ekki með fingrafaralesara."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Slökkt tímabundið á skynjara."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Fingur <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Notaðu fingrafarið þitt til að halda áfram"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Fingrafaratákn"</string>
@@ -1664,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Nota flýtileið"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Umsnúningur lita"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Litaleiðrétting"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Draga úr birtu"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Hljóðstyrkstökkum haldið inni. Kveikt á <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Hljóðstyrkstökkum haldið inni. Slökkt á <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Haltu báðum hljóðstyrkstökkunum inni í þrjár sekúndur til að nota <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -1880,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"Stækka"</string>
<string name="close_button_text" msgid="10603510034455258">"Loka"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"Svara"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"Hafna"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Leggja á"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"Símtal berst"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Símtal í gangi"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"Síar símtal sem berst"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> valið</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> valin</item>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 2fcc273880f7..34ee5dc4a664 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -148,8 +148,7 @@
<string name="wfc_mode_wifi_only_summary" msgid="104951993894678665">"Solo Wi-Fi"</string>
<!-- no translation found for crossSimFormat_spn (9125246077491634262) -->
<skip />
- <!-- no translation found for crossSimFormat_spn_cross_sim_calling (5620807020002879057) -->
- <skip />
+ <string name="crossSimFormat_spn_cross_sim_calling" msgid="5620807020002879057">"Chiamate di backup <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="cfTemplateNotForwarded" msgid="862202427794270501">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: inoltro non effettuato"</string>
<string name="cfTemplateForwarded" msgid="9132506315842157860">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
<string name="cfTemplateForwardedTime" msgid="735042369233323609">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g><xliff:g id="DIALING_NUMBER">{1}</xliff:g> dopo <xliff:g id="TIME_DELAY">{2}</xliff:g> secondi"</string>
@@ -580,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Questo dispositivo non dispone di sensore di impronte."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensore temporaneamente disattivato."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Dito <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Utilizza la tua impronta per continuare"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Icona dell\'impronta"</string>
@@ -1665,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Usa scorciatoia"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Inversione dei colori"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Correzione del colore"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Riduci la luminosità"</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="4228997042855695090">"Tieni premuti entrambi i tasti del volume per tre secondi per utilizzare <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -1881,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"Ingrandisci"</string>
<string name="close_button_text" msgid="10603510034455258">"Chiudi"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"Rispondi"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"Rifiuta"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Riaggancia"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"Chiamata in arrivo"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Chiamata in corso"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"Applicazione filtro a chiamata in arrivo"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> file selezionati</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> file selezionato</item>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index f104d442d154..9595da6f3871 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -585,6 +585,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"במכשיר זה אין חיישן טביעות אצבע."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"החיישן מושבת באופן זמני."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"אצבע <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"יש להשתמש בטביעת האצבע כדי להמשיך"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"סמל טביעת אצבע"</string>
@@ -1708,6 +1709,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"השתמש בקיצור הדרך"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"היפוך צבעים"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"תיקון צבעים"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"הפחתה של עוצמת הבהירות"</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="4228997042855695090">"יש ללחוץ לחיצה ארוכה על שני לחצני עוצמת הקול למשך שלוש שניות כדי להשתמש בשירות <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -1942,6 +1944,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"הגדל"</string>
<string name="close_button_text" msgid="10603510034455258">"סגירה"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"תשובה"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"דחייה"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"ניתוק"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"שיחה נכנסת"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"שיחה פעילה"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"סינון שיחה נכנסת"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="two">בחרת <xliff:g id="COUNT_1">%1$d</xliff:g></item>
<item quantity="many">בחרת <xliff:g id="COUNT_1">%1$d</xliff:g></item>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 69822ac67fb5..dd3667edd022 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -203,7 +203,7 @@
<string name="sensor_notification_service" msgid="7474531979178682676">"センサー通知サービス"</string>
<string name="twilight_service" msgid="8964898045693187224">"トワイライト サービス"</string>
<string name="offline_location_time_zone_detection_service_attribution" msgid="303754195048744816">"Time Zone Detector(未接続)"</string>
- <string name="gnss_time_update_service" msgid="9039489496037616095">"GNSS Time Update Service"</string>
+ <string name="gnss_time_update_service" msgid="9039489496037616095">"GNSS 時間アップデートサービス"</string>
<string name="factory_reset_warning" msgid="6858705527798047809">"デバイスのデータが消去されます"</string>
<string name="factory_reset_message" msgid="2657049595153992213">"管理アプリを使用できません。デバイスのデータはこれから消去されます。\n\nご不明な点がある場合は、組織の管理者にお問い合わせください。"</string>
<string name="printing_disabled_by" msgid="3517499806528864633">"「<xliff:g id="OWNER_APP">%s</xliff:g>」により印刷は無効にされています。"</string>
@@ -579,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"このデバイスには指紋認証センサーがありません。"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"センサーが一時的に無効になっています。"</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"指紋 <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"続行するには指紋認証を使用してください"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"指紋アイコン"</string>
@@ -1664,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"ショートカットを使用"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"色反転"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"色補正"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"明るさを下げる"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"音量ボタンを長押ししました。<xliff:g id="SERVICE_NAME">%1$s</xliff:g> が ON になりました。"</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"音量ボタンを長押ししました。<xliff:g id="SERVICE_NAME">%1$s</xliff:g> が OFF になりました。"</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> を使用するには、音量大と音量小の両方のボタンを 3 秒間長押ししてください"</string>
@@ -1880,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"最大化"</string>
<string name="close_button_text" msgid="10603510034455258">"閉じる"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"応答"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"拒否"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"通話終了"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"着信"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"通話中"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"着信をスクリーニング中"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>件選択済み</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g>件選択済み</item>
@@ -2060,9 +2068,9 @@
<string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"電源ダイアログ"</string>
<string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"ロック画面"</string>
<string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"スクリーンショット"</string>
- <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"画面上のユーザー補助のショートカット"</string>
- <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"画面上のユーザー補助のショートカットの選択メニュー"</string>
- <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"ユーザー補助のショートカット"</string>
+ <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"画面上のユーザー補助機能のショートカット"</string>
+ <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"画面上のユーザー補助機能のショートカットの選択メニュー"</string>
+ <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"ユーザー補助機能のショートカット"</string>
<string name="accessibility_freeform_caption" msgid="8377519323496290122">"<xliff:g id="APP_NAME">%1$s</xliff:g> のキャプション バーです。"</string>
<string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> は RESTRICTED バケットに移動しました。"</string>
<string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index 6a7d563c2dc7..b8454983ed2f 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -579,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ამ მოწყობილობას არ აქვს თითის ანაბეჭდის სენსორი."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"სენსორი დროებით გათიშულია."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"თითი <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"გასაგრძელებლად გამოიყენეთ თქვენი თითის ანაბეჭდი"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"თითის ანაბეჭდის ხატულა"</string>
@@ -1664,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"მალსახმობის გამოყენება"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"ფერთა ინვერსია"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"ფერთა კორექცია"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"სიკაშკაშის შემცირება"</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="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> რომ გამოიყენოთ, დააჭირეთ ხმის ორივე ღილაკზე 3 წამის განმავლობაში"</string>
@@ -1880,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"მაქსიმალური ზომა"</string>
<string name="close_button_text" msgid="10603510034455258">"დახურვა"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"პასუხი"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"უარყოფა"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"გათიშვა"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"შემომავალი ზარი"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"მიმდინარე ზარი"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"შემომავალი ზარების გაცხრილვა"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> შერჩეული</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> შერჩეული</item>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index aec2312c0a21..5cb4f755578f 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -148,8 +148,7 @@
<string name="wfc_mode_wifi_only_summary" msgid="104951993894678665">"Тек Wi-Fi"</string>
<!-- no translation found for crossSimFormat_spn (9125246077491634262) -->
<skip />
- <!-- no translation found for crossSimFormat_spn_cross_sim_calling (5620807020002879057) -->
- <skip />
+ <string name="crossSimFormat_spn_cross_sim_calling" msgid="5620807020002879057">"<xliff:g id="SPN">%s</xliff:g> Қосалқы қоңырау шалу"</string>
<string name="cfTemplateNotForwarded" msgid="862202427794270501">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Басқа нөмірге бағытталмады"</string>
<string name="cfTemplateForwarded" msgid="9132506315842157860">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
<string name="cfTemplateForwardedTime" msgid="735042369233323609">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g> <xliff:g id="TIME_DELAY">{2}</xliff:g> секундтан кейін"</string>
@@ -580,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Бұл құрылғыда саусақ ізін оқу сканері жоқ."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Датчик уақытша өшірулі."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g> саусағы"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Жалғастыру үшін саусақ ізін пайдаланыңыз."</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Саусақ ізі белгішесі"</string>
@@ -1665,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Төте жолды пайдалану"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Түстер инверсиясы"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Түсті түзету"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Жарықтығын азайту"</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="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> қызметін пайдалану үшін дыбыс деңгейін реттейтін екі түймені де 3 секунд басып тұрыңыз"</string>
@@ -1881,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"Жазу"</string>
<string name="close_button_text" msgid="10603510034455258">"Жабу"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"Жауап"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"Қабылдамау"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Тұтқаны қою"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"Кіріс қоңырау"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Қоңырау"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"Келген қоңырауды сүзу"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> таңдалды</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> таңдалды</item>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index d1400b9d17ff..d0093115924e 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -579,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ឧបករណ៍នេះ​មិនមាន​ឧបករណ៍ចាប់​ស្នាមម្រាមដៃទេ។"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"បានបិទ​ឧបករណ៍​ចាប់សញ្ញាជា​បណ្តោះអាសន្ន។"</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"ម្រាមដៃ <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"ប្រើ​ស្នាមម្រាមដៃ​របស់អ្នក ដើម្បីបន្ត"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"រូបស្នាមម្រាមដៃ"</string>
@@ -1108,7 +1109,7 @@
<string name="cut" msgid="2561199725874745819">"កាត់"</string>
<string name="copy" msgid="5472512047143665218">"ចម្លង"</string>
<string name="failed_to_copy_to_clipboard" msgid="725919885138539875">"មិនអាច​ចម្លងទៅ​អង្គចងចាំទេ"</string>
- <string name="paste" msgid="461843306215520225">"បិទ​ភ្ជាប់"</string>
+ <string name="paste" msgid="461843306215520225">"ដាក់ចូល"</string>
<string name="paste_as_plain_text" msgid="7664800665823182587">"បិទភ្ជាប់ជាអត្ថបទធម្មតា"</string>
<string name="replace" msgid="7842675434546657444">"ជំនួស..."</string>
<string name="delete" msgid="1514113991712129054">"លុប"</string>
@@ -1664,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"ប្រើប្រាស់​ផ្លូវកាត់"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"បញ្ច្រាស​ពណ៌"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"ការ​កែ​ពណ៌"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"បន្ថយពន្លឺ"</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="4228997042855695090">"ចុចគ្រាប់ចុច​កម្រិត​សំឡេងទាំងពីរ​ឱ្យជាប់រយៈពេលបីវិនាទី ដើម្បីប្រើ <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -1880,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"ពង្រីក"</string>
<string name="close_button_text" msgid="10603510034455258">"បិទ"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>៖ <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"ឆ្លើយ"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"បដិសេធ"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"ដាក់​ចុះ"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"ការ​ហៅ​ចូល"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"ការ​ហៅដែលកំពុងដំណើរការ"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"កំពុងពិនិត្យការ​ហៅ​ចូល"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="other">បានជ្រើស <xliff:g id="COUNT_1">%1$d</xliff:g></item>
<item quantity="one">បានជ្រើស <xliff:g id="COUNT_0">%1$d</xliff:g></item>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index 32e3c4d98578..48684866ffdc 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -579,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ಈ ಸಾಧನವು ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಸೆನ್ಸರ್‌‌ ಅನ್ನು ಹೊಂದಿಲ್ಲ."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ಸೆನ್ಸಾರ್ ಅನ್ನು ತಾತ್ಕಾಲಿಕವಾಗಿ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"ಫಿಂಗರ್ <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"ಮುಂದುವರಿಸಲು ನಿಮ್ಮ ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಬಳಸಿ"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಐಕಾನ್"</string>
@@ -1664,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"ಶಾರ್ಟ್‌ಕಟ್ ಬಳಸಿ"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"ಬಣ್ಣ ವಿಲೋಮ"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"ಬಣ್ಣ ತಿದ್ದುಪಡಿ"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"ಪ್ರಖರತೆಯನ್ನು ಕಡಿಮೆ ಮಾಡಿ"</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="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> ಅನ್ನು ಬಳಸಲು ಎರಡೂ ಧ್ವನಿ ಕೀಗಳನ್ನು ಮೂರು ಸೆಕೆಂಡ್‌ಗಳ ಕಾಲ ಒತ್ತಿ ಹಿಡಿದುಕೊಳ್ಳಿ"</string>
@@ -1880,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"ಹಿಗ್ಗಿಸು"</string>
<string name="close_button_text" msgid="10603510034455258">"ಮುಚ್ಚು"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"ಉತ್ತರಿಸಿ"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"ನಿರಾಕರಿಸಿ"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"ಹ್ಯಾಂಗ್ ಅಪ್"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"ಒಳಬರುವ ಕರೆ"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"ಚಾಲ್ತಿಯಲ್ಲಿರುವ ಕರೆ"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"ಒಳಬರುವ ಕರೆಯನ್ನು ಸ್ಕ್ರೀನ್ ಮಾಡಲಾಗುತ್ತಿದೆ"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ಆಯ್ಕೆಮಾಡಲಾಗಿದೆ</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ಆಯ್ಕೆಮಾಡಲಾಗಿದೆ</item>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 34074312e70d..6149e4b048ef 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -579,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"기기에 지문 센서가 없습니다."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"센서가 일시적으로 사용 중지되었습니다."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"손가락 <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"계속하려면 지문을 사용하세요."</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"지문 아이콘"</string>
@@ -1664,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"단축키 사용"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"색상 반전"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"색상 보정"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"밝기 낮추기"</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="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> 서비스를 사용하려면 두 볼륨 키를 3초 동안 길게 누르세요"</string>
@@ -1880,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"최대화"</string>
<string name="close_button_text" msgid="10603510034455258">"닫기"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"답변"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"거절"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"전화 끊기"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"수신 전화"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"진행 중인 통화"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"수신 전화 검사 중"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>개 선택됨</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g>개 선택됨</item>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index 9a84d0a985e6..e2f539728f25 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -298,7 +298,7 @@
<string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Батареянын кубаты жана трафиктин көлөмү жөнүндө билүү үчүн таптап коюңуз"</string>
<string name="foreground_service_multiple_separator" msgid="5002287361849863168">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="8974401416068943888">"Коопсуз режим"</string>
- <string name="android_system_label" msgid="5974767339591067210">"Android тутуму"</string>
+ <string name="android_system_label" msgid="5974767339591067210">"Android системасы"</string>
<string name="user_owner_label" msgid="8628726904184471211">"Жеке профилге которулуу"</string>
<string name="managed_profile_label" msgid="7316778766973512382">"Жумуш профилине которулуу"</string>
<string name="permgrouplab_contacts" msgid="4254143639307316920">"Байланыштар"</string>
@@ -332,7 +332,7 @@
<string name="capability_title_canControlMagnification" msgid="7701572187333415795">"Көрүнүштү чоңойтуп кичирейтет"</string>
<string name="capability_desc_canControlMagnification" msgid="2206586716709254805">"Экрандагы сүрөттү тууралап жайгаштырып, өлчөмүн өзгөртөт."</string>
<string name="capability_title_canPerformGestures" msgid="9106545062106728987">"Жаңсоолорду аткаруу"</string>
- <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Таптап, серпип, чымчып жана башка жаңсоолорду аткара алат."</string>
+ <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Таптап, сүрүп, чымчып жана башка жаңсоолорду аткара алат."</string>
<string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Манжа изинин жаңсоолору"</string>
<string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Түзмөктөгү манжа изинин сенсорунда жасалган жаңсоолорду жаздырып алат."</string>
<string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Скриншот тартып алуу"</string>
@@ -579,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Бул түзмөктө манжа изинин сенсору жок."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Сенсор убактылуу өчүрүлгөн."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g>-манжа"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Улантуу үчүн манжаңыздын изин колдонуңуз"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Манжа изинин сүрөтчөсү"</string>
@@ -886,7 +887,7 @@
<string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="2203704707679895487">"Сиз телефонду бөгөттөн чыгарууга <xliff:g id="NUMBER">%d</xliff:g> жолу туура эмес аракет кылдыңыз. Телефон баштапкы абалына келтирилет."</string>
<string name="lockscreen_too_many_failed_attempts_countdown" msgid="6807200118164539589">"<xliff:g id="NUMBER">%d</xliff:g> секунддан кийин кайталаңыз."</string>
<string name="lockscreen_forgot_pattern_button_text" msgid="8362442730606839031">"Сүрөт үлгүсүн унутуп калдыңызбы?"</string>
- <string name="lockscreen_glogin_forgot_pattern" msgid="9218940117797602518">"Каттоо эсеби менен кулпусун ачуу"</string>
+ <string name="lockscreen_glogin_forgot_pattern" msgid="9218940117797602518">"Аккаунт менен кулпусун ачуу"</string>
<string name="lockscreen_glogin_too_many_attempts" msgid="3775904917743034195">"Өтө көп үлгү киргизүү аракети болду"</string>
<string name="lockscreen_glogin_instructions" msgid="4695162942525531700">"Бөгөттөн чыгарыш үчүн, Google эсебиңиз менен кириңиз."</string>
<string name="lockscreen_glogin_username_hint" msgid="6916101478673157045">"Колдонуучунун аты (электрондук почта)"</string>
@@ -1664,12 +1665,13 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Кыска жолду колдонуу"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Түстү инверсиялоо"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Түсүн тууралоо"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Экрандын жарыктыгын төмөндөтүү"</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="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> кызматын колдонуу үчүн үнүн чоңойтуп/кичирейтүү баскычтарын үч секунд коё бербей басып туруңуз"</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Атайын мүмкүнчүлүктөр баскычын таптаганыңызда иштей турган функцияны тандаңыз:"</string>
- <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Атайын мүмкүнчүлүктөр жаңсоосу үчүн функцияны тандаңыз (эки манжаңыз менен экрандын ылдый жагынан өйдө карай сүрүңүз):"</string>
- <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Атайын мүмкүнчүлүктөр жаңсоосу аркылуу иштетиле турган функцияны тандаңыз (үч манжаңыз менен экрандын ылдый жагынан өйдө карай сүрүңүз):"</string>
+ <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_3finger_instructional_text" msgid="3425123684990193765">"Башка функцияга которулуу үчүн үч манжаңыз менен экранды өйдө сүрүп, кармап туруңуз."</string>
@@ -1880,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"Чоңойтуу"</string>
<string name="close_button_text" msgid="10603510034455258">"Жабуу"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"Жооп берүү"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"Четке кагуу"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Чалууну бүтүрүү"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"Кирүүчү чалуу"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Учурдагы чалуу"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"Кирүүчү чалууну иргөө"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> тандалды</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> тандалды</item>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index 9977f9fca122..c41c4111e87c 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -148,8 +148,7 @@
<string name="wfc_mode_wifi_only_summary" msgid="104951993894678665">"Wi​-Fi ເທົ່າ​ນັ້ນ"</string>
<!-- no translation found for crossSimFormat_spn (9125246077491634262) -->
<skip />
- <!-- no translation found for crossSimFormat_spn_cross_sim_calling (5620807020002879057) -->
- <skip />
+ <string name="crossSimFormat_spn_cross_sim_calling" msgid="5620807020002879057">"<xliff:g id="SPN">%s</xliff:g> ການໂທສຳຮອງ"</string>
<string name="cfTemplateNotForwarded" msgid="862202427794270501">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: ບໍ່ຖືກສົ່ງຕໍ່"</string>
<string name="cfTemplateForwarded" msgid="9132506315842157860">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
<string name="cfTemplateForwardedTime" msgid="735042369233323609">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g> ຫຼັງຈາກ <xliff:g id="TIME_DELAY">{2}</xliff:g> ວິນາທີ"</string>
@@ -580,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ອຸປະກອນນີ້ບໍ່ມີເຊັນເຊີລາຍນິ້ວມື."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ປິດການເຮັດວຽກຂອງເຊັນເຊີໄວ້ຊົ່ວຄາວແລ້ວ."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"ນີ້ວ​ມື <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"ໃຊ້​ລາຍ​ນີ້ວ​ມື​ຂອງ​ທ່ານ​ເພື່ອ​ສືບ​ຕໍ່"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"ໄອຄອນລາຍນິ້ວມື"</string>
@@ -1665,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"ໃຊ້ປຸ່ມລັດ"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"ການປີ້ນສີ"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"ການແກ້ໄຂຄ່າສີ"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"ຫຼຸດຄວາມສະຫວ່າງ"</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="4228997042855695090">"ກົດປຸ່ມສຽງທັງສອງພ້ອມກັນຄ້າງໄວ້ສາມວິນາທີເພື່ອໃຊ້ <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -1881,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"ຂະຫຍາຍອອກ"</string>
<string name="close_button_text" msgid="10603510034455258">"ປິດ"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"ຮັບສາຍ"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"ປະຕິເສດ"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"ວາງສາຍ"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"ສາຍໂທເຂົ້າ"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"ສາຍໂທອອກ"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"ກຳລັງກວດສອບສາຍໂທເຂົ້າ"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ຖືກເລືອກ​ແລ້ວ</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ຖືກເລືອກ​ແລ້ວ</item>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 5f72e07a6959..b9b2131341b4 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -585,6 +585,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Šiame įrenginyje nėra kontrolinio kodo jutiklio."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Jutiklis laikinai išjungtas."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g> pirštas"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Naudokite kontrolinį kodą, kad galėtumėte tęsti"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Piršto antspaudo piktograma"</string>
@@ -1708,6 +1709,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Naudoti spartųjį klavišą"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Spalvų inversija"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Spalvų taisymas"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Šviesumo mažinimas"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Laikomi garsumo klavišai. „<xliff:g id="SERVICE_NAME">%1$s</xliff:g>“ įjungta."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Laikomi garsumo klavišai. „<xliff:g id="SERVICE_NAME">%1$s</xliff:g>“ išjungta."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Jei norite naudoti „<xliff:g id="SERVICE_NAME">%1$s</xliff:g>“, paspauskite abu garsumo klavišus ir palaikykite tris sekundes"</string>
@@ -1942,6 +1944,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"Padidinti"</string>
<string name="close_button_text" msgid="10603510034455258">"Uždaryti"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"Atsakyti"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"Atmesti"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Baigti pok."</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"Gaunamasis skambutis"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Vykstantis skambutis"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"Gaunamojo skambučio tikrinimas"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="one">Pasir. <xliff:g id="COUNT_1">%1$d</xliff:g> elem.</item>
<item quantity="few">Pasir. <xliff:g id="COUNT_1">%1$d</xliff:g> elem.</item>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 37e417fa6a56..803574fe85b8 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -582,6 +582,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Šajā ierīcē nav pirksta nospieduma sensora."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensors ir īslaicīgi atspējots."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g>. pirksts"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Lai turpinātu, izmantojiet pirksta nospiedumu"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Pirksta nospieduma ikona"</string>
@@ -1686,6 +1687,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Izmantot saīsni"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Krāsu inversija"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Krāsu korekcija"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Spilgtuma samazināšana"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Turējāt nospiestas skaļuma pogas. Pakalpojums <xliff:g id="SERVICE_NAME">%1$s</xliff:g> tika ieslēgts."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Turējāt nospiestas skaļuma pogas. Pakalpojums <xliff:g id="SERVICE_NAME">%1$s</xliff:g> tika izslēgts."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Lai izmantotu pakalpojumu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, nospiediet abus skaļuma taustiņus un turiet tos trīs sekundes."</string>
@@ -1911,6 +1913,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"Maksimizēt"</string>
<string name="close_button_text" msgid="10603510034455258">"Aizvērt"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"Atbildēt"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"Noraidīt"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Pārtraukt"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"Ienākošais zvans"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Pašreizējais zvans"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"Ienākošā zvana filtrēšana"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="zero"><xliff:g id="COUNT_1">%1$d</xliff:g> atlasīti</item>
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> atlasīts</item>
diff --git a/core/res/res/values-mcc310-mnc950-si/strings.xml b/core/res/res/values-mcc310-mnc950-si/strings.xml
new file mode 100644
index 000000000000..26fe4ac265a3
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc950-si/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, 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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="mmcc_imsi_unknown_in_hlr" msgid="615419724607901560">"SIM MM#2 ප්‍රතිපාදනය නොකරයි"</string>
+ <string name="mmcc_illegal_ms" msgid="7801541624846497489">"SIM MM#3 ඉඩ නොදේ"</string>
+ <string name="mmcc_illegal_me" msgid="7066936962628406316">"දුරකථනය MM#6 ඉඩ නොදේ"</string>
+</resources>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index 5666cc23f2be..dd48273acca0 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -579,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Уредов нема сензор за отпечатоци."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Сензорот е привремено оневозможен."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Прст <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Користете го отпечатокот за да продолжите"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Икона за отпечатоци"</string>
@@ -1664,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Користи кратенка"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Инверзија на бои"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Корекција на бои"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Намалете ја осветленоста"</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="4228997042855695090">"Притиснете ги и задржете ги двете копчиња за јачина на звукот во траење од три секунди за да користите <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -1880,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"Зголеми"</string>
<string name="close_button_text" msgid="10603510034455258">"Затвори"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"Одговори"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"Одбиј"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Спушти"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"Дојдовен повик"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Тековен повик"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"Проверка на дојдовен повик"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> е избрана</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> се избрани</item>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index e0d4b0179624..c2576fe92fb6 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -148,8 +148,7 @@
<string name="wfc_mode_wifi_only_summary" msgid="104951993894678665">"വൈഫൈ മാത്രം"</string>
<!-- no translation found for crossSimFormat_spn (9125246077491634262) -->
<skip />
- <!-- no translation found for crossSimFormat_spn_cross_sim_calling (5620807020002879057) -->
- <skip />
+ <string name="crossSimFormat_spn_cross_sim_calling" msgid="5620807020002879057">"<xliff:g id="SPN">%s</xliff:g> ബാക്കപ്പ് കോളിംഗ്"</string>
<string name="cfTemplateNotForwarded" msgid="862202427794270501">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: കൈമാറിയില്ല"</string>
<string name="cfTemplateForwarded" msgid="9132506315842157860">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
<string name="cfTemplateForwardedTime" msgid="735042369233323609">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="TIME_DELAY">{2}</xliff:g> നിമിഷത്തിനുശേഷം <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -580,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ഈ ഉപകരണത്തിൽ ഫിംഗർപ്രിന്റ് സെൻസറില്ല."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"സെൻസർ താൽക്കാലികമായി പ്രവർത്തനരഹിതമാക്കി."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"കൈവിരൽ <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"തുടരുന്നതിന് നിങ്ങളുടെ ഫിംഗർപ്രിന്റ് ഉപയോഗിക്കുക"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"ഫിംഗർപ്രിന്റ് ഐക്കൺ"</string>
@@ -1665,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"കുറുക്കുവഴി ഉപയോഗിക്കുക"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"വർണ്ണ വിപര്യയം"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"നിറം ക്രമീകരിക്കൽ"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"തെളിച്ചം കുറയ്ക്കുക"</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="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> ഉപയോഗിക്കാൻ, രണ്ട് വോളിയം കീകളും മൂന്ന് സെക്കൻഡ് അമർത്തിപ്പിടിക്കുക"</string>
@@ -1881,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"വലുതാക്കുക"</string>
<string name="close_button_text" msgid="10603510034455258">"അവസാനിപ്പിക്കുക"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"മറുപടി നൽകുക"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"നിരസിക്കുക"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"കോൾ നിർത്തുക"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"ഇൻകമിംഗ് കോൾ"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"സജീവമായ കോൾ"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"ഇൻകമിംഗ് കോൾ സ്‌ക്രീൻ ചെയ്യൽ"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> എണ്ണം തിരഞ്ഞെടുത്തു</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> എണ്ണം തിരഞ്ഞെടുത്തു</item>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index 891ac47191e1..786f722132fc 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -325,7 +325,7 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"таны биеийн байдлын талаарх мэдрэгч бүхий өгөгдөлд нэвтрэх"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Цонхны агуулгыг авах"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Таны харилцан үйлчлэх цонхны контентоос шалгах."</string>
- <string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Хүрч танихыг асаах"</string>
+ <string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Хүрэлтээр сонсохыг асаах"</string>
<string name="capability_desc_canRequestTouchExploration" msgid="4394677060796752976">"Товшсон зүйлсийг чангаар хэлэх ба дэлгэцийг дохио ашиглан таних боломжтой."</string>
<string name="capability_title_canRequestFilterKeyEvents" msgid="2772371671541753254">"Бичсэн текстээ ажиглах"</string>
<string name="capability_desc_canRequestFilterKeyEvents" msgid="2381315802405773092">"Кредит картын дугаар болон нууц үг зэрэг хувийн датаг агуулж байна."</string>
@@ -579,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Энэ төхөөрөмжид хурууны хээ мэдрэгч алга."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Мэдрэгчийг түр хугацаанд идэвхгүй болгосон."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Хурууны хээ <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Үргэлжлүүлэхийн тулд хурууны хээгээ ашиглаарай"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Хурууны хээний дүрс"</string>
@@ -1002,9 +1003,9 @@
<string name="searchview_description_clear" msgid="1989371719192982900">"Асуулгыг цэвэрлэх"</string>
<string name="searchview_description_submit" msgid="6771060386117334686">"Асуулгыг илгээх"</string>
<string name="searchview_description_voice" msgid="42360159504884679">"Дуут хайлт"</string>
- <string name="enable_explore_by_touch_warning_title" msgid="5095399706284943314">"Хүрч хайх функцийг идэвхтэй болгох уу?"</string>
- <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="1037295476738940824">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> нь Хүрч танихыг идэвхжүүлэхийг шаардаж байна. Хүрч таних идэвхжсэн үед та хуруун доороо юу байгааг сонсох, тайлбарыг харах боломжтой ба таблеттайгаа дохиогоор харилцах боломжтой."</string>
- <string name="enable_explore_by_touch_warning_message" product="default" msgid="4312979647356179250">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> нь Хүрч танихыг идэвхжүүлэхийг шаардаж байна. Хүрч таних идэвхжсэн тохиолдолд та хуруун доороо юу байгааг сонсох, тайлбарыг харах боломжтой ба утастайгаа дохиогоор харилцах боломжтой."</string>
+ <string name="enable_explore_by_touch_warning_title" msgid="5095399706284943314">"Хүрэлтээр сонсохыг идэвхжүүлэх үү?"</string>
+ <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="1037295476738940824">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> нь Хүрэлтээр сонсохыг идэвхжүүлэхийг шаардаж байна. Хүрэлтээр сонсох идэвхжсэн үед та хуруун доороо юу байгааг сонсох, тайлбарыг харах боломжтой ба таблеттайгаа дохиогоор харилцах боломжтой."</string>
+ <string name="enable_explore_by_touch_warning_message" product="default" msgid="4312979647356179250">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> нь Хүрэлтээр сонсохыг идэвхжүүлэхийг шаардаж байна. Хүрэлтээр сонсох идэвхжсэн тохиолдолд та хуруун доороо юу байгааг сонсох, тайлбарыг харах боломжтой ба утастайгаа дохиогоор харилцах боломжтой."</string>
<string name="oneMonthDurationPast" msgid="4538030857114635777">"1 сарын өмнө"</string>
<string name="beforeOneMonthDurationPast" msgid="8315149541372065392">"1 сарын өмнө"</string>
<plurals name="last_num_days" formatted="false" msgid="687443109145393632">
@@ -1664,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Товчлол ашиглах"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Өнгө хувиргалт"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Өнгөний засвар"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Гэрэлтүүлгийг багасгах"</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="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>-г ашиглахын тулд дууны түвшнийг ихэсгэх, багасгах түлхүүрийг 3 секундийн турш зэрэг дарна уу"</string>
@@ -1871,7 +1873,7 @@
<string name="notification_alerted_content_description" msgid="6139691253611265992">"Мэдэгдсэн"</string>
<string name="expand_button_content_description_collapsed" msgid="3873368935659010279">"Дэлгэх"</string>
<string name="expand_button_content_description_expanded" msgid="7484217944948667489">"Буулгах"</string>
- <string name="expand_action_accessibility" msgid="1947657036871746627">"унтраах/асаах өргөтгөл"</string>
+ <string name="expand_action_accessibility" msgid="1947657036871746627">"асаах/унтраах өргөтгөл"</string>
<string name="usb_midi_peripheral_name" msgid="490523464968655741">"Андройд USB Peripheral Port"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7557148557088787741">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="2836276258480904434">"USB Peripheral Port"</string>
@@ -1880,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"Томруулах"</string>
<string name="close_button_text" msgid="10603510034455258">"Хаах"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"Хариулах"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"Татгалзах"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Таслах"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"Ирсэн дуудлага"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Дуудлага хийгдэж байна"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"Ирсэн дуудлагыг харуулж байна"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> сонгосон</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> сонгосон</item>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index d57c4c1d0d05..c1b8088a870e 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -148,8 +148,7 @@
<string name="wfc_mode_wifi_only_summary" msgid="104951993894678665">"केवळ वाय-फाय"</string>
<!-- no translation found for crossSimFormat_spn (9125246077491634262) -->
<skip />
- <!-- no translation found for crossSimFormat_spn_cross_sim_calling (5620807020002879057) -->
- <skip />
+ <string name="crossSimFormat_spn_cross_sim_calling" msgid="5620807020002879057">"<xliff:g id="SPN">%s</xliff:g> बॅकअप कॉलिंग"</string>
<string name="cfTemplateNotForwarded" msgid="862202427794270501">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: फॉरवर्ड केला नाही"</string>
<string name="cfTemplateForwarded" msgid="9132506315842157860">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
<string name="cfTemplateForwardedTime" msgid="735042369233323609">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="TIME_DELAY">{2}</xliff:g> सेकंदांनंतर <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -580,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"या डिव्हाइसमध्ये फिंगरप्रिंट सेन्सर नाही."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"सेन्सर तात्पुरता बंद केला आहे."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g> बोट"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"पुढे सुरू ठेवण्‍यासाठी तुमची फिंगरप्रिंट वापरा"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"फिंगरप्रिंट आयकन"</string>
@@ -1665,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"शॉर्टकट वापरा"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"रंगांची उलटापालट"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"रंग सुधारणा"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"ब्राइटनेस कमी करा"</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="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> वापरण्यासाठी दोन्ही व्हॉल्युम की तीन सेकंद दाबा आणि धरून ठेवा"</string>
@@ -1881,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"मोठे करा"</string>
<string name="close_button_text" msgid="10603510034455258">"बंद करा"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"उत्तर द्या"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"नकार द्या"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"कॉल बंद करा"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"इनकमिंग कॉल"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"सुरू असलेला कॉल"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"इनकमिंग कॉल स्क्रीन करत आहे"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> निवडले</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> निवडला</item>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index ec0aa5d6fae6..5e26682fd664 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -325,7 +325,7 @@
<string name="permgroupdesc_sensors" msgid="2610631290633747752">"akses data penderia tentang tanda vital anda"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Dapatkan kembali kandungan tetingkap"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Periksa kandungan tetingkap yang berinteraksi dengan anda."</string>
- <string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Hidupkan Jelajah melalui Sentuhan"</string>
+ <string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"Hidupkan Teroka melalui Sentuhan"</string>
<string name="capability_desc_canRequestTouchExploration" msgid="4394677060796752976">"Item yang diketik akan dituturkan dengan lantang dan skrin boleh dijelajah menggunakan gerak isyarat."</string>
<string name="capability_title_canRequestFilterKeyEvents" msgid="2772371671541753254">"Perhatikan teks yang anda taip"</string>
<string name="capability_desc_canRequestFilterKeyEvents" msgid="2381315802405773092">"Termasuk data peribadi seperti nombor kad kredit dan kata laluan."</string>
@@ -579,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Peranti ini tiada penderia cap jari."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Penderia dilumpuhkan sementara."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Jari <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Gunakan cap jari anda untuk teruskan"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ikon cap jari"</string>
@@ -1002,9 +1003,9 @@
<string name="searchview_description_clear" msgid="1989371719192982900">"Pertanyaan jelas"</string>
<string name="searchview_description_submit" msgid="6771060386117334686">"Serah pertanyaan"</string>
<string name="searchview_description_voice" msgid="42360159504884679">"Carian suara"</string>
- <string name="enable_explore_by_touch_warning_title" msgid="5095399706284943314">"Dayakan Jelajah melalui Sentuhan?"</string>
- <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="1037295476738940824">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> ingin mendayakan Jelajah melalui Sentuhan. Apabila Jelajah melalui Sentuhan didayakan, anda boleh mendengar atau melihat penerangan tentang apa di bawah jari anda atau melakukan gerak isyarat untuk berinteraksi dengan tablet."</string>
- <string name="enable_explore_by_touch_warning_message" product="default" msgid="4312979647356179250">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> ingin mendayakan Jelajah melalui Sentuhan. Apabila Jelajah melalui Sentuhan didayakan, anda boleh mendengar atau melihat penerangan tentang apa di bawah jari anda atau melakukan gerak isyarat untuk berinteraksi dengan telefon."</string>
+ <string name="enable_explore_by_touch_warning_title" msgid="5095399706284943314">"Dayakan Teroka melalui Sentuhan?"</string>
+ <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="1037295476738940824">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> ingin mendayakan Teroka melalui Sentuhan. Apabila Teroka melalui Sentuhan didayakan, anda boleh mendengar atau melihat penerangan tentang apa-apa di bawah jari anda atau melakukan gerak isyarat untuk berinteraksi dengan tablet."</string>
+ <string name="enable_explore_by_touch_warning_message" product="default" msgid="4312979647356179250">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> ingin mendayakan Teroka melalui Sentuhan. Apabila Teroka melalui Sentuhan didayakan, anda boleh mendengar atau melihat penerangan tentang apa-apa di bawah jari anda atau melakukan gerak isyarat untuk berinteraksi dengan telefon."</string>
<string name="oneMonthDurationPast" msgid="4538030857114635777">"1 bulan yang lalu"</string>
<string name="beforeOneMonthDurationPast" msgid="8315149541372065392">"Sebelum 1 bulan yang lalu"</string>
<plurals name="last_num_days" formatted="false" msgid="687443109145393632">
@@ -1664,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Gunakan Pintasan"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Penyongsangan Warna"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Pembetulan Warna"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Kurangkan Kecerahan"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Kekunci kelantangan ditahan. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> dihidupkan."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Kekunci kelantangan ditahan. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> dimatikan."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Tekan dan tahan kedua-dua kekunci kelantangan selama tiga saat untuk menggunakan <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -1880,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"Maksimumkan"</string>
<string name="close_button_text" msgid="10603510034455258">"Tutup"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"Jawapan"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"Tolak"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Tamatkan Panggilan"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"Panggilan masuk"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Panggilan sedang berlangsung"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"Menyaring panggilan masuk"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> dipilih</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> dipilih</item>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index 7b4a430fc1bb..aff554916517 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -579,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ဤစက်တွင် လက်ဗွေအာရုံခံကိရိယာ မရှိပါ။"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"အာရုံခံကိရိယာကို ယာယီပိတ်ထားသည်။"</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"လက်ချောင်း <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"ရှေ့ဆက်ရန် သင့်လက်ဗွေကို သုံးပါ"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"လက်ဗွေ သင်္ကေတ"</string>
@@ -1664,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"ဖြတ်လမ်းလင့်ခ်ကို သုံးရန်"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"အရောင် ပြောင်းပြန်လှန်ခြင်း"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"အရောင်ပြင်ဆင်ခြင်း"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"တောက်ပမှုကို လျှော့ခြင်း"</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="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> ကို သုံးရန် အသံအတိုးအလျှော့ ခလုတ်နှစ်ခုလုံးကို သုံးစက္ကန့်ကြာ ဖိထားပါ"</string>
@@ -1880,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"အများဆုံး လုပ်ပေးရန်"</string>
<string name="close_button_text" msgid="10603510034455258">"ပိတ်ရန်"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>− <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"ဖုန်းကိုင်ရန်"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"ငြင်းပယ်ရန်"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"ဖုန်းချရန်"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"အဝင်ခေါ်ဆိုမှု"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"လက်ရှိခေါ်ဆိုမှု"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"အဝင်ခေါ်ဆိုမှုကို စစ်ဆေးနေသည်"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ရွေးချယ်ပြီးပါပြီ</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ရွေးချယ်ပြီးပါပြီ</item>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 496818426714..21ca11701f08 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -579,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Denne enheten har ikke fingeravtrykkssensor."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensoren er midlertidig slått av."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Bruk fingeravtrykket ditt for å fortsette"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ikon for fingeravtrykk"</string>
@@ -1664,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Bruk snarveien"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Fargeinvertering"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Fargekorrigering"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Reduser lysstyrken"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Volumtastene holdes inne. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> er slått på."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Volumtastene holdes inne. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> er slått av."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Trykk og hold inne begge volumtastene i tre sekunder for å bruke <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -1880,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"Maksimer"</string>
<string name="close_button_text" msgid="10603510034455258">"Lukk"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g><xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"Svar"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"Avvis"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Legg på"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"Innkommende anrop"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Pågående samtale"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"Filtrerer et innkommende anrop"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> er valgt</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> er valgt</item>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 541ace80518c..09b97652bb6c 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -148,8 +148,7 @@
<string name="wfc_mode_wifi_only_summary" msgid="104951993894678665">"Wi-Fi मात्र"</string>
<!-- no translation found for crossSimFormat_spn (9125246077491634262) -->
<skip />
- <!-- no translation found for crossSimFormat_spn_cross_sim_calling (5620807020002879057) -->
- <skip />
+ <string name="crossSimFormat_spn_cross_sim_calling" msgid="5620807020002879057">"<xliff:g id="SPN">%s</xliff:g> ब्याकअप कलिङ"</string>
<string name="cfTemplateNotForwarded" msgid="862202427794270501">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: अगाडि पठाइएको छैन"</string>
<string name="cfTemplateForwarded" msgid="9132506315842157860">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
<string name="cfTemplateForwardedTime" msgid="735042369233323609">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g> पछि <xliff:g id="TIME_DELAY">{2}</xliff:g> सेकेन्ड"</string>
@@ -580,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"यो यन्त्रमा कुनै पनि फिंगरप्रिन्ट सेन्सर छैन।"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"केही समयका लागि सेन्सर असक्षम पारियो।"</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"औंला <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"जारी राख्न आफ्नो फिंगरप्रिन्ट प्रयोग गर्नुहोस्"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"फिंगरप्रिन्ट आइकन"</string>
@@ -1665,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"सर्टकट प्रयोग गर्नुहोस्"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"रङ्ग उल्टाउने सुविधा"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"रङ्ग सच्याउने सुविधा"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"स्क्रिनको चमक घटाउनुहोस्"</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="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> प्रयोग गर्न दुवै भोल्युम कुञ्जीहरूलाई तीन सेकेन्डसम्म थिचिराख्नुहोस्"</string>
@@ -1881,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"ठुलो बनाउनुहोस्"</string>
<string name="close_button_text" msgid="10603510034455258">"बन्द गर्नुहोस्"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"कलको जवाफ दिनु…"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"अस्वीकार गर्नुहोस्"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"फोन राख्नुहोस्"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"आगमन कल"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"भइरहेको कल"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"आगमन कल जाँचिँदै छ"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> चयन गरियो</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> चयन गरियो</item>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 7f23cbbbb6dd..6d1b8e77ed9b 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -515,9 +515,9 @@
<string name="permdesc_changeWifiMulticastState" product="tv" msgid="1336952358450652595">"Hiermee kan de app pakketten ontvangen die via multicastadressen naar alle apparaten in een wifi-netwerk worden verzonden, niet alleen naar je Android TV-apparaat. Het stroomgebruik ligt hierbij hoger dan in de niet-multicastmodus."</string>
<string name="permdesc_changeWifiMulticastState" product="default" msgid="8296627590220222740">"Hiermee kan de app pakketten ontvangen die via multicastadressen naar alle apparaten in een wifi-netwerk worden verzonden, niet alleen naar je telefoon. Het stroomgebruik ligt hierbij hoger dan in de niet-multicastmodus."</string>
<string name="permlab_bluetoothAdmin" msgid="6490373569441946064">"Bluetooth-instellingen openen"</string>
- <string name="permdesc_bluetoothAdmin" product="tablet" msgid="5370837055438574863">"Hiermee kan de app de lokale bluetooth-tablet configureren en externe apparaten zoeken en koppelen."</string>
- <string name="permdesc_bluetoothAdmin" product="tv" msgid="1623992984547014588">"Hiermee kan de app Bluetooth op je Android TV-apparaat configureren en externe apparaten zoeken en koppelen."</string>
- <string name="permdesc_bluetoothAdmin" product="default" msgid="7381341743021234863">"Hiermee kan de app de lokale bluetooth-telefoon configureren en externe apparaten zoeken en koppelen."</string>
+ <string name="permdesc_bluetoothAdmin" product="tablet" msgid="5370837055438574863">"Hiermee kan de app de lokale bluetooth-tablet instellen en externe apparaten zoeken en koppelen."</string>
+ <string name="permdesc_bluetoothAdmin" product="tv" msgid="1623992984547014588">"Hiermee kan de app Bluetooth op je Android TV-apparaat isntellen en externe apparaten zoeken en koppelen."</string>
+ <string name="permdesc_bluetoothAdmin" product="default" msgid="7381341743021234863">"Hiermee kan de app de lokale bluetooth-telefoon instellen en externe apparaten zoeken en koppelen."</string>
<string name="permlab_accessWimaxState" msgid="7029563339012437434">"WiMAX-verbinding maken en verbreken"</string>
<string name="permdesc_accessWimaxState" msgid="5372734776802067708">"Hiermee kan de app bepalen of WiMAX is ingeschakeld en informatie bekijken over alle WiMAX-netwerken waarmee verbinding is gemaakt."</string>
<string name="permlab_changeWimaxState" msgid="6223305780806267462">"WiMAX-status wijzigen"</string>
@@ -579,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Dit apparaat heeft geen vingerafdruksensor."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor tijdelijk uitgeschakeld."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Vinger <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Gebruik je vingerafdruk om door te gaan."</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Vingerafdruk-icoon"</string>
@@ -1346,7 +1347,7 @@
<string name="select_input_method" msgid="3971267998568587025">"Invoermethode selecteren"</string>
<string name="show_ime" msgid="6406112007347443383">"Dit op het scherm weergeven terwijl het fysieke toetsenbord actief is"</string>
<string name="hardware" msgid="1800597768237606953">"Virtueel toetsenbord tonen"</string>
- <string name="select_keyboard_layout_notification_title" msgid="4427643867639774118">"Fysiek toetsenbord configureren"</string>
+ <string name="select_keyboard_layout_notification_title" msgid="4427643867639774118">"Fysiek toetsenbord instellen"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Tik om een taal en indeling te selecteren"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1369,7 +1370,7 @@
<string name="ext_media_unmountable_notification_message" product="automotive" msgid="2274596120715020680">"Je moet het apparaat misschien opnieuw formatteren. Tik om het uit te werpen."</string>
<string name="ext_media_unsupported_notification_title" msgid="4358280700537030333">"<xliff:g id="NAME">%s</xliff:g> niet ondersteund"</string>
<string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> werkt niet"</string>
- <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"Dit apparaat biedt geen ondersteuning voor deze <xliff:g id="NAME">%s</xliff:g>. Tik om te configureren in een ondersteunde indeling."</string>
+ <string name="ext_media_unsupported_notification_message" msgid="917738524888367560">"Dit apparaat biedt geen ondersteuning voor deze <xliff:g id="NAME">%s</xliff:g>. Tik om in te stellen in een ondersteunde indeling."</string>
<string name="ext_media_unsupported_notification_message" product="tv" msgid="7744945987775645685">"Dit apparaat biedt geen ondersteuning voor deze <xliff:g id="NAME">%s</xliff:g>. Selecteer om in te stellen in een ondersteunde indeling."</string>
<string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"Je moet het apparaat misschien opnieuw formatteren"</string>
<string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g> is onverwacht verwijderd"</string>
@@ -1664,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Sneltoets gebruiken"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Kleurinversie"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Kleurcorrectie"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Helderheid verlagen"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Volumetoetsen ingedrukt gehouden. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> is ingeschakeld."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Volumetoetsen ingedrukt gehouden. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> uitgeschakeld."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Houd beide volumetoetsen drie seconden ingedrukt om <xliff:g id="SERVICE_NAME">%1$s</xliff:g> te gebruiken"</string>
@@ -1880,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"Maximaliseren"</string>
<string name="close_button_text" msgid="10603510034455258">"Sluiten"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"Beantwoorden"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"Weigeren"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Ophangen"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"Inkomend gesprek"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Actief gesprek"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"Een inkomend gesprek screenen"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> geselecteerd</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> geselecteerd</item>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index f02d1573b7b2..dc28d60ca05e 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -148,8 +148,7 @@
<string name="wfc_mode_wifi_only_summary" msgid="104951993894678665">"କେବଳ ୱାଇ-ଫାଇ"</string>
<!-- no translation found for crossSimFormat_spn (9125246077491634262) -->
<skip />
- <!-- no translation found for crossSimFormat_spn_cross_sim_calling (5620807020002879057) -->
- <skip />
+ <string name="crossSimFormat_spn_cross_sim_calling" msgid="5620807020002879057">"<xliff:g id="SPN">%s</xliff:g> ବ୍ୟାକଅପ୍ କଲିଂ"</string>
<string name="cfTemplateNotForwarded" msgid="862202427794270501">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: ଫରୱାର୍ଡ କରାଯାଇନାହିଁ"</string>
<string name="cfTemplateForwarded" msgid="9132506315842157860">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
<string name="cfTemplateForwardedTime" msgid="735042369233323609">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g> <xliff:g id="TIME_DELAY">{2}</xliff:g> ସେକେଣ୍ଡ ପରେ"</string>
@@ -580,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ଏହି ଡିଭାଇସ୍‌ରେ ଟିପଚିହ୍ନ ସେନ୍‍ସର୍ ନାହିଁ।"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ସେନ୍ସରକୁ ଅସ୍ଥାୟୀ ଭାବେ ଅକ୍ଷମ କରାଯାଇଛି।"</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"ଆଙ୍ଗୁଠି <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"ଜାରି ରଖିବାକୁ ଆପଣଙ୍କ ଟିପଚିହ୍ନ ବ୍ୟବହାର କରନ୍ତୁ"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"ଟିପଚିହ୍ନ ଆଇକନ୍"</string>
@@ -1665,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"ଶର୍ଟକଟ୍‍ ବ୍ୟବହାର କରନ୍ତୁ"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"ରଙ୍ଗ ବଦଳାଇବାର ସୁବିଧା"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"ରଙ୍ଗ ସଂଶୋଧନ"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"ଉଜ୍ଜ୍ୱଳତା କମାନ୍ତୁ"</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="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> ବ୍ୟବହାର କରିବାକୁ ତିନି ସେକେଣ୍ଡ ପାଇଁ ଉଭୟ ଭଲ୍ୟୁମ୍‍ କୀ ଦବାଇ ଧରି ରଖନ୍ତୁ"</string>
@@ -1881,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"ବଡ଼ କରନ୍ତୁ"</string>
<string name="close_button_text" msgid="10603510034455258">"ବନ୍ଦ କରନ୍ତୁ"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"ଉତ୍ତର ଦିଅନ୍ତୁ"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"ଅଗ୍ରାହ୍ୟ କର"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"ସମାପ୍ତ କରନ୍ତୁ"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"ଇନକମିଂ କଲ୍"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"ଚାଲିଥିବା କଲ୍"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"ଏକ ଇନକମିଂ କଲକୁ ସ୍କ୍ରିନ୍ କରୁଛି"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ଚୟନିତ</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ଚୟନିତ</item>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index a717af6ae89b..5c96f88b9bab 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -148,8 +148,7 @@
<string name="wfc_mode_wifi_only_summary" msgid="104951993894678665">"ਸਿਰਫ਼ ਵਾਈ-ਫਾਈ"</string>
<!-- no translation found for crossSimFormat_spn (9125246077491634262) -->
<skip />
- <!-- no translation found for crossSimFormat_spn_cross_sim_calling (5620807020002879057) -->
- <skip />
+ <string name="crossSimFormat_spn_cross_sim_calling" msgid="5620807020002879057">"<xliff:g id="SPN">%s</xliff:g> ਬੈਕਅੱਪ ਕਾਲਿੰਗ"</string>
<string name="cfTemplateNotForwarded" msgid="862202427794270501">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: ਅੱਗੇ ਨਹੀਂ ਭੇਜਿਆ ਗਿਆ"</string>
<string name="cfTemplateForwarded" msgid="9132506315842157860">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
<string name="cfTemplateForwardedTime" msgid="735042369233323609">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g> <xliff:g id="TIME_DELAY">{2}</xliff:g> ਸਕਿੰਟਾਂ ਬਾਅਦ"</string>
@@ -580,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ਇਸ ਡੀਵਾਈਸ ਵਿੱਚ ਫਿੰਗਰਪ੍ਰਿੰਟ ਸੈਂਸਰ ਨਹੀਂ ਹੈ।"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ਸੈਂਸਰ ਅਸਥਾਈ ਤੌਰ \'ਤੇ ਬੰਦ ਕੀਤਾ ਗਿਆ।"</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"ਉਂਗਲ <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"ਜਾਰੀ ਰੱਖਣ ਲਈ ਆਪਣਾ ਫਿੰਗਰਪ੍ਰਿੰਟ ਵਰਤੋ"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਪ੍ਰਤੀਕ"</string>
@@ -1665,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"ਸ਼ਾਰਟਕੱਟ ਦੀ ਵਰਤੋਂ ਕਰੋ"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"ਰੰਗ ਪਲਟਨਾ"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"ਰੰਗ ਸੁਧਾਈ"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"ਚਮਕ ਘਟਾਓ"</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="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> ਦੀ ਵਰਤੋਂ ਕਰਨ ਲਈ ਦੋਵੇਂ ਅਵਾਜ਼ ਕੁੰਜੀਆਂ ਨੂੰ 3 ਸਕਿੰਟਾਂ ਲਈ ਦਬਾਈ ਰੱਖੋ"</string>
@@ -1881,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"ਵੱਡਾ ਕਰੋ"</string>
<string name="close_button_text" msgid="10603510034455258">"ਬੰਦ ਕਰੋ"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"ਜਵਾਬ ਦਿਓ"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"ਅਸਵੀਕਾਰ ਕਰੋ"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"ਸਮਾਪਤ ਕਰੋ"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"ਇਨਕਮਿੰਗ ਕਾਲ"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"ਜਾਰੀ ਕਾਲ"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"ਇਨਕਮਿੰਗ ਕਾਲ ਦੀ ਸਕ੍ਰੀਨਿੰਗ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ਚੁਣਿਆ ਗਿਆ</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ਚੁਣਿਆ ਗਿਆ</item>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index f73b38246e5a..612a0e52957c 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -585,6 +585,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"To urządzenie nie jest wyposażone w czytnik linii papilarnych."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Czujnik jest tymczasowo wyłączony."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Odcisk palca <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Użyj odcisku palca, by kontynuować"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ikona odcisku palca"</string>
@@ -1708,6 +1709,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Użyj skrótu"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Odwrócenie kolorów"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Korekcja kolorów"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Zmniejsz jasność"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Przytrzymano klawisze głośności. Usługa <xliff:g id="SERVICE_NAME">%1$s</xliff:g> została włączona."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Przytrzymano klawisze głośności. Usługa <xliff:g id="SERVICE_NAME">%1$s</xliff:g> została wyłączona."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Naciśnij i przytrzymaj oba przyciski głośności przez trzy sekundy, by użyć usługi <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -1942,6 +1944,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"Maksymalizuj"</string>
<string name="close_button_text" msgid="10603510034455258">"Zamknij"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"Odbierz"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"Odrzuć"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Rozłącz"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"Połączenie przychodzące"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Trwa połączenie"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"Filtruję połączenie przychodzące"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="few">Wybrano <xliff:g id="COUNT_1">%1$d</xliff:g></item>
<item quantity="many">Wybrano <xliff:g id="COUNT_1">%1$d</xliff:g></item>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index 693af83522e7..f54635bad3b0 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -579,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Este dispositivo não tem um sensor de impressão digital."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor desativado temporariamente."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Use sua impressão digital para continuar"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ícone de impressão digital"</string>
@@ -1664,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Usar atalho"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Inversão de cores"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Correção de cor"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Reduzir brilho"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Teclas de volume pressionadas. Serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ativado."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Teclas de volume pressionadas. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> desativado."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Toque nos dois botões de volume e os mantenha pressionados por três segundo para usar o <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -1880,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"Maximizar"</string>
<string name="close_button_text" msgid="10603510034455258">"Fechar"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"Atender"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"Recusar"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Desligar"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"Chamada recebida"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Chamada em andamento"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"Filtrando uma chamada recebida"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> selecionado</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> selecionados</item>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index e00034acf491..c57e0db40b9d 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -579,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Este dispositivo não tem sensor de impressões digitais."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor temporariamente desativado."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Utilize a sua impressão digital para continuar."</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ícone de impressão digital"</string>
@@ -1664,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Utilizar atalho"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Inversão de cores"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Correção da cor"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Reduzir o brilho"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Teclas do volume premidas. Serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ativado."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Teclas de volume premidas. Serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g> desativado."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Prima sem soltar as teclas de volume durante três segundos para utilizar o serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
@@ -1880,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"Maximizar"</string>
<string name="close_button_text" msgid="10603510034455258">"Fechar"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"Atender"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"Recusar"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Desligar"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"Chamada recebida"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Chamada em curso"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"A filtrar uma chamada recebida…"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> selecionados</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> selecionado</item>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 693af83522e7..f54635bad3b0 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -579,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Este dispositivo não tem um sensor de impressão digital."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor desativado temporariamente."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Dedo <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Use sua impressão digital para continuar"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ícone de impressão digital"</string>
@@ -1664,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Usar atalho"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Inversão de cores"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Correção de cor"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Reduzir brilho"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Teclas de volume pressionadas. Serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ativado."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Teclas de volume pressionadas. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> desativado."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Toque nos dois botões de volume e os mantenha pressionados por três segundo para usar o <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -1880,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"Maximizar"</string>
<string name="close_button_text" msgid="10603510034455258">"Fechar"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"Atender"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"Recusar"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Desligar"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"Chamada recebida"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Chamada em andamento"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"Filtrando uma chamada recebida"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> selecionado</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> selecionados</item>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 5fd6f1a0634b..9096b8c77493 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -582,6 +582,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Dispozitivul nu are senzor de amprentă."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Senzorul este dezactivat temporar."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Degetul <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Folosiți amprenta pentru a continua"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Pictograma amprentă"</string>
@@ -1686,6 +1687,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Utilizați comanda rapidă"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Inversarea culorilor"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Corecția culorii"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Reduceți luminozitatea"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"S-au apăsat lung tastele de volum. S-a activat <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"S-au apăsat lung tastele de volum. S-a dezactivat <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Apăsați ambele butoane de volum timp de trei secunde pentru a folosi <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -1911,6 +1913,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"Maximizați"</string>
<string name="close_button_text" msgid="10603510034455258">"Închideți"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"Răspundeți"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"Respingeți"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Încheiați"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"Apel primit"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Apel în desfășurare"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"Se filtrează un apel primit"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> selectate</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> selectate</item>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index d1cd374d2bc7..df2906f348b5 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -585,6 +585,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"На этом устройстве нет сканера отпечатков пальцев."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Сканер отпечатков пальцев временно отключен."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Отпечаток <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Чтобы продолжить, используйте цифровой отпечаток"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Значок отпечатка пальца"</string>
@@ -1708,6 +1709,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Использовать быстрое включение"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Инверсия цветов"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Коррекция цвета"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Уменьшение яркости"</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="4228997042855695090">"Чтобы использовать сервис \"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\", нажмите и удерживайте обе клавиши громкости в течение трех секунд."</string>
@@ -1942,6 +1944,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"Развернуть"</string>
<string name="close_button_text" msgid="10603510034455258">"Закрыть"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"Ответить"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"Отклонить"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Завершить"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"Входящий вызов"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Текущий вызов"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"Фильтрация входящего вызова"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="one">Выбрано: <xliff:g id="COUNT_1">%1$d</xliff:g></item>
<item quantity="few">Выбрано: <xliff:g id="COUNT_1">%1$d</xliff:g></item>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index d102183f25ad..b061248b5bfc 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -579,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"මෙම උපාංගයේ ඇඟිලි සලකුණු සංවේදකයක් නොමැත."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"සංවේදකය තාවකාලිකව අබල කර ඇත."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"ඇඟිලි <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"ඉදිරියට යාමට ඔබගේ ඇඟිලි සලකුණ භාවිත කරන්න"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"ඇඟිලි සලකුණු නිරූපකය"</string>
@@ -1664,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"කෙටිමඟ භාවිතා කරන්න"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"වර්ණ අපවර්තනය"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"වර්ණ නිවැරදි කිරීම"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"දීප්තිය අඩු කරන්න"</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="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> භාවිත කිරීමට හඬ පරිමා යතුරු දෙකම තත්පර තුනකට ඔබාගෙන සිටින්න"</string>
@@ -1880,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"විහිදන්න"</string>
<string name="close_button_text" msgid="10603510034455258">"වසන්න"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"පිළිතුරු දෙ."</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"ප්‍රතික්ෂේප ක"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"විසන්ධි කරන්න"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"එන ඇමතුම"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"කරගෙන යන ඇමතුම"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"එන ඇමතුමක් පරීක්ෂා කරන්න"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ක් තෝරන ලදි</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ක් තෝරන ලදි</item>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index ffa4b26589d5..dcf19f734514 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -585,6 +585,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Toto zariadenie nemá senzor odtlačkov prstov."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Senzor je dočasne vypnutý."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Prst: <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Pokračujte nasnímaním odtlačku prsta"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ikona odtlačku prsta"</string>
@@ -1708,6 +1709,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Použiť skratku"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Inverzia farieb"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Úprava farieb"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Zníženie jasu"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Pridržali ste tlačidlá hlasitosti. Služba <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je zapnutá."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Pridržali ste tlačidlá hlasitosti. Služba <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je vypnutá."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Ak chcete používať službu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, pridržte tri sekundy oba klávesy hlasitosti"</string>
@@ -1942,6 +1944,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"Maximalizovať"</string>
<string name="close_button_text" msgid="10603510034455258">"Zavrieť"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"Prijať"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"Odmietnuť"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Zložiť"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"Prichádzajúci hovor"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Prebiehajúci hovor"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"Preveruje sa prichádzajúci hovor"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="few">Vybrané: <xliff:g id="COUNT_1">%1$d</xliff:g></item>
<item quantity="many">Vybrané: <xliff:g id="COUNT_1">%1$d</xliff:g></item>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index d09ef047c624..88bb116a9c77 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -150,8 +150,7 @@
<string name="wfc_mode_wifi_only_summary" msgid="104951993894678665">"Samo Wi-Fi"</string>
<!-- no translation found for crossSimFormat_spn (9125246077491634262) -->
<skip />
- <!-- no translation found for crossSimFormat_spn_cross_sim_calling (5620807020002879057) -->
- <skip />
+ <string name="crossSimFormat_spn_cross_sim_calling" msgid="5620807020002879057">"Pomožno klicanje prek operaterja <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="cfTemplateNotForwarded" msgid="862202427794270501">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: ni posredovano"</string>
<string name="cfTemplateForwarded" msgid="9132506315842157860">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
<string name="cfTemplateForwardedTime" msgid="735042369233323609">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g> po toliko sekundah: <xliff:g id="TIME_DELAY">{2}</xliff:g>"</string>
@@ -586,6 +585,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Ta naprava nima tipala prstnih odtisov."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Tipalo je začasno onemogočeno."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Uporabite prstni odtis, če želite nadaljevati."</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ikona prstnih odtisov"</string>
@@ -1709,6 +1709,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Uporabi bližnjico"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Inverzija barv"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Popravljanje barv"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Zmanjšanje svetlosti"</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="4228997042855695090">"Za uporabo storitve <xliff:g id="SERVICE_NAME">%1$s</xliff:g> pritisnite obe tipki za glasnost in ju pridržite tri sekunde"</string>
@@ -1943,6 +1944,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"Maksimiziraj"</string>
<string name="close_button_text" msgid="10603510034455258">"Zapri"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"Sprejmi"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"Zavrni"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Prekini klic"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"Dohodni klic"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Aktivni klic"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"Preverjanje dohodnega klica"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> izbran</item>
<item quantity="two"><xliff:g id="COUNT_1">%1$d</xliff:g> izbrana</item>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index 592e54ddceb9..b5eaa7a752fd 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -579,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Kjo pajisje nuk ka sensor të gjurmës së gishtit."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensori është çaktivizuar përkohësisht."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Gishti <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Përdor gjurmën e gishtit për të vazhduar"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ikona e gjurmës së gishtit"</string>
@@ -1664,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Përdor shkurtoren"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Kthimi i ngjyrës"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Korrigjimi i ngjyrës"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Redukto ndriçimin"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Tastet e volumit të mbajtura shtypur. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> i aktivizuar."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Tastet e volumit të mbajtura shtypur. U çaktivizua \"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\"."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Shtyp dhe mbaj shtypur të dy butonat e volumit për tre sekonda për të përdorur <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -1880,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"Maksimizo"</string>
<string name="close_button_text" msgid="10603510034455258">"Mbyll"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"Përgjigju"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"Refuzo"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Mbyll"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"Telefonatë hyrëse"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Telefonatë në vazhdim"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"Po filtron një telefonatë hyrëse"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> të zgjedhura</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> i zgjedhur</item>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 65037a058067..d50f659bbc31 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -582,6 +582,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Овај уређај нема сензор за отисак прста."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Сензор је привремено онемогућен."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Прст <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Наставите помоћу отиска прста"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Икона отиска прста"</string>
@@ -1686,6 +1687,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Користи пречицу"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Инверзија боја"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Корекција боја"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Смањите осветљеност"</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="4228997042855695090">"Притисните и задржите оба тастера за јачину звука три секунде да бисте користили <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -1911,6 +1913,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"Увећај"</string>
<string name="close_button_text" msgid="10603510034455258">"Затвори"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"Одговори"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"Одбиј"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Прекини везу"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"Долазни позив"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Позив је у току"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"Проверава се долазни позив"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="one">Изабрана је <xliff:g id="COUNT_1">%1$d</xliff:g> ставка</item>
<item quantity="few">Изабране су <xliff:g id="COUNT_1">%1$d</xliff:g> ставке</item>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index ef7a102fa257..892272ab15a0 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -579,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Enheten har ingen fingeravtryckssensor."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensorn har tillfälligt inaktiverats."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Finger <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Fortsätt med hjälp av ditt fingeravtryck"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ikon för fingeravtryck"</string>
@@ -1664,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Använd kortkommandot"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Inverterade färger"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Färgkorrigering"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Minska ljusstyrkan"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Volymknapparna har tryckts ned. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> har aktiverats."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Volymknapparna har tryckts ned. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> har inaktiverats."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Tryck och håll båda volymknapparna i tre sekunder för att använda <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -1880,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"Maximera"</string>
<string name="close_button_text" msgid="10603510034455258">"Stäng"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"Svara"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"Avvisa"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Lägg på"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"Inkommande samtal"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Pågående samtal"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"Ett inkommande samtal förhandsgranskas"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> har valts</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> har valts</item>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index cc82f4ec8fea..093ebb17b8bd 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -579,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Kifaa hiki hakina kitambua alama ya kidole."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Kitambuzi kimezimwa kwa muda."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Kidole cha <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Tumia alama ya kidole chako ili uendelee"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Aikoni ya alama ya kidole"</string>
@@ -1664,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Tumia Njia ya Mkato"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Ugeuzaji rangi"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Usahihishaji wa rangi"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Punguza Ung\'aavu"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Vitufe vya sauti vilivyoshikiliwa. Umewasha <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Vitufe vya sauti vimeshikiliwa. Umezima <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Bonyeza na ushikilie vitufe vyote viwili vya sauti kwa sekunde tatu ili utumie <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -1880,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"Panua"</string>
<string name="close_button_text" msgid="10603510034455258">"Funga"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"Jibu"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"Kataa"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Kata simu"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"Simu uliyopigiwa"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Simu inayoendelea"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"Inachuja simu unayopigiwa"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> vimechaguliwa</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> kimechaguliwa</item>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index ca90171d50ce..bc08a58b1906 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -579,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"இந்தச் சாதனத்தில் கைரேகை சென்சார் இல்லை."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"சென்சார் தற்காலிகமாக முடக்கப்பட்டுள்ளது."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"கைரேகை <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"தொடர்வதற்கு கைரேகையைப் பயன்படுத்துங்கள்"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"கைரேகை ஐகான்"</string>
@@ -1664,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"ஷார்ட்கட்டைப் பயன்படுத்து"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"கலர் இன்வெர்ஷன்"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"வண்ணத் திருத்தம்"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"ஒளிர்வைக் குறைத்தல்"</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="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>ஐப் பயன்படுத்த 3 விநாடிகளுக்கு இரண்டு ஒலியளவு பட்டன்களையும் அழுத்திப் பிடிக்கவும்"</string>
@@ -1880,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"பெரிதாக்கு"</string>
<string name="close_button_text" msgid="10603510034455258">"மூடு"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"பதிலளி"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"நிராகரி"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"துண்டி"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"உள்வரும் அழைப்பு"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"செயலில் இருக்கும் அழைப்பு"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"உள்வரும் அழைப்பை மதிப்பாய்வு செய்கிறது"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> தேர்ந்தெடுக்கப்பட்டன</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> தேர்ந்தெடுக்கப்பட்டது</item>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index b0726e811d47..1f783bef81f7 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -148,8 +148,7 @@
<string name="wfc_mode_wifi_only_summary" msgid="104951993894678665">"Wi-Fi మాత్రమే"</string>
<!-- no translation found for crossSimFormat_spn (9125246077491634262) -->
<skip />
- <!-- no translation found for crossSimFormat_spn_cross_sim_calling (5620807020002879057) -->
- <skip />
+ <string name="crossSimFormat_spn_cross_sim_calling" msgid="5620807020002879057">"<xliff:g id="SPN">%s</xliff:g> బ్యాకప్ కాలింగ్"</string>
<string name="cfTemplateNotForwarded" msgid="862202427794270501">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: ఫార్వార్డ్ చేయబడలేదు"</string>
<string name="cfTemplateForwarded" msgid="9132506315842157860">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
<string name="cfTemplateForwardedTime" msgid="735042369233323609">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="TIME_DELAY">{2}</xliff:g> సెకన్ల తర్వాత <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -580,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"ఈ పరికరంలో వేలిముద్ర సెన్సార్ ఎంపిక లేదు."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"సెన్సార్ తాత్కాలికంగా డిజేబుల్ చేయబడింది."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"వేలు <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"కొనసాగించడానికి మీ వేలిముద్రను ఉపయోగించండి"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"వేలిముద్ర చిహ్నం"</string>
@@ -1665,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"సత్వరమార్గాన్ని ఉపయోగించు"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"కలర్ మార్పిడి"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"కలర్ సరిచేయడం"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"ప్రకాశాన్ని తగ్గించండి"</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="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>ని ఉపయోగించడానికి వాల్యూమ్ కీలు రెండింటినీ 3 సెకన్లు నొక్కి ఉంచండి"</string>
@@ -1881,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"గరిష్టీకరించు"</string>
<string name="close_button_text" msgid="10603510034455258">"మూసివేయి"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"సమాధానం ఇవ్వు"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"తిరస్కరించండి"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"కాల్ ముగించు"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"ఇన్‌కమింగ్ కాల్"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"కాల్ కొనసాగుతోంది"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"ఇన్‌కమింగ్ కాల్‌ను స్క్రీన్ చేయండి"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ఎంచుకోబడ్డాయి</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ఎంచుకోబడింది</item>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 5079f232091b..f5ed8a1bae18 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -579,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"อุปกรณ์นี้ไม่มีเซ็นเซอร์ลายนิ้วมือ"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"ปิดใช้เซ็นเซอร์ชั่วคราวแล้ว"</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"นิ้ว <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"ใช้ลายนิ้วมือของคุณเพื่อดำเนินการต่อ"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"ไอคอนลายนิ้วมือ"</string>
@@ -1664,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"ใช้ทางลัด"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"การกลับสี"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"การแก้สี"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"ลดความสว่าง"</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="4228997042855695090">"กดปุ่มปรับระดับเสียงทั้ง 2 ปุ่มค้างไว้ 3 วินาทีเพื่อใช้ <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -1880,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"ขยายใหญ่สุด"</string>
<string name="close_button_text" msgid="10603510034455258">"ปิด"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"รับสาย"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"ปฏิเสธ"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"วางสาย"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"สายเรียกเข้า"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"สายที่สนทนาอยู่"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"กำลังสกรีนสายเรียกเข้า"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="other">เลือกไว้ <xliff:g id="COUNT_1">%1$d</xliff:g> รายการ</item>
<item quantity="one">เลือกไว้ <xliff:g id="COUNT_0">%1$d</xliff:g> รายการ</item>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 81bfe5258284..d1b506cbef20 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -579,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Walang sensor ng fingerprint ang device na ito."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Pansamantalang na-disable ang sensor."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Daliri <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Gamitin ang iyong fingerprint para magpatuloy"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Icon ng fingerprint"</string>
@@ -1664,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Gamitin ang Shortcut"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Pag-invert ng Kulay"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Pagwawasto ng Kulay"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Bawasan ang Liwanag"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Pinindot nang matagal ang volume keys. Na-on ang <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Pinindot nang matagal ang volume keys. Na-off ang <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Pindutin nang matagal ang parehong volume key sa loob ng tatlong segundo para magamit ang <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -1880,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"I-maximize"</string>
<string name="close_button_text" msgid="10603510034455258">"Isara"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"Sagutin"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"Tanggihan"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Ibaba"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"Papasok na tawag"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Kasalukuyang tawag"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"Nagsi-screen ng papasok na tawag"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ang napili</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ang napili</item>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 7095bb8c5875..23cf1bd37d04 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -579,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Bu cihazda parmak izi sensörü yok."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensör geçici olarak devre dışı bırakıldı."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"<xliff:g id="FINGERID">%d</xliff:g>. parmak"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Devam etmek için parmak izinizi kullanın"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Parmak izi simgesi"</string>
@@ -1664,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Kısayolu Kullan"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Rengi Ters Çevirme"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Renk Düzeltme"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Parlaklığı Azaltma"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Ses tuşlarını basılı tuttunuz. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> açıldı."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Ses tuşlarını basılı tuttunuz. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> kapatıldı."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> hizmetini kullanmak için her iki ses tuşunu basılı tutun"</string>
@@ -1880,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"Ekranı Kapla"</string>
<string name="close_button_text" msgid="10603510034455258">"Kapat"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"Yanıtla"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"Reddet"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Kapat"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"Gelen çağrı"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Devam eden çağrı"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"Gelen arama süzülüyor"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> öğe seçildi</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> öğe seçildi</item>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 9864b4b4e4a4..7f68ddd4a36b 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -585,6 +585,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"На цьому пристрої немає сканера відбитків пальців."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Датчик тимчасово вимкнено."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Відбиток пальця <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Щоб продовжити, скористайтеся своїм відбитком пальця"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Значок відбитка пальця"</string>
@@ -1708,6 +1709,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Використовувати ярлик"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Інверсія кольорів"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Корекція кольорів"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Зменшення яскравості"</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="4228997042855695090">"Щоб скористатися службою <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, утримуйте обидві клавіші гучності впродовж трьох секунд"</string>
@@ -1942,6 +1944,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"Розгорнути"</string>
<string name="close_button_text" msgid="10603510034455258">"Закрити"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"Відповісти"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"Відхилити"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Завершити"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"Вхідний виклик"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Активний виклик"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"Фільтрування вхідного виклику"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="one">Вибрано <xliff:g id="COUNT_1">%1$d</xliff:g></item>
<item quantity="few">Вибрано <xliff:g id="COUNT_1">%1$d</xliff:g></item>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index 64fb2fc414e2..7935744ce9ff 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -148,8 +148,7 @@
<string name="wfc_mode_wifi_only_summary" msgid="104951993894678665">"‏صرف Wi-Fi"</string>
<!-- no translation found for crossSimFormat_spn (9125246077491634262) -->
<skip />
- <!-- no translation found for crossSimFormat_spn_cross_sim_calling (5620807020002879057) -->
- <skip />
+ <string name="crossSimFormat_spn_cross_sim_calling" msgid="5620807020002879057">"<xliff:g id="SPN">%s</xliff:g> بیک اپ کالنگ"</string>
<string name="cfTemplateNotForwarded" msgid="862202427794270501">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g> : فارورڈ نہیں کی گئی"</string>
<string name="cfTemplateForwarded" msgid="9132506315842157860">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
<string name="cfTemplateForwardedTime" msgid="735042369233323609">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g> بعد از <xliff:g id="TIME_DELAY">{2}</xliff:g> سیکنڈ"</string>
@@ -580,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"اس آلہ میں فنگر پرنٹ سینسر نہیں ہے۔"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"سینسر عارضی طور غیر فعال ہے۔"</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"انگلی <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"جاری رکھنے کیلئے اپنا فنگر پرنٹ استعمال کریں"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"فنگر پرنٹ آئیکن"</string>
@@ -1665,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"شارٹ کٹ استعمال کریں"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"رنگوں کی تقلیب"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"رنگ کی تصحیح"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"چمک کم کریں"</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="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> کا استعمال کرنے کے لیے 3 سیکنڈ تک والیوم کی دونوں کلیدوں کو چھوئیں اور دبائے رکھیں"</string>
@@ -1881,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"بڑا کریں"</string>
<string name="close_button_text" msgid="10603510034455258">"بند کریں"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"جواب"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"مسترد کریں"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"منقطع کر دیں"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"اِن کمنگ کال"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"جاری کال"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"اِن کمنگ کال کی اسکریننگ"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> منتخب کردہ</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> منتخب کردہ</item>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index 6612cc9a875a..bdba644b56d3 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -579,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Bu qurilmada barmoq izi skaneri mavjud emas."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Sensor vaqtincha faol emas."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Barmoq izi <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Davom etish uchun barmoq izingizdan foydalaning"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Barmoq izi belgisi"</string>
@@ -1664,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Tezkor ishga tushirishdan foydalanish"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Ranglarni akslantirish"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Rangni tuzatish"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Yorqinlikni pasaytirish"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Tovush tugmalari bosib turildi. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> yoqildi."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Tovush tugmalari bosib turildi. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> faolsizlantirildi."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"<xliff:g id="SERVICE_NAME">%1$s</xliff:g> xizmatidan foydalanish uchun ikkala ovoz balandligi tugmalarini uzoq bosib turing"</string>
@@ -1880,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"Maksimallashtirish"</string>
<string name="close_button_text" msgid="10603510034455258">"Yopish"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"Javob berish"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"Rad etish"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Tugatish"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"Kiruvchi chaqiruv"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Joriy chaqiruv"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"Kiruvchi chaqiruvni filtrlash"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="other">Belgilandi: <xliff:g id="COUNT_1">%1$d</xliff:g></item>
<item quantity="one">Belgilandi: <xliff:g id="COUNT_0">%1$d</xliff:g></item>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 8f8e0bce3409..745550cc1757 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -579,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Thiết bị này không có cảm biến vân tay."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Đã tạm thời tắt cảm biến."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Ngón tay <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Sử dụng dấu vân tay của bạn để tiếp tục"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Biểu tượng vân tay"</string>
@@ -1664,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Sử dụng phím tắt"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Đảo màu"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Chỉnh màu"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Giảm độ sáng"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Bạn đã giữ các phím âm lượng. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> đã bật."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Bạn đã giữ các phím âm lượng. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> đã tắt."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Nhấn và giữ đồng thời cả hai phím âm lượng trong 3 giây để sử dụng <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -1880,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"Tối đa hóa"</string>
<string name="close_button_text" msgid="10603510034455258">"Đóng"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"Trả lời"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"Từ chối"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Kết thúc"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"Cuộc gọi đến"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Cuộc gọi đang thực hiện"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"Đang sàng lọc cuộc gọi đến"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="other">Đã chọn <xliff:g id="COUNT_1">%1$d</xliff:g></item>
<item quantity="one">Đã chọn <xliff:g id="COUNT_0">%1$d</xliff:g></item>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index af5f846d368b..56182394a466 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -579,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"此设备没有指纹传感器。"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"传感器已暂时停用。"</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"手指 <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"使用指纹完成验证才能继续"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"指纹图标"</string>
@@ -1664,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"使用快捷方式"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"颜色反转"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"色彩校正"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"调低亮度"</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="4228997042855695090">"同时按住两个音量键 3 秒钟即可使用 <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -1880,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"最大化"</string>
<string name="close_button_text" msgid="10603510034455258">"关闭"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>:<xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"接听"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"拒接"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"挂断"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"来电"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"正在通话"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"正在过滤来电"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="other">已选择 <xliff:g id="COUNT_1">%1$d</xliff:g> 项</item>
<item quantity="one">已选择 <xliff:g id="COUNT_0">%1$d</xliff:g> 项</item>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 65586f7f1b09..47651c799aa1 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -148,7 +148,7 @@
<string name="wfc_mode_wifi_only_summary" msgid="104951993894678665">"只限 Wi-Fi"</string>
<!-- no translation found for crossSimFormat_spn (9125246077491634262) -->
<skip />
- <string name="crossSimFormat_spn_cross_sim_calling" msgid="5620807020002879057">"「<xliff:g id="SPN">%s</xliff:g>」備用通話網路"</string>
+ <string name="crossSimFormat_spn_cross_sim_calling" msgid="5620807020002879057">"「<xliff:g id="SPN">%s</xliff:g>」備用通話"</string>
<string name="cfTemplateNotForwarded" msgid="862202427794270501">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>:尚未轉接"</string>
<string name="cfTemplateForwarded" msgid="9132506315842157860">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>:<xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
<string name="cfTemplateForwardedTime" msgid="735042369233323609">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g> 於 <xliff:g id="TIME_DELAY">{2}</xliff:g> 秒後轉接"</string>
@@ -579,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"此裝置沒有指紋感應器。"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"感應器已暫時停用。"</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"手指 <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"請使用您的指紋繼續"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"指紋圖示"</string>
@@ -1664,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"使用快速鍵"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"色彩反轉"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"色彩校正"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"調低亮度"</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="4228997042855695090">"㩒住兩個音量鍵 3 秒就可以用 <xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -1880,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"最大化"</string>
<string name="close_button_text" msgid="10603510034455258">"關閉"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>:<xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"接聽"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"拒接"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"掛斷"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"來電"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"通話中"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"正在過濾來電"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="other">已選取 <xliff:g id="COUNT_1">%1$d</xliff:g> 個項目</item>
<item quantity="one">已選取 <xliff:g id="COUNT_0">%1$d</xliff:g> 個項目</item>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 6facceb39df7..71292c3d9615 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -579,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"這個裝置沒有指紋感應器。"</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"感應器已暫時停用。"</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"手指 <xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"使用指紋完成驗證才能繼續操作"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"指紋圖示"</string>
@@ -1664,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"使用捷徑"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"色彩反轉"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"色彩校正"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"調低亮度"</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="4228997042855695090">"同時按住調低及調高音量鍵三秒即可使用「<xliff:g id="SERVICE_NAME">%1$s</xliff:g>」"</string>
@@ -1880,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"最大化"</string>
<string name="close_button_text" msgid="10603510034455258">"關閉"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>:<xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"接聽"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"拒接"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"掛斷"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"來電"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"通話中"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"正在過濾來電"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="other">已選取 <xliff:g id="COUNT_1">%1$d</xliff:g> 個項目</item>
<item quantity="one">已選取 <xliff:g id="COUNT_0">%1$d</xliff:g> 個項目</item>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 3b22e9435462..6202ba84dc3e 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -579,6 +579,7 @@
<string name="fingerprint_error_hw_not_present" msgid="578914350967423382">"Le divayisi ayinayo inzwa yezigxivizo zeminwe."</string>
<string name="fingerprint_error_security_update_required" msgid="7750187320640856433">"Inzwa ikhutshazwe okwesikhashana."</string>
<string name="fingerprint_name_template" msgid="8941662088160289778">"Umunwe ongu-<xliff:g id="FINGERID">%d</xliff:g>"</string>
+ <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Sebenzisa izigxivizo zakho zeminwe ukuze uqhubeke"</string>
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Isithonjana sezigxivizo zeminwe"</string>
@@ -1664,6 +1665,7 @@
<string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Sebenzisa isinqamuleli"</string>
<string name="color_inversion_feature_name" msgid="326050048927789012">"Ukuguqulwa kombala"</string>
<string name="color_correction_feature_name" msgid="3655077237805422597">"Ukulungiswa kombala"</string>
+ <string name="reduce_bright_colors_feature_name" msgid="6222956501418407642">"Nciphisa ukukhanya"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Ubambe okhiye bevolumu. I-<xliff:g id="SERVICE_NAME">%1$s</xliff:g> ivuliwe."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Ubambe okhiye bevolumu. I-<xliff:g id="SERVICE_NAME">%1$s</xliff:g> ivaliwe."</string>
<string name="accessibility_shortcut_spoken_feedback" msgid="4228997042855695090">"Cindezela uphinde ubambe bobabili okhiye bevolumu ngamasekhondi amathathu ukuze usebenzise i-<xliff:g id="SERVICE_NAME">%1$s</xliff:g>"</string>
@@ -1880,6 +1882,12 @@
<string name="maximize_button_text" msgid="4258922519914732645">"Khulisa"</string>
<string name="close_button_text" msgid="10603510034455258">"Vala"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
+ <string name="call_notification_answer_action" msgid="5999246836247132937">"Phendula"</string>
+ <string name="call_notification_decline_action" msgid="3700345945214000726">"Yenqaba"</string>
+ <string name="call_notification_hang_up_action" msgid="9130720590159188131">"Vala Ucingo"</string>
+ <string name="call_notification_incoming_text" msgid="6143109825406638201">"Ikholi engenayo"</string>
+ <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Ikholi eqhubekayo"</string>
+ <string name="call_notification_screening_text" msgid="8396931408268940208">"Ukuveza ikholi engenayo"</string>
<plurals name="selected_count" formatted="false" msgid="3946212171128200491">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> okukhethiwe</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> okukhethiwe</item>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index faa2157be302..59285d794045 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -3205,6 +3205,10 @@
panning to scaling the magnification viewport. -->
<item name="config_screen_magnification_scaling_threshold" format="float" type="dimen">0.3</item>
+ <!-- Whether to support magnification area. If not enabled, it would hide the entry in
+ magnification settings and adjust the default magnification capability. -->
+ <bool name="config_magnification_area">true</bool>
+
<!-- If true, the display will be shifted around in ambient mode. -->
<bool name="config_enableBurnInProtection">false</bool>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index f66d33b02b69..50809140f66a 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -4174,6 +4174,8 @@
<java-symbol type="string" name="turn_on_magnification_settings_action" />
<java-symbol type="string" name="dismiss_action" />
+ <java-symbol type="bool" name="config_magnification_area" />
+
<java-symbol type="bool" name="config_trackerAppNeedsPermissions"/>
<!-- Package with global data query permissions for AppSearch -->
diff --git a/core/tests/uwbtests/src/android/uwb/AngleMeasurementTest.java b/core/tests/uwbtests/src/android/uwb/AngleMeasurementTest.java
deleted file mode 100644
index 7769c28202f2..000000000000
--- a/core/tests/uwbtests/src/android/uwb/AngleMeasurementTest.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.uwb;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-
-import android.os.Parcel;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-/**
- * Test of {@link AngleMeasurement}.
- */
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class AngleMeasurementTest {
- private static final double EPSILON = 0.00000000001;
-
- @Test
- public void testBuilder() {
- double radians = 0.1234;
- double errorRadians = 0.5678;
- double confidence = 0.5;
-
- AngleMeasurement.Builder builder = new AngleMeasurement.Builder();
- tryBuild(builder, false);
-
- builder.setRadians(radians);
- tryBuild(builder, false);
-
- builder.setErrorRadians(errorRadians);
- tryBuild(builder, false);
-
- builder.setConfidenceLevel(confidence);
- AngleMeasurement measurement = tryBuild(builder, true);
-
- assertEquals(measurement.getRadians(), radians, 0);
- assertEquals(measurement.getErrorRadians(), errorRadians, 0);
- assertEquals(measurement.getConfidenceLevel(), confidence, 0);
- }
-
- private AngleMeasurement tryBuild(AngleMeasurement.Builder builder, boolean expectSuccess) {
- AngleMeasurement measurement = null;
- try {
- measurement = builder.build();
- if (!expectSuccess) {
- fail("Expected AngleMeasurement.Builder.build() to fail, but it succeeded");
- }
- } catch (IllegalStateException e) {
- if (expectSuccess) {
- fail("Expected AngleMeasurement.Builder.build() to succeed, but it failed");
- }
- }
- return measurement;
- }
-
- @Test
- public void testParcel() {
- Parcel parcel = Parcel.obtain();
- AngleMeasurement measurement = UwbTestUtils.getAngleMeasurement();
- measurement.writeToParcel(parcel, 0);
- parcel.setDataPosition(0);
- AngleMeasurement fromParcel = AngleMeasurement.CREATOR.createFromParcel(parcel);
- assertEquals(measurement, fromParcel);
- }
-}
diff --git a/core/tests/uwbtests/src/android/uwb/AngleOfArrivalMeasurementTest.java b/core/tests/uwbtests/src/android/uwb/AngleOfArrivalMeasurementTest.java
deleted file mode 100644
index 9394dec7f46f..000000000000
--- a/core/tests/uwbtests/src/android/uwb/AngleOfArrivalMeasurementTest.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.uwb;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-
-import android.os.Parcel;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-/**
- * Test of {@link AngleOfArrivalMeasurement}.
- */
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class AngleOfArrivalMeasurementTest {
-
- @Test
- public void testBuilder() {
- AngleMeasurement azimuth = UwbTestUtils.getAngleMeasurement();
- AngleMeasurement altitude = UwbTestUtils.getAngleMeasurement();
-
- AngleOfArrivalMeasurement.Builder builder = new AngleOfArrivalMeasurement.Builder();
- tryBuild(builder, false);
-
- builder.setAltitude(altitude);
- tryBuild(builder, false);
-
- builder.setAzimuth(azimuth);
- AngleOfArrivalMeasurement measurement = tryBuild(builder, true);
-
- assertEquals(azimuth, measurement.getAzimuth());
- assertEquals(altitude, measurement.getAltitude());
- }
-
- private AngleMeasurement getAngleMeasurement(double radian, double error, double confidence) {
- return new AngleMeasurement.Builder()
- .setRadians(radian)
- .setErrorRadians(error)
- .setConfidenceLevel(confidence)
- .build();
- }
-
- private AngleOfArrivalMeasurement tryBuild(AngleOfArrivalMeasurement.Builder builder,
- boolean expectSuccess) {
- AngleOfArrivalMeasurement measurement = null;
- try {
- measurement = builder.build();
- if (!expectSuccess) {
- fail("Expected AngleOfArrivalMeasurement.Builder.build() to fail");
- }
- } catch (IllegalStateException e) {
- if (expectSuccess) {
- fail("Expected AngleOfArrivalMeasurement.Builder.build() to succeed");
- }
- }
- return measurement;
- }
-
- @Test
- public void testParcel() {
- Parcel parcel = Parcel.obtain();
- AngleOfArrivalMeasurement measurement = UwbTestUtils.getAngleOfArrivalMeasurement();
- measurement.writeToParcel(parcel, 0);
- parcel.setDataPosition(0);
- AngleOfArrivalMeasurement fromParcel =
- AngleOfArrivalMeasurement.CREATOR.createFromParcel(parcel);
- assertEquals(measurement, fromParcel);
- }
-}
diff --git a/core/tests/uwbtests/src/android/uwb/DistanceMeasurementTest.java b/core/tests/uwbtests/src/android/uwb/DistanceMeasurementTest.java
deleted file mode 100644
index 439c884723be..000000000000
--- a/core/tests/uwbtests/src/android/uwb/DistanceMeasurementTest.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.uwb;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-
-import android.os.Parcel;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-/**
- * Test of {@link DistanceMeasurement}.
- */
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class DistanceMeasurementTest {
- private static final double EPSILON = 0.00000000001;
-
- @Test
- public void testBuilder() {
- double meters = 0.12;
- double error = 0.54;
- double confidence = 0.99;
-
- DistanceMeasurement.Builder builder = new DistanceMeasurement.Builder();
- tryBuild(builder, false);
-
- builder.setMeters(meters);
- tryBuild(builder, false);
-
- builder.setErrorMeters(error);
- tryBuild(builder, false);
-
- builder.setConfidenceLevel(confidence);
- DistanceMeasurement measurement = tryBuild(builder, true);
-
- assertEquals(meters, measurement.getMeters(), 0);
- assertEquals(error, measurement.getErrorMeters(), 0);
- assertEquals(confidence, measurement.getConfidenceLevel(), 0);
- }
-
- private DistanceMeasurement tryBuild(DistanceMeasurement.Builder builder,
- boolean expectSuccess) {
- DistanceMeasurement measurement = null;
- try {
- measurement = builder.build();
- if (!expectSuccess) {
- fail("Expected DistanceMeasurement.Builder.build() to fail");
- }
- } catch (IllegalStateException e) {
- if (expectSuccess) {
- fail("Expected DistanceMeasurement.Builder.build() to succeed");
- }
- }
- return measurement;
- }
-
- @Test
- public void testParcel() {
- Parcel parcel = Parcel.obtain();
- DistanceMeasurement measurement = UwbTestUtils.getDistanceMeasurement();
- measurement.writeToParcel(parcel, 0);
- parcel.setDataPosition(0);
- DistanceMeasurement fromParcel =
- DistanceMeasurement.CREATOR.createFromParcel(parcel);
- assertEquals(measurement, fromParcel);
- }
-}
diff --git a/core/tests/uwbtests/src/android/uwb/RangingMeasurementTest.java b/core/tests/uwbtests/src/android/uwb/RangingMeasurementTest.java
deleted file mode 100644
index edd4d08992ba..000000000000
--- a/core/tests/uwbtests/src/android/uwb/RangingMeasurementTest.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.uwb;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-
-import android.os.Parcel;
-import android.os.SystemClock;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-/**
- * Test of {@link RangingMeasurement}.
- */
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class RangingMeasurementTest {
-
- @Test
- public void testBuilder() {
- int status = RangingMeasurement.RANGING_STATUS_SUCCESS;
- UwbAddress address = UwbTestUtils.getUwbAddress(false);
- long time = SystemClock.elapsedRealtimeNanos();
- AngleOfArrivalMeasurement angleMeasurement = UwbTestUtils.getAngleOfArrivalMeasurement();
- DistanceMeasurement distanceMeasurement = UwbTestUtils.getDistanceMeasurement();
-
- RangingMeasurement.Builder builder = new RangingMeasurement.Builder();
-
- builder.setStatus(status);
- tryBuild(builder, false);
-
- builder.setElapsedRealtimeNanos(time);
- tryBuild(builder, false);
-
- builder.setAngleOfArrivalMeasurement(angleMeasurement);
- tryBuild(builder, false);
-
- builder.setDistanceMeasurement(distanceMeasurement);
- tryBuild(builder, false);
-
- builder.setRemoteDeviceAddress(address);
- RangingMeasurement measurement = tryBuild(builder, true);
-
- assertEquals(status, measurement.getStatus());
- assertEquals(address, measurement.getRemoteDeviceAddress());
- assertEquals(time, measurement.getElapsedRealtimeNanos());
- assertEquals(angleMeasurement, measurement.getAngleOfArrivalMeasurement());
- assertEquals(distanceMeasurement, measurement.getDistanceMeasurement());
- }
-
- private RangingMeasurement tryBuild(RangingMeasurement.Builder builder,
- boolean expectSuccess) {
- RangingMeasurement measurement = null;
- try {
- measurement = builder.build();
- if (!expectSuccess) {
- fail("Expected RangingMeasurement.Builder.build() to fail");
- }
- } catch (IllegalStateException e) {
- if (expectSuccess) {
- fail("Expected DistanceMeasurement.Builder.build() to succeed");
- }
- }
- return measurement;
- }
-
- @Test
- public void testParcel() {
- Parcel parcel = Parcel.obtain();
- RangingMeasurement measurement = UwbTestUtils.getRangingMeasurement();
- measurement.writeToParcel(parcel, 0);
- parcel.setDataPosition(0);
- RangingMeasurement fromParcel = RangingMeasurement.CREATOR.createFromParcel(parcel);
- assertEquals(measurement, fromParcel);
- }
-}
diff --git a/core/tests/uwbtests/src/android/uwb/RangingReportTest.java b/core/tests/uwbtests/src/android/uwb/RangingReportTest.java
deleted file mode 100644
index 64c48ba4b6f4..000000000000
--- a/core/tests/uwbtests/src/android/uwb/RangingReportTest.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.uwb;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-
-import android.os.Parcel;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.List;
-
-/**
- * Test of {@link RangingReport}.
- */
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class RangingReportTest {
-
- @Test
- public void testBuilder() {
- List<RangingMeasurement> measurements = UwbTestUtils.getRangingMeasurements(5);
-
- RangingReport.Builder builder = new RangingReport.Builder();
- builder.addMeasurements(measurements);
- RangingReport report = tryBuild(builder, true);
- verifyMeasurementsEqual(measurements, report.getMeasurements());
-
-
- builder = new RangingReport.Builder();
- for (RangingMeasurement measurement : measurements) {
- builder.addMeasurement(measurement);
- }
- report = tryBuild(builder, true);
- verifyMeasurementsEqual(measurements, report.getMeasurements());
- }
-
- private void verifyMeasurementsEqual(List<RangingMeasurement> expected,
- List<RangingMeasurement> actual) {
- assertEquals(expected.size(), actual.size());
- for (int i = 0; i < expected.size(); i++) {
- assertEquals(expected.get(i), actual.get(i));
- }
- }
-
- private RangingReport tryBuild(RangingReport.Builder builder,
- boolean expectSuccess) {
- RangingReport report = null;
- try {
- report = builder.build();
- if (!expectSuccess) {
- fail("Expected RangingReport.Builder.build() to fail");
- }
- } catch (IllegalStateException e) {
- if (expectSuccess) {
- fail("Expected RangingReport.Builder.build() to succeed");
- }
- }
- return report;
- }
-
- @Test
- public void testParcel() {
- Parcel parcel = Parcel.obtain();
- RangingReport report = UwbTestUtils.getRangingReports(5);
- report.writeToParcel(parcel, 0);
- parcel.setDataPosition(0);
- RangingReport fromParcel = RangingReport.CREATOR.createFromParcel(parcel);
- assertEquals(report, fromParcel);
- }
-}
diff --git a/core/tests/uwbtests/src/android/uwb/RangingSessionTest.java b/core/tests/uwbtests/src/android/uwb/RangingSessionTest.java
deleted file mode 100644
index e5eea26f5d11..000000000000
--- a/core/tests/uwbtests/src/android/uwb/RangingSessionTest.java
+++ /dev/null
@@ -1,378 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.uwb;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import android.os.PersistableBundle;
-import android.os.RemoteException;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
-
-import java.util.concurrent.Executor;
-
-/**
- * Test of {@link RangingSession}.
- */
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class RangingSessionTest {
- private static final Executor EXECUTOR = UwbTestUtils.getExecutor();
- private static final PersistableBundle PARAMS = new PersistableBundle();
- private static final @RangingSession.Callback.Reason int REASON =
- RangingSession.Callback.REASON_GENERIC_ERROR;
-
- @Test
- public void testOnRangingOpened_OnOpenSuccessCalled() {
- SessionHandle handle = new SessionHandle(123);
- RangingSession.Callback callback = mock(RangingSession.Callback.class);
- IUwbAdapter adapter = mock(IUwbAdapter.class);
- RangingSession session = new RangingSession(EXECUTOR, callback, adapter, handle);
- verifyOpenState(session, false);
-
- session.onRangingOpened();
- verifyOpenState(session, true);
-
- // Verify that the onOpenSuccess callback was invoked
- verify(callback, times(1)).onOpened(eq(session));
- verify(callback, times(0)).onClosed(anyInt(), any());
- }
-
- @Test
- public void testOnRangingOpened_CannotOpenClosedSession() {
- SessionHandle handle = new SessionHandle(123);
- RangingSession.Callback callback = mock(RangingSession.Callback.class);
- IUwbAdapter adapter = mock(IUwbAdapter.class);
- RangingSession session = new RangingSession(EXECUTOR, callback, adapter, handle);
-
- session.onRangingOpened();
- verifyOpenState(session, true);
- verify(callback, times(1)).onOpened(eq(session));
- verify(callback, times(0)).onClosed(anyInt(), any());
-
- session.onRangingClosed(REASON, PARAMS);
- verifyOpenState(session, false);
- verify(callback, times(1)).onOpened(eq(session));
- verify(callback, times(1)).onClosed(anyInt(), any());
-
- // Now invoke the ranging started callback and ensure the session remains closed
- session.onRangingOpened();
- verifyOpenState(session, false);
- verify(callback, times(1)).onOpened(eq(session));
- verify(callback, times(1)).onClosed(anyInt(), any());
- }
-
- @Test
- public void testOnRangingClosed_OnClosedCalledWhenSessionNotOpen() {
- SessionHandle handle = new SessionHandle(123);
- RangingSession.Callback callback = mock(RangingSession.Callback.class);
- IUwbAdapter adapter = mock(IUwbAdapter.class);
- RangingSession session = new RangingSession(EXECUTOR, callback, adapter, handle);
- verifyOpenState(session, false);
-
- session.onRangingClosed(REASON, PARAMS);
- verifyOpenState(session, false);
-
- // Verify that the onOpenSuccess callback was invoked
- verify(callback, times(0)).onOpened(eq(session));
- verify(callback, times(1)).onClosed(anyInt(), any());
- }
-
- @Test
- public void testOnRangingClosed_OnClosedCalled() {
- SessionHandle handle = new SessionHandle(123);
- RangingSession.Callback callback = mock(RangingSession.Callback.class);
- IUwbAdapter adapter = mock(IUwbAdapter.class);
- RangingSession session = new RangingSession(EXECUTOR, callback, adapter, handle);
- session.onRangingStarted(PARAMS);
- session.onRangingClosed(REASON, PARAMS);
- verify(callback, times(1)).onClosed(anyInt(), any());
-
- verifyOpenState(session, false);
- session.onRangingClosed(REASON, PARAMS);
- verify(callback, times(2)).onClosed(anyInt(), any());
- }
-
- @Test
- public void testOnRangingResult_OnReportReceivedCalled() {
- SessionHandle handle = new SessionHandle(123);
- RangingSession.Callback callback = mock(RangingSession.Callback.class);
- IUwbAdapter adapter = mock(IUwbAdapter.class);
- RangingSession session = new RangingSession(EXECUTOR, callback, adapter, handle);
- verifyOpenState(session, false);
-
- session.onRangingStarted(PARAMS);
- verifyOpenState(session, true);
-
- RangingReport report = UwbTestUtils.getRangingReports(1);
- session.onRangingResult(report);
- verify(callback, times(1)).onReportReceived(eq(report));
- }
-
- @Test
- public void testStart_CannotStartIfAlreadyStarted() throws RemoteException {
- SessionHandle handle = new SessionHandle(123);
- RangingSession.Callback callback = mock(RangingSession.Callback.class);
- IUwbAdapter adapter = mock(IUwbAdapter.class);
- RangingSession session = new RangingSession(EXECUTOR, callback, adapter, handle);
- doAnswer(new StartAnswer(session)).when(adapter).startRanging(any(), any());
- session.onRangingOpened();
-
- session.start(PARAMS);
- verify(callback, times(1)).onStarted(any());
-
- // Calling start again should throw an illegal state
- verifyThrowIllegalState(() -> session.start(PARAMS));
- verify(callback, times(1)).onStarted(any());
- }
-
- @Test
- public void testStop_CannotStopIfAlreadyStopped() throws RemoteException {
- SessionHandle handle = new SessionHandle(123);
- RangingSession.Callback callback = mock(RangingSession.Callback.class);
- IUwbAdapter adapter = mock(IUwbAdapter.class);
- RangingSession session = new RangingSession(EXECUTOR, callback, adapter, handle);
- doAnswer(new StartAnswer(session)).when(adapter).startRanging(any(), any());
- doAnswer(new StopAnswer(session)).when(adapter).stopRanging(any());
- session.onRangingOpened();
- session.start(PARAMS);
-
- verifyNoThrowIllegalState(session::stop);
- verify(callback, times(1)).onStopped();
-
- // Calling stop again should throw an illegal state
- verifyThrowIllegalState(session::stop);
- verify(callback, times(1)).onStopped();
- }
-
- @Test
- public void testReconfigure_OnlyWhenOpened() throws RemoteException {
- SessionHandle handle = new SessionHandle(123);
- RangingSession.Callback callback = mock(RangingSession.Callback.class);
- IUwbAdapter adapter = mock(IUwbAdapter.class);
- RangingSession session = new RangingSession(EXECUTOR, callback, adapter, handle);
- doAnswer(new StartAnswer(session)).when(adapter).startRanging(any(), any());
- doAnswer(new ReconfigureAnswer(session)).when(adapter).reconfigureRanging(any(), any());
-
- verifyThrowIllegalState(() -> session.reconfigure(PARAMS));
- verify(callback, times(0)).onReconfigured(any());
- verifyOpenState(session, false);
-
- session.onRangingOpened();
- verifyNoThrowIllegalState(() -> session.reconfigure(PARAMS));
- verify(callback, times(1)).onReconfigured(any());
- verifyOpenState(session, true);
-
- session.onRangingStarted(PARAMS);
- verifyNoThrowIllegalState(() -> session.reconfigure(PARAMS));
- verify(callback, times(2)).onReconfigured(any());
- verifyOpenState(session, true);
-
- session.onRangingStopped();
- verifyNoThrowIllegalState(() -> session.reconfigure(PARAMS));
- verify(callback, times(3)).onReconfigured(any());
- verifyOpenState(session, true);
-
-
- session.onRangingClosed(REASON, PARAMS);
- verifyThrowIllegalState(() -> session.reconfigure(PARAMS));
- verify(callback, times(3)).onReconfigured(any());
- verifyOpenState(session, false);
- }
-
- @Test
- public void testClose_NoCallbackUntilInvoked() throws RemoteException {
- SessionHandle handle = new SessionHandle(123);
- RangingSession.Callback callback = mock(RangingSession.Callback.class);
- IUwbAdapter adapter = mock(IUwbAdapter.class);
- RangingSession session = new RangingSession(EXECUTOR, callback, adapter, handle);
- session.onRangingOpened();
-
- // Calling close multiple times should invoke closeRanging until the session receives
- // the onClosed callback.
- int totalCallsBeforeOnRangingClosed = 3;
- for (int i = 1; i <= totalCallsBeforeOnRangingClosed; i++) {
- session.close();
- verifyOpenState(session, true);
- verify(adapter, times(i)).closeRanging(handle);
- verify(callback, times(0)).onClosed(anyInt(), any());
- }
-
- // After onClosed is invoked, then the adapter should no longer be called for each call to
- // the session's close.
- final int totalCallsAfterOnRangingClosed = 2;
- for (int i = 1; i <= totalCallsAfterOnRangingClosed; i++) {
- session.onRangingClosed(REASON, PARAMS);
- verifyOpenState(session, false);
- verify(adapter, times(totalCallsBeforeOnRangingClosed)).closeRanging(handle);
- verify(callback, times(i)).onClosed(anyInt(), any());
- }
- }
-
- @Test
- public void testClose_OnClosedCalled() throws RemoteException {
- SessionHandle handle = new SessionHandle(123);
- RangingSession.Callback callback = mock(RangingSession.Callback.class);
- IUwbAdapter adapter = mock(IUwbAdapter.class);
- RangingSession session = new RangingSession(EXECUTOR, callback, adapter, handle);
- doAnswer(new CloseAnswer(session)).when(adapter).closeRanging(any());
- session.onRangingOpened();
-
- session.close();
- verify(callback, times(1)).onClosed(anyInt(), any());
- }
-
- @Test
- public void testClose_CannotInteractFurther() throws RemoteException {
- SessionHandle handle = new SessionHandle(123);
- RangingSession.Callback callback = mock(RangingSession.Callback.class);
- IUwbAdapter adapter = mock(IUwbAdapter.class);
- RangingSession session = new RangingSession(EXECUTOR, callback, adapter, handle);
- doAnswer(new CloseAnswer(session)).when(adapter).closeRanging(any());
- session.close();
-
- verifyThrowIllegalState(() -> session.start(PARAMS));
- verifyThrowIllegalState(() -> session.reconfigure(PARAMS));
- verifyThrowIllegalState(() -> session.stop());
- verifyNoThrowIllegalState(() -> session.close());
- }
-
- @Test
- public void testOnRangingResult_OnReportReceivedCalledWhenOpen() {
- SessionHandle handle = new SessionHandle(123);
- RangingSession.Callback callback = mock(RangingSession.Callback.class);
- IUwbAdapter adapter = mock(IUwbAdapter.class);
- RangingSession session = new RangingSession(EXECUTOR, callback, adapter, handle);
-
- assertFalse(session.isOpen());
- session.onRangingStarted(PARAMS);
- assertTrue(session.isOpen());
-
- // Verify that the onReportReceived callback was invoked
- RangingReport report = UwbTestUtils.getRangingReports(1);
- session.onRangingResult(report);
- verify(callback, times(1)).onReportReceived(report);
- }
-
- @Test
- public void testOnRangingResult_OnReportReceivedNotCalledWhenNotOpen() {
- SessionHandle handle = new SessionHandle(123);
- RangingSession.Callback callback = mock(RangingSession.Callback.class);
- IUwbAdapter adapter = mock(IUwbAdapter.class);
- RangingSession session = new RangingSession(EXECUTOR, callback, adapter, handle);
-
- assertFalse(session.isOpen());
-
- // Verify that the onReportReceived callback was invoked
- RangingReport report = UwbTestUtils.getRangingReports(1);
- session.onRangingResult(report);
- verify(callback, times(0)).onReportReceived(report);
- }
-
- private void verifyOpenState(RangingSession session, boolean expected) {
- assertEquals(expected, session.isOpen());
- }
-
- private void verifyThrowIllegalState(Runnable runnable) {
- try {
- runnable.run();
- fail();
- } catch (IllegalStateException e) {
- // Pass
- }
- }
-
- private void verifyNoThrowIllegalState(Runnable runnable) {
- try {
- runnable.run();
- } catch (IllegalStateException e) {
- fail();
- }
- }
-
- abstract class AdapterAnswer implements Answer {
- protected RangingSession mSession;
-
- protected AdapterAnswer(RangingSession session) {
- mSession = session;
- }
- }
-
- class StartAnswer extends AdapterAnswer {
- StartAnswer(RangingSession session) {
- super(session);
- }
-
- @Override
- public Object answer(InvocationOnMock invocation) {
- mSession.onRangingStarted(PARAMS);
- return null;
- }
- }
-
- class ReconfigureAnswer extends AdapterAnswer {
- ReconfigureAnswer(RangingSession session) {
- super(session);
- }
-
- @Override
- public Object answer(InvocationOnMock invocation) {
- mSession.onRangingReconfigured(PARAMS);
- return null;
- }
- }
-
- class StopAnswer extends AdapterAnswer {
- StopAnswer(RangingSession session) {
- super(session);
- }
-
- @Override
- public Object answer(InvocationOnMock invocation) {
- mSession.onRangingStopped();
- return null;
- }
- }
-
- class CloseAnswer extends AdapterAnswer {
- CloseAnswer(RangingSession session) {
- super(session);
- }
-
- @Override
- public Object answer(InvocationOnMock invocation) {
- mSession.onRangingClosed(REASON, PARAMS);
- return null;
- }
- }
-}
diff --git a/core/tests/uwbtests/src/android/uwb/SessionHandleTest.java b/core/tests/uwbtests/src/android/uwb/SessionHandleTest.java
deleted file mode 100644
index 8b42ff7f62a7..000000000000
--- a/core/tests/uwbtests/src/android/uwb/SessionHandleTest.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.uwb;
-
-import static org.junit.Assert.assertEquals;
-
-import android.os.Parcel;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-/**
- * Test of {@link SessionHandle}.
- */
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class SessionHandleTest {
-
- @Test
- public void testBasic() {
- int handleId = 12;
- SessionHandle handle = new SessionHandle(handleId);
- assertEquals(handle.getId(), handleId);
- }
-
- @Test
- public void testParcel() {
- Parcel parcel = Parcel.obtain();
- SessionHandle handle = new SessionHandle(10);
- handle.writeToParcel(parcel, 0);
- parcel.setDataPosition(0);
- SessionHandle fromParcel = SessionHandle.CREATOR.createFromParcel(parcel);
- assertEquals(handle, fromParcel);
- }
-}
diff --git a/core/tests/uwbtests/src/android/uwb/UwbAddressTest.java b/core/tests/uwbtests/src/android/uwb/UwbAddressTest.java
deleted file mode 100644
index ccc88a9a5399..000000000000
--- a/core/tests/uwbtests/src/android/uwb/UwbAddressTest.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.uwb;
-
-import static org.junit.Assert.assertEquals;
-
-import android.os.Parcel;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-/**
- * Test of {@link UwbAddress}.
- */
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class UwbAddressTest {
-
- @Test
- public void testFromBytes_Short() {
- runFromBytes(UwbAddress.SHORT_ADDRESS_BYTE_LENGTH);
- }
-
- @Test
- public void testFromBytes_Extended() {
- runFromBytes(UwbAddress.EXTENDED_ADDRESS_BYTE_LENGTH);
- }
-
- private void runFromBytes(int len) {
- byte[] addressBytes = getByteArray(len);
- UwbAddress address = UwbAddress.fromBytes(addressBytes);
- assertEquals(address.size(), len);
- assertEquals(addressBytes, address.toBytes());
- }
-
- private byte[] getByteArray(int len) {
- byte[] res = new byte[len];
- for (int i = 0; i < len; i++) {
- res[i] = (byte) i;
- }
- return res;
- }
-
- @Test
- public void testParcel_Short() {
- runParcel(true);
- }
-
- @Test
- public void testParcel_Extended() {
- runParcel(false);
- }
-
- private void runParcel(boolean useShortAddress) {
- Parcel parcel = Parcel.obtain();
- UwbAddress address = UwbTestUtils.getUwbAddress(useShortAddress);
- address.writeToParcel(parcel, 0);
- parcel.setDataPosition(0);
- UwbAddress fromParcel = UwbAddress.CREATOR.createFromParcel(parcel);
- assertEquals(address, fromParcel);
- }
-}
diff --git a/core/tests/uwbtests/src/android/uwb/UwbManagerTest.java b/core/tests/uwbtests/src/android/uwb/UwbManagerTest.java
deleted file mode 100644
index 4983bed742fd..000000000000
--- a/core/tests/uwbtests/src/android/uwb/UwbManagerTest.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.uwb;
-
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-
-import android.content.Context;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-/**
- * Test of {@link UwbManager}.
- */
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class UwbManagerTest {
-
- public final Context mContext = InstrumentationRegistry.getContext();
-
- @Test
- public void testServiceAvailable() {
- UwbManager manager = mContext.getSystemService(UwbManager.class);
- if (UwbTestUtils.isUwbSupported(mContext)) {
- assertNotNull(manager);
- } else {
- assertNull(manager);
- }
- }
-}
diff --git a/libs/WindowManager/Shell/res/drawable/pip_expand.xml b/libs/WindowManager/Shell/res/drawable/pip_expand.xml
index c99d81934aab..d36c4f72ecd0 100644
--- a/libs/WindowManager/Shell/res/drawable/pip_expand.xml
+++ b/libs/WindowManager/Shell/res/drawable/pip_expand.xml
@@ -14,8 +14,8 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="36dp"
- android:height="36dp"
+ android:width="@dimen/pip_expand_action_inner_size"
+ android:height="@dimen/pip_expand_action_inner_size"
android:viewportWidth="36"
android:viewportHeight="36">
@@ -25,4 +25,4 @@
android:fillColor="#FFFFFF"
android:pathData="M10 21H7v8h8v-3h-5v-5zm-3-6h3v-5h5V7H7v8zm19 11h-5v3h8v-8h-3v5zM21
7v3h5v5h3V7h-8z" />
-</vector> \ No newline at end of file
+</vector>
diff --git a/libs/WindowManager/Shell/res/drawable/pip_ic_close_white.xml b/libs/WindowManager/Shell/res/drawable/pip_ic_close_white.xml
index bcc850a854de..60456267afef 100644
--- a/libs/WindowManager/Shell/res/drawable/pip_ic_close_white.xml
+++ b/libs/WindowManager/Shell/res/drawable/pip_ic_close_white.xml
@@ -15,8 +15,8 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24.0dp"
- android:height="24.0dp"
+ android:width="@dimen/pip_action_inner_size"
+ android:height="@dimen/pip_action_inner_size"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
diff --git a/libs/WindowManager/Shell/res/drawable/pip_ic_pause_white.xml b/libs/WindowManager/Shell/res/drawable/pip_ic_pause_white.xml
index ef9b2d9c1c63..0c469f7abb78 100644
--- a/libs/WindowManager/Shell/res/drawable/pip_ic_pause_white.xml
+++ b/libs/WindowManager/Shell/res/drawable/pip_ic_pause_white.xml
@@ -15,8 +15,8 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24dp"
- android:height="24dp"
+ android:width="@dimen/pip_action_inner_size"
+ android:height="@dimen/pip_action_inner_size"
android:viewportWidth="24"
android:viewportHeight="24">
diff --git a/libs/WindowManager/Shell/res/drawable/pip_ic_play_arrow_white.xml b/libs/WindowManager/Shell/res/drawable/pip_ic_play_arrow_white.xml
index f12d2cbebc87..8567afa3232c 100644
--- a/libs/WindowManager/Shell/res/drawable/pip_ic_play_arrow_white.xml
+++ b/libs/WindowManager/Shell/res/drawable/pip_ic_play_arrow_white.xml
@@ -15,8 +15,8 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24dp"
- android:height="24dp"
+ android:width="@dimen/pip_action_inner_size"
+ android:height="@dimen/pip_action_inner_size"
android:viewportWidth="24"
android:viewportHeight="24">
diff --git a/libs/WindowManager/Shell/res/drawable/pip_ic_settings.xml b/libs/WindowManager/Shell/res/drawable/pip_ic_settings.xml
index b61e98ce2f9f..73ec167f1f6f 100644
--- a/libs/WindowManager/Shell/res/drawable/pip_ic_settings.xml
+++ b/libs/WindowManager/Shell/res/drawable/pip_ic_settings.xml
@@ -15,8 +15,8 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24dp"
- android:height="24dp"
+ android:width="@dimen/pip_action_inner_size"
+ android:height="@dimen/pip_action_inner_size"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
diff --git a/libs/WindowManager/Shell/res/drawable/pip_ic_skip_next_white.xml b/libs/WindowManager/Shell/res/drawable/pip_ic_skip_next_white.xml
index 040c7e642241..6c5542131ab8 100644
--- a/libs/WindowManager/Shell/res/drawable/pip_ic_skip_next_white.xml
+++ b/libs/WindowManager/Shell/res/drawable/pip_ic_skip_next_white.xml
@@ -15,8 +15,8 @@ Copyright (C) 2017 The Android Open Source Project
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24dp"
- android:height="24dp"
+ android:width="@dimen/pip_action_inner_size"
+ android:height="@dimen/pip_action_inner_size"
android:viewportWidth="24"
android:viewportHeight="24">
@@ -25,4 +25,4 @@ Copyright (C) 2017 The Android Open Source Project
android:pathData="M6 18l8.5-6L6 6v12zM16 6v12h2V6h-2z" />
<path
android:pathData="M0 0h24v24H0z" />
-</vector> \ No newline at end of file
+</vector>
diff --git a/libs/WindowManager/Shell/res/drawable/pip_ic_skip_previous_white.xml b/libs/WindowManager/Shell/res/drawable/pip_ic_skip_previous_white.xml
index b9b94b73a00f..6b5382b662b1 100644
--- a/libs/WindowManager/Shell/res/drawable/pip_ic_skip_previous_white.xml
+++ b/libs/WindowManager/Shell/res/drawable/pip_ic_skip_previous_white.xml
@@ -15,8 +15,8 @@ Copyright (C) 2017 The Android Open Source Project
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24dp"
- android:height="24dp"
+ android:width="@dimen/pip_action_inner_size"
+ android:height="@dimen/pip_action_inner_size"
android:viewportWidth="24"
android:viewportHeight="24">
@@ -25,4 +25,4 @@ Copyright (C) 2017 The Android Open Source Project
android:pathData="M6 6h2v12H6zm3.5 6l8.5 6V6z" />
<path
android:pathData="M0 0h24v24H0z" />
-</vector> \ No newline at end of file
+</vector>
diff --git a/libs/WindowManager/Shell/res/layout/pip_menu.xml b/libs/WindowManager/Shell/res/layout/pip_menu.xml
index b581f555c234..9fe024748610 100644
--- a/libs/WindowManager/Shell/res/layout/pip_menu.xml
+++ b/libs/WindowManager/Shell/res/layout/pip_menu.xml
@@ -40,7 +40,7 @@
android:layout_height="@dimen/pip_expand_action_size"
android:layout_gravity="center"
android:contentDescription="@string/pip_phone_expand"
- android:padding="10dp"
+ android:gravity="center"
android:src="@drawable/pip_expand"
android:background="?android:selectableItemBackgroundBorderless" />
</FrameLayout>
@@ -72,8 +72,8 @@
android:id="@+id/settings"
android:layout_width="@dimen/pip_action_size"
android:layout_height="@dimen/pip_action_size"
- android:padding="@dimen/pip_action_padding"
android:contentDescription="@string/pip_phone_settings"
+ android:gravity="center"
android:src="@drawable/pip_ic_settings"
android:background="?android:selectableItemBackgroundBorderless" />
@@ -81,8 +81,8 @@
android:id="@+id/dismiss"
android:layout_width="@dimen/pip_action_size"
android:layout_height="@dimen/pip_action_size"
- android:padding="@dimen/pip_action_padding"
android:contentDescription="@string/pip_phone_close"
+ android:gravity="center"
android:src="@drawable/pip_ic_close_white"
android:background="?android:selectableItemBackgroundBorderless" />
</LinearLayout>
diff --git a/libs/WindowManager/Shell/res/layout/pip_menu_action.xml b/libs/WindowManager/Shell/res/layout/pip_menu_action.xml
index 7a026ca63f50..a733b31d9fb0 100644
--- a/libs/WindowManager/Shell/res/layout/pip_menu_action.xml
+++ b/libs/WindowManager/Shell/res/layout/pip_menu_action.xml
@@ -14,10 +14,18 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<ImageButton
+<com.android.wm.shell.pip.phone.PipMenuActionView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="@dimen/pip_action_size"
android:layout_height="@dimen/pip_action_size"
- android:padding="@dimen/pip_action_padding"
android:background="?android:selectableItemBackgroundBorderless"
- android:forceHasOverlappingRendering="false" />
+ android:forceHasOverlappingRendering="false">
+
+ <ImageView
+ android:id="@+id/image"
+ android:layout_width="@dimen/pip_action_inner_size"
+ android:layout_height="@dimen/pip_action_inner_size"
+ android:layout_gravity="center"
+ android:scaleType="fitXY"/>
+
+</com.android.wm.shell.pip.phone.PipMenuActionView>
diff --git a/libs/WindowManager/Shell/res/values/dimen.xml b/libs/WindowManager/Shell/res/values/dimen.xml
index 583964b2f4a4..75bed3777a9d 100644
--- a/libs/WindowManager/Shell/res/values/dimen.xml
+++ b/libs/WindowManager/Shell/res/values/dimen.xml
@@ -21,14 +21,20 @@
<dimen name="floating_dismiss_gradient_height">250dp</dimen>
<!-- The padding around a PiP actions. -->
- <dimen name="pip_action_padding">12dp</dimen>
+ <dimen name="pip_action_padding">16dp</dimen>
<!-- The height of the PiP actions container in which the actions are vertically centered. -->
<dimen name="pip_action_size">48dp</dimen>
- <!-- The width and height of the PiP expand action. -->
+ <!-- The width and height of the PiP action asset drawn within the container. -->
+ <dimen name="pip_action_inner_size">20dp</dimen>
+
+ <!-- The width and height of the PiP expand action container. -->
<dimen name="pip_expand_action_size">60dp</dimen>
+ <!-- The width and height of the PiP expand action asset drawn within the container. -->
+ <dimen name="pip_expand_action_inner_size">28dp</dimen>
+
<!-- The padding between actions in the PiP in landscape Note that the PiP does not reflect
the configuration of the device, so we can't use -land resources. -->
<dimen name="pip_between_action_padding_land">8dp</dimen>
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuActionView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuActionView.java
new file mode 100644
index 000000000000..f11ae422e837
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuActionView.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2021 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.wm.shell.pip.phone;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+
+import com.android.wm.shell.R;
+
+/**
+ * Container layout wraps single action image view drawn in PiP menu and can restrict the size of
+ * action image view (see pip_menu_action.xml).
+ */
+public class PipMenuActionView extends FrameLayout {
+ private ImageView mImageView;
+
+ public PipMenuActionView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+ mImageView = findViewById(R.id.image);
+ }
+
+ /** pass through to internal {@link #mImageView} */
+ public void setImageDrawable(Drawable drawable) {
+ mImageView.setImageDrawable(drawable);
+ }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java
index 1cf3a48e9575..0d64407f649f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java
@@ -59,7 +59,6 @@ import android.view.ViewRootImpl;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.FrameLayout;
-import android.widget.ImageButton;
import android.widget.LinearLayout;
import com.android.wm.shell.R;
@@ -407,7 +406,7 @@ public class PipMenuView extends FrameLayout {
// Ensure we have as many buttons as actions
final LayoutInflater inflater = LayoutInflater.from(mContext);
while (mActionsGroup.getChildCount() < mActions.size()) {
- final ImageButton actionView = (ImageButton) inflater.inflate(
+ final PipMenuActionView actionView = (PipMenuActionView) inflater.inflate(
R.layout.pip_menu_action, mActionsGroup, false);
mActionsGroup.addView(actionView);
}
@@ -424,7 +423,8 @@ public class PipMenuView extends FrameLayout {
&& (stackBounds.width() > stackBounds.height());
for (int i = 0; i < mActions.size(); i++) {
final RemoteAction action = mActions.get(i);
- final ImageButton actionView = (ImageButton) mActionsGroup.getChildAt(i);
+ final PipMenuActionView actionView =
+ (PipMenuActionView) mActionsGroup.getChildAt(i);
// TODO: Check if the action drawable has changed before we reload it
action.getIcon().loadDrawableAsync(mContext, d -> {
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index 607c8f11e01a..cf31e4141a6d 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -2414,37 +2414,44 @@ final public class MediaCodec implements PlaybackComponent {
* This indicates that the requested key was not found when trying to
* perform a decrypt operation. The operation can be retried after adding
* the correct decryption key.
+ * @deprecated Please use {@link MediaDrm.ErrorCodes#ERROR_NO_KEY}.
*/
- public static final int ERROR_NO_KEY = 1;
+ public static final int ERROR_NO_KEY = MediaDrm.ErrorCodes.ERROR_NO_KEY;
/**
* This indicates that the key used for decryption is no longer
* valid due to license term expiration. The operation can be retried
* after updating the expired keys.
+ * @deprecated Please use {@link MediaDrm.ErrorCodes#ERROR_KEY_EXPIRED}.
*/
- public static final int ERROR_KEY_EXPIRED = 2;
+ public static final int ERROR_KEY_EXPIRED = MediaDrm.ErrorCodes.ERROR_KEY_EXPIRED;
/**
* This indicates that a required crypto resource was not able to be
* allocated while attempting the requested operation. The operation
* can be retried if the app is able to release resources.
+ * @deprecated Please use {@link MediaDrm.ErrorCodes#ERROR_RESOURCE_BUSY}
*/
- public static final int ERROR_RESOURCE_BUSY = 3;
+ public static final int ERROR_RESOURCE_BUSY = MediaDrm.ErrorCodes.ERROR_RESOURCE_BUSY;
/**
* This indicates that the output protection levels supported by the
* device are not sufficient to meet the requirements set by the
* content owner in the license policy.
+ * @deprecated Please use {@link MediaDrm.ErrorCodes#ERROR_INSUFFICIENT_OUTPUT_PROTECTION}
*/
- public static final int ERROR_INSUFFICIENT_OUTPUT_PROTECTION = 4;
+ public static final int ERROR_INSUFFICIENT_OUTPUT_PROTECTION =
+ MediaDrm.ErrorCodes.ERROR_INSUFFICIENT_OUTPUT_PROTECTION;
/**
* This indicates that decryption was attempted on a session that is
* not opened, which could be due to a failure to open the session,
* closing the session prematurely, or the session being reclaimed
* by the resource manager.
+ * @deprecated Please use {@link MediaDrm.ErrorCodes#ERROR_SESSION_NOT_OPENED}
*/
- public static final int ERROR_SESSION_NOT_OPENED = 5;
+ public static final int ERROR_SESSION_NOT_OPENED =
+ MediaDrm.ErrorCodes.ERROR_SESSION_NOT_OPENED;
/**
* This indicates that an operation was attempted that could not be
@@ -2453,23 +2460,28 @@ final public class MediaCodec implements PlaybackComponent {
* device security features that aren't supported by the device,
* or due to an internal error in the crypto system that prevents
* the specified security policy from being met.
+ * @deprecated Please use {@link MediaDrm.ErrorCodes#ERROR_UNSUPPORTED_OPERATION}
*/
- public static final int ERROR_UNSUPPORTED_OPERATION = 6;
+ public static final int ERROR_UNSUPPORTED_OPERATION =
+ MediaDrm.ErrorCodes.ERROR_UNSUPPORTED_OPERATION;
/**
* This indicates that the security level of the device is not
* sufficient to meet the requirements set by the content owner
* in the license policy.
+ * @deprecated Please use {@link MediaDrm.ErrorCodes#ERROR_INSUFFICIENT_SECURITY}
*/
- public static final int ERROR_INSUFFICIENT_SECURITY = 7;
+ public static final int ERROR_INSUFFICIENT_SECURITY =
+ MediaDrm.ErrorCodes.ERROR_INSUFFICIENT_SECURITY;
/**
* This indicates that the video frame being decrypted exceeds
* the size of the device's protected output buffers. When
* encountering this error the app should try playing content
* of a lower resolution.
+ * @deprecated Please use {@link MediaDrm.ErrorCodes#ERROR_FRAME_TOO_LARGE}
*/
- public static final int ERROR_FRAME_TOO_LARGE = 8;
+ public static final int ERROR_FRAME_TOO_LARGE = MediaDrm.ErrorCodes.ERROR_FRAME_TOO_LARGE;
/**
* This error indicates that session state has been
@@ -2477,26 +2489,37 @@ final public class MediaCodec implements PlaybackComponent {
* of retaining crypto session state across device
* suspend/resume. The session must be closed and a new
* session opened to resume operation.
+ * @deprecated Please use {@link MediaDrm.ErrorCodes#ERROR_LOST_STATE}
*/
- public static final int ERROR_LOST_STATE = 9;
+ public static final int ERROR_LOST_STATE = MediaDrm.ErrorCodes.ERROR_LOST_STATE;
/** @hide */
@IntDef({
- ERROR_NO_KEY,
- ERROR_KEY_EXPIRED,
- ERROR_RESOURCE_BUSY,
- ERROR_INSUFFICIENT_OUTPUT_PROTECTION,
- ERROR_SESSION_NOT_OPENED,
- ERROR_UNSUPPORTED_OPERATION,
- ERROR_INSUFFICIENT_SECURITY,
- ERROR_FRAME_TOO_LARGE,
- ERROR_LOST_STATE
+ MediaDrm.ErrorCodes.ERROR_NO_KEY,
+ MediaDrm.ErrorCodes.ERROR_KEY_EXPIRED,
+ MediaDrm.ErrorCodes.ERROR_RESOURCE_BUSY,
+ MediaDrm.ErrorCodes.ERROR_INSUFFICIENT_OUTPUT_PROTECTION,
+ MediaDrm.ErrorCodes.ERROR_SESSION_NOT_OPENED,
+ MediaDrm.ErrorCodes.ERROR_UNSUPPORTED_OPERATION,
+ MediaDrm.ErrorCodes.ERROR_INSUFFICIENT_SECURITY,
+ MediaDrm.ErrorCodes.ERROR_FRAME_TOO_LARGE,
+ MediaDrm.ErrorCodes.ERROR_LOST_STATE,
+ MediaDrm.ErrorCodes.ERROR_GENERIC_OEM,
+ MediaDrm.ErrorCodes.ERROR_GENERIC_PLUGIN,
+ MediaDrm.ErrorCodes.ERROR_LICENSE_PARSE,
+ MediaDrm.ErrorCodes.ERROR_MEDIA_FRAMEWORK,
+ MediaDrm.ErrorCodes.ERROR_ZERO_SUBSAMPLES
})
@Retention(RetentionPolicy.SOURCE)
public @interface CryptoErrorCode {}
/**
- * Retrieve the error code associated with a CryptoException
+ * Returns error code associated with this {@link CryptoException}.
+ * <p>
+ * Please refer to {@link MediaDrm.ErrorCodes} for the general error
+ * handling strategy and details about each possible return value.
+ *
+ * @return an error code defined in {@link MediaDrm.ErrorCodes}.
*/
@CryptoErrorCode
public int getErrorCode() {
diff --git a/media/java/android/media/MediaDrm.java b/media/java/android/media/MediaDrm.java
index adb8a54c0167..f7467a636024 100644
--- a/media/java/android/media/MediaDrm.java
+++ b/media/java/android/media/MediaDrm.java
@@ -23,7 +23,11 @@ import android.annotation.Nullable;
import android.annotation.StringDef;
import android.annotation.TestApi;
import android.app.ActivityThread;
+import android.app.Application;
import android.compat.annotation.UnsupportedAppUsage;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.Signature;
import android.media.metrics.PlaybackComponent;
import android.os.Handler;
import android.os.HandlerExecutor;
@@ -39,7 +43,10 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.ref.WeakReference;
import java.nio.ByteBuffer;
import java.time.Instant;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
+import java.util.Base64;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
@@ -144,6 +151,7 @@ public final class MediaDrm implements AutoCloseable {
private static final String PERMISSION = android.Manifest.permission.ACCESS_DRM_CERTIFICATES;
private long mNativeContext;
+ private final String mAppPackageName;
/**
* Specify no certificate type
@@ -281,16 +289,371 @@ public final class MediaDrm implements AutoCloseable {
/* Native setup requires a weak reference to our object.
* It's easier to create it here than in C++.
*/
+ mAppPackageName = ActivityThread.currentOpPackageName();
native_setup(new WeakReference<MediaDrm>(this),
- getByteArrayFromUUID(uuid), ActivityThread.currentOpPackageName());
+ getByteArrayFromUUID(uuid), mAppPackageName);
mCloseGuard.open("release");
}
/**
- * Thrown when an unrecoverable failure occurs during a MediaDrm operation.
- * Extends java.lang.IllegalStateException with the addition of an error
+ * Error codes that may be returned from {@link
+ * MediaDrmStateException#getErrorCode()} and {@link
+ * MediaCodec.CryptoException#getErrorCode()}
+ * <p>
+ * The description of each error code includes steps that may be taken to
+ * resolve the error condition. For some errors however, a recovery action
+ * cannot be predetermined. The description of those codes refers to a
+ * general strategy for handling the error condition programmatically, which
+ * is to try the following in listed order until successful:
+ * <ol>
+ * <li> retry the operation </li>
+ * <li> if the operation is related to a session, {@link
+ * #closeSession(byte[]) close} the session, {@link #openSession() open} a
+ * new session, and retry the operation </li>
+ * <li> {@link #close() close} the {@link MediaDrm} instance and any other
+ * related components such as the {@link MediaCodec codec} and retry
+ * playback, or </li>
+ * <li> try using a different configuration of the {@link MediaDrm} plugin,
+ * such as a different {@link #openSession(int) security level}. </li>
+ * </ol>
+ * <p>
+ * If the problem still persists after all the aforementioned steps, please
+ * report the failure to the {@link MediaDrm} plugin vendor along with the
+ * {@link LogMessage log messages} returned by {@link
+ * MediaDrm#getLogMessages()}, and a bugreport if possible.
+ */
+ public final static class ErrorCodes {
+ private ErrorCodes() {}
+
+ /**
+ * ERROR_UNKNOWN is used where no other defined error code is applicable
+ * to the current failure.
+ * <p>
+ * Please see the general error handling strategy for unexpected errors
+ * described in {@link ErrorCodes}.
+ */
+ public static final int ERROR_UNKNOWN = 0;
+
+ /**
+ * The requested key was not found when trying to perform a decrypt
+ * operation.
+ * <p>
+ * The operation can be retried after adding the correct decryption key.
+ */
+ public static final int ERROR_NO_KEY = 1;
+
+ /**
+ * The key used for decryption is no longer valid due to license term
+ * expiration.
+ * <p>
+ * The operation can be retried after updating the expired keys.
+ */
+ public static final int ERROR_KEY_EXPIRED = 2;
+
+ /**
+ * A required crypto resource was not able to be allocated while
+ * attempting the requested operation.
+ * <p>
+ * The operation can be retried if the app is able to release resources.
+ */
+ public static final int ERROR_RESOURCE_BUSY = 3;
+
+ /**
+ * The output protection levels supported by the device are not
+ * sufficient to meet the requirements set by the content owner in the
+ * license policy.
+ */
+ public static final int ERROR_INSUFFICIENT_OUTPUT_PROTECTION = 4;
+
+ /**
+ * Decryption was attempted on a session that is not opened, which could
+ * be due to a failure to open the session, closing the session
+ * prematurely, the session being reclaimed by the resource manager, or
+ * a non-existent session id.
+ */
+ public static final int ERROR_SESSION_NOT_OPENED = 5;
+
+ /**
+ * An operation was attempted that could not be supported by the crypto
+ * system of the device in its current configuration.
+ * <p>
+ * This may occur when the license policy requires device security
+ * features that aren't supported by the device, or due to an internal
+ * error in the crypto system that prevents the specified security
+ * policy from being met.
+ */
+ public static final int ERROR_UNSUPPORTED_OPERATION = 6;
+
+ /**
+ * The security level of the device is not sufficient to meet the
+ * requirements set by the content owner in the license policy.
+ */
+ public static final int ERROR_INSUFFICIENT_SECURITY = 7;
+
+ /**
+ * The video frame being decrypted exceeds the size of the device's
+ * protected output buffers.
+ * <p>
+ * When encountering this error the app should try playing content
+ * of a lower resolution or skipping the problematic frame.
+ */
+ public static final int ERROR_FRAME_TOO_LARGE = 8;
+
+ /**
+ * The session state has been invalidated. This can occur on devices
+ * that are not capable of retaining crypto session state across device
+ * suspend/resume.
+ * <p>
+ * The session must be closed and a new session opened to resume
+ * operation.
+ */
+ public static final int ERROR_LOST_STATE = 9;
+
+ /**
+ * Certificate is malformed or is of the wrong type.
+ * <p>
+ * Ensure the certificate provided by the app or returned from the
+ * license server is valid. Check with the {@link MediaDrm} plugin
+ * vendor for the expected certificate format.
+ */
+ public static final int ERROR_CERTIFICATE_MALFORMED = 10;
+
+ /**
+ * Certificate has not been set.
+ * <p>
+ * Ensure the certificate has been provided by the app. Check with the
+ * {@link MediaDrm} plugin vendor for the expected method to provide
+ * {@link MediaDrm} a certificate.
+ */
+ public static final int ERROR_CERTIFICATE_MISSING = 11;
+
+ /**
+ * An error happened within the crypto library used by the drm plugin.
+ */
+ public static final int ERROR_CRYPTO_LIBRARY = 12;
+
+ /**
+ * Unexpected error reported by the device OEM subsystem.
+ * <p>
+ * Please see the general error handling strategy for unexpected errors
+ * described in {@link ErrorCodes}.
+ */
+ public static final int ERROR_GENERIC_OEM = 13;
+
+ /**
+ * Unexpected internal failure in {@link MediaDrm}/{@link MediaCrypto}.
+ * <p>
+ * Please see the general error handling strategy for unexpected errors
+ * described in {@link ErrorCodes}.
+ */
+ public static final int ERROR_GENERIC_PLUGIN = 14;
+
+ /**
+ * The init data parameter passed to {@link MediaDrm#getKeyRequest} is
+ * empty or invalid.
+ * <p>
+ * Init data is typically obtained from {@link
+ * MediaExtractor#getPsshInfo()} or {@link
+ * MediaExtractor#getDrmInitData()}. Check with the {@link MediaDrm}
+ * plugin vendor for the expected init data format.
+ */
+ public static final int ERROR_INIT_DATA = 15;
+
+ /**
+ * Either the key was not loaded from the license before attempting the
+ * operation, or the key ID parameter provided by the app is incorrect.
+ * <p>
+ * Ensure the proper keys are in the license, and check the key ID
+ * parameter provided by the app is correct. Check with the {@link
+ * MediaDrm} plugin vendor for the expected license format.
+ */
+ public static final int ERROR_KEY_NOT_LOADED = 16;
+
+ /**
+ * The license response was empty, fields are missing or otherwise
+ * unable to be parsed or decrypted.
+ * <p>
+ * Check for mistakes such as empty or overwritten buffers. Otherwise,
+ * check with the {@link MediaDrm} plugin vendor for the expected
+ * license format.
+ */
+ public static final int ERROR_LICENSE_PARSE = 17;
+
+ /**
+ * The operation (e.g. to renew or persist a license) is prohibited by
+ * the license policy.
+ * <p>
+ * Check the license policy configuration on the license server.
+ */
+ public static final int ERROR_LICENSE_POLICY = 18;
+
+ /**
+ * Failed to generate a release request because a field in the offline
+ * license is empty or malformed.
+ * <p>
+ * The license can't be released on the server, but the app may remove
+ * the offline license explicitly using {@link
+ * MediaDrm#removeOfflineLicense}.
+ */
+ public static final int ERROR_LICENSE_RELEASE = 19;
+
+ /**
+ * The license server detected an error in the license request.
+ * <p>
+ * Check for errors on the license server.
+ */
+ public static final int ERROR_LICENSE_REQUEST_REJECTED = 20;
+
+ /**
+ * Failed to restore an offline license because a field in the offline
+ * license is empty or malformed.
+ * <p>
+ * Try requesting the license again if the device is online.
+ */
+ public static final int ERROR_LICENSE_RESTORE = 21;
+
+ /**
+ * Offline license is in an invalid state for the attempted operation.
+ * <p>
+ * Check the sequence of API calls made that can affect offline license
+ * state. For example, this could happen when the app attempts to
+ * restore a license after it has been released.
+ */
+ public static final int ERROR_LICENSE_STATE = 22;
+
+ /**
+ * Failure in the media framework.
+ * <p>
+ * Try releasing media resources (e.g. {@link MediaCodec}, {@link
+ * MediaDrm}), and restarting playback.
+ */
+ public static final int ERROR_MEDIA_FRAMEWORK = 23;
+
+ /**
+ * Error loading the provisioned certificate.
+ * <p>
+ * Re-provisioning may resolve the problem; check with the {@link
+ * MediaDrm} plugin vendor for re-provisioning instructions. Otherwise,
+ * using a different security level may resolve the issue.
+ */
+ public static final int ERROR_PROVISIONING_CERTIFICATE = 24;
+
+ /**
+ * Required steps were not performed before provisioning was attempted.
+ * <p>
+ * Ask the {@link MediaDrm} plugin vendor for situations where this
+ * error may occur.
+ */
+ public static final int ERROR_PROVISIONING_CONFIG = 25;
+
+ /**
+ * The provisioning response was empty, fields are missing or otherwise
+ * unable to be parsed.
+ * <p>
+ * Check for mistakes such as empty or overwritten buffers. Otherwise,
+ * check with the {@link MediaDrm} plugin vendor for the expected
+ * provisioning response format.
+ */
+ public static final int ERROR_PROVISIONING_PARSE = 26;
+
+ /**
+ * Provisioning failed in a way that is likely to succeed on a
+ * subsequent attempt.
+ * <p>
+ * The app should retry the operation.
+ */
+ public static final int ERROR_PROVISIONING_RETRY = 27;
+
+ /**
+ * This indicates that apps using MediaDrm sessions are
+ * temporarily exceeding the capacity of available crypto
+ * resources.
+ * <p>
+ * The app should retry the operation later.
+ */
+ public static final int ERROR_RESOURCE_CONTENTION = 28;
+
+ /**
+ * Failed to generate a secure stop request because a field in the
+ * stored license is empty or malformed.
+ * <p>
+ * The secure stop can't be released on the server, but the app may
+ * remove it explicitly using {@link MediaDrm#removeSecureStop}.
+ */
+ public static final int ERROR_SECURE_STOP_RELEASE = 29;
+
+ /**
+ * The plugin was unable to read data from the filesystem.
+ * <p>
+ * Please see the general error handling strategy for unexpected errors
+ * described in {@link ErrorCodes}.
+ */
+ public static final int ERROR_STORAGE_READ = 30;
+
+ /**
+ * The plugin was unable to write data to the filesystem.
+ * <p>
+ * Please see the general error handling strategy for unexpected errors
+ * described in {@link ErrorCodes}.
+ */
+ public static final int ERROR_STORAGE_WRITE = 31;
+
+ /**
+ * {@link MediaCodec#queueSecureInputBuffer} called with 0 subsamples.
+ * <p>
+ * Check the {@link MediaCodec.CryptoInfo} object passed to {@link
+ * MediaCodec#queueSecureInputBuffer}.
+ */
+ public static final int ERROR_ZERO_SUBSAMPLES = 32;
+
+ }
+
+ /** @hide */
+ @IntDef({
+ ErrorCodes.ERROR_NO_KEY,
+ ErrorCodes.ERROR_KEY_EXPIRED,
+ ErrorCodes.ERROR_RESOURCE_BUSY,
+ ErrorCodes.ERROR_INSUFFICIENT_OUTPUT_PROTECTION,
+ ErrorCodes.ERROR_SESSION_NOT_OPENED,
+ ErrorCodes.ERROR_UNSUPPORTED_OPERATION,
+ ErrorCodes.ERROR_INSUFFICIENT_SECURITY,
+ ErrorCodes.ERROR_FRAME_TOO_LARGE,
+ ErrorCodes.ERROR_LOST_STATE,
+ ErrorCodes.ERROR_CERTIFICATE_MALFORMED,
+ ErrorCodes.ERROR_CERTIFICATE_MISSING,
+ ErrorCodes.ERROR_CRYPTO_LIBRARY,
+ ErrorCodes.ERROR_GENERIC_OEM,
+ ErrorCodes.ERROR_GENERIC_PLUGIN,
+ ErrorCodes.ERROR_INIT_DATA,
+ ErrorCodes.ERROR_KEY_NOT_LOADED,
+ ErrorCodes.ERROR_LICENSE_PARSE,
+ ErrorCodes.ERROR_LICENSE_POLICY,
+ ErrorCodes.ERROR_LICENSE_RELEASE,
+ ErrorCodes.ERROR_LICENSE_REQUEST_REJECTED,
+ ErrorCodes.ERROR_LICENSE_RESTORE,
+ ErrorCodes.ERROR_LICENSE_STATE,
+ ErrorCodes.ERROR_MEDIA_FRAMEWORK,
+ ErrorCodes.ERROR_PROVISIONING_CERTIFICATE,
+ ErrorCodes.ERROR_PROVISIONING_CONFIG,
+ ErrorCodes.ERROR_PROVISIONING_PARSE,
+ ErrorCodes.ERROR_PROVISIONING_RETRY,
+ ErrorCodes.ERROR_SECURE_STOP_RELEASE,
+ ErrorCodes.ERROR_STORAGE_READ,
+ ErrorCodes.ERROR_STORAGE_WRITE,
+ ErrorCodes.ERROR_ZERO_SUBSAMPLES
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface MediaDrmErrorCode {}
+
+ /**
+ * Thrown when a general failure occurs during a MediaDrm operation.
+ * Extends {@link IllegalStateException} with the addition of an error
* code that may be useful in diagnosing the failure.
+ * <p>
+ * Please refer to {@link ErrorCodes} for the general error handling
+ * strategy and details about each possible return value from {@link
+ * MediaDrmStateException#getErrorCode()}.
*/
public static final class MediaDrmStateException extends java.lang.IllegalStateException {
private final int mErrorCode;
@@ -311,15 +674,30 @@ public final class MediaDrm implements AutoCloseable {
}
/**
- * Retrieve the associated error code
+ * Returns error code associated with this {@link
+ * MediaDrmStateException}.
+ * <p>
+ * Please refer to {@link ErrorCodes} for the general error handling
+ * strategy and details about each possible return value.
*
- * @hide
+ * @return an error code defined in {@link MediaDrm.ErrorCodes}.
*/
+ @MediaDrmErrorCode
public int getErrorCode() {
return mErrorCode;
}
/**
+ * Returns true if the {@link MediaDrmStateException} is a transient
+ * issue, perhaps due to resource constraints, and that the operation
+ * (e.g. provisioning) may succeed on a subsequent attempt.
+ */
+ public boolean isTransient() {
+ return mErrorCode == ErrorCodes.ERROR_PROVISIONING_RETRY
+ || mErrorCode == ErrorCodes.ERROR_RESOURCE_CONTENTION;
+ }
+
+ /**
* Retrieve a developer-readable diagnostic information string
* associated with the exception. Do not show this to end-users,
* since this string will not be localized or generally comprehensible
@@ -332,7 +710,13 @@ public final class MediaDrm implements AutoCloseable {
}
/**
- * Thrown when an error occurs in any method that has a session context.
+ * {@link SessionException} is a misnomer because it may occur in methods
+ * <b>without</b> a session context.
+ * <p>
+ * A {@link SessionException} is most likely to be thrown when an operation
+ * failed in a way that is likely to succeed on a subsequent attempt; call
+ * {@link #isTransient()} to determine whether the app should retry the
+ * failing operation.
*/
public static final class SessionException extends RuntimeException {
public SessionException(int errorCode, @Nullable String detailMessage) {
@@ -342,6 +726,7 @@ public final class MediaDrm implements AutoCloseable {
/**
* The SessionException has an unknown error code.
+ * @deprecated Unused.
*/
public static final int ERROR_UNKNOWN = 0;
@@ -349,6 +734,10 @@ public final class MediaDrm implements AutoCloseable {
* This indicates that apps using MediaDrm sessions are
* temporarily exceeding the capacity of available crypto
* resources. The app should retry the operation later.
+ *
+ * @deprecated Please use {@link #isTransient()} instead of comparing
+ * the return value of {@link #getErrorCode()} against
+ * {@link SessionException#ERROR_RESOURCE_CONTENTION}.
*/
public static final int ERROR_RESOURCE_CONTENTION = 1;
@@ -361,12 +750,26 @@ public final class MediaDrm implements AutoCloseable {
/**
* Retrieve the error code associated with the SessionException
+ *
+ * @deprecated Please use {@link #isTransient()} instead of comparing
+ * the return value of {@link #getErrorCode()} against
+ * {@link SessionException#ERROR_RESOURCE_CONTENTION}.
*/
@SessionErrorCode
public int getErrorCode() {
return mErrorCode;
}
+ /**
+ * Returns true if the {@link SessionException} is a transient
+ * issue, perhaps due to resource constraints, and that the operation
+ * (e.g. provisioning, generating requests) may succeed on a subsequent
+ * attempt.
+ */
+ public boolean isTransient() {
+ return mErrorCode == ERROR_RESOURCE_CONTENTION;
+ }
+
private final int mErrorCode;
}
@@ -1144,12 +1547,78 @@ public final class MediaDrm implements AutoCloseable {
* problem with the certifcate
*/
@NonNull
- public native KeyRequest getKeyRequest(
+ public KeyRequest getKeyRequest(
@NonNull byte[] scope, @Nullable byte[] init,
@Nullable String mimeType, @KeyType int keyType,
@Nullable HashMap<String, String> optionalParameters)
- throws NotProvisionedException;
+ throws NotProvisionedException {
+ HashMap<String, String> internalParams;
+ if (optionalParameters == null) {
+ internalParams = new HashMap<>();
+ } else {
+ internalParams = new HashMap<>(optionalParameters);
+ }
+ byte[] rawBytes = getNewestAvailablePackageCertificateRawBytes();
+ byte[] hashBytes = null;
+ if (rawBytes != null) {
+ hashBytes = getDigestBytes(rawBytes, "SHA-256");
+ }
+ if (hashBytes != null) {
+ Base64.Encoder encoderB64 = Base64.getEncoder();
+ String hashBytesB64 = encoderB64.encodeToString(hashBytes);
+ internalParams.put("package_certificate_hash_bytes", hashBytesB64);
+ }
+ return getKeyRequestNative(scope, init, mimeType, keyType, internalParams);
+ }
+
+ @Nullable
+ private byte[] getNewestAvailablePackageCertificateRawBytes() {
+ Application application = ActivityThread.currentApplication();
+ if (application == null) {
+ Log.w(TAG, "pkg cert: Application is null");
+ return null;
+ }
+ PackageManager pm = application.getPackageManager();
+ if (pm == null) {
+ Log.w(TAG, "pkg cert: PackageManager is null");
+ return null;
+ }
+ PackageInfo packageInfo = null;
+ try {
+ packageInfo = pm.getPackageInfo(mAppPackageName,
+ PackageManager.GET_SIGNING_CERTIFICATES);
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.w(TAG, mAppPackageName, e);
+ }
+ if (packageInfo == null || packageInfo.signingInfo == null) {
+ Log.w(TAG, "pkg cert: PackageInfo or SigningInfo is null");
+ return null;
+ }
+ Signature[] signers = packageInfo.signingInfo.getApkContentsSigners();
+ if (signers != null && signers.length == 1) {
+ return signers[0].toByteArray();
+ }
+ Log.w(TAG, "pkg cert: " + signers.length + " signers");
+ return null;
+ }
+
+ @Nullable
+ private static byte[] getDigestBytes(@NonNull byte[] rawBytes, @NonNull String algorithm) {
+ try {
+ MessageDigest messageDigest = MessageDigest.getInstance(algorithm);
+ return messageDigest.digest(rawBytes);
+ } catch (NoSuchAlgorithmException e) {
+ Log.w(TAG, algorithm, e);
+ }
+ return null;
+ }
+ @NonNull
+ private native KeyRequest getKeyRequestNative(
+ @NonNull byte[] scope, @Nullable byte[] init,
+ @Nullable String mimeType, @KeyType int keyType,
+ @Nullable HashMap<String, String> optionalParameters)
+ throws NotProvisionedException;
/**
* A key response is received from the license server by the app, then it is
diff --git a/media/java/android/media/tv/TvInputManager.java b/media/java/android/media/tv/TvInputManager.java
index 740bc2dbeb43..c0185dcc4539 100644
--- a/media/java/android/media/tv/TvInputManager.java
+++ b/media/java/android/media/tv/TvInputManager.java
@@ -2525,7 +2525,9 @@ public final class TvInputManager {
/**
* Pauses TV program recording in the current recording session.
*
- * @param params A set of extra parameters which might be handled with this event.
+ * @param params Domain-specific data for this request. Keys <em>must</em> be a scoped
+ * name, i.e. prefixed with a package name you own, so that different developers
+ * will not create conflicting keys.
* {@link TvRecordingClient#pauseRecording(Bundle)}.
*/
void pauseRecording(@NonNull Bundle params) {
@@ -2543,7 +2545,9 @@ public final class TvInputManager {
/**
* Resumes TV program recording in the current recording session.
*
- * @param params A set of extra parameters which might be handled with this event.
+ * @param params Domain-specific data for this request. Keys <em>must</em> be a scoped
+ * name, i.e. prefixed with a package name you own, so that different developers
+ * will not create conflicting keys.
* {@link TvRecordingClient#resumeRecording(Bundle)}.
*/
void resumeRecording(@NonNull Bundle params) {
diff --git a/media/jni/android_media_MediaDrm.cpp b/media/jni/android_media_MediaDrm.cpp
index 22c3572e963b..6f1b6d3ba7b5 100644
--- a/media/jni/android_media_MediaDrm.cpp
+++ b/media/jni/android_media_MediaDrm.cpp
@@ -343,11 +343,56 @@ void JNIDrmListener::notify(DrmPlugin::EventType eventType, int extra,
}
}
+jint MediaErrorToJavaError(status_t err) {
+#define STATUS_CASE(status) \
+ case status: \
+ return J##status
+
+ switch (err) {
+ STATUS_CASE(ERROR_DRM_UNKNOWN);
+ STATUS_CASE(ERROR_DRM_NO_LICENSE);
+ STATUS_CASE(ERROR_DRM_LICENSE_EXPIRED);
+ STATUS_CASE(ERROR_DRM_RESOURCE_BUSY);
+ STATUS_CASE(ERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION);
+ STATUS_CASE(ERROR_DRM_SESSION_NOT_OPENED);
+ STATUS_CASE(ERROR_DRM_CANNOT_HANDLE);
+ STATUS_CASE(ERROR_DRM_INSUFFICIENT_SECURITY);
+ STATUS_CASE(ERROR_DRM_FRAME_TOO_LARGE);
+ STATUS_CASE(ERROR_DRM_SESSION_LOST_STATE);
+ STATUS_CASE(ERROR_DRM_CERTIFICATE_MALFORMED);
+ STATUS_CASE(ERROR_DRM_CERTIFICATE_MISSING);
+ STATUS_CASE(ERROR_DRM_CRYPTO_LIBRARY);
+ STATUS_CASE(ERROR_DRM_GENERIC_OEM);
+ STATUS_CASE(ERROR_DRM_GENERIC_PLUGIN);
+ STATUS_CASE(ERROR_DRM_INIT_DATA);
+ STATUS_CASE(ERROR_DRM_KEY_NOT_LOADED);
+ STATUS_CASE(ERROR_DRM_LICENSE_PARSE);
+ STATUS_CASE(ERROR_DRM_LICENSE_POLICY);
+ STATUS_CASE(ERROR_DRM_LICENSE_RELEASE);
+ STATUS_CASE(ERROR_DRM_LICENSE_REQUEST_REJECTED);
+ STATUS_CASE(ERROR_DRM_LICENSE_RESTORE);
+ STATUS_CASE(ERROR_DRM_LICENSE_STATE);
+ STATUS_CASE(ERROR_DRM_MEDIA_FRAMEWORK);
+ STATUS_CASE(ERROR_DRM_PROVISIONING_CERTIFICATE);
+ STATUS_CASE(ERROR_DRM_PROVISIONING_CONFIG);
+ STATUS_CASE(ERROR_DRM_PROVISIONING_PARSE);
+ STATUS_CASE(ERROR_DRM_PROVISIONING_RETRY);
+ STATUS_CASE(ERROR_DRM_RESOURCE_CONTENTION);
+ STATUS_CASE(ERROR_DRM_SECURE_STOP_RELEASE);
+ STATUS_CASE(ERROR_DRM_STORAGE_READ);
+ STATUS_CASE(ERROR_DRM_STORAGE_WRITE);
+ STATUS_CASE(ERROR_DRM_ZERO_SUBSAMPLES);
+#undef STATUS_CASE
+ }
+ return static_cast<jint>(err);
+}
+
static void throwStateException(JNIEnv *env, const char *msg, status_t err) {
ALOGE("Illegal state exception: %s (%d)", msg, err);
+ jint jerr = MediaErrorToJavaError(err);
jobject exception = env->NewObject(gFields.stateException.classId,
- gFields.stateException.init, static_cast<int>(err),
+ gFields.stateException.init, static_cast<int>(jerr),
env->NewStringUTF(msg));
env->Throw(static_cast<jthrowable>(exception));
}
@@ -2056,7 +2101,7 @@ static const JNINativeMethod gMethods[] = {
{ "closeSessionNative", "([B)V",
(void *)android_media_MediaDrm_closeSession },
- { "getKeyRequest", "([B[BLjava/lang/String;ILjava/util/HashMap;)"
+ { "getKeyRequestNative", "([B[BLjava/lang/String;ILjava/util/HashMap;)"
"Landroid/media/MediaDrm$KeyRequest;",
(void *)android_media_MediaDrm_getKeyRequest },
diff --git a/media/jni/android_media_MediaDrm.h b/media/jni/android_media_MediaDrm.h
index b1f544cb2dbe..dc0793af2d17 100644
--- a/media/jni/android_media_MediaDrm.h
+++ b/media/jni/android_media_MediaDrm.h
@@ -28,6 +28,44 @@
namespace {
+enum {
+ // TODO(b/180483929): use reverse jni e.g. android_media_MediaDrm_native_init
+ // KEEP IN SYNC with MediaDrm$ErrorCodes in MediaDrm.java!
+ JERROR_DRM_UNKNOWN = 0,
+ JERROR_DRM_NO_LICENSE = 1,
+ JERROR_DRM_LICENSE_EXPIRED = 2,
+ JERROR_DRM_RESOURCE_BUSY = 3,
+ JERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION = 4,
+ JERROR_DRM_SESSION_NOT_OPENED = 5,
+ JERROR_DRM_CANNOT_HANDLE = 6,
+ JERROR_DRM_INSUFFICIENT_SECURITY = 7,
+ JERROR_DRM_FRAME_TOO_LARGE = 8,
+ JERROR_DRM_SESSION_LOST_STATE = 9,
+ JERROR_DRM_CERTIFICATE_MALFORMED = 10,
+ JERROR_DRM_CERTIFICATE_MISSING = 11,
+ JERROR_DRM_CRYPTO_LIBRARY = 12,
+ JERROR_DRM_GENERIC_OEM = 13,
+ JERROR_DRM_GENERIC_PLUGIN = 14,
+ JERROR_DRM_INIT_DATA = 15,
+ JERROR_DRM_KEY_NOT_LOADED = 16,
+ JERROR_DRM_LICENSE_PARSE = 17,
+ JERROR_DRM_LICENSE_POLICY = 18,
+ JERROR_DRM_LICENSE_RELEASE = 19,
+ JERROR_DRM_LICENSE_REQUEST_REJECTED = 20,
+ JERROR_DRM_LICENSE_RESTORE = 21,
+ JERROR_DRM_LICENSE_STATE = 22,
+ JERROR_DRM_MEDIA_FRAMEWORK = 23,
+ JERROR_DRM_PROVISIONING_CERTIFICATE = 24,
+ JERROR_DRM_PROVISIONING_CONFIG = 25,
+ JERROR_DRM_PROVISIONING_PARSE = 26,
+ JERROR_DRM_PROVISIONING_RETRY = 27,
+ JERROR_DRM_RESOURCE_CONTENTION = 28,
+ JERROR_DRM_SECURE_STOP_RELEASE = 29,
+ JERROR_DRM_STORAGE_READ = 30,
+ JERROR_DRM_STORAGE_WRITE = 31,
+ JERROR_DRM_ZERO_SUBSAMPLES = 32,
+};
+
struct ListenerArgs {
jbyteArray jSessionId;
jbyteArray jData;
@@ -98,6 +136,8 @@ private:
DISALLOW_EVIL_CONSTRUCTORS(JDrm);
};
+jint MediaErrorToJavaError(status_t err);
+
} // namespace android
#endif // _ANDROID_MEDIA_DRM_H_
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index a1fd7eefaf9a..e427981b87d7 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -4780,17 +4780,23 @@ public class SettingsProvider extends ContentProvider {
}
if (currentVersion == 192) {
- // Version 192: set the default value for magnification capabilities. If
- // magnification is enabled by the user, set it to full-screen, and set a value
- // to show a prompt when using the magnification first time after upgrading.
+ // Version 192: set the default value for magnification capabilities.
+ // If the device supports magnification area and magnification is enabled
+ // by the user, set it to full-screen, and set a value to show a prompt
+ // when using the magnification first time after upgrading.
final SettingsState secureSettings = getSecureSettingsLocked(userId);
final Setting magnificationCapabilities = secureSettings.getSettingLocked(
Secure.ACCESSIBILITY_MAGNIFICATION_CAPABILITY);
+ final boolean supportMagnificationArea = getContext().getResources().getBoolean(
+ com.android.internal.R.bool.config_magnification_area);
+ final int capability = supportMagnificationArea
+ ? R.integer.def_accessibility_magnification_capabilities
+ : Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN;
+ final String supportShowPrompt = supportMagnificationArea ? "1" : "0";
if (magnificationCapabilities.isNull()) {
secureSettings.insertSettingLocked(
Secure.ACCESSIBILITY_MAGNIFICATION_CAPABILITY,
- String.valueOf(getContext().getResources().getInteger(
- R.integer.def_accessibility_magnification_capabilities)),
+ String.valueOf(getContext().getResources().getInteger(capability)),
null, true, SettingsState.SYSTEM_PACKAGE_NAME);
if (isMagnificationSettingsOn(secureSettings)) {
@@ -4800,7 +4806,8 @@ public class SettingsProvider extends ContentProvider {
null, false /* makeDefault */,
SettingsState.SYSTEM_PACKAGE_NAME);
secureSettings.insertSettingLocked(
- Secure.ACCESSIBILITY_SHOW_WINDOW_MAGNIFICATION_PROMPT, "1",
+ Secure.ACCESSIBILITY_SHOW_WINDOW_MAGNIFICATION_PROMPT,
+ supportShowPrompt,
null, false /* makeDefault */,
SettingsState.SYSTEM_PACKAGE_NAME);
}
diff --git a/packages/SystemUI/res/layout/pip_menu_activity.xml b/packages/SystemUI/res/layout/pip_menu_activity.xml
deleted file mode 100644
index 2b33e17a5fbd..000000000000
--- a/packages/SystemUI/res/layout/pip_menu_activity.xml
+++ /dev/null
@@ -1,93 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2016 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.
--->
-<FrameLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/background"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
-
- <!-- Menu layout -->
- <FrameLayout
- android:id="@+id/menu_container"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:forceHasOverlappingRendering="false"
- android:accessibilityTraversalAfter="@id/dismiss">
-
- <!-- The margins for this container is calculated in the code depending on whether the
- actions_container is visible. -->
- <FrameLayout
- android:id="@+id/expand_container"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
- <ImageButton
- android:id="@+id/expand_button"
- android:layout_width="60dp"
- android:layout_height="60dp"
- android:layout_gravity="center"
- android:contentDescription="@string/pip_phone_expand"
- android:padding="10dp"
- android:src="@drawable/pip_expand"
- android:background="?android:selectableItemBackgroundBorderless" />
- </FrameLayout>
-
- <FrameLayout
- android:id="@+id/actions_container"
- android:layout_width="match_parent"
- android:layout_height="@dimen/pip_action_size"
- android:layout_gravity="bottom"
- android:visibility="invisible">
- <LinearLayout
- android:id="@+id/actions_group"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_gravity="center_horizontal"
- android:orientation="horizontal"
- android:divider="@android:color/transparent"
- android:showDividers="middle" />
- </FrameLayout>
- </FrameLayout>
-
- <ImageButton
- android:id="@+id/settings"
- android:layout_width="@dimen/pip_action_size"
- android:layout_height="@dimen/pip_action_size"
- android:layout_gravity="top|start"
- android:padding="@dimen/pip_action_padding"
- android:contentDescription="@string/pip_phone_settings"
- android:src="@drawable/ic_settings"
- android:background="?android:selectableItemBackgroundBorderless" />
-
- <ImageButton
- android:id="@+id/dismiss"
- android:layout_width="@dimen/pip_action_size"
- android:layout_height="@dimen/pip_action_size"
- android:layout_gravity="top|end"
- android:padding="@dimen/pip_action_padding"
- android:contentDescription="@string/pip_phone_close"
- android:src="@drawable/ic_close_white"
- android:background="?android:selectableItemBackgroundBorderless" />
-
- <!--TODO (b/156917828): Add content description for a11y purposes?-->
- <ImageButton
- android:id="@+id/resize_handle"
- android:layout_width="@dimen/pip_resize_handle_size"
- android:layout_height="@dimen/pip_resize_handle_size"
- android:layout_gravity="top|start"
- android:layout_margin="@dimen/pip_resize_handle_margin"
- android:src="@drawable/pip_resize_handle"
- android:background="?android:selectableItemBackgroundBorderless" />
-</FrameLayout>
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/Task.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/Task.java
index f6b239e31e99..ebb6e30d4b3b 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/Task.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/Task.java
@@ -254,6 +254,7 @@ public class Task {
public Task(Task other) {
this(other.key, other.colorPrimary, other.colorBackground, other.isDockable,
other.isLocked, other.taskDescription, other.topActivity);
+ lastSnapshotData.set(other.lastSnapshotData);
}
/**
@@ -281,6 +282,25 @@ public class Task {
: key.baseIntent.getComponent();
}
+ public void setLastSnapshotData(ActivityManager.RecentTaskInfo rawTask) {
+ lastSnapshotData.set(rawTask.lastSnapshotData);
+ }
+
+ /**
+ * Returns the visible width to height ratio. Returns 0f if snapshot data is not available.
+ */
+ public float getVisibleThumbnailRatio() {
+ if (lastSnapshotData.taskSize == null || lastSnapshotData.contentInsets == null) {
+ return 0f;
+ }
+
+ float availableWidth = lastSnapshotData.taskSize.x - (lastSnapshotData.contentInsets.left
+ + lastSnapshotData.contentInsets.right);
+ float availableHeight = lastSnapshotData.taskSize.y - (lastSnapshotData.contentInsets.top
+ + lastSnapshotData.contentInsets.bottom);
+ return availableWidth / availableHeight;
+ }
+
@Override
public boolean equals(Object o) {
// Check that the id matches
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java
index 6c77af7bbddd..c5d54391959a 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java
@@ -100,4 +100,10 @@ public abstract class TaskStackChangeListener {
/** @see ITaskStackListener#onActivityRotation(int)*/
public void onActivityRotation(int displayId) { }
+
+ /**
+ * Called when the lock task mode changes. See ActivityManager#LOCK_TASK_MODE_* and
+ * LockTaskController.
+ */
+ public void onLockTaskModeChanged(int mode) { }
}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java
index 8f08f5a51143..d2698ee9fe3b 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java
@@ -93,6 +93,7 @@ public class TaskStackChangeListeners {
private static final int ON_TASK_LIST_FROZEN_UNFROZEN = 20;
private static final int ON_TASK_DESCRIPTION_CHANGED = 21;
private static final int ON_ACTIVITY_ROTATION = 22;
+ private static final int ON_LOCK_TASK_MODE_CHANGED = 23;
/**
* List of {@link TaskStackChangeListener} registered from {@link #addListener}.
@@ -273,6 +274,11 @@ public class TaskStackChangeListeners {
}
@Override
+ public void onLockTaskModeChanged(int mode) {
+ mHandler.obtainMessage(ON_LOCK_TASK_MODE_CHANGED, mode, 0 /* unused */).sendToTarget();
+ }
+
+ @Override
public boolean handleMessage(Message msg) {
synchronized (mTaskStackListeners) {
switch (msg.what) {
@@ -421,6 +427,12 @@ public class TaskStackChangeListeners {
}
break;
}
+ case ON_LOCK_TASK_MODE_CHANGED: {
+ for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
+ mTaskStackListeners.get(i).onLockTaskModeChanged(msg.arg1);
+ }
+ break;
+ }
}
}
if (msg.obj instanceof SomeArgs) {
diff --git a/packages/SystemUI/src/com/android/keyguard/CarrierText.java b/packages/SystemUI/src/com/android/keyguard/CarrierText.java
index e4f6e131258e..f6b03c1fa013 100644
--- a/packages/SystemUI/src/com/android/keyguard/CarrierText.java
+++ b/packages/SystemUI/src/com/android/keyguard/CarrierText.java
@@ -24,14 +24,41 @@ import android.util.AttributeSet;
import android.view.View;
import android.widget.TextView;
+import com.android.systemui.Dependency;
import com.android.systemui.R;
import java.util.Locale;
public class CarrierText extends TextView {
- private final boolean mShowMissingSim;
+ private static final boolean DEBUG = KeyguardConstants.DEBUG;
+ private static final String TAG = "CarrierText";
- private final boolean mShowAirplaneMode;
+ private static CharSequence mSeparator;
+
+ private boolean mShowMissingSim;
+
+ private boolean mShowAirplaneMode;
+ private boolean mShouldMarquee;
+
+ private CarrierTextController mCarrierTextController;
+
+ private CarrierTextController.CarrierTextCallback mCarrierTextCallback =
+ new CarrierTextController.CarrierTextCallback() {
+ @Override
+ public void updateCarrierInfo(CarrierTextController.CarrierTextCallbackInfo info) {
+ setText(info.carrierText);
+ }
+
+ @Override
+ public void startedGoingToSleep() {
+ setSelected(false);
+ }
+
+ @Override
+ public void finishedWakingUp() {
+ setSelected(true);
+ }
+ };
public CarrierText(Context context) {
this(context, null);
@@ -51,6 +78,30 @@ public class CarrierText extends TextView {
}
setTransformationMethod(new CarrierTextTransformationMethod(mContext, useAllCaps));
}
+
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+ mSeparator = getResources().getString(
+ com.android.internal.R.string.kg_text_message_separator);
+ mCarrierTextController = new CarrierTextController(mContext, mSeparator, mShowAirplaneMode,
+ mShowMissingSim);
+ mShouldMarquee = Dependency.get(KeyguardUpdateMonitor.class).isDeviceInteractive();
+ setSelected(mShouldMarquee); // Allow marquee to work.
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ mCarrierTextController.setListening(mCarrierTextCallback);
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ mCarrierTextController.setListening(null);
+ }
+
@Override
protected void onVisibilityChanged(View changedView, int visibility) {
super.onVisibilityChanged(changedView, visibility);
@@ -62,15 +113,7 @@ public class CarrierText extends TextView {
}
}
- public boolean getShowAirplaneMode() {
- return mShowAirplaneMode;
- }
-
- public boolean getShowMissingSim() {
- return mShowMissingSim;
- }
-
- private static class CarrierTextTransformationMethod extends SingleLineTransformationMethod {
+ private class CarrierTextTransformationMethod extends SingleLineTransformationMethod {
private final Locale mLocale;
private final boolean mAllCaps;
diff --git a/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java b/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java
index 46a6d8b82911..b1e14346c3fa 100644
--- a/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java
+++ b/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright (C) 2019 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.
@@ -16,61 +16,680 @@
package com.android.keyguard;
-import com.android.systemui.util.ViewController;
+import static android.telephony.PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE;
+import static android.telephony.PhoneStateListener.LISTEN_NONE;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.res.Resources;
+import android.net.ConnectivityManager;
+import android.net.wifi.WifiManager;
+import android.os.Handler;
+import android.telephony.PhoneStateListener;
+import android.telephony.ServiceState;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+import android.text.TextUtils;
+import android.util.Log;
+
+import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
+
+import com.android.settingslib.WirelessUtils;
+import com.android.systemui.Dependency;
+import com.android.systemui.R;
+import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.keyguard.WakefulnessLifecycle;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.concurrent.atomic.AtomicBoolean;
import javax.inject.Inject;
/**
- * Controller for {@link CarrierText}.
+ * Controller that generates text including the carrier names and/or the status of all the SIM
+ * interfaces in the device. Through a callback, the updates can be retrieved either as a list or
+ * separated by a given separator {@link CharSequence}.
*/
-public class CarrierTextController extends ViewController<CarrierText> {
- private final CarrierTextManager mCarrierTextManager;
- private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
+public class CarrierTextController {
+ private static final boolean DEBUG = KeyguardConstants.DEBUG;
+ private static final String TAG = "CarrierTextController";
- private final CarrierTextManager.CarrierTextCallback mCarrierTextCallback =
- new CarrierTextManager.CarrierTextCallback() {
+ private final boolean mIsEmergencyCallCapable;
+ private final Handler mMainHandler;
+ private final Handler mBgHandler;
+ private boolean mTelephonyCapable;
+ private boolean mShowMissingSim;
+ private boolean mShowAirplaneMode;
+ private final AtomicBoolean mNetworkSupported = new AtomicBoolean();
+ @VisibleForTesting
+ protected KeyguardUpdateMonitor mKeyguardUpdateMonitor;
+ private WifiManager mWifiManager;
+ private boolean[] mSimErrorState;
+ private final int mSimSlotsNumber;
+ @Nullable // Check for nullability before dispatching
+ private CarrierTextCallback mCarrierTextCallback;
+ private Context mContext;
+ private CharSequence mSeparator;
+ private WakefulnessLifecycle mWakefulnessLifecycle;
+ private final WakefulnessLifecycle.Observer mWakefulnessObserver =
+ new WakefulnessLifecycle.Observer() {
@Override
- public void updateCarrierInfo(CarrierTextManager.CarrierTextCallbackInfo info) {
- mView.setText(info.carrierText);
+ public void onFinishedWakingUp() {
+ final CarrierTextCallback callback = mCarrierTextCallback;
+ if (callback != null) callback.finishedWakingUp();
}
@Override
- public void startedGoingToSleep() {
- mView.setSelected(false);
+ public void onStartedGoingToSleep() {
+ final CarrierTextCallback callback = mCarrierTextCallback;
+ if (callback != null) callback.startedGoingToSleep();
}
+ };
- @Override
- public void finishedWakingUp() {
- mView.setSelected(true);
+ @VisibleForTesting
+ protected final KeyguardUpdateMonitorCallback mCallback = new KeyguardUpdateMonitorCallback() {
+ @Override
+ public void onRefreshCarrierInfo() {
+ if (DEBUG) {
+ Log.d(TAG, "onRefreshCarrierInfo(), mTelephonyCapable: "
+ + Boolean.toString(mTelephonyCapable));
+ }
+ updateCarrierText();
+ }
+
+ @Override
+ public void onTelephonyCapable(boolean capable) {
+ if (DEBUG) {
+ Log.d(TAG, "onTelephonyCapable() mTelephonyCapable: "
+ + Boolean.toString(capable));
+ }
+ mTelephonyCapable = capable;
+ updateCarrierText();
+ }
+
+ public void onSimStateChanged(int subId, int slotId, int simState) {
+ if (slotId < 0 || slotId >= mSimSlotsNumber) {
+ Log.d(TAG, "onSimStateChanged() - slotId invalid: " + slotId
+ + " mTelephonyCapable: " + Boolean.toString(mTelephonyCapable));
+ return;
+ }
+
+ if (DEBUG) Log.d(TAG, "onSimStateChanged: " + getStatusForIccState(simState));
+ if (getStatusForIccState(simState) == CarrierTextController.StatusMode.SimIoError) {
+ mSimErrorState[slotId] = true;
+ updateCarrierText();
+ } else if (mSimErrorState[slotId]) {
+ mSimErrorState[slotId] = false;
+ updateCarrierText();
+ }
+ }
+ };
+
+ private int mActiveMobileDataSubscription = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+ private PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
+ @Override
+ public void onActiveDataSubscriptionIdChanged(int subId) {
+ mActiveMobileDataSubscription = subId;
+ if (mNetworkSupported.get() && mCarrierTextCallback != null) {
+ updateCarrierText();
+ }
+ }
+ };
+
+ /**
+ * The status of this lock screen. Primarily used for widgets on LockScreen.
+ */
+ private enum StatusMode {
+ Normal, // Normal case (sim card present, it's not locked)
+ NetworkLocked, // SIM card is 'network locked'.
+ SimMissing, // SIM card is missing.
+ SimMissingLocked, // SIM card is missing, and device isn't provisioned; don't allow access
+ SimPukLocked, // SIM card is PUK locked because SIM entered wrong too many times
+ SimLocked, // SIM card is currently locked
+ SimPermDisabled, // SIM card is permanently disabled due to PUK unlock failure
+ SimNotReady, // SIM is not ready yet. May never be on devices w/o a SIM.
+ SimIoError, // SIM card is faulty
+ SimUnknown // SIM card is unknown
+ }
+
+ /**
+ * Controller that provides updates on text with carriers names or SIM status.
+ * Used by {@link CarrierText}.
+ *
+ * @param separator Separator between different parts of the text
+ */
+ public CarrierTextController(Context context, CharSequence separator, boolean showAirplaneMode,
+ boolean showMissingSim) {
+ mContext = context;
+ mIsEmergencyCallCapable = getTelephonyManager().isVoiceCapable();
+
+ mShowAirplaneMode = showAirplaneMode;
+ mShowMissingSim = showMissingSim;
+
+ mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
+ mSeparator = separator;
+ mWakefulnessLifecycle = Dependency.get(WakefulnessLifecycle.class);
+ mSimSlotsNumber = getTelephonyManager().getSupportedModemCount();
+ mSimErrorState = new boolean[mSimSlotsNumber];
+ mMainHandler = Dependency.get(Dependency.MAIN_HANDLER);
+ mBgHandler = new Handler(Dependency.get(Dependency.BG_LOOPER));
+ mKeyguardUpdateMonitor = Dependency.get(KeyguardUpdateMonitor.class);
+ mBgHandler.post(() -> {
+ boolean supported = ConnectivityManager.from(mContext).isNetworkSupported(
+ ConnectivityManager.TYPE_MOBILE);
+ if (supported && mNetworkSupported.compareAndSet(false, supported)) {
+ // This will set/remove the listeners appropriately. Note that it will never double
+ // add the listeners.
+ handleSetListening(mCarrierTextCallback);
+ }
+ });
+ }
+
+ private TelephonyManager getTelephonyManager() {
+ return (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
+ }
+
+ /**
+ * Checks if there are faulty cards. Adds the text depending on the slot of the card
+ *
+ * @param text: current carrier text based on the sim state
+ * @param carrierNames names order by subscription order
+ * @param subOrderBySlot array containing the sub index for each slot ID
+ * @param noSims: whether a valid sim card is inserted
+ * @return text
+ */
+ private CharSequence updateCarrierTextWithSimIoError(CharSequence text,
+ CharSequence[] carrierNames, int[] subOrderBySlot, boolean noSims) {
+ final CharSequence carrier = "";
+ CharSequence carrierTextForSimIOError = getCarrierTextForSimState(
+ TelephonyManager.SIM_STATE_CARD_IO_ERROR, carrier);
+ // mSimErrorState has the state of each sim indexed by slotID.
+ for (int index = 0; index < getTelephonyManager().getActiveModemCount(); index++) {
+ if (!mSimErrorState[index]) {
+ continue;
+ }
+ // In the case when no sim cards are detected but a faulty card is inserted
+ // overwrite the text and only show "Invalid card"
+ if (noSims) {
+ return concatenate(carrierTextForSimIOError,
+ getContext().getText(
+ com.android.internal.R.string.emergency_calls_only),
+ mSeparator);
+ } else if (subOrderBySlot[index] != -1) {
+ int subIndex = subOrderBySlot[index];
+ // prepend "Invalid card" when faulty card is inserted in slot 0 or 1
+ carrierNames[subIndex] = concatenate(carrierTextForSimIOError,
+ carrierNames[subIndex],
+ mSeparator);
+ } else {
+ // concatenate "Invalid card" when faulty card is inserted in other slot
+ text = concatenate(text, carrierTextForSimIOError, mSeparator);
+ }
+
+ }
+ return text;
+ }
+
+ /**
+ * This may be called internally after retrieving the correct value of {@code mNetworkSupported}
+ * (assumed false to start). In that case, the following happens:
+ * <ul>
+ * <li> If there was a registered callback, and the network is supported, it will register
+ * listeners.
+ * <li> If there was not a registered callback, it will try to remove unregistered listeners
+ * which is a no-op
+ * </ul>
+ *
+ * This call will always be processed in a background thread.
+ */
+ private void handleSetListening(CarrierTextCallback callback) {
+ TelephonyManager telephonyManager = getTelephonyManager();
+ if (callback != null) {
+ mCarrierTextCallback = callback;
+ if (mNetworkSupported.get()) {
+ // Keyguard update monitor expects callbacks from main thread
+ mMainHandler.post(() -> mKeyguardUpdateMonitor.registerCallback(mCallback));
+ mWakefulnessLifecycle.addObserver(mWakefulnessObserver);
+ telephonyManager.listen(mPhoneStateListener,
+ LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE);
+ } else {
+ // Don't listen and clear out the text when the device isn't a phone.
+ mMainHandler.post(() -> callback.updateCarrierInfo(
+ new CarrierTextCallbackInfo("", null, false, null)
+ ));
+ }
+ } else {
+ mCarrierTextCallback = null;
+ mMainHandler.post(() -> mKeyguardUpdateMonitor.removeCallback(mCallback));
+ mWakefulnessLifecycle.removeObserver(mWakefulnessObserver);
+ telephonyManager.listen(mPhoneStateListener, LISTEN_NONE);
+ }
+ }
+
+ /**
+ * Sets the listening status of this controller. If the callback is null, it is set to
+ * not listening.
+ *
+ * @param callback Callback to provide text updates
+ */
+ public void setListening(CarrierTextCallback callback) {
+ mBgHandler.post(() -> handleSetListening(callback));
+ }
+
+ protected List<SubscriptionInfo> getSubscriptionInfo() {
+ return mKeyguardUpdateMonitor.getFilteredSubscriptionInfo(false);
+ }
+
+ protected void updateCarrierText() {
+ boolean allSimsMissing = true;
+ boolean anySimReadyAndInService = false;
+ CharSequence displayText = null;
+ List<SubscriptionInfo> subs = getSubscriptionInfo();
+
+ final int numSubs = subs.size();
+ final int[] subsIds = new int[numSubs];
+ // This array will contain in position i, the index of subscription in slot ID i.
+ // -1 if no subscription in that slot
+ final int[] subOrderBySlot = new int[mSimSlotsNumber];
+ for (int i = 0; i < mSimSlotsNumber; i++) {
+ subOrderBySlot[i] = -1;
+ }
+ final CharSequence[] carrierNames = new CharSequence[numSubs];
+ if (DEBUG) Log.d(TAG, "updateCarrierText(): " + numSubs);
+
+ for (int i = 0; i < numSubs; i++) {
+ int subId = subs.get(i).getSubscriptionId();
+ carrierNames[i] = "";
+ subsIds[i] = subId;
+ subOrderBySlot[subs.get(i).getSimSlotIndex()] = i;
+ int simState = mKeyguardUpdateMonitor.getSimState(subId);
+ CharSequence carrierName = subs.get(i).getCarrierName();
+ CharSequence carrierTextForSimState = getCarrierTextForSimState(simState, carrierName);
+ if (DEBUG) {
+ Log.d(TAG, "Handling (subId=" + subId + "): " + simState + " " + carrierName);
+ }
+ if (carrierTextForSimState != null) {
+ allSimsMissing = false;
+ carrierNames[i] = carrierTextForSimState;
+ }
+ if (simState == TelephonyManager.SIM_STATE_READY) {
+ ServiceState ss = mKeyguardUpdateMonitor.mServiceStates.get(subId);
+ if (ss != null && ss.getDataRegistrationState() == ServiceState.STATE_IN_SERVICE) {
+ // hack for WFC (IWLAN) not turning off immediately once
+ // Wi-Fi is disassociated or disabled
+ if (ss.getRilDataRadioTechnology() != ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN
+ || (mWifiManager.isWifiEnabled()
+ && mWifiManager.getConnectionInfo() != null
+ && mWifiManager.getConnectionInfo().getBSSID() != null)) {
+ if (DEBUG) {
+ Log.d(TAG, "SIM ready and in service: subId=" + subId + ", ss=" + ss);
+ }
+ anySimReadyAndInService = true;
+ }
}
- };
+ }
+ }
+ // Only create "No SIM card" if no cards with CarrierName && no wifi when some sim is READY
+ // This condition will also be true always when numSubs == 0
+ if (allSimsMissing && !anySimReadyAndInService) {
+ if (numSubs != 0) {
+ // Shows "No SIM card | Emergency calls only" on devices that are voice-capable.
+ // This depends on mPlmn containing the text "Emergency calls only" when the radio
+ // has some connectivity. Otherwise, it should be null or empty and just show
+ // "No SIM card"
+ // Grab the first subscripton, because they all should contain the emergency text,
+ // described above.
+ displayText = makeCarrierStringOnEmergencyCapable(
+ getMissingSimMessage(), subs.get(0).getCarrierName());
+ } else {
+ // We don't have a SubscriptionInfo to get the emergency calls only from.
+ // Grab it from the old sticky broadcast if possible instead. We can use it
+ // here because no subscriptions are active, so we don't have
+ // to worry about MSIM clashing.
+ CharSequence text =
+ getContext().getText(com.android.internal.R.string.emergency_calls_only);
+ Intent i = getContext().registerReceiver(null,
+ new IntentFilter(TelephonyManager.ACTION_SERVICE_PROVIDERS_UPDATED));
+ if (i != null) {
+ String spn = "";
+ String plmn = "";
+ if (i.getBooleanExtra(TelephonyManager.EXTRA_SHOW_SPN, false)) {
+ spn = i.getStringExtra(TelephonyManager.EXTRA_SPN);
+ }
+ if (i.getBooleanExtra(TelephonyManager.EXTRA_SHOW_PLMN, false)) {
+ plmn = i.getStringExtra(TelephonyManager.EXTRA_PLMN);
+ }
+ if (DEBUG) Log.d(TAG, "Getting plmn/spn sticky brdcst " + plmn + "/" + spn);
+ if (Objects.equals(plmn, spn)) {
+ text = plmn;
+ } else {
+ text = concatenate(plmn, spn, mSeparator);
+ }
+ }
+ displayText = makeCarrierStringOnEmergencyCapable(getMissingSimMessage(), text);
+ }
+ }
+
+ if (TextUtils.isEmpty(displayText)) displayText = joinNotEmpty(mSeparator, carrierNames);
+
+ displayText = updateCarrierTextWithSimIoError(displayText, carrierNames, subOrderBySlot,
+ allSimsMissing);
+
+ boolean airplaneMode = false;
+ // APM (airplane mode) != no carrier state. There are carrier services
+ // (e.g. WFC = Wi-Fi calling) which may operate in APM.
+ if (!anySimReadyAndInService && WirelessUtils.isAirplaneModeOn(mContext)) {
+ displayText = getAirplaneModeMessage();
+ airplaneMode = true;
+ }
+
+ final CarrierTextCallbackInfo info = new CarrierTextCallbackInfo(
+ displayText,
+ carrierNames,
+ !allSimsMissing,
+ subsIds,
+ airplaneMode);
+ postToCallback(info);
+ }
- @Inject
- public CarrierTextController(CarrierText view,
- CarrierTextManager.Builder carrierTextManagerBuilder,
- KeyguardUpdateMonitor keyguardUpdateMonitor) {
- super(view);
+ @VisibleForTesting
+ protected void postToCallback(CarrierTextCallbackInfo info) {
+ final CarrierTextCallback callback = mCarrierTextCallback;
+ if (callback != null) {
+ mMainHandler.post(() -> callback.updateCarrierInfo(info));
+ }
+ }
- mCarrierTextManager = carrierTextManagerBuilder
- .setShowAirplaneMode(mView.getShowAirplaneMode())
- .setShowMissingSim(mView.getShowMissingSim())
- .build();
- mKeyguardUpdateMonitor = keyguardUpdateMonitor;
+ private Context getContext() {
+ return mContext;
}
- @Override
- protected void onInit() {
- super.onInit();
- mView.setSelected(mKeyguardUpdateMonitor.isDeviceInteractive());
+ private String getMissingSimMessage() {
+ return mShowMissingSim && mTelephonyCapable
+ ? getContext().getString(R.string.keyguard_missing_sim_message_short) : "";
}
- @Override
- protected void onViewAttached() {
- mCarrierTextManager.setListening(mCarrierTextCallback);
+ private String getAirplaneModeMessage() {
+ return mShowAirplaneMode
+ ? getContext().getString(R.string.airplane_mode) : "";
}
- @Override
- protected void onViewDetached() {
- mCarrierTextManager.setListening(null);
+ /**
+ * Top-level function for creating carrier text. Makes text based on simState, PLMN
+ * and SPN as well as device capabilities, such as being emergency call capable.
+ *
+ * @return Carrier text if not in missing state, null otherwise.
+ */
+ private CharSequence getCarrierTextForSimState(int simState, CharSequence text) {
+ CharSequence carrierText = null;
+ CarrierTextController.StatusMode status = getStatusForIccState(simState);
+ switch (status) {
+ case Normal:
+ carrierText = text;
+ break;
+
+ case SimNotReady:
+ // Null is reserved for denoting missing, in this case we have nothing to display.
+ carrierText = ""; // nothing to display yet.
+ break;
+
+ case NetworkLocked:
+ carrierText = makeCarrierStringOnEmergencyCapable(
+ mContext.getText(R.string.keyguard_network_locked_message), text);
+ break;
+
+ case SimMissing:
+ carrierText = null;
+ break;
+
+ case SimPermDisabled:
+ carrierText = makeCarrierStringOnEmergencyCapable(
+ getContext().getText(
+ R.string.keyguard_permanent_disabled_sim_message_short),
+ text);
+ break;
+
+ case SimMissingLocked:
+ carrierText = null;
+ break;
+
+ case SimLocked:
+ carrierText = makeCarrierStringOnLocked(
+ getContext().getText(R.string.keyguard_sim_locked_message),
+ text);
+ break;
+
+ case SimPukLocked:
+ carrierText = makeCarrierStringOnLocked(
+ getContext().getText(R.string.keyguard_sim_puk_locked_message),
+ text);
+ break;
+ case SimIoError:
+ carrierText = makeCarrierStringOnEmergencyCapable(
+ getContext().getText(R.string.keyguard_sim_error_message_short),
+ text);
+ break;
+ case SimUnknown:
+ carrierText = null;
+ break;
+ }
+
+ return carrierText;
+ }
+
+ /*
+ * Add emergencyCallMessage to carrier string only if phone supports emergency calls.
+ */
+ private CharSequence makeCarrierStringOnEmergencyCapable(
+ CharSequence simMessage, CharSequence emergencyCallMessage) {
+ if (mIsEmergencyCallCapable) {
+ return concatenate(simMessage, emergencyCallMessage, mSeparator);
+ }
+ return simMessage;
+ }
+
+ /*
+ * Add "SIM card is locked" in parenthesis after carrier name, so it is easily associated in
+ * DSDS
+ */
+ private CharSequence makeCarrierStringOnLocked(CharSequence simMessage,
+ CharSequence carrierName) {
+ final boolean simMessageValid = !TextUtils.isEmpty(simMessage);
+ final boolean carrierNameValid = !TextUtils.isEmpty(carrierName);
+ if (simMessageValid && carrierNameValid) {
+ return mContext.getString(R.string.keyguard_carrier_name_with_sim_locked_template,
+ carrierName, simMessage);
+ } else if (simMessageValid) {
+ return simMessage;
+ } else if (carrierNameValid) {
+ return carrierName;
+ } else {
+ return "";
+ }
+ }
+
+ /**
+ * Determine the current status of the lock screen given the SIM state and other stuff.
+ */
+ private CarrierTextController.StatusMode getStatusForIccState(int simState) {
+ final boolean missingAndNotProvisioned =
+ !mKeyguardUpdateMonitor.isDeviceProvisioned()
+ && (simState == TelephonyManager.SIM_STATE_ABSENT
+ || simState == TelephonyManager.SIM_STATE_PERM_DISABLED);
+
+ // Assume we're NETWORK_LOCKED if not provisioned
+ simState = missingAndNotProvisioned ? TelephonyManager.SIM_STATE_NETWORK_LOCKED : simState;
+ switch (simState) {
+ case TelephonyManager.SIM_STATE_ABSENT:
+ return CarrierTextController.StatusMode.SimMissing;
+ case TelephonyManager.SIM_STATE_NETWORK_LOCKED:
+ return CarrierTextController.StatusMode.SimMissingLocked;
+ case TelephonyManager.SIM_STATE_NOT_READY:
+ return CarrierTextController.StatusMode.SimNotReady;
+ case TelephonyManager.SIM_STATE_PIN_REQUIRED:
+ return CarrierTextController.StatusMode.SimLocked;
+ case TelephonyManager.SIM_STATE_PUK_REQUIRED:
+ return CarrierTextController.StatusMode.SimPukLocked;
+ case TelephonyManager.SIM_STATE_READY:
+ return CarrierTextController.StatusMode.Normal;
+ case TelephonyManager.SIM_STATE_PERM_DISABLED:
+ return CarrierTextController.StatusMode.SimPermDisabled;
+ case TelephonyManager.SIM_STATE_UNKNOWN:
+ return CarrierTextController.StatusMode.SimUnknown;
+ case TelephonyManager.SIM_STATE_CARD_IO_ERROR:
+ return CarrierTextController.StatusMode.SimIoError;
+ }
+ return CarrierTextController.StatusMode.SimUnknown;
+ }
+
+ private static CharSequence concatenate(CharSequence plmn, CharSequence spn,
+ CharSequence separator) {
+ final boolean plmnValid = !TextUtils.isEmpty(plmn);
+ final boolean spnValid = !TextUtils.isEmpty(spn);
+ if (plmnValid && spnValid) {
+ return new StringBuilder().append(plmn).append(separator).append(spn).toString();
+ } else if (plmnValid) {
+ return plmn;
+ } else if (spnValid) {
+ return spn;
+ } else {
+ return "";
+ }
+ }
+
+ /**
+ * Joins the strings in a sequence using a separator. Empty strings are discarded with no extra
+ * separator added so there are no extra separators that are not needed.
+ */
+ private static CharSequence joinNotEmpty(CharSequence separator, CharSequence[] sequences) {
+ int length = sequences.length;
+ if (length == 0) return "";
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < length; i++) {
+ if (!TextUtils.isEmpty(sequences[i])) {
+ if (!TextUtils.isEmpty(sb)) {
+ sb.append(separator);
+ }
+ sb.append(sequences[i]);
+ }
+ }
+ return sb.toString();
+ }
+
+ private static List<CharSequence> append(List<CharSequence> list, CharSequence string) {
+ if (!TextUtils.isEmpty(string)) {
+ list.add(string);
+ }
+ return list;
+ }
+
+ private CharSequence getCarrierHelpTextForSimState(int simState,
+ String plmn, String spn) {
+ int carrierHelpTextId = 0;
+ CarrierTextController.StatusMode status = getStatusForIccState(simState);
+ switch (status) {
+ case NetworkLocked:
+ carrierHelpTextId = R.string.keyguard_instructions_when_pattern_disabled;
+ break;
+
+ case SimMissing:
+ carrierHelpTextId = R.string.keyguard_missing_sim_instructions_long;
+ break;
+
+ case SimPermDisabled:
+ carrierHelpTextId = R.string.keyguard_permanent_disabled_sim_instructions;
+ break;
+
+ case SimMissingLocked:
+ carrierHelpTextId = R.string.keyguard_missing_sim_instructions;
+ break;
+
+ case Normal:
+ case SimLocked:
+ case SimPukLocked:
+ break;
+ }
+
+ return mContext.getText(carrierHelpTextId);
+ }
+
+ public static class Builder {
+ private final Context mContext;
+ private final String mSeparator;
+ private boolean mShowAirplaneMode;
+ private boolean mShowMissingSim;
+
+ @Inject
+ public Builder(Context context, @Main Resources resources) {
+ mContext = context;
+ mSeparator = resources.getString(
+ com.android.internal.R.string.kg_text_message_separator);
+ }
+
+
+ public Builder setShowAirplaneMode(boolean showAirplaneMode) {
+ mShowAirplaneMode = showAirplaneMode;
+ return this;
+ }
+
+ public Builder setShowMissingSim(boolean showMissingSim) {
+ mShowMissingSim = showMissingSim;
+ return this;
+ }
+
+ public CarrierTextController build() {
+ return new CarrierTextController(
+ mContext, mSeparator, mShowAirplaneMode, mShowMissingSim);
+ }
+ }
+ /**
+ * Data structure for passing information to CarrierTextController subscribers
+ */
+ public static final class CarrierTextCallbackInfo {
+ public final CharSequence carrierText;
+ public final CharSequence[] listOfCarriers;
+ public final boolean anySimReady;
+ public final int[] subscriptionIds;
+ public boolean airplaneMode;
+
+ @VisibleForTesting
+ public CarrierTextCallbackInfo(CharSequence carrierText, CharSequence[] listOfCarriers,
+ boolean anySimReady, int[] subscriptionIds) {
+ this(carrierText, listOfCarriers, anySimReady, subscriptionIds, false);
+ }
+
+ @VisibleForTesting
+ public CarrierTextCallbackInfo(CharSequence carrierText, CharSequence[] listOfCarriers,
+ boolean anySimReady, int[] subscriptionIds, boolean airplaneMode) {
+ this.carrierText = carrierText;
+ this.listOfCarriers = listOfCarriers;
+ this.anySimReady = anySimReady;
+ this.subscriptionIds = subscriptionIds;
+ this.airplaneMode = airplaneMode;
+ }
+ }
+
+ /**
+ * Callback to communicate to Views
+ */
+ public interface CarrierTextCallback {
+ /**
+ * Provides updated carrier information.
+ */
+ default void updateCarrierInfo(CarrierTextCallbackInfo info) {};
+
+ /**
+ * Notifies the View that the device is going to sleep
+ */
+ default void startedGoingToSleep() {};
+
+ /**
+ * Notifies the View that the device finished waking up
+ */
+ default void finishedWakingUp() {};
}
}
diff --git a/packages/SystemUI/src/com/android/keyguard/CarrierTextManager.java b/packages/SystemUI/src/com/android/keyguard/CarrierTextManager.java
deleted file mode 100644
index 87b01e8671f0..000000000000
--- a/packages/SystemUI/src/com/android/keyguard/CarrierTextManager.java
+++ /dev/null
@@ -1,720 +0,0 @@
-/*
- * Copyright (C) 2019 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.keyguard;
-
-import static android.telephony.PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE;
-import static android.telephony.PhoneStateListener.LISTEN_NONE;
-
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.res.Resources;
-import android.net.ConnectivityManager;
-import android.net.wifi.WifiManager;
-import android.os.Handler;
-import android.telephony.PhoneStateListener;
-import android.telephony.ServiceState;
-import android.telephony.SubscriptionInfo;
-import android.telephony.TelephonyManager;
-import android.text.TextUtils;
-import android.util.Log;
-
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-
-import com.android.settingslib.WirelessUtils;
-import com.android.systemui.R;
-import com.android.systemui.dagger.qualifiers.Background;
-import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.keyguard.WakefulnessLifecycle;
-
-import java.util.List;
-import java.util.Objects;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import javax.inject.Inject;
-
-/**
- * Controller that generates text including the carrier names and/or the status of all the SIM
- * interfaces in the device. Through a callback, the updates can be retrieved either as a list or
- * separated by a given separator {@link CharSequence}.
- */
-public class CarrierTextManager {
- private static final boolean DEBUG = KeyguardConstants.DEBUG;
- private static final String TAG = "CarrierTextController";
-
- private final boolean mIsEmergencyCallCapable;
- private final Handler mMainHandler;
- private final Handler mBgHandler;
- private boolean mTelephonyCapable;
- private final boolean mShowMissingSim;
- private final boolean mShowAirplaneMode;
- private final AtomicBoolean mNetworkSupported = new AtomicBoolean();
- @VisibleForTesting
- protected KeyguardUpdateMonitor mKeyguardUpdateMonitor;
- private final WifiManager mWifiManager;
- private final boolean[] mSimErrorState;
- private final int mSimSlotsNumber;
- @Nullable // Check for nullability before dispatching
- private CarrierTextCallback mCarrierTextCallback;
- private final Context mContext;
- private final TelephonyManager mTelephonyManager;
- private final CharSequence mSeparator;
- private final WakefulnessLifecycle mWakefulnessLifecycle;
- private final WakefulnessLifecycle.Observer mWakefulnessObserver =
- new WakefulnessLifecycle.Observer() {
- @Override
- public void onFinishedWakingUp() {
- final CarrierTextCallback callback = mCarrierTextCallback;
- if (callback != null) callback.finishedWakingUp();
- }
-
- @Override
- public void onStartedGoingToSleep() {
- final CarrierTextCallback callback = mCarrierTextCallback;
- if (callback != null) callback.startedGoingToSleep();
- }
- };
-
- @VisibleForTesting
- protected final KeyguardUpdateMonitorCallback mCallback = new KeyguardUpdateMonitorCallback() {
- @Override
- public void onRefreshCarrierInfo() {
- if (DEBUG) {
- Log.d(TAG, "onRefreshCarrierInfo(), mTelephonyCapable: "
- + Boolean.toString(mTelephonyCapable));
- }
- updateCarrierText();
- }
-
- @Override
- public void onTelephonyCapable(boolean capable) {
- if (DEBUG) {
- Log.d(TAG, "onTelephonyCapable() mTelephonyCapable: "
- + Boolean.toString(capable));
- }
- mTelephonyCapable = capable;
- updateCarrierText();
- }
-
- public void onSimStateChanged(int subId, int slotId, int simState) {
- if (slotId < 0 || slotId >= mSimSlotsNumber) {
- Log.d(TAG, "onSimStateChanged() - slotId invalid: " + slotId
- + " mTelephonyCapable: " + Boolean.toString(mTelephonyCapable));
- return;
- }
-
- if (DEBUG) Log.d(TAG, "onSimStateChanged: " + getStatusForIccState(simState));
- if (getStatusForIccState(simState) == CarrierTextManager.StatusMode.SimIoError) {
- mSimErrorState[slotId] = true;
- updateCarrierText();
- } else if (mSimErrorState[slotId]) {
- mSimErrorState[slotId] = false;
- updateCarrierText();
- }
- }
- };
-
- private final PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
- @Override
- public void onActiveDataSubscriptionIdChanged(int subId) {
- if (mNetworkSupported.get() && mCarrierTextCallback != null) {
- updateCarrierText();
- }
- }
- };
-
- /**
- * The status of this lock screen. Primarily used for widgets on LockScreen.
- */
- private enum StatusMode {
- Normal, // Normal case (sim card present, it's not locked)
- NetworkLocked, // SIM card is 'network locked'.
- SimMissing, // SIM card is missing.
- SimMissingLocked, // SIM card is missing, and device isn't provisioned; don't allow access
- SimPukLocked, // SIM card is PUK locked because SIM entered wrong too many times
- SimLocked, // SIM card is currently locked
- SimPermDisabled, // SIM card is permanently disabled due to PUK unlock failure
- SimNotReady, // SIM is not ready yet. May never be on devices w/o a SIM.
- SimIoError, // SIM card is faulty
- SimUnknown // SIM card is unknown
- }
-
- /**
- * Controller that provides updates on text with carriers names or SIM status.
- * Used by {@link CarrierText}.
- *
- * @param separator Separator between different parts of the text
- */
- private CarrierTextManager(Context context, CharSequence separator, boolean showAirplaneMode,
- boolean showMissingSim, @Nullable WifiManager wifiManager,
- ConnectivityManager connectivityManager, TelephonyManager telephonyManager,
- WakefulnessLifecycle wakefulnessLifecycle, @Main Handler mainHandler,
- @Background Handler bgHandler, KeyguardUpdateMonitor keyguardUpdateMonitor) {
- mContext = context;
- mIsEmergencyCallCapable = telephonyManager.isVoiceCapable();
-
- mShowAirplaneMode = showAirplaneMode;
- mShowMissingSim = showMissingSim;
-
- mWifiManager = wifiManager;
- mTelephonyManager = telephonyManager;
- mSeparator = separator;
- mWakefulnessLifecycle = wakefulnessLifecycle;
- mSimSlotsNumber = getTelephonyManager().getSupportedModemCount();
- mSimErrorState = new boolean[mSimSlotsNumber];
- mMainHandler = mainHandler;
- mBgHandler = bgHandler;
- mKeyguardUpdateMonitor = keyguardUpdateMonitor;
- mBgHandler.post(() -> {
- boolean supported = connectivityManager.isNetworkSupported(
- ConnectivityManager.TYPE_MOBILE);
- if (supported && mNetworkSupported.compareAndSet(false, supported)) {
- // This will set/remove the listeners appropriately. Note that it will never double
- // add the listeners.
- handleSetListening(mCarrierTextCallback);
- }
- });
- }
-
- private TelephonyManager getTelephonyManager() {
- return mTelephonyManager;
- }
-
- /**
- * Checks if there are faulty cards. Adds the text depending on the slot of the card
- *
- * @param text: current carrier text based on the sim state
- * @param carrierNames names order by subscription order
- * @param subOrderBySlot array containing the sub index for each slot ID
- * @param noSims: whether a valid sim card is inserted
- * @return text
- */
- private CharSequence updateCarrierTextWithSimIoError(CharSequence text,
- CharSequence[] carrierNames, int[] subOrderBySlot, boolean noSims) {
- final CharSequence carrier = "";
- CharSequence carrierTextForSimIOError = getCarrierTextForSimState(
- TelephonyManager.SIM_STATE_CARD_IO_ERROR, carrier);
- // mSimErrorState has the state of each sim indexed by slotID.
- for (int index = 0; index < getTelephonyManager().getActiveModemCount(); index++) {
- if (!mSimErrorState[index]) {
- continue;
- }
- // In the case when no sim cards are detected but a faulty card is inserted
- // overwrite the text and only show "Invalid card"
- if (noSims) {
- return concatenate(carrierTextForSimIOError,
- getContext().getText(
- com.android.internal.R.string.emergency_calls_only),
- mSeparator);
- } else if (subOrderBySlot[index] != -1) {
- int subIndex = subOrderBySlot[index];
- // prepend "Invalid card" when faulty card is inserted in slot 0 or 1
- carrierNames[subIndex] = concatenate(carrierTextForSimIOError,
- carrierNames[subIndex],
- mSeparator);
- } else {
- // concatenate "Invalid card" when faulty card is inserted in other slot
- text = concatenate(text, carrierTextForSimIOError, mSeparator);
- }
-
- }
- return text;
- }
-
- /**
- * This may be called internally after retrieving the correct value of {@code mNetworkSupported}
- * (assumed false to start). In that case, the following happens:
- * <ul>
- * <li> If there was a registered callback, and the network is supported, it will register
- * listeners.
- * <li> If there was not a registered callback, it will try to remove unregistered listeners
- * which is a no-op
- * </ul>
- *
- * This call will always be processed in a background thread.
- */
- private void handleSetListening(CarrierTextCallback callback) {
- TelephonyManager telephonyManager = getTelephonyManager();
- if (callback != null) {
- mCarrierTextCallback = callback;
- if (mNetworkSupported.get()) {
- // Keyguard update monitor expects callbacks from main thread
- mMainHandler.post(() -> mKeyguardUpdateMonitor.registerCallback(mCallback));
- mWakefulnessLifecycle.addObserver(mWakefulnessObserver);
- telephonyManager.listen(mPhoneStateListener,
- LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE);
- } else {
- // Don't listen and clear out the text when the device isn't a phone.
- mMainHandler.post(() -> callback.updateCarrierInfo(
- new CarrierTextCallbackInfo("", null, false, null)
- ));
- }
- } else {
- mCarrierTextCallback = null;
- mMainHandler.post(() -> mKeyguardUpdateMonitor.removeCallback(mCallback));
- mWakefulnessLifecycle.removeObserver(mWakefulnessObserver);
- telephonyManager.listen(mPhoneStateListener, LISTEN_NONE);
- }
- }
-
- /**
- * Sets the listening status of this controller. If the callback is null, it is set to
- * not listening.
- *
- * @param callback Callback to provide text updates
- */
- public void setListening(CarrierTextCallback callback) {
- mBgHandler.post(() -> handleSetListening(callback));
- }
-
- protected List<SubscriptionInfo> getSubscriptionInfo() {
- return mKeyguardUpdateMonitor.getFilteredSubscriptionInfo(false);
- }
-
- protected void updateCarrierText() {
- boolean allSimsMissing = true;
- boolean anySimReadyAndInService = false;
- CharSequence displayText = null;
- List<SubscriptionInfo> subs = getSubscriptionInfo();
-
- final int numSubs = subs.size();
- final int[] subsIds = new int[numSubs];
- // This array will contain in position i, the index of subscription in slot ID i.
- // -1 if no subscription in that slot
- final int[] subOrderBySlot = new int[mSimSlotsNumber];
- for (int i = 0; i < mSimSlotsNumber; i++) {
- subOrderBySlot[i] = -1;
- }
- final CharSequence[] carrierNames = new CharSequence[numSubs];
- if (DEBUG) Log.d(TAG, "updateCarrierText(): " + numSubs);
-
- for (int i = 0; i < numSubs; i++) {
- int subId = subs.get(i).getSubscriptionId();
- carrierNames[i] = "";
- subsIds[i] = subId;
- subOrderBySlot[subs.get(i).getSimSlotIndex()] = i;
- int simState = mKeyguardUpdateMonitor.getSimState(subId);
- CharSequence carrierName = subs.get(i).getCarrierName();
- CharSequence carrierTextForSimState = getCarrierTextForSimState(simState, carrierName);
- if (DEBUG) {
- Log.d(TAG, "Handling (subId=" + subId + "): " + simState + " " + carrierName);
- }
- if (carrierTextForSimState != null) {
- allSimsMissing = false;
- carrierNames[i] = carrierTextForSimState;
- }
- if (simState == TelephonyManager.SIM_STATE_READY) {
- ServiceState ss = mKeyguardUpdateMonitor.mServiceStates.get(subId);
- if (ss != null && ss.getDataRegistrationState() == ServiceState.STATE_IN_SERVICE) {
- // hack for WFC (IWLAN) not turning off immediately once
- // Wi-Fi is disassociated or disabled
- if (ss.getRilDataRadioTechnology() != ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN
- || (mWifiManager != null && mWifiManager.isWifiEnabled()
- && mWifiManager.getConnectionInfo() != null
- && mWifiManager.getConnectionInfo().getBSSID() != null)) {
- if (DEBUG) {
- Log.d(TAG, "SIM ready and in service: subId=" + subId + ", ss=" + ss);
- }
- anySimReadyAndInService = true;
- }
- }
- }
- }
- // Only create "No SIM card" if no cards with CarrierName && no wifi when some sim is READY
- // This condition will also be true always when numSubs == 0
- if (allSimsMissing && !anySimReadyAndInService) {
- if (numSubs != 0) {
- // Shows "No SIM card | Emergency calls only" on devices that are voice-capable.
- // This depends on mPlmn containing the text "Emergency calls only" when the radio
- // has some connectivity. Otherwise, it should be null or empty and just show
- // "No SIM card"
- // Grab the first subscripton, because they all should contain the emergency text,
- // described above.
- displayText = makeCarrierStringOnEmergencyCapable(
- getMissingSimMessage(), subs.get(0).getCarrierName());
- } else {
- // We don't have a SubscriptionInfo to get the emergency calls only from.
- // Grab it from the old sticky broadcast if possible instead. We can use it
- // here because no subscriptions are active, so we don't have
- // to worry about MSIM clashing.
- CharSequence text =
- getContext().getText(com.android.internal.R.string.emergency_calls_only);
- Intent i = getContext().registerReceiver(null,
- new IntentFilter(TelephonyManager.ACTION_SERVICE_PROVIDERS_UPDATED));
- if (i != null) {
- String spn = "";
- String plmn = "";
- if (i.getBooleanExtra(TelephonyManager.EXTRA_SHOW_SPN, false)) {
- spn = i.getStringExtra(TelephonyManager.EXTRA_SPN);
- }
- if (i.getBooleanExtra(TelephonyManager.EXTRA_SHOW_PLMN, false)) {
- plmn = i.getStringExtra(TelephonyManager.EXTRA_PLMN);
- }
- if (DEBUG) Log.d(TAG, "Getting plmn/spn sticky brdcst " + plmn + "/" + spn);
- if (Objects.equals(plmn, spn)) {
- text = plmn;
- } else {
- text = concatenate(plmn, spn, mSeparator);
- }
- }
- displayText = makeCarrierStringOnEmergencyCapable(getMissingSimMessage(), text);
- }
- }
-
- if (TextUtils.isEmpty(displayText)) displayText = joinNotEmpty(mSeparator, carrierNames);
-
- displayText = updateCarrierTextWithSimIoError(displayText, carrierNames, subOrderBySlot,
- allSimsMissing);
-
- boolean airplaneMode = false;
- // APM (airplane mode) != no carrier state. There are carrier services
- // (e.g. WFC = Wi-Fi calling) which may operate in APM.
- if (!anySimReadyAndInService && WirelessUtils.isAirplaneModeOn(mContext)) {
- displayText = getAirplaneModeMessage();
- airplaneMode = true;
- }
-
- final CarrierTextCallbackInfo info = new CarrierTextCallbackInfo(
- displayText,
- carrierNames,
- !allSimsMissing,
- subsIds,
- airplaneMode);
- postToCallback(info);
- }
-
- @VisibleForTesting
- protected void postToCallback(CarrierTextCallbackInfo info) {
- final CarrierTextCallback callback = mCarrierTextCallback;
- if (callback != null) {
- mMainHandler.post(() -> callback.updateCarrierInfo(info));
- }
- }
-
- private Context getContext() {
- return mContext;
- }
-
- private String getMissingSimMessage() {
- return mShowMissingSim && mTelephonyCapable
- ? getContext().getString(R.string.keyguard_missing_sim_message_short) : "";
- }
-
- private String getAirplaneModeMessage() {
- return mShowAirplaneMode
- ? getContext().getString(R.string.airplane_mode) : "";
- }
-
- /**
- * Top-level function for creating carrier text. Makes text based on simState, PLMN
- * and SPN as well as device capabilities, such as being emergency call capable.
- *
- * @return Carrier text if not in missing state, null otherwise.
- */
- private CharSequence getCarrierTextForSimState(int simState, CharSequence text) {
- CharSequence carrierText = null;
- CarrierTextManager.StatusMode status = getStatusForIccState(simState);
- switch (status) {
- case Normal:
- carrierText = text;
- break;
-
- case SimNotReady:
- // Null is reserved for denoting missing, in this case we have nothing to display.
- carrierText = ""; // nothing to display yet.
- break;
-
- case NetworkLocked:
- carrierText = makeCarrierStringOnEmergencyCapable(
- mContext.getText(R.string.keyguard_network_locked_message), text);
- break;
-
- case SimMissing:
- carrierText = null;
- break;
-
- case SimPermDisabled:
- carrierText = makeCarrierStringOnEmergencyCapable(
- getContext().getText(
- R.string.keyguard_permanent_disabled_sim_message_short),
- text);
- break;
-
- case SimMissingLocked:
- carrierText = null;
- break;
-
- case SimLocked:
- carrierText = makeCarrierStringOnLocked(
- getContext().getText(R.string.keyguard_sim_locked_message),
- text);
- break;
-
- case SimPukLocked:
- carrierText = makeCarrierStringOnLocked(
- getContext().getText(R.string.keyguard_sim_puk_locked_message),
- text);
- break;
- case SimIoError:
- carrierText = makeCarrierStringOnEmergencyCapable(
- getContext().getText(R.string.keyguard_sim_error_message_short),
- text);
- break;
- case SimUnknown:
- carrierText = null;
- break;
- }
-
- return carrierText;
- }
-
- /*
- * Add emergencyCallMessage to carrier string only if phone supports emergency calls.
- */
- private CharSequence makeCarrierStringOnEmergencyCapable(
- CharSequence simMessage, CharSequence emergencyCallMessage) {
- if (mIsEmergencyCallCapable) {
- return concatenate(simMessage, emergencyCallMessage, mSeparator);
- }
- return simMessage;
- }
-
- /*
- * Add "SIM card is locked" in parenthesis after carrier name, so it is easily associated in
- * DSDS
- */
- private CharSequence makeCarrierStringOnLocked(CharSequence simMessage,
- CharSequence carrierName) {
- final boolean simMessageValid = !TextUtils.isEmpty(simMessage);
- final boolean carrierNameValid = !TextUtils.isEmpty(carrierName);
- if (simMessageValid && carrierNameValid) {
- return mContext.getString(R.string.keyguard_carrier_name_with_sim_locked_template,
- carrierName, simMessage);
- } else if (simMessageValid) {
- return simMessage;
- } else if (carrierNameValid) {
- return carrierName;
- } else {
- return "";
- }
- }
-
- /**
- * Determine the current status of the lock screen given the SIM state and other stuff.
- */
- private CarrierTextManager.StatusMode getStatusForIccState(int simState) {
- final boolean missingAndNotProvisioned =
- !mKeyguardUpdateMonitor.isDeviceProvisioned()
- && (simState == TelephonyManager.SIM_STATE_ABSENT
- || simState == TelephonyManager.SIM_STATE_PERM_DISABLED);
-
- // Assume we're NETWORK_LOCKED if not provisioned
- simState = missingAndNotProvisioned ? TelephonyManager.SIM_STATE_NETWORK_LOCKED : simState;
- switch (simState) {
- case TelephonyManager.SIM_STATE_ABSENT:
- return CarrierTextManager.StatusMode.SimMissing;
- case TelephonyManager.SIM_STATE_NETWORK_LOCKED:
- return CarrierTextManager.StatusMode.SimMissingLocked;
- case TelephonyManager.SIM_STATE_NOT_READY:
- return CarrierTextManager.StatusMode.SimNotReady;
- case TelephonyManager.SIM_STATE_PIN_REQUIRED:
- return CarrierTextManager.StatusMode.SimLocked;
- case TelephonyManager.SIM_STATE_PUK_REQUIRED:
- return CarrierTextManager.StatusMode.SimPukLocked;
- case TelephonyManager.SIM_STATE_READY:
- return CarrierTextManager.StatusMode.Normal;
- case TelephonyManager.SIM_STATE_PERM_DISABLED:
- return CarrierTextManager.StatusMode.SimPermDisabled;
- case TelephonyManager.SIM_STATE_UNKNOWN:
- return CarrierTextManager.StatusMode.SimUnknown;
- case TelephonyManager.SIM_STATE_CARD_IO_ERROR:
- return CarrierTextManager.StatusMode.SimIoError;
- }
- return CarrierTextManager.StatusMode.SimUnknown;
- }
-
- private static CharSequence concatenate(CharSequence plmn, CharSequence spn,
- CharSequence separator) {
- final boolean plmnValid = !TextUtils.isEmpty(plmn);
- final boolean spnValid = !TextUtils.isEmpty(spn);
- if (plmnValid && spnValid) {
- return new StringBuilder().append(plmn).append(separator).append(spn).toString();
- } else if (plmnValid) {
- return plmn;
- } else if (spnValid) {
- return spn;
- } else {
- return "";
- }
- }
-
- /**
- * Joins the strings in a sequence using a separator. Empty strings are discarded with no extra
- * separator added so there are no extra separators that are not needed.
- */
- private static CharSequence joinNotEmpty(CharSequence separator, CharSequence[] sequences) {
- int length = sequences.length;
- if (length == 0) return "";
- StringBuilder sb = new StringBuilder();
- for (int i = 0; i < length; i++) {
- if (!TextUtils.isEmpty(sequences[i])) {
- if (!TextUtils.isEmpty(sb)) {
- sb.append(separator);
- }
- sb.append(sequences[i]);
- }
- }
- return sb.toString();
- }
-
- private static List<CharSequence> append(List<CharSequence> list, CharSequence string) {
- if (!TextUtils.isEmpty(string)) {
- list.add(string);
- }
- return list;
- }
-
- private CharSequence getCarrierHelpTextForSimState(int simState,
- String plmn, String spn) {
- int carrierHelpTextId = 0;
- CarrierTextManager.StatusMode status = getStatusForIccState(simState);
- switch (status) {
- case NetworkLocked:
- carrierHelpTextId = R.string.keyguard_instructions_when_pattern_disabled;
- break;
-
- case SimMissing:
- carrierHelpTextId = R.string.keyguard_missing_sim_instructions_long;
- break;
-
- case SimPermDisabled:
- carrierHelpTextId = R.string.keyguard_permanent_disabled_sim_instructions;
- break;
-
- case SimMissingLocked:
- carrierHelpTextId = R.string.keyguard_missing_sim_instructions;
- break;
-
- case Normal:
- case SimLocked:
- case SimPukLocked:
- break;
- }
-
- return mContext.getText(carrierHelpTextId);
- }
-
- /** Injectable Buildeer for {@#link CarrierTextManager}. */
- public static class Builder {
- private final Context mContext;
- private final String mSeparator;
- private final WifiManager mWifiManager;
- private final ConnectivityManager mConnectivityManager;
- private final TelephonyManager mTelephonyManager;
- private final WakefulnessLifecycle mWakefulnessLifecycle;
- private final Handler mMainHandler;
- private final Handler mBgHandler;
- private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
- private boolean mShowAirplaneMode;
- private boolean mShowMissingSim;
-
- @Inject
- public Builder(Context context, @Main Resources resources,
- @Nullable WifiManager wifiManager, ConnectivityManager connectivityManager,
- TelephonyManager telephonyManager, WakefulnessLifecycle wakefulnessLifecycle,
- @Main Handler mainHandler, @Background Handler bgHandler,
- KeyguardUpdateMonitor keyguardUpdateMonitor) {
- mContext = context;
- mSeparator = resources.getString(
- com.android.internal.R.string.kg_text_message_separator);
- mWifiManager = wifiManager;
- mConnectivityManager = connectivityManager;
- mTelephonyManager = telephonyManager;
- mWakefulnessLifecycle = wakefulnessLifecycle;
- mMainHandler = mainHandler;
- mBgHandler = bgHandler;
- mKeyguardUpdateMonitor = keyguardUpdateMonitor;
- }
-
- /** */
- public Builder setShowAirplaneMode(boolean showAirplaneMode) {
- mShowAirplaneMode = showAirplaneMode;
- return this;
- }
-
- /** */
- public Builder setShowMissingSim(boolean showMissingSim) {
- mShowMissingSim = showMissingSim;
- return this;
- }
-
- /** Create a CarrierTextManager. */
- public CarrierTextManager build() {
- return new CarrierTextManager(
- mContext, mSeparator, mShowAirplaneMode, mShowMissingSim, mWifiManager,
- mConnectivityManager, mTelephonyManager, mWakefulnessLifecycle, mMainHandler,
- mBgHandler, mKeyguardUpdateMonitor);
- }
- }
- /**
- * Data structure for passing information to CarrierTextController subscribers
- */
- public static final class CarrierTextCallbackInfo {
- public final CharSequence carrierText;
- public final CharSequence[] listOfCarriers;
- public final boolean anySimReady;
- public final int[] subscriptionIds;
- public boolean airplaneMode;
-
- @VisibleForTesting
- public CarrierTextCallbackInfo(CharSequence carrierText, CharSequence[] listOfCarriers,
- boolean anySimReady, int[] subscriptionIds) {
- this(carrierText, listOfCarriers, anySimReady, subscriptionIds, false);
- }
-
- @VisibleForTesting
- public CarrierTextCallbackInfo(CharSequence carrierText, CharSequence[] listOfCarriers,
- boolean anySimReady, int[] subscriptionIds, boolean airplaneMode) {
- this.carrierText = carrierText;
- this.listOfCarriers = listOfCarriers;
- this.anySimReady = anySimReady;
- this.subscriptionIds = subscriptionIds;
- this.airplaneMode = airplaneMode;
- }
- }
-
- /**
- * Callback to communicate to Views
- */
- public interface CarrierTextCallback {
- /**
- * Provides updated carrier information.
- */
- default void updateCarrierInfo(CarrierTextCallbackInfo info) {};
-
- /**
- * Notifies the View that the device is going to sleep
- */
- default void startedGoingToSleep() {};
-
- /**
- * Notifies the View that the device finished waking up
- */
- default void finishedWakingUp() {};
- }
-}
diff --git a/packages/SystemUI/src/com/android/keyguard/EmergencyButton.java b/packages/SystemUI/src/com/android/keyguard/EmergencyButton.java
index c4b02f62f291..707ee298a55a 100644
--- a/packages/SystemUI/src/com/android/keyguard/EmergencyButton.java
+++ b/packages/SystemUI/src/com/android/keyguard/EmergencyButton.java
@@ -16,16 +16,34 @@
package com.android.keyguard;
+import static com.android.systemui.DejankUtils.whitelistIpcs;
+
+import android.app.ActivityOptions;
+import android.app.ActivityTaskManager;
import android.content.Context;
+import android.content.Intent;
+import android.content.res.Configuration;
+import android.os.PowerManager;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.os.UserHandle;
+import android.telecom.TelecomManager;
+import android.telephony.TelephonyManager;
import android.util.AttributeSet;
+import android.util.Log;
+import android.util.Slog;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.widget.Button;
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.util.EmergencyAffordanceManager;
import com.android.internal.widget.LockPatternUtils;
import com.android.settingslib.Utils;
+import com.android.systemui.Dependency;
+import com.android.systemui.util.EmergencyDialerConstants;
/**
* This class implements a smart emergency button that updates itself based
@@ -35,14 +53,34 @@ import com.android.settingslib.Utils;
*/
public class EmergencyButton extends Button {
+ private static final String LOG_TAG = "EmergencyButton";
private final EmergencyAffordanceManager mEmergencyAffordanceManager;
private int mDownX;
private int mDownY;
+ KeyguardUpdateMonitorCallback mInfoCallback = new KeyguardUpdateMonitorCallback() {
+
+ @Override
+ public void onSimStateChanged(int subId, int slotId, int simState) {
+ updateEmergencyCallButton();
+ }
+
+ @Override
+ public void onPhoneStateChanged(int phoneState) {
+ updateEmergencyCallButton();
+ }
+ };
private boolean mLongPressWasDragged;
+ public interface EmergencyButtonCallback {
+ public void onEmergencyButtonClickedWhenInCall();
+ }
+
private LockPatternUtils mLockPatternUtils;
+ private PowerManager mPowerManager;
+ private EmergencyButtonCallback mEmergencyButtonCallback;
+ private final boolean mIsVoiceCapable;
private final boolean mEnableEmergencyCallWhileSimLocked;
public EmergencyButton(Context context) {
@@ -51,15 +89,34 @@ public class EmergencyButton extends Button {
public EmergencyButton(Context context, AttributeSet attrs) {
super(context, attrs);
+ mIsVoiceCapable = getTelephonyManager().isVoiceCapable();
mEnableEmergencyCallWhileSimLocked = mContext.getResources().getBoolean(
com.android.internal.R.bool.config_enable_emergency_call_while_sim_locked);
mEmergencyAffordanceManager = new EmergencyAffordanceManager(context);
}
+ private TelephonyManager getTelephonyManager() {
+ return (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ Dependency.get(KeyguardUpdateMonitor.class).registerCallback(mInfoCallback);
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ Dependency.get(KeyguardUpdateMonitor.class).removeCallback(mInfoCallback);
+ }
+
@Override
protected void onFinishInflate() {
super.onFinishInflate();
mLockPatternUtils = new LockPatternUtils(mContext);
+ mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
+ setOnClickListener(v -> takeEmergencyCallAction());
if (mEmergencyAffordanceManager.needsEmergencyAffordance()) {
setOnLongClickListener(v -> {
if (!mLongPressWasDragged
@@ -70,6 +127,7 @@ public class EmergencyButton extends Button {
return false;
});
}
+ whitelistIpcs(this::updateEmergencyCallButton);
}
@Override
@@ -107,13 +165,65 @@ public class EmergencyButton extends Button {
return super.performLongClick();
}
- void updateEmergencyCallButton(boolean isInCall, boolean isVoiceCapable, boolean simLocked) {
+ @Override
+ protected void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+ updateEmergencyCallButton();
+ }
+
+ /**
+ * Shows the emergency dialer or returns the user to the existing call.
+ */
+ public void takeEmergencyCallAction() {
+ MetricsLogger.action(mContext, MetricsEvent.ACTION_EMERGENCY_CALL);
+ if (mPowerManager != null) {
+ mPowerManager.userActivity(SystemClock.uptimeMillis(), true);
+ }
+ try {
+ ActivityTaskManager.getService().stopSystemLockTaskMode();
+ } catch (RemoteException e) {
+ Slog.w(LOG_TAG, "Failed to stop app pinning");
+ }
+ if (isInCall()) {
+ resumeCall();
+ if (mEmergencyButtonCallback != null) {
+ mEmergencyButtonCallback.onEmergencyButtonClickedWhenInCall();
+ }
+ } else {
+ KeyguardUpdateMonitor updateMonitor = Dependency.get(KeyguardUpdateMonitor.class);
+ if (updateMonitor != null) {
+ updateMonitor.reportEmergencyCallAction(true /* bypassHandler */);
+ } else {
+ Log.w(LOG_TAG, "KeyguardUpdateMonitor was null, launching intent anyway.");
+ }
+ TelecomManager telecomManager = getTelecommManager();
+ if (telecomManager == null) {
+ Log.wtf(LOG_TAG, "TelecomManager was null, cannot launch emergency dialer");
+ return;
+ }
+ Intent emergencyDialIntent =
+ telecomManager.createLaunchEmergencyDialerIntent(null /* number*/)
+ .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+ | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
+ | Intent.FLAG_ACTIVITY_CLEAR_TOP)
+ .putExtra(EmergencyDialerConstants.EXTRA_ENTRY_TYPE,
+ EmergencyDialerConstants.ENTRY_TYPE_LOCKSCREEN_BUTTON);
+
+ getContext().startActivityAsUser(emergencyDialIntent,
+ ActivityOptions.makeCustomAnimation(getContext(), 0, 0).toBundle(),
+ new UserHandle(KeyguardUpdateMonitor.getCurrentUser()));
+ }
+ }
+
+ private void updateEmergencyCallButton() {
boolean visible = false;
- if (isVoiceCapable) {
+ if (mIsVoiceCapable) {
// Emergency calling requires voice capability.
- if (isInCall) {
+ if (isInCall()) {
visible = true; // always show "return to call" if phone is off-hook
} else {
+ final boolean simLocked = Dependency.get(KeyguardUpdateMonitor.class)
+ .isSimPinVoiceSecure();
if (simLocked) {
// Some countries can't handle emergency calls while SIM is locked.
visible = mEnableEmergencyCallWhileSimLocked;
@@ -127,7 +237,7 @@ public class EmergencyButton extends Button {
setVisibility(View.VISIBLE);
int textId;
- if (isInCall) {
+ if (isInCall()) {
textId = com.android.internal.R.string.lockscreen_return_to_call;
} else {
textId = com.android.internal.R.string.lockscreen_emergency_call;
@@ -137,4 +247,26 @@ public class EmergencyButton extends Button {
setVisibility(View.GONE);
}
}
+
+ public void setCallback(EmergencyButtonCallback callback) {
+ mEmergencyButtonCallback = callback;
+ }
+
+ /**
+ * Resumes a call in progress.
+ */
+ private void resumeCall() {
+ getTelecommManager().showInCallScreen(false);
+ }
+
+ /**
+ * @return {@code true} if there is a call currently in progress.
+ */
+ private boolean isInCall() {
+ return getTelecommManager().isInCall();
+ }
+
+ private TelecomManager getTelecommManager() {
+ return (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
+ }
}
diff --git a/packages/SystemUI/src/com/android/keyguard/EmergencyButtonController.java b/packages/SystemUI/src/com/android/keyguard/EmergencyButtonController.java
deleted file mode 100644
index 4275189cfe26..000000000000
--- a/packages/SystemUI/src/com/android/keyguard/EmergencyButtonController.java
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * Copyright (C) 2021 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.keyguard;
-
-import static com.android.systemui.DejankUtils.whitelistIpcs;
-
-import android.app.ActivityOptions;
-import android.app.ActivityTaskManager;
-import android.content.Intent;
-import android.content.res.Configuration;
-import android.os.PowerManager;
-import android.os.SystemClock;
-import android.os.UserHandle;
-import android.telecom.TelecomManager;
-import android.telephony.TelephonyManager;
-import android.util.Log;
-
-import androidx.annotation.Nullable;
-
-import com.android.internal.logging.MetricsLogger;
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.keyguard.dagger.KeyguardBouncerScope;
-import com.android.systemui.statusbar.policy.ConfigurationController;
-import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
-import com.android.systemui.util.EmergencyDialerConstants;
-import com.android.systemui.util.ViewController;
-
-import javax.inject.Inject;
-
-/** View Controller for {@link com.android.keyguard.EmergencyButton}. */
-@KeyguardBouncerScope
-public class EmergencyButtonController extends ViewController<EmergencyButton> {
- static final String LOG_TAG = "EmergencyButton";
- private final ConfigurationController mConfigurationController;
- private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
- private final TelephonyManager mTelephonyManager;
- private final PowerManager mPowerManager;
- private final ActivityTaskManager mActivityTaskManager;
- private final TelecomManager mTelecomManager;
- private final MetricsLogger mMetricsLogger;
-
- private EmergencyButtonCallback mEmergencyButtonCallback;
-
- private final KeyguardUpdateMonitorCallback mInfoCallback =
- new KeyguardUpdateMonitorCallback() {
- @Override
- public void onSimStateChanged(int subId, int slotId, int simState) {
- updateEmergencyCallButton();
- }
-
- @Override
- public void onPhoneStateChanged(int phoneState) {
- updateEmergencyCallButton();
- }
- };
-
- private final ConfigurationListener mConfigurationListener = new ConfigurationListener() {
- @Override
- public void onConfigChanged(Configuration newConfig) {
- updateEmergencyCallButton();
- }
- };
-
- private EmergencyButtonController(@Nullable EmergencyButton view,
- ConfigurationController configurationController,
- KeyguardUpdateMonitor keyguardUpdateMonitor, TelephonyManager telephonyManager,
- PowerManager powerManager, ActivityTaskManager activityTaskManager,
- @Nullable TelecomManager telecomManager, MetricsLogger metricsLogger) {
- super(view);
- mConfigurationController = configurationController;
- mKeyguardUpdateMonitor = keyguardUpdateMonitor;
- mTelephonyManager = telephonyManager;
- mPowerManager = powerManager;
- mActivityTaskManager = activityTaskManager;
- mTelecomManager = telecomManager;
- mMetricsLogger = metricsLogger;
- }
-
- @Override
- protected void onInit() {
- whitelistIpcs(this::updateEmergencyCallButton);
- }
-
- @Override
- protected void onViewAttached() {
- mKeyguardUpdateMonitor.registerCallback(mInfoCallback);
- mConfigurationController.addCallback(mConfigurationListener);
- mView.setOnClickListener(v -> takeEmergencyCallAction());
- }
-
- @Override
- protected void onViewDetached() {
- mKeyguardUpdateMonitor.removeCallback(mInfoCallback);
- mConfigurationController.removeCallback(mConfigurationListener);
- }
-
- private void updateEmergencyCallButton() {
- if (mView != null) {
- mView.updateEmergencyCallButton(
- mTelecomManager != null && mTelecomManager.isInCall(),
- mTelephonyManager.isVoiceCapable(),
- mKeyguardUpdateMonitor.isSimPinVoiceSecure());
- }
- }
-
- public void setEmergencyButtonCallback(EmergencyButtonCallback callback) {
- mEmergencyButtonCallback = callback;
- }
- /**
- * Shows the emergency dialer or returns the user to the existing call.
- */
- public void takeEmergencyCallAction() {
- mMetricsLogger.action(MetricsEvent.ACTION_EMERGENCY_CALL);
- if (mPowerManager != null) {
- mPowerManager.userActivity(SystemClock.uptimeMillis(), true);
- }
- mActivityTaskManager.stopSystemLockTaskMode();
- if (mTelecomManager != null && mTelecomManager.isInCall()) {
- mTelecomManager.showInCallScreen(false);
- if (mEmergencyButtonCallback != null) {
- mEmergencyButtonCallback.onEmergencyButtonClickedWhenInCall();
- }
- } else {
- mKeyguardUpdateMonitor.reportEmergencyCallAction(true /* bypassHandler */);
- if (mTelecomManager == null) {
- Log.wtf(LOG_TAG, "TelecomManager was null, cannot launch emergency dialer");
- return;
- }
- Intent emergencyDialIntent =
- mTelecomManager.createLaunchEmergencyDialerIntent(null /* number*/)
- .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
- | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
- | Intent.FLAG_ACTIVITY_CLEAR_TOP)
- .putExtra(EmergencyDialerConstants.EXTRA_ENTRY_TYPE,
- EmergencyDialerConstants.ENTRY_TYPE_LOCKSCREEN_BUTTON);
-
- getContext().startActivityAsUser(emergencyDialIntent,
- ActivityOptions.makeCustomAnimation(getContext(), 0, 0).toBundle(),
- new UserHandle(KeyguardUpdateMonitor.getCurrentUser()));
- }
- }
-
- /** */
- public interface EmergencyButtonCallback {
- /** */
- void onEmergencyButtonClickedWhenInCall();
- }
-
- /** Injectable Factory for creating {@link EmergencyButtonController}. */
- public static class Factory {
- private final ConfigurationController mConfigurationController;
- private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
- private final TelephonyManager mTelephonyManager;
- private final PowerManager mPowerManager;
- private final ActivityTaskManager mActivityTaskManager;
- @Nullable
- private final TelecomManager mTelecomManager;
- private final MetricsLogger mMetricsLogger;
-
- @Inject
- public Factory(ConfigurationController configurationController,
- KeyguardUpdateMonitor keyguardUpdateMonitor, TelephonyManager telephonyManager,
- PowerManager powerManager, ActivityTaskManager activityTaskManager,
- @Nullable TelecomManager telecomManager, MetricsLogger metricsLogger) {
-
- mConfigurationController = configurationController;
- mKeyguardUpdateMonitor = keyguardUpdateMonitor;
- mTelephonyManager = telephonyManager;
- mPowerManager = powerManager;
- mActivityTaskManager = activityTaskManager;
- mTelecomManager = telecomManager;
- mMetricsLogger = metricsLogger;
- }
-
- /** Construct an {@link com.android.keyguard.EmergencyButtonController}. */
- public EmergencyButtonController create(EmergencyButton view) {
- return new EmergencyButtonController(view, mConfigurationController,
- mKeyguardUpdateMonitor, mTelephonyManager, mPowerManager, mActivityTaskManager,
- mTelecomManager, mMetricsLogger);
- }
- }
-}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputViewController.java
index 7a05a17c8010..5760565aaab1 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputViewController.java
@@ -31,7 +31,7 @@ import com.android.internal.util.LatencyTracker;
import com.android.internal.widget.LockPatternChecker;
import com.android.internal.widget.LockPatternUtils;
import com.android.internal.widget.LockscreenCredential;
-import com.android.keyguard.EmergencyButtonController.EmergencyButtonCallback;
+import com.android.keyguard.EmergencyButton.EmergencyButtonCallback;
import com.android.keyguard.KeyguardAbsKeyInputView.KeyDownListener;
import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
import com.android.systemui.R;
@@ -41,7 +41,6 @@ public abstract class KeyguardAbsKeyInputViewController<T extends KeyguardAbsKey
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
private final LockPatternUtils mLockPatternUtils;
private final LatencyTracker mLatencyTracker;
- private final EmergencyButtonController mEmergencyButtonController;
private CountDownTimer mCountdownTimer;
protected KeyguardMessageAreaController mMessageAreaController;
private boolean mDismissing;
@@ -71,12 +70,11 @@ public abstract class KeyguardAbsKeyInputViewController<T extends KeyguardAbsKey
LockPatternUtils lockPatternUtils,
KeyguardSecurityCallback keyguardSecurityCallback,
KeyguardMessageAreaController.Factory messageAreaControllerFactory,
- LatencyTracker latencyTracker, EmergencyButtonController emergencyButtonController) {
- super(view, securityMode, keyguardSecurityCallback, emergencyButtonController);
+ LatencyTracker latencyTracker) {
+ super(view, securityMode, keyguardSecurityCallback);
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
mLockPatternUtils = lockPatternUtils;
mLatencyTracker = latencyTracker;
- mEmergencyButtonController = emergencyButtonController;
KeyguardMessageArea kma = KeyguardMessageArea.findSecurityMessageDisplay(mView);
mMessageAreaController = messageAreaControllerFactory.create(kma);
}
@@ -85,7 +83,6 @@ public abstract class KeyguardAbsKeyInputViewController<T extends KeyguardAbsKey
@Override
public void onInit() {
- super.onInit();
mMessageAreaController.init();
}
@@ -94,7 +91,10 @@ public abstract class KeyguardAbsKeyInputViewController<T extends KeyguardAbsKey
super.onViewAttached();
mView.setKeyDownListener(mKeyDownListener);
mView.setEnableHaptics(mLockPatternUtils.isTactileFeedbackEnabled());
- mEmergencyButtonController.setEmergencyButtonCallback(mEmergencyButtonCallback);
+ EmergencyButton button = mView.findViewById(R.id.emergency_call_button);
+ if (button != null) {
+ button.setCallback(mEmergencyButtonCallback);
+ }
}
@Override
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java b/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java
index 76a7473e25e8..276036c400e1 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java
@@ -36,6 +36,7 @@ import android.view.WindowManager;
import com.android.internal.annotations.VisibleForTesting;
import com.android.keyguard.dagger.KeyguardStatusViewComponent;
+import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.dagger.qualifiers.UiBackground;
import com.android.systemui.navigationbar.NavigationBarController;
@@ -45,15 +46,12 @@ import java.util.concurrent.Executor;
import javax.inject.Inject;
-import dagger.Lazy;
-
public class KeyguardDisplayManager {
protected static final String TAG = "KeyguardDisplayManager";
private static boolean DEBUG = KeyguardConstants.DEBUG;
private MediaRouter mMediaRouter = null;
private final DisplayManager mDisplayService;
- private final Lazy<NavigationBarController> mNavigationBarControllerLazy;
private final KeyguardStatusViewComponent.Factory mKeyguardStatusViewComponentFactory;
private final Context mContext;
@@ -87,11 +85,9 @@ public class KeyguardDisplayManager {
@Inject
public KeyguardDisplayManager(Context context,
- Lazy<NavigationBarController> navigationBarControllerLazy,
KeyguardStatusViewComponent.Factory keyguardStatusViewComponentFactory,
@UiBackground Executor uiBgExecutor) {
mContext = context;
- mNavigationBarControllerLazy = navigationBarControllerLazy;
mKeyguardStatusViewComponentFactory = keyguardStatusViewComponentFactory;
uiBgExecutor.execute(() -> mMediaRouter = mContext.getSystemService(MediaRouter.class));
mDisplayService = mContext.getSystemService(DisplayManager.class);
@@ -244,7 +240,7 @@ public class KeyguardDisplayManager {
// Leave this task to {@link StatusBarKeyguardViewManager}
if (displayId == DEFAULT_DISPLAY) return;
- NavigationBarView navBarView = mNavigationBarControllerLazy.get()
+ NavigationBarView navBarView = Dependency.get(NavigationBarController.class)
.getNavigationBarView(displayId);
// We may not have nav bar on a display.
if (navBarView == null) return;
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardInputViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardInputViewController.java
index a0c5958284ec..957882dc9c6b 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardInputViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardInputViewController.java
@@ -42,7 +42,6 @@ public abstract class KeyguardInputViewController<T extends KeyguardInputView>
private final SecurityMode mSecurityMode;
private final KeyguardSecurityCallback mKeyguardSecurityCallback;
private final EmergencyButton mEmergencyButton;
- private final EmergencyButtonController mEmergencyButtonController;
private boolean mPaused;
@@ -70,18 +69,11 @@ public abstract class KeyguardInputViewController<T extends KeyguardInputView>
};
protected KeyguardInputViewController(T view, SecurityMode securityMode,
- KeyguardSecurityCallback keyguardSecurityCallback,
- EmergencyButtonController emergencyButtonController) {
+ KeyguardSecurityCallback keyguardSecurityCallback) {
super(view);
mSecurityMode = securityMode;
mKeyguardSecurityCallback = keyguardSecurityCallback;
mEmergencyButton = view == null ? null : view.findViewById(R.id.emergency_call_button);
- mEmergencyButtonController = emergencyButtonController;
- }
-
- @Override
- protected void onInit() {
- mEmergencyButtonController.init();
}
@Override
@@ -163,9 +155,8 @@ public abstract class KeyguardInputViewController<T extends KeyguardInputView>
private final InputMethodManager mInputMethodManager;
private final DelayableExecutor mMainExecutor;
private final Resources mResources;
- private final LiftToActivateListener mLiftToActivateListener;
- private final TelephonyManager mTelephonyManager;
- private final EmergencyButtonController.Factory mEmergencyButtonControllerFactory;
+ private LiftToActivateListener mLiftToActivateListener;
+ private TelephonyManager mTelephonyManager;
private final FalsingCollector mFalsingCollector;
private final boolean mIsNewLayoutEnabled;
@@ -177,7 +168,6 @@ public abstract class KeyguardInputViewController<T extends KeyguardInputView>
InputMethodManager inputMethodManager, @Main DelayableExecutor mainExecutor,
@Main Resources resources, LiftToActivateListener liftToActivateListener,
TelephonyManager telephonyManager,
- EmergencyButtonController.Factory emergencyButtonControllerFactory,
FalsingCollector falsingCollector,
FeatureFlags featureFlags) {
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
@@ -189,7 +179,6 @@ public abstract class KeyguardInputViewController<T extends KeyguardInputView>
mResources = resources;
mLiftToActivateListener = liftToActivateListener;
mTelephonyManager = telephonyManager;
- mEmergencyButtonControllerFactory = emergencyButtonControllerFactory;
mFalsingCollector = falsingCollector;
mIsNewLayoutEnabled = featureFlags.isKeyguardLayoutEnabled();
}
@@ -197,40 +186,31 @@ public abstract class KeyguardInputViewController<T extends KeyguardInputView>
/** Create a new {@link KeyguardInputViewController}. */
public KeyguardInputViewController create(KeyguardInputView keyguardInputView,
SecurityMode securityMode, KeyguardSecurityCallback keyguardSecurityCallback) {
- EmergencyButtonController emergencyButtonController =
- mEmergencyButtonControllerFactory.create(
- keyguardInputView.findViewById(R.id.emergency_call_button));
-
if (keyguardInputView instanceof KeyguardPatternView) {
return new KeyguardPatternViewController((KeyguardPatternView) keyguardInputView,
mKeyguardUpdateMonitor, securityMode, mLockPatternUtils,
- keyguardSecurityCallback, mLatencyTracker,
- emergencyButtonController,
- mMessageAreaControllerFactory);
+ keyguardSecurityCallback, mLatencyTracker, mMessageAreaControllerFactory);
} else if (keyguardInputView instanceof KeyguardPasswordView) {
return new KeyguardPasswordViewController((KeyguardPasswordView) keyguardInputView,
mKeyguardUpdateMonitor, securityMode, mLockPatternUtils,
keyguardSecurityCallback, mMessageAreaControllerFactory, mLatencyTracker,
- mInputMethodManager, emergencyButtonController, mMainExecutor, mResources);
+ mInputMethodManager, mMainExecutor, mResources);
} else if (keyguardInputView instanceof KeyguardPINView) {
return new KeyguardPinViewController((KeyguardPINView) keyguardInputView,
mKeyguardUpdateMonitor, securityMode, mLockPatternUtils,
keyguardSecurityCallback, mMessageAreaControllerFactory, mLatencyTracker,
- mLiftToActivateListener, emergencyButtonController, mFalsingCollector,
- mIsNewLayoutEnabled);
+ mLiftToActivateListener, mFalsingCollector, mIsNewLayoutEnabled);
} else if (keyguardInputView instanceof KeyguardSimPinView) {
return new KeyguardSimPinViewController((KeyguardSimPinView) keyguardInputView,
mKeyguardUpdateMonitor, securityMode, mLockPatternUtils,
keyguardSecurityCallback, mMessageAreaControllerFactory, mLatencyTracker,
mLiftToActivateListener, mTelephonyManager,
- emergencyButtonController,
mFalsingCollector, mIsNewLayoutEnabled);
} else if (keyguardInputView instanceof KeyguardSimPukView) {
return new KeyguardSimPukViewController((KeyguardSimPukView) keyguardInputView,
mKeyguardUpdateMonitor, securityMode, mLockPatternUtils,
keyguardSecurityCallback, mMessageAreaControllerFactory, mLatencyTracker,
mLiftToActivateListener, mTelephonyManager,
- emergencyButtonController,
mFalsingCollector, mIsNewLayoutEnabled);
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java
index 2e4554592580..0f1c3c8a20b7 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java
@@ -111,11 +111,10 @@ public class KeyguardPasswordViewController
KeyguardMessageAreaController.Factory messageAreaControllerFactory,
LatencyTracker latencyTracker,
InputMethodManager inputMethodManager,
- EmergencyButtonController emergencyButtonController,
@Main DelayableExecutor mainExecutor,
@Main Resources resources) {
super(view, keyguardUpdateMonitor, securityMode, lockPatternUtils, keyguardSecurityCallback,
- messageAreaControllerFactory, latencyTracker, emergencyButtonController);
+ messageAreaControllerFactory, latencyTracker);
mKeyguardSecurityCallback = keyguardSecurityCallback;
mInputMethodManager = inputMethodManager;
mMainExecutor = mainExecutor;
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java
index 55e348cc06b1..2aaf748e2415 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java
@@ -31,7 +31,7 @@ import com.android.internal.widget.LockPatternUtils;
import com.android.internal.widget.LockPatternView;
import com.android.internal.widget.LockPatternView.Cell;
import com.android.internal.widget.LockscreenCredential;
-import com.android.keyguard.EmergencyButtonController.EmergencyButtonCallback;
+import com.android.keyguard.EmergencyButton.EmergencyButtonCallback;
import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
import com.android.settingslib.Utils;
import com.android.systemui.R;
@@ -50,7 +50,6 @@ public class KeyguardPatternViewController
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
private final LockPatternUtils mLockPatternUtils;
private final LatencyTracker mLatencyTracker;
- private final EmergencyButtonController mEmergencyButtonController;
private final KeyguardMessageAreaController.Factory mMessageAreaControllerFactory;
private KeyguardMessageAreaController mMessageAreaController;
@@ -180,13 +179,11 @@ public class KeyguardPatternViewController
LockPatternUtils lockPatternUtils,
KeyguardSecurityCallback keyguardSecurityCallback,
LatencyTracker latencyTracker,
- EmergencyButtonController emergencyButtonController,
KeyguardMessageAreaController.Factory messageAreaControllerFactory) {
- super(view, securityMode, keyguardSecurityCallback, emergencyButtonController);
+ super(view, securityMode, keyguardSecurityCallback);
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
mLockPatternUtils = lockPatternUtils;
mLatencyTracker = latencyTracker;
- mEmergencyButtonController = emergencyButtonController;
mMessageAreaControllerFactory = messageAreaControllerFactory;
KeyguardMessageArea kma = KeyguardMessageArea.findSecurityMessageDisplay(mView);
mMessageAreaController = mMessageAreaControllerFactory.create(kma);
@@ -208,7 +205,11 @@ public class KeyguardPatternViewController
KeyguardUpdateMonitor.getCurrentUser()));
// vibrate mode will be the same for the life of this screen
mLockPatternView.setTactileFeedbackEnabled(mLockPatternUtils.isTactileFeedbackEnabled());
- mEmergencyButtonController.setEmergencyButtonCallback(mEmergencyButtonCallback);
+
+ EmergencyButton button = mView.findViewById(R.id.emergency_call_button);
+ if (button != null) {
+ button.setCallback(mEmergencyButtonCallback);
+ }
View cancelBtn = mView.findViewById(R.id.cancel_button);
if (cancelBtn != null) {
@@ -223,7 +224,10 @@ public class KeyguardPatternViewController
protected void onViewDetached() {
super.onViewDetached();
mLockPatternView.setOnPatternListener(null);
- mEmergencyButtonController.setEmergencyButtonCallback(null);
+ EmergencyButton button = mView.findViewById(R.id.emergency_call_button);
+ if (button != null) {
+ button.setCallback(null);
+ }
View cancelBtn = mView.findViewById(R.id.cancel_button);
if (cancelBtn != null) {
cancelBtn.setOnClickListener(null);
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputViewController.java
index 1b5aa453ac97..f2479488db0f 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputViewController.java
@@ -71,10 +71,9 @@ public abstract class KeyguardPinBasedInputViewController<T extends KeyguardPinB
KeyguardMessageAreaController.Factory messageAreaControllerFactory,
LatencyTracker latencyTracker,
LiftToActivateListener liftToActivateListener,
- EmergencyButtonController emergencyButtonController,
FalsingCollector falsingCollector) {
super(view, keyguardUpdateMonitor, securityMode, lockPatternUtils, keyguardSecurityCallback,
- messageAreaControllerFactory, latencyTracker, emergencyButtonController);
+ messageAreaControllerFactory, latencyTracker);
mLiftToActivateListener = liftToActivateListener;
mFalsingCollector = falsingCollector;
mPasswordEntry = mView.findViewById(mView.getPasswordTextViewId());
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPinViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPinViewController.java
index a456d42f5be5..49099fa18323 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPinViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPinViewController.java
@@ -34,11 +34,10 @@ public class KeyguardPinViewController
KeyguardSecurityCallback keyguardSecurityCallback,
KeyguardMessageAreaController.Factory messageAreaControllerFactory,
LatencyTracker latencyTracker, LiftToActivateListener liftToActivateListener,
- EmergencyButtonController emergencyButtonController,
FalsingCollector falsingCollector, boolean isNewLayoutEnabled) {
super(view, keyguardUpdateMonitor, securityMode, lockPatternUtils, keyguardSecurityCallback,
messageAreaControllerFactory, latencyTracker, liftToActivateListener,
- emergencyButtonController, falsingCollector);
+ falsingCollector);
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
view.setIsNewLayoutEnabled(isNewLayoutEnabled);
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityModel.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityModel.java
index bacd29f661ae..c77c86711abf 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityModel.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityModel.java
@@ -23,6 +23,7 @@ import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import com.android.internal.widget.LockPatternUtils;
+import com.android.systemui.Dependency;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
@@ -48,27 +49,24 @@ public class KeyguardSecurityModel {
private final boolean mIsPukScreenAvailable;
private final LockPatternUtils mLockPatternUtils;
- private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
@Inject
- KeyguardSecurityModel(@Main Resources resources, LockPatternUtils lockPatternUtils,
- KeyguardUpdateMonitor keyguardUpdateMonitor) {
+ KeyguardSecurityModel(@Main Resources resources, LockPatternUtils lockPatternUtils) {
mIsPukScreenAvailable = resources.getBoolean(
com.android.internal.R.bool.config_enable_puk_unlock_screen);
mLockPatternUtils = lockPatternUtils;
- mKeyguardUpdateMonitor = keyguardUpdateMonitor;
}
public SecurityMode getSecurityMode(int userId) {
+ KeyguardUpdateMonitor monitor = Dependency.get(KeyguardUpdateMonitor.class);
+
if (mIsPukScreenAvailable && SubscriptionManager.isValidSubscriptionId(
- mKeyguardUpdateMonitor.getNextSubIdForState(
- TelephonyManager.SIM_STATE_PUK_REQUIRED))) {
+ monitor.getNextSubIdForState(TelephonyManager.SIM_STATE_PUK_REQUIRED))) {
return SecurityMode.SimPuk;
}
if (SubscriptionManager.isValidSubscriptionId(
- mKeyguardUpdateMonitor.getNextSubIdForState(
- TelephonyManager.SIM_STATE_PIN_REQUIRED))) {
+ monitor.getNextSubIdForState(TelephonyManager.SIM_STATE_PIN_REQUIRED))) {
return SecurityMode.SimPin;
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewFlipperController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewFlipperController.java
index 33d47fe13f38..f1b504e9f941 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewFlipperController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewFlipperController.java
@@ -44,18 +44,15 @@ public class KeyguardSecurityViewFlipperController
private final List<KeyguardInputViewController<KeyguardInputView>> mChildren =
new ArrayList<>();
private final LayoutInflater mLayoutInflater;
- private final EmergencyButtonController.Factory mEmergencyButtonControllerFactory;
private final Factory mKeyguardSecurityViewControllerFactory;
@Inject
protected KeyguardSecurityViewFlipperController(KeyguardSecurityViewFlipper view,
LayoutInflater layoutInflater,
- KeyguardInputViewController.Factory keyguardSecurityViewControllerFactory,
- EmergencyButtonController.Factory emergencyButtonControllerFactory) {
+ KeyguardInputViewController.Factory keyguardSecurityViewControllerFactory) {
super(view);
mKeyguardSecurityViewControllerFactory = keyguardSecurityViewControllerFactory;
mLayoutInflater = layoutInflater;
- mEmergencyButtonControllerFactory = emergencyButtonControllerFactory;
}
@Override
@@ -114,8 +111,7 @@ public class KeyguardSecurityViewFlipperController
if (childController == null) {
childController = new NullKeyguardInputViewController(
- securityMode, keyguardSecurityCallback,
- mEmergencyButtonControllerFactory.create(null));
+ securityMode, keyguardSecurityCallback);
}
return childController;
@@ -144,9 +140,8 @@ public class KeyguardSecurityViewFlipperController
private static class NullKeyguardInputViewController
extends KeyguardInputViewController<KeyguardInputView> {
protected NullKeyguardInputViewController(SecurityMode securityMode,
- KeyguardSecurityCallback keyguardSecurityCallback,
- EmergencyButtonController emergencyButtonController) {
- super(null, securityMode, keyguardSecurityCallback, emergencyButtonController);
+ KeyguardSecurityCallback keyguardSecurityCallback) {
+ super(null, securityMode, keyguardSecurityCallback);
}
@Override
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinViewController.java
index 4d2ebbb4a594..cdbbfe643812 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinViewController.java
@@ -78,11 +78,11 @@ public class KeyguardSimPinViewController
KeyguardSecurityCallback keyguardSecurityCallback,
KeyguardMessageAreaController.Factory messageAreaControllerFactory,
LatencyTracker latencyTracker, LiftToActivateListener liftToActivateListener,
- TelephonyManager telephonyManager, EmergencyButtonController emergencyButtonController,
+ TelephonyManager telephonyManager,
FalsingCollector falsingCollector, boolean isNewLayoutEnabled) {
super(view, keyguardUpdateMonitor, securityMode, lockPatternUtils, keyguardSecurityCallback,
messageAreaControllerFactory, latencyTracker, liftToActivateListener,
- emergencyButtonController, falsingCollector);
+ falsingCollector);
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
mTelephonyManager = telephonyManager;
mSimImageView = mView.findViewById(R.id.keyguard_sim);
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukViewController.java
index 0d9bb6f73b49..8fff34278216 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukViewController.java
@@ -37,6 +37,7 @@ import android.widget.ImageView;
import com.android.internal.util.LatencyTracker;
import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
+import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.classifier.FalsingCollector;
@@ -84,11 +85,11 @@ public class KeyguardSimPukViewController
KeyguardSecurityCallback keyguardSecurityCallback,
KeyguardMessageAreaController.Factory messageAreaControllerFactory,
LatencyTracker latencyTracker, LiftToActivateListener liftToActivateListener,
- TelephonyManager telephonyManager, EmergencyButtonController emergencyButtonController,
+ TelephonyManager telephonyManager,
FalsingCollector falsingCollector, boolean isNewLayoutEnabled) {
super(view, keyguardUpdateMonitor, securityMode, lockPatternUtils, keyguardSecurityCallback,
messageAreaControllerFactory, latencyTracker, liftToActivateListener,
- emergencyButtonController, falsingCollector);
+ falsingCollector);
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
mTelephonyManager = telephonyManager;
mSimImageView = mView.findViewById(R.id.keyguard_sim);
@@ -197,7 +198,8 @@ public class KeyguardSimPukViewController
if (count < 2) {
msg = rez.getString(R.string.kg_puk_enter_puk_hint);
} else {
- SubscriptionInfo info = mKeyguardUpdateMonitor.getSubscriptionInfoForSubId(mSubId);
+ SubscriptionInfo info = Dependency.get(KeyguardUpdateMonitor.class)
+ .getSubscriptionInfoForSubId(mSubId);
CharSequence displayName = info != null ? info.getDisplayName() : "";
msg = rez.getString(R.string.kg_puk_enter_puk_hint_multi, displayName);
if (info != null) {
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
index 1fbf71de47ca..fb97a30f93fb 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
@@ -49,8 +49,10 @@ import androidx.slice.widget.SliceContent;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.graphics.ColorUtils;
import com.android.settingslib.Utils;
+import com.android.systemui.Dependency;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.util.wakelock.KeepAwakeAnimationListener;
import java.io.FileDescriptor;
@@ -315,22 +317,6 @@ public class KeyguardSliceView extends LinearLayout {
R.dimen.widget_label_font_size);
mRowWithHeaderTextSize = mContext.getResources().getDimensionPixelSize(
R.dimen.header_row_font_size);
-
- for (int i = 0; i < mRow.getChildCount(); i++) {
- View child = mRow.getChildAt(i);
- if (child instanceof KeyguardSliceTextView) {
- ((KeyguardSliceTextView) child).onDensityOrFontScaleChanged();
- }
- }
- }
-
- void onOverlayChanged() {
- for (int i = 0; i < mRow.getChildCount(); i++) {
- View child = mRow.getChildAt(i);
- if (child instanceof KeyguardSliceTextView) {
- ((KeyguardSliceTextView) child).onOverlayChanged();
- }
- }
}
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
@@ -493,7 +479,8 @@ public class KeyguardSliceView extends LinearLayout {
* Representation of an item that appears under the clock on main keyguard message.
*/
@VisibleForTesting
- static class KeyguardSliceTextView extends TextView {
+ static class KeyguardSliceTextView extends TextView implements
+ ConfigurationController.ConfigurationListener {
private int mLockScreenMode = KeyguardUpdateMonitor.LOCK_SCREEN_MODE_NORMAL;
@StyleRes
@@ -505,10 +492,24 @@ public class KeyguardSliceView extends LinearLayout {
setEllipsize(TruncateAt.END);
}
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ Dependency.get(ConfigurationController.class).addCallback(this);
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ Dependency.get(ConfigurationController.class).removeCallback(this);
+ }
+
+ @Override
public void onDensityOrFontScaleChanged() {
updatePadding();
}
+ @Override
public void onOverlayChanged() {
setTextAppearance(sStyleId);
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceViewController.java
index 8038ce4c7b69..1b0a7faeddab 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceViewController.java
@@ -83,10 +83,6 @@ public class KeyguardSliceViewController extends ViewController<KeyguardSliceVie
public void onDensityOrFontScaleChanged() {
mView.onDensityOrFontScaleChanged();
}
- @Override
- public void onOverlayChanged() {
- mView.onOverlayChanged();
- }
};
Observer<Slice> mObserver = new Observer<Slice>() {
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
index 5db4f9e61140..fea152abe36a 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
@@ -34,6 +34,7 @@ import android.widget.TextView;
import androidx.core.graphics.ColorUtils;
import com.android.internal.widget.LockPatternUtils;
+import com.android.systemui.Dependency;
import com.android.systemui.R;
import java.io.FileDescriptor;
@@ -55,6 +56,7 @@ public class KeyguardStatusView extends GridLayout {
private final IActivityManager mIActivityManager;
private TextView mLogoutView;
+ private boolean mCanShowLogout = true; // by default, try to show the logout button here
private KeyguardClockSwitch mClockView;
private TextView mOwnerInfo;
private boolean mCanShowOwnerInfo = true; // by default, try to show the owner information here
@@ -128,6 +130,11 @@ public class KeyguardStatusView extends GridLayout {
}
}
+ void setCanShowLogout(boolean canShowLogout) {
+ mCanShowLogout = canShowLogout;
+ updateLogoutView();
+ }
+
@Override
protected void onFinishInflate() {
super.onFinishInflate();
@@ -152,7 +159,10 @@ public class KeyguardStatusView extends GridLayout {
mKeyguardSlice.setContentChangeListener(this::onSliceContentChanged);
onSliceContentChanged();
+ boolean shouldMarquee = Dependency.get(KeyguardUpdateMonitor.class).isDeviceInteractive();
+ setEnableMarquee(shouldMarquee);
updateOwnerInfo();
+ updateLogoutView();
updateDark();
}
@@ -199,11 +209,11 @@ public class KeyguardStatusView extends GridLayout {
return mOwnerInfo.getVisibility() == VISIBLE ? mOwnerInfo.getHeight() : 0;
}
- void updateLogoutView(boolean shouldShowLogout) {
+ void updateLogoutView() {
if (mLogoutView == null) {
return;
}
- mLogoutView.setVisibility(shouldShowLogout ? VISIBLE : GONE);
+ mLogoutView.setVisibility(mCanShowLogout && shouldShowLogout() ? VISIBLE : GONE);
// Logout button will stay in language of user 0 if we don't set that manually.
mLogoutView.setText(mContext.getResources().getString(
com.android.internal.R.string.global_action_logout));
@@ -303,6 +313,11 @@ public class KeyguardStatusView extends GridLayout {
}
}
+ private boolean shouldShowLogout() {
+ return Dependency.get(KeyguardUpdateMonitor.class).isLogoutEnabled()
+ && KeyguardUpdateMonitor.getCurrentUser() != UserHandle.USER_SYSTEM;
+ }
+
private void onLogoutClicked(View view) {
int currentUserId = KeyguardUpdateMonitor.getCurrentUser();
try {
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
index bfe7f8c7ebd8..6fb6760be653 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
@@ -16,7 +16,6 @@
package com.android.keyguard;
-import android.os.UserHandle;
import android.util.Slog;
import android.view.View;
@@ -79,8 +78,6 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
@Override
public void onInit() {
mKeyguardClockSwitchController.init();
- mView.setEnableMarquee(mKeyguardUpdateMonitor.isDeviceInteractive());
- mView.updateLogoutView(shouldShowLogout());
}
@Override
@@ -248,11 +245,6 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
}
}
- private boolean shouldShowLogout() {
- return mKeyguardUpdateMonitor.isLogoutEnabled()
- && KeyguardUpdateMonitor.getCurrentUser() != UserHandle.USER_SYSTEM;
- }
-
private final ConfigurationController.ConfigurationListener mConfigurationListener =
new ConfigurationController.ConfigurationListener() {
@Override
@@ -279,12 +271,12 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
mKeyguardSliceViewController.updateTopMargin(
mKeyguardClockSwitchController.getClockTextTopPadding());
mView.setCanShowOwnerInfo(false);
- mView.updateLogoutView(false);
+ mView.setCanShowLogout(false);
} else {
// reset margin
mKeyguardSliceViewController.updateTopMargin(0);
mView.setCanShowOwnerInfo(true);
- mView.updateLogoutView(false);
+ mView.setCanShowLogout(false);
}
updateAodIcons();
}
@@ -310,7 +302,7 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
if (DEBUG) Slog.v(TAG, "refresh statusview showing:" + showing);
refreshTime();
mView.updateOwnerInfo();
- mView.updateLogoutView(shouldShowLogout());
+ mView.updateLogoutView();
}
}
@@ -328,12 +320,12 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
public void onUserSwitchComplete(int userId) {
mKeyguardClockSwitchController.refreshFormat();
mView.updateOwnerInfo();
- mView.updateLogoutView(shouldShowLogout());
+ mView.updateLogoutView();
}
@Override
public void onLogoutEnabledChanged() {
- mView.updateLogoutView(shouldShowLogout());
+ mView.updateLogoutView();
}
};
}
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/ClockOptionsProvider.java b/packages/SystemUI/src/com/android/keyguard/clock/ClockOptionsProvider.java
index b6413cb61deb..5ef35be8df51 100644
--- a/packages/SystemUI/src/com/android/keyguard/clock/ClockOptionsProvider.java
+++ b/packages/SystemUI/src/com/android/keyguard/clock/ClockOptionsProvider.java
@@ -28,12 +28,11 @@ import android.text.TextUtils;
import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.systemui.Dependency;
import java.io.FileNotFoundException;
import java.util.List;
-
-import javax.inject.Inject;
-import javax.inject.Provider;
+import java.util.function.Supplier;
/**
* Exposes custom clock face options and provides realistic preview images.
@@ -66,12 +65,15 @@ public final class ClockOptionsProvider extends ContentProvider {
private static final String CONTENT_SCHEME = "content";
private static final String AUTHORITY = "com.android.keyguard.clock";
- @Inject
- public Provider<List<ClockInfo>> mClockInfosProvider;
+ private final Supplier<List<ClockInfo>> mClocksSupplier;
+
+ public ClockOptionsProvider() {
+ this(() -> Dependency.get(ClockManager.class).getClockInfos());
+ }
@VisibleForTesting
- ClockOptionsProvider(Provider<List<ClockInfo>> clockInfosProvider) {
- mClockInfosProvider = clockInfosProvider;
+ ClockOptionsProvider(Supplier<List<ClockInfo>> clocksSupplier) {
+ mClocksSupplier = clocksSupplier;
}
@Override
@@ -97,7 +99,7 @@ public final class ClockOptionsProvider extends ContentProvider {
}
MatrixCursor cursor = new MatrixCursor(new String[] {
COLUMN_NAME, COLUMN_TITLE, COLUMN_ID, COLUMN_THUMBNAIL, COLUMN_PREVIEW});
- List<ClockInfo> clocks = mClockInfosProvider.get();
+ List<ClockInfo> clocks = mClocksSupplier.get();
for (int i = 0; i < clocks.size(); i++) {
ClockInfo clock = clocks.get(i);
cursor.newRow()
@@ -137,7 +139,7 @@ public final class ClockOptionsProvider extends ContentProvider {
throw new FileNotFoundException("Invalid preview url, missing id");
}
ClockInfo clock = null;
- List<ClockInfo> clocks = mClockInfosProvider.get();
+ List<ClockInfo> clocks = mClocksSupplier.get();
for (int i = 0; i < clocks.size(); i++) {
if (id.equals(clocks.get(i).getId())) {
clock = clocks.get(i);
diff --git a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusBarViewComponent.java b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusBarViewComponent.java
deleted file mode 100644
index 49a617eeb6c0..000000000000
--- a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusBarViewComponent.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2020 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.keyguard.dagger;
-
-import com.android.keyguard.KeyguardStatusViewController;
-import com.android.systemui.statusbar.phone.KeyguardStatusBarView;
-import com.android.systemui.statusbar.phone.KeyguardStatusBarViewController;
-
-import dagger.BindsInstance;
-import dagger.Subcomponent;
-
-/**
- * Subcomponent for helping work with KeyguardStatusView and its children.
- *
- * TODO: unify this with {@link KeyguardStatusViewComponent}
- */
-@Subcomponent(modules = {KeyguardStatusBarViewModule.class})
-@KeyguardStatusBarViewScope
-public interface KeyguardStatusBarViewComponent {
- /** Simple factory for {@link KeyguardStatusBarViewComponent}. */
- @Subcomponent.Factory
- interface Factory {
- KeyguardStatusBarViewComponent build(@BindsInstance KeyguardStatusBarView view);
- }
-
- /** Builds a {@link KeyguardStatusViewController}. */
- KeyguardStatusBarViewController getKeyguardStatusBarViewController();
-}
diff --git a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusBarViewModule.java b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusBarViewModule.java
deleted file mode 100644
index a6725234e4af..000000000000
--- a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusBarViewModule.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2020 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.keyguard.dagger;
-
-import com.android.keyguard.CarrierText;
-import com.android.systemui.R;
-import com.android.systemui.statusbar.phone.KeyguardStatusBarView;
-
-import dagger.Module;
-import dagger.Provides;
-
-/** Dagger module for {@link KeyguardStatusBarViewComponent}. */
-@Module
-public abstract class KeyguardStatusBarViewModule {
- @Provides
- @KeyguardStatusBarViewScope
- static CarrierText getCarrierText(KeyguardStatusBarView view) {
- return view.findViewById(R.id.keyguard_carrier_text);
- }
-}
diff --git a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusViewComponent.java b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusViewComponent.java
index d342377da49b..1b6476ce74df 100644
--- a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusViewComponent.java
+++ b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusViewComponent.java
@@ -25,8 +25,6 @@ import dagger.Subcomponent;
/**
* Subcomponent for helping work with KeyguardStatusView and its children.
- *
- * TODO: unify this with {@link KeyguardStatusBarViewComponent}
*/
@Subcomponent(modules = {KeyguardStatusViewModule.class})
@KeyguardStatusViewScope
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java b/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java
index 91c2dcfd9202..ffb8446f3e21 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java
@@ -16,7 +16,6 @@
package com.android.systemui.dagger;
-import com.android.keyguard.clock.ClockOptionsProvider;
import com.android.systemui.BootCompleteCacheImpl;
import com.android.systemui.Dependency;
import com.android.systemui.InitController;
@@ -147,9 +146,4 @@ public interface SysUIComponent {
* Member injection into the supplied argument.
*/
void inject(KeyguardSliceProvider keyguardSliceProvider);
-
- /**
- * Member injection into the supplied argument.
- */
- void inject(ClockOptionsProvider clockOptionsProvider);
}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
index b67db03a743c..b0067cd15c1b 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
@@ -22,7 +22,6 @@ import android.content.Context;
import androidx.annotation.Nullable;
import com.android.internal.statusbar.IStatusBarService;
-import com.android.keyguard.clock.ClockModule;
import com.android.keyguard.dagger.KeyguardBouncerComponent;
import com.android.systemui.BootCompleteCache;
import com.android.systemui.BootCompleteCacheImpl;
@@ -91,7 +90,6 @@ import dagger.Provides;
@Module(includes = {
AppOpsModule.class,
AssistModule.class,
- ClockModule.class,
ControlsModule.class,
DemoModeModule.class,
FalsingModule.class,
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
index 5c8c9f22d585..8ab135ced97e 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
@@ -23,6 +23,7 @@ import android.app.AlarmManager;
import android.content.Context;
import android.os.Handler;
import android.os.SystemClock;
+import android.provider.Settings;
import android.text.format.Formatter;
import android.util.Log;
@@ -32,6 +33,7 @@ import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.doze.dagger.DozeScope;
import com.android.systemui.statusbar.phone.DozeParameters;
+import com.android.systemui.tuner.TunerService;
import com.android.systemui.util.AlarmTimeout;
import com.android.systemui.util.wakelock.WakeLock;
@@ -43,7 +45,7 @@ import javax.inject.Inject;
* The policy controlling doze.
*/
@DozeScope
-public class DozeUi implements DozeMachine.Part {
+public class DozeUi implements DozeMachine.Part, TunerService.Tunable {
private static final long TIME_TICK_DEADLINE_MILLIS = 90 * 1000; // 1.5min
private final Context mContext;
@@ -73,7 +75,7 @@ public class DozeUi implements DozeMachine.Part {
public DozeUi(Context context, AlarmManager alarmManager,
WakeLock wakeLock, DozeHost host, @Main Handler handler,
DozeParameters params, KeyguardUpdateMonitor keyguardUpdateMonitor,
- DozeLog dozeLog) {
+ DozeLog dozeLog, TunerService tunerService) {
mContext = context;
mWakeLock = wakeLock;
mHost = host;
@@ -83,6 +85,8 @@ public class DozeUi implements DozeMachine.Part {
mTimeTicker = new AlarmTimeout(alarmManager, this::onTimeTick, "doze_time_tick", handler);
keyguardUpdateMonitor.registerCallback(mKeyguardVisibilityCallback);
mDozeLog = dozeLog;
+
+ tunerService.addTunable(this, Settings.Secure.DOZE_ALWAYS_ON);
}
@Override
@@ -238,4 +242,11 @@ public class DozeUi implements DozeMachine.Part {
KeyguardUpdateMonitorCallback getKeyguardCallback() {
return mKeyguardVisibilityCallback;
}
+
+ @Override
+ public void onTuningChanged(String key, String newValue) {
+ if (key.equals(Settings.Secure.DOZE_ALWAYS_ON)) {
+ updateAnimateScreenOff();
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagReader.java b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagReader.java
index b77fcc822b88..073586e88a8b 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagReader.java
+++ b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagReader.java
@@ -16,24 +16,18 @@
package com.android.systemui.flags;
-import android.annotation.NonNull;
import android.content.res.Resources;
-import android.provider.DeviceConfig;
import android.util.SparseArray;
import androidx.annotation.BoolRes;
import androidx.annotation.Nullable;
import com.android.systemui.R;
-import com.android.systemui.assist.DeviceConfigHelper;
import com.android.systemui.dagger.SysUISingleton;
-import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.statusbar.FeatureFlags;
import com.android.systemui.util.wrapper.BuildInfo;
-import java.util.concurrent.Executor;
-
import javax.inject.Inject;
/**
* Reads and caches feature flags for quick access
@@ -60,23 +54,19 @@ import javax.inject.Inject;
@SysUISingleton
public class FeatureFlagReader {
private final Resources mResources;
- private final DeviceConfigHelper mDeviceConfig;
private final boolean mAreFlagsOverrideable;
-
+ private final SystemPropertiesHelper mSystemPropertiesHelper;
private final SparseArray<CachedFlag> mCachedFlags = new SparseArray<>();
@Inject
public FeatureFlagReader(
@Main Resources resources,
BuildInfo build,
- DeviceConfigHelper deviceConfig,
- @Background Executor executor) {
+ SystemPropertiesHelper systemPropertiesHelper) {
mResources = resources;
- mDeviceConfig = deviceConfig;
+ mSystemPropertiesHelper = systemPropertiesHelper;
mAreFlagsOverrideable =
build.isDebuggable() && mResources.getBoolean(R.bool.are_flags_overrideable);
-
- mDeviceConfig.addOnPropertiesChangedListener(executor, this::onPropertiesChanged);
}
/**
@@ -93,7 +83,7 @@ public class FeatureFlagReader {
String name = resourceIdToFlagName(resId);
boolean value = mResources.getBoolean(resId);
if (mAreFlagsOverrideable) {
- value = mDeviceConfig.getBoolean(flagNameToStorageKey(name), value);
+ value = mSystemPropertiesHelper.getBoolean(flagNameToStorageKey(name), value);
}
cachedFlag = new CachedFlag(name, value);
@@ -104,27 +94,6 @@ public class FeatureFlagReader {
}
}
- private void onPropertiesChanged(@NonNull DeviceConfig.Properties properties) {
- synchronized (mCachedFlags) {
- for (String key : properties.getKeyset()) {
- String flagName = storageKeyToFlagName(key);
- if (flagName != null) {
- clearCachedFlag(flagName);
- }
- }
- }
- }
-
- private void clearCachedFlag(String flagName) {
- for (int i = 0; i < mCachedFlags.size(); i++) {
- CachedFlag flag = mCachedFlags.valueAt(i);
- if (flag.name.equals(flagName)) {
- mCachedFlags.removeAt(i);
- break;
- }
- }
- }
-
private String resourceIdToFlagName(@BoolRes int resId) {
String resName = mResources.getResourceEntryName(resId);
if (resName.startsWith(RESNAME_PREFIX)) {
@@ -160,6 +129,6 @@ public class FeatureFlagReader {
}
}
- private static final String STORAGE_KEY_PREFIX = "flag_";
+ private static final String STORAGE_KEY_PREFIX = "persist.systemui.flag_";
private static final String RESNAME_PREFIX = "flag_";
}
diff --git a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusBarViewScope.java b/packages/SystemUI/src/com/android/systemui/flags/SystemPropertiesHelper.kt
index ba0642f57a88..28f63b07e584 100644
--- a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusBarViewScope.java
+++ b/packages/SystemUI/src/com/android/systemui/flags/SystemPropertiesHelper.kt
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2020 The Android Open Source Project
+ * Copyright (C) 2021 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.
@@ -14,19 +14,19 @@
* limitations under the License.
*/
-package com.android.keyguard.dagger;
+package com.android.systemui.flags
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import android.os.SystemProperties
+import com.android.systemui.dagger.SysUISingleton
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-
-import javax.inject.Scope;
+import javax.inject.Inject
/**
- * Scope annotation for singleton items within the StatusBarComponent.
+ * Proxy to make {@link SystemProperties} easily testable.
*/
-@Documented
-@Retention(RUNTIME)
-@Scope
-public @interface KeyguardStatusBarViewScope {}
+@SysUISingleton
+class SystemPropertiesHelper @Inject constructor() {
+ fun getBoolean(name: String, default: Boolean): Boolean {
+ return SystemProperties.getBoolean(name, default)
+ }
+} \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 91cf7108c728..eef41e045948 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -2395,6 +2395,9 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable,
return;
}
mDozing = dozing;
+ if (!dozing) {
+ mAnimatingScreenOff = false;
+ }
setShowingLocked(mShowing);
}
@@ -2404,7 +2407,7 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable,
// is 1f), then show the activity lock screen.
if (mAnimatingScreenOff && mDozing && linear == 1f) {
mAnimatingScreenOff = false;
- setShowingLocked(mShowing);
+ setShowingLocked(mShowing, true);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java b/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java
index a747edd0580a..de2e7c476e18 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java
@@ -30,7 +30,6 @@ import com.android.keyguard.KeyguardDisplayManager;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardViewController;
import com.android.keyguard.dagger.KeyguardQsUserSwitchComponent;
-import com.android.keyguard.dagger.KeyguardStatusBarViewComponent;
import com.android.keyguard.dagger.KeyguardStatusViewComponent;
import com.android.keyguard.dagger.KeyguardUserSwitcherComponent;
import com.android.systemui.broadcast.BroadcastDispatcher;
@@ -64,11 +63,8 @@ import dagger.Provides;
/**
* Dagger Module providing {@link StatusBar}.
*/
-@Module(subcomponents = {
- KeyguardQsUserSwitchComponent.class,
- KeyguardStatusBarViewComponent.class,
- KeyguardStatusViewComponent.class,
- KeyguardUserSwitcherComponent.class},
+@Module(subcomponents = {KeyguardStatusViewComponent.class,
+ KeyguardQsUserSwitchComponent.class, KeyguardUserSwitcherComponent.class},
includes = {FalsingModule.class})
public class KeyguardModule {
/**
diff --git a/packages/SystemUI/src/com/android/systemui/qs/carrier/QSCarrierGroupController.java b/packages/SystemUI/src/com/android/systemui/qs/carrier/QSCarrierGroupController.java
index aa6bbbda04fb..a567f512b204 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/carrier/QSCarrierGroupController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/carrier/QSCarrierGroupController.java
@@ -34,7 +34,7 @@ import android.widget.TextView;
import androidx.annotation.VisibleForTesting;
-import com.android.keyguard.CarrierTextManager;
+import com.android.keyguard.CarrierTextController;
import com.android.settingslib.AccessibilityContentDescriptions;
import com.android.settingslib.mobile.TelephonyIcons;
import com.android.systemui.R;
@@ -58,7 +58,7 @@ public class QSCarrierGroupController {
private final ActivityStarter mActivityStarter;
private final Handler mBgHandler;
private final NetworkController mNetworkController;
- private final CarrierTextManager mCarrierTextManager;
+ private final CarrierTextController mCarrierTextController;
private final TextView mNoSimTextView;
private final H mMainHandler;
private final Callback mCallback;
@@ -153,7 +153,7 @@ public class QSCarrierGroupController {
}
};
- private static class Callback implements CarrierTextManager.CarrierTextCallback {
+ private static class Callback implements CarrierTextController.CarrierTextCallback {
private H mHandler;
Callback(H handler) {
@@ -161,7 +161,7 @@ public class QSCarrierGroupController {
}
@Override
- public void updateCarrierInfo(CarrierTextManager.CarrierTextCallbackInfo info) {
+ public void updateCarrierInfo(CarrierTextController.CarrierTextCallbackInfo info) {
mHandler.obtainMessage(H.MSG_UPDATE_CARRIER_INFO, info).sendToTarget();
}
}
@@ -169,7 +169,7 @@ public class QSCarrierGroupController {
private QSCarrierGroupController(QSCarrierGroup view, ActivityStarter activityStarter,
@Background Handler bgHandler, @Main Looper mainLooper,
NetworkController networkController,
- CarrierTextManager.Builder carrierTextManagerBuilder, Context context) {
+ CarrierTextController.Builder carrierTextControllerBuilder, Context context) {
if (FeatureFlagUtils.isEnabled(context, FeatureFlagUtils.SETTINGS_PROVIDER_MODEL)) {
mProviderModel = true;
} else {
@@ -178,7 +178,7 @@ public class QSCarrierGroupController {
mActivityStarter = activityStarter;
mBgHandler = bgHandler;
mNetworkController = networkController;
- mCarrierTextManager = carrierTextManagerBuilder
+ mCarrierTextController = carrierTextControllerBuilder
.setShowAirplaneMode(false)
.setShowMissingSim(false)
.build();
@@ -196,6 +196,7 @@ public class QSCarrierGroupController {
mMainHandler = new H(mainLooper, this::handleUpdateCarrierInfo, this::handleUpdateState);
mCallback = new Callback(mMainHandler);
+
mCarrierGroups[0] = view.getCarrier1View();
mCarrierGroups[1] = view.getCarrier2View();
mCarrierGroups[2] = view.getCarrier3View();
@@ -246,10 +247,10 @@ public class QSCarrierGroupController {
if (mNetworkController.hasVoiceCallingFeature()) {
mNetworkController.addCallback(mSignalCallback);
}
- mCarrierTextManager.setListening(mCallback);
+ mCarrierTextController.setListening(mCallback);
} else {
mNetworkController.removeCallback(mSignalCallback);
- mCarrierTextManager.setListening(null);
+ mCarrierTextController.setListening(null);
}
}
@@ -276,7 +277,7 @@ public class QSCarrierGroupController {
}
@MainThread
- private void handleUpdateCarrierInfo(CarrierTextManager.CarrierTextCallbackInfo info) {
+ private void handleUpdateCarrierInfo(CarrierTextController.CarrierTextCallbackInfo info) {
if (!mMainHandler.getLooper().isCurrentThread()) {
mMainHandler.obtainMessage(H.MSG_UPDATE_CARRIER_INFO, info).sendToTarget();
return;
@@ -330,13 +331,13 @@ public class QSCarrierGroupController {
}
private static class H extends Handler {
- private Consumer<CarrierTextManager.CarrierTextCallbackInfo> mUpdateCarrierInfo;
+ private Consumer<CarrierTextController.CarrierTextCallbackInfo> mUpdateCarrierInfo;
private Runnable mUpdateState;
static final int MSG_UPDATE_CARRIER_INFO = 0;
static final int MSG_UPDATE_STATE = 1;
H(Looper looper,
- Consumer<CarrierTextManager.CarrierTextCallbackInfo> updateCarrierInfo,
+ Consumer<CarrierTextController.CarrierTextCallbackInfo> updateCarrierInfo,
Runnable updateState) {
super(looper);
mUpdateCarrierInfo = updateCarrierInfo;
@@ -348,7 +349,7 @@ public class QSCarrierGroupController {
switch (msg.what) {
case MSG_UPDATE_CARRIER_INFO:
mUpdateCarrierInfo.accept(
- (CarrierTextManager.CarrierTextCallbackInfo) msg.obj);
+ (CarrierTextController.CarrierTextCallbackInfo) msg.obj);
break;
case MSG_UPDATE_STATE:
mUpdateState.run();
@@ -365,13 +366,13 @@ public class QSCarrierGroupController {
private final Handler mHandler;
private final Looper mLooper;
private final NetworkController mNetworkController;
- private final CarrierTextManager.Builder mCarrierTextControllerBuilder;
+ private final CarrierTextController.Builder mCarrierTextControllerBuilder;
private final Context mContext;
@Inject
public Builder(ActivityStarter activityStarter, @Background Handler handler,
@Main Looper looper, NetworkController networkController,
- CarrierTextManager.Builder carrierTextControllerBuilder, Context context) {
+ CarrierTextController.Builder carrierTextControllerBuilder, Context context) {
mActivityStarter = activityStarter;
mHandler = handler;
mLooper = looper;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt
index e391250dc8fd..50cbbd5d4852 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt
@@ -264,6 +264,20 @@ class NotificationWakeUpCoordinator @Inject constructor(
}
override fun onStateChanged(newState: Int) {
+ if (dozeParameters.shouldControlUnlockedScreenOff()) {
+ if (animatingScreenOff &&
+ state == StatusBarState.KEYGUARD &&
+ newState == StatusBarState.SHADE) {
+ // If we're animating the screen off and going from KEYGUARD back to SHADE, the
+ // animation was cancelled and we are unlocking. Override the doze amount to 0f (not
+ // dozing) so that the notifications are no longer hidden.
+ setDozeAmount(0f, 0f)
+ }
+
+ animatingScreenOff =
+ state == StatusBarState.SHADE && newState == StatusBarState.KEYGUARD
+ }
+
overrideDozeAmountIfBypass()
if (bypassController.bypassEnabled &&
newState == StatusBarState.KEYGUARD && state == StatusBarState.SHADE_LOCKED &&
@@ -273,13 +287,6 @@ class NotificationWakeUpCoordinator @Inject constructor(
setNotificationsVisible(visible = false, increaseSpeed = false, animate = true)
}
- // If we want to control the screen off animation, check whether we are going from SHADE to
- // KEYGUARD.
- if (dozeParameters.shouldControlUnlockedScreenOff()) {
- animatingScreenOff =
- state == StatusBarState.SHADE && newState == StatusBarState.KEYGUARD
- }
-
this.state = newState
}
@@ -386,8 +393,6 @@ class NotificationWakeUpCoordinator @Inject constructor(
override fun onDozingChanged(isDozing: Boolean) {
if (isDozing) {
setNotificationsVisible(visible = false, animate = false, increaseSpeed = false)
- } else {
- animatingScreenOff = false
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java
deleted file mode 100644
index 377fb92ac6ba..000000000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.statusbar.phone;
-
-import com.android.keyguard.CarrierTextController;
-import com.android.systemui.util.ViewController;
-
-import javax.inject.Inject;
-
-/** View Controller for {@link com.android.systemui.statusbar.phone.KeyguardStatusBarView}. */
-public class KeyguardStatusBarViewController extends ViewController<KeyguardStatusBarView> {
- private final CarrierTextController mCarrierTextController;
-
- @Inject
- public KeyguardStatusBarViewController(
- KeyguardStatusBarView view, CarrierTextController carrierTextController) {
- super(view);
- mCarrierTextController = carrierTextController;
- }
-
- @Override
- protected void onInit() {
- super.onInit();
- mCarrierTextController.init();
- }
-
- @Override
- protected void onViewAttached() {
- }
-
- @Override
- protected void onViewDetached() {
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
index 2f9fa9e6ec41..0b3fd161d865 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
@@ -83,7 +83,6 @@ import com.android.keyguard.KeyguardStatusViewController;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.keyguard.dagger.KeyguardQsUserSwitchComponent;
-import com.android.keyguard.dagger.KeyguardStatusBarViewComponent;
import com.android.keyguard.dagger.KeyguardStatusViewComponent;
import com.android.keyguard.dagger.KeyguardUserSwitcherComponent;
import com.android.systemui.DejankUtils;
@@ -326,7 +325,6 @@ public class NotificationPanelViewController extends PanelViewController {
private final KeyguardStatusViewComponent.Factory mKeyguardStatusViewComponentFactory;
private final KeyguardQsUserSwitchComponent.Factory mKeyguardQsUserSwitchComponentFactory;
private final KeyguardUserSwitcherComponent.Factory mKeyguardUserSwitcherComponentFactory;
- private final KeyguardStatusBarViewComponent.Factory mKeyguardStatusBarViewComponentFactory;
private final QSDetailDisplayer mQSDetailDisplayer;
private final FeatureFlags mFeatureFlags;
private final ScrimController mScrimController;
@@ -343,7 +341,6 @@ public class NotificationPanelViewController extends PanelViewController {
private boolean mKeyguardUserSwitcherIsShowing;
private KeyguardUserSwitcherController mKeyguardUserSwitcherController;
private KeyguardStatusBarView mKeyguardStatusBar;
- private KeyguardStatusBarViewController mKeyguarStatusBarViewController;
private ViewGroup mBigClockContainer;
private QS mQs;
private FrameLayout mQsFrame;
@@ -597,7 +594,6 @@ public class NotificationPanelViewController extends PanelViewController {
KeyguardStatusViewComponent.Factory keyguardStatusViewComponentFactory,
KeyguardQsUserSwitchComponent.Factory keyguardQsUserSwitchComponentFactory,
KeyguardUserSwitcherComponent.Factory keyguardUserSwitcherComponentFactory,
- KeyguardStatusBarViewComponent.Factory keyguardStatusBarViewComponentFactory,
QSDetailDisplayer qsDetailDisplayer,
NotificationGroupManagerLegacy groupManager,
NotificationIconAreaController notificationIconAreaController,
@@ -624,7 +620,6 @@ public class NotificationPanelViewController extends PanelViewController {
mGroupManager = groupManager;
mNotificationIconAreaController = notificationIconAreaController;
mKeyguardStatusViewComponentFactory = keyguardStatusViewComponentFactory;
- mKeyguardStatusBarViewComponentFactory = keyguardStatusBarViewComponentFactory;
mFeatureFlags = featureFlags;
mKeyguardQsUserSwitchComponentFactory = keyguardQsUserSwitchComponentFactory;
mKeyguardUserSwitcherComponentFactory = keyguardUserSwitcherComponentFactory;
@@ -728,9 +723,7 @@ public class NotificationPanelViewController extends PanelViewController {
}
updateViewControllers(mView.findViewById(R.id.keyguard_status_view),
- userAvatarView,
- mKeyguardStatusBar,
- keyguardUserSwitcherView);
+ userAvatarView, keyguardUserSwitcherView);
mNotificationContainerParent = mView.findViewById(R.id.notification_container_parent);
NotificationStackScrollLayout stackScrollLayout = mView.findViewById(
R.id.notification_stack_scroller);
@@ -808,21 +801,13 @@ public class NotificationPanelViewController extends PanelViewController {
}
private void updateViewControllers(KeyguardStatusView keyguardStatusView,
- UserAvatarView userAvatarView,
- KeyguardStatusBarView keyguardStatusBarView,
- KeyguardUserSwitcherView keyguardUserSwitcherView) {
+ UserAvatarView userAvatarView, KeyguardUserSwitcherView keyguardUserSwitcherView) {
// Re-associate the KeyguardStatusViewController
KeyguardStatusViewComponent statusViewComponent =
mKeyguardStatusViewComponentFactory.build(keyguardStatusView);
mKeyguardStatusViewController = statusViewComponent.getKeyguardStatusViewController();
mKeyguardStatusViewController.init();
- KeyguardStatusBarViewComponent statusBarViewComponent =
- mKeyguardStatusBarViewComponentFactory.build(keyguardStatusBarView);
- mKeyguarStatusBarViewController =
- statusBarViewComponent.getKeyguardStatusBarViewController();
- mKeyguarStatusBarViewController.init();
-
// Re-associate the clock container with the keyguard clock switch.
KeyguardClockSwitchController keyguardClockSwitchController =
statusViewComponent.getKeyguardClockSwitchController();
@@ -970,8 +955,7 @@ public class NotificationPanelViewController extends PanelViewController {
showKeyguardUserSwitcher /* enabled */);
mBigClockContainer.removeAllViews();
- updateViewControllers(
- keyguardStatusView, userAvatarView, mKeyguardStatusBar, keyguardUserSwitcherView);
+ updateViewControllers(keyguardStatusView, userAvatarView, keyguardUserSwitcherView);
// Update keyguard bottom area
index = mView.indexOfChild(mKeyguardBottomArea);
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextManagerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java
index d3f9d641ca9f..aa4122fd190a 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java
@@ -54,6 +54,7 @@ import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.text.TextUtils;
+import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.keyguard.WakefulnessLifecycle;
@@ -73,7 +74,7 @@ import java.util.List;
@SmallTest
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
-public class CarrierTextManagerTest extends SysuiTestCase {
+public class CarrierTextControllerTest extends SysuiTestCase {
private static final CharSequence SEPARATOR = " \u2014 ";
private static final CharSequence INVALID_CARD_TEXT = "Invalid card";
@@ -94,9 +95,7 @@ public class CarrierTextManagerTest extends SysuiTestCase {
@Mock
private WifiManager mWifiManager;
@Mock
- private WakefulnessLifecycle mWakefulnessLifecycle;
- @Mock
- private CarrierTextManager.CarrierTextCallback mCarrierTextCallback;
+ private CarrierTextController.CarrierTextCallback mCarrierTextCallback;
@Mock
private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
@Mock
@@ -105,14 +104,13 @@ public class CarrierTextManagerTest extends SysuiTestCase {
private TelephonyManager mTelephonyManager;
@Mock
private SubscriptionManager mSubscriptionManager;
- private CarrierTextManager.CarrierTextCallbackInfo mCarrierTextCallbackInfo;
+ private CarrierTextController.CarrierTextCallbackInfo mCarrierTextCallbackInfo;
- private CarrierTextManager mCarrierTextManager;
+ private CarrierTextController mCarrierTextController;
private TestableLooper mTestableLooper;
- private Handler mMainHandler;
private Void checkMainThread(InvocationOnMock inv) {
- Looper mainLooper = mMainHandler.getLooper();
+ Looper mainLooper = Dependency.get(Dependency.MAIN_HANDLER).getLooper();
if (!mainLooper.isCurrentThread()) {
fail("This call should be done from the main thread");
}
@@ -124,33 +122,35 @@ public class CarrierTextManagerTest extends SysuiTestCase {
MockitoAnnotations.initMocks(this);
mTestableLooper = TestableLooper.get(this);
- mMainHandler = new Handler(mTestableLooper.getLooper());
+ mContext.addMockSystemService(WifiManager.class, mWifiManager);
+ mContext.addMockSystemService(ConnectivityManager.class, mConnectivityManager);
when(mConnectivityManager.isNetworkSupported(anyInt())).thenReturn(true);
+ mContext.addMockSystemService(TelephonyManager.class, mTelephonyManager);
+ mContext.addMockSystemService(SubscriptionManager.class, mSubscriptionManager);
mContext.getOrCreateTestableResources().addOverride(
R.string.keyguard_sim_error_message_short, INVALID_CARD_TEXT);
mContext.getOrCreateTestableResources().addOverride(
R.string.airplane_mode, AIRPLANE_MODE_TEXT);
+ mDependency.injectMockDependency(WakefulnessLifecycle.class);
+ mDependency.injectTestDependency(Dependency.MAIN_HANDLER,
+ new Handler(mTestableLooper.getLooper()));
+ mDependency.injectTestDependency(Dependency.BG_LOOPER, mTestableLooper.getLooper());
+ mDependency.injectTestDependency(KeyguardUpdateMonitor.class, mKeyguardUpdateMonitor);
doAnswer(this::checkMainThread).when(mKeyguardUpdateMonitor)
.registerCallback(any(KeyguardUpdateMonitorCallback.class));
doAnswer(this::checkMainThread).when(mKeyguardUpdateMonitor)
.removeCallback(any(KeyguardUpdateMonitorCallback.class));
- mCarrierTextCallbackInfo = new CarrierTextManager.CarrierTextCallbackInfo("",
+ mCarrierTextCallbackInfo = new CarrierTextController.CarrierTextCallbackInfo("",
new CharSequence[]{}, false, new int[]{});
when(mTelephonyManager.getSupportedModemCount()).thenReturn(3);
when(mTelephonyManager.getActiveModemCount()).thenReturn(3);
- mCarrierTextManager = new CarrierTextManager.Builder(
- mContext, mContext.getResources(), mWifiManager, mConnectivityManager,
- mTelephonyManager, mWakefulnessLifecycle, new Handler(mTestableLooper.getLooper()),
- mMainHandler, mKeyguardUpdateMonitor)
- .setShowAirplaneMode(true)
- .setShowMissingSim(true)
- .build();
+ mCarrierTextController = new CarrierTextController(mContext, SEPARATOR, true, true);
// This should not start listening on any of the real dependencies but will test that
// callbacks in mKeyguardUpdateMonitor are done in the mTestableLooper thread
- mCarrierTextManager.setListening(mCarrierTextCallback);
+ mCarrierTextController.setListening(mCarrierTextCallback);
mTestableLooper.processAllMessages();
}
@@ -165,8 +165,8 @@ public class CarrierTextManagerTest extends SysuiTestCase {
TestableLooper testableLooper = new TestableLooper(thread.getLooper());
Handler h = new Handler(testableLooper.getLooper());
h.post(() -> {
- mCarrierTextManager.setListening(null);
- mCarrierTextManager.setListening(mCarrierTextCallback);
+ mCarrierTextController.setListening(null);
+ mCarrierTextController.setListening(mCarrierTextCallback);
});
testableLooper.processAllMessages();
mTestableLooper.processAllMessages();
@@ -183,11 +183,11 @@ public class CarrierTextManagerTest extends SysuiTestCase {
when(mKeyguardUpdateMonitor.getSimState(0)).thenReturn(TelephonyManager.SIM_STATE_READY);
mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
- mCarrierTextManager.updateCarrierText();
+ mCarrierTextController.updateCarrierText();
- ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
+ ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
ArgumentCaptor.forClass(
- CarrierTextManager.CarrierTextCallbackInfo.class);
+ CarrierTextController.CarrierTextCallbackInfo.class);
mTestableLooper.processAllMessages();
verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
@@ -205,12 +205,12 @@ public class CarrierTextManagerTest extends SysuiTestCase {
TelephonyManager.SIM_STATE_CARD_IO_ERROR);
mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
- mCarrierTextManager.mCallback.onSimStateChanged(3, 1,
+ mCarrierTextController.mCallback.onSimStateChanged(3, 1,
TelephonyManager.SIM_STATE_CARD_IO_ERROR);
- ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
+ ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
ArgumentCaptor.forClass(
- CarrierTextManager.CarrierTextCallbackInfo.class);
+ CarrierTextController.CarrierTextCallbackInfo.class);
mTestableLooper.processAllMessages();
verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
@@ -223,7 +223,7 @@ public class CarrierTextManagerTest extends SysuiTestCase {
reset(mCarrierTextCallback);
when(mTelephonyManager.getActiveModemCount()).thenReturn(1);
// Update carrier text. It should ignore error state of subId 3 in inactive slotId.
- mCarrierTextManager.updateCarrierText();
+ mCarrierTextController.updateCarrierText();
mTestableLooper.processAllMessages();
verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
assertEquals("TEST_CARRIER", captor.getValue().carrierText);
@@ -237,9 +237,9 @@ public class CarrierTextManagerTest extends SysuiTestCase {
when(mKeyguardUpdateMonitor.getSimState(anyInt())).thenReturn(
TelephonyManager.SIM_STATE_CARD_IO_ERROR);
// This should not produce an out of bounds error, even though there are no subscriptions
- mCarrierTextManager.mCallback.onSimStateChanged(0, -3,
+ mCarrierTextController.mCallback.onSimStateChanged(0, -3,
TelephonyManager.SIM_STATE_CARD_IO_ERROR);
- mCarrierTextManager.mCallback.onSimStateChanged(0, 3, TelephonyManager.SIM_STATE_READY);
+ mCarrierTextController.mCallback.onSimStateChanged(0, 3, TelephonyManager.SIM_STATE_READY);
verify(mCarrierTextCallback, never()).updateCarrierInfo(any());
}
@@ -257,23 +257,23 @@ public class CarrierTextManagerTest extends SysuiTestCase {
when(mKeyguardUpdateMonitor.getSimState(anyInt())).thenReturn(
TelephonyManager.SIM_STATE_CARD_IO_ERROR);
// This should not produce an out of bounds error, even though there are no subscriptions
- mCarrierTextManager.mCallback.onSimStateChanged(0, 1,
+ mCarrierTextController.mCallback.onSimStateChanged(0, 1,
TelephonyManager.SIM_STATE_CARD_IO_ERROR);
mTestableLooper.processAllMessages();
verify(mCarrierTextCallback).updateCarrierInfo(
- any(CarrierTextManager.CarrierTextCallbackInfo.class));
+ any(CarrierTextController.CarrierTextCallbackInfo.class));
}
@Test
public void testCallback() {
reset(mCarrierTextCallback);
- mCarrierTextManager.postToCallback(mCarrierTextCallbackInfo);
+ mCarrierTextController.postToCallback(mCarrierTextCallbackInfo);
mTestableLooper.processAllMessages();
- ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
+ ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
ArgumentCaptor.forClass(
- CarrierTextManager.CarrierTextCallbackInfo.class);
+ CarrierTextController.CarrierTextCallbackInfo.class);
verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
assertEquals(mCarrierTextCallbackInfo, captor.getValue());
}
@@ -282,8 +282,8 @@ public class CarrierTextManagerTest extends SysuiTestCase {
public void testNullingCallback() {
reset(mCarrierTextCallback);
- mCarrierTextManager.postToCallback(mCarrierTextCallbackInfo);
- mCarrierTextManager.setListening(null);
+ mCarrierTextController.postToCallback(mCarrierTextCallbackInfo);
+ mCarrierTextController.setListening(null);
// This shouldn't produce NPE
mTestableLooper.processAllMessages();
@@ -301,15 +301,15 @@ public class CarrierTextManagerTest extends SysuiTestCase {
mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
- ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
+ ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
ArgumentCaptor.forClass(
- CarrierTextManager.CarrierTextCallbackInfo.class);
+ CarrierTextController.CarrierTextCallbackInfo.class);
- mCarrierTextManager.updateCarrierText();
+ mCarrierTextController.updateCarrierText();
mTestableLooper.processAllMessages();
verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
- CarrierTextManager.CarrierTextCallbackInfo info = captor.getValue();
+ CarrierTextController.CarrierTextCallbackInfo info = captor.getValue();
assertEquals(1, info.listOfCarriers.length);
assertEquals(TEST_CARRIER, info.listOfCarriers[0]);
assertEquals(1, info.subscriptionIds.length);
@@ -326,15 +326,15 @@ public class CarrierTextManagerTest extends SysuiTestCase {
mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
- ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
+ ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
ArgumentCaptor.forClass(
- CarrierTextManager.CarrierTextCallbackInfo.class);
+ CarrierTextController.CarrierTextCallbackInfo.class);
- mCarrierTextManager.updateCarrierText();
+ mCarrierTextController.updateCarrierText();
mTestableLooper.processAllMessages();
verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
- CarrierTextManager.CarrierTextCallbackInfo info = captor.getValue();
+ CarrierTextController.CarrierTextCallbackInfo info = captor.getValue();
assertEquals(1, info.listOfCarriers.length);
assertTrue(info.listOfCarriers[0].toString().contains(TEST_CARRIER));
assertEquals(1, info.subscriptionIds.length);
@@ -346,16 +346,16 @@ public class CarrierTextManagerTest extends SysuiTestCase {
List<SubscriptionInfo> list = new ArrayList<>();
list.add(TEST_SUBSCRIPTION_NULL);
when(mKeyguardUpdateMonitor.getSimState(anyInt())).thenReturn(
- TelephonyManager.SIM_STATE_READY);
+ TelephonyManager.SIM_STATE_READY);
when(mKeyguardUpdateMonitor.getFilteredSubscriptionInfo(anyBoolean())).thenReturn(list);
mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
- ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
+ ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
ArgumentCaptor.forClass(
- CarrierTextManager.CarrierTextCallbackInfo.class);
+ CarrierTextController.CarrierTextCallbackInfo.class);
- mCarrierTextManager.updateCarrierText();
+ mCarrierTextController.updateCarrierText();
mTestableLooper.processAllMessages();
verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
@@ -380,11 +380,11 @@ public class CarrierTextManagerTest extends SysuiTestCase {
when(ss.getDataRegistrationState()).thenReturn(ServiceState.STATE_IN_SERVICE);
mKeyguardUpdateMonitor.mServiceStates.put(TEST_SUBSCRIPTION_NULL.getSubscriptionId(), ss);
- ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
+ ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
ArgumentCaptor.forClass(
- CarrierTextManager.CarrierTextCallbackInfo.class);
+ CarrierTextController.CarrierTextCallbackInfo.class);
- mCarrierTextManager.updateCarrierText();
+ mCarrierTextController.updateCarrierText();
mTestableLooper.processAllMessages();
verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
@@ -407,15 +407,15 @@ public class CarrierTextManagerTest extends SysuiTestCase {
when(mKeyguardUpdateMonitor.getFilteredSubscriptionInfo(anyBoolean())).thenReturn(
new ArrayList<>());
- ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
+ ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
ArgumentCaptor.forClass(
- CarrierTextManager.CarrierTextCallbackInfo.class);
+ CarrierTextController.CarrierTextCallbackInfo.class);
- mCarrierTextManager.updateCarrierText();
+ mCarrierTextController.updateCarrierText();
mTestableLooper.processAllMessages();
verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
- CarrierTextManager.CarrierTextCallbackInfo info = captor.getValue();
+ CarrierTextController.CarrierTextCallbackInfo info = captor.getValue();
assertEquals(0, info.listOfCarriers.length);
assertEquals(0, info.subscriptionIds.length);
@@ -428,16 +428,16 @@ public class CarrierTextManagerTest extends SysuiTestCase {
list.add(TEST_SUBSCRIPTION);
list.add(TEST_SUBSCRIPTION);
when(mKeyguardUpdateMonitor.getSimState(anyInt())).thenReturn(
- TelephonyManager.SIM_STATE_READY);
+ TelephonyManager.SIM_STATE_READY);
when(mKeyguardUpdateMonitor.getFilteredSubscriptionInfo(anyBoolean())).thenReturn(list);
mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
- ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
+ ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
ArgumentCaptor.forClass(
- CarrierTextManager.CarrierTextCallbackInfo.class);
+ CarrierTextController.CarrierTextCallbackInfo.class);
- mCarrierTextManager.updateCarrierText();
+ mCarrierTextController.updateCarrierText();
mTestableLooper.processAllMessages();
verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
@@ -458,11 +458,11 @@ public class CarrierTextManagerTest extends SysuiTestCase {
mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
- ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
+ ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
ArgumentCaptor.forClass(
- CarrierTextManager.CarrierTextCallbackInfo.class);
+ CarrierTextController.CarrierTextCallbackInfo.class);
- mCarrierTextManager.updateCarrierText();
+ mCarrierTextController.updateCarrierText();
mTestableLooper.processAllMessages();
verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
@@ -483,11 +483,11 @@ public class CarrierTextManagerTest extends SysuiTestCase {
mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
- ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
+ ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
ArgumentCaptor.forClass(
- CarrierTextManager.CarrierTextCallbackInfo.class);
+ CarrierTextController.CarrierTextCallbackInfo.class);
- mCarrierTextManager.updateCarrierText();
+ mCarrierTextController.updateCarrierText();
mTestableLooper.processAllMessages();
verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
@@ -509,11 +509,11 @@ public class CarrierTextManagerTest extends SysuiTestCase {
when(mKeyguardUpdateMonitor.getFilteredSubscriptionInfo(anyBoolean())).thenReturn(list);
mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
- ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
+ ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
ArgumentCaptor.forClass(
- CarrierTextManager.CarrierTextCallbackInfo.class);
+ CarrierTextController.CarrierTextCallbackInfo.class);
- mCarrierTextManager.updateCarrierText();
+ mCarrierTextController.updateCarrierText();
mTestableLooper.processAllMessages();
verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardAbsKeyInputViewControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardAbsKeyInputViewControllerTest.java
index d67fe6dfb0b2..c2ade81a9877 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardAbsKeyInputViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardAbsKeyInputViewControllerTest.java
@@ -69,8 +69,6 @@ public class KeyguardAbsKeyInputViewControllerTest extends SysuiTestCase {
private KeyguardMessageAreaController mKeyguardMessageAreaController;
@Mock
private LatencyTracker mLatencyTracker;
- @Mock
- private EmergencyButtonController mEmergencyButtonController;
private KeyguardAbsKeyInputViewController mKeyguardAbsKeyInputViewController;
@@ -86,8 +84,7 @@ public class KeyguardAbsKeyInputViewControllerTest extends SysuiTestCase {
.thenReturn(mKeyguardMessageArea);
mKeyguardAbsKeyInputViewController = new KeyguardAbsKeyInputViewController(mAbsKeyInputView,
mKeyguardUpdateMonitor, mSecurityMode, mLockPatternUtils, mKeyguardSecurityCallback,
- mKeyguardMessageAreaControllerFactory, mLatencyTracker,
- mEmergencyButtonController) {
+ mKeyguardMessageAreaControllerFactory, mLatencyTracker) {
@Override
void resetState() {
}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardDisplayManagerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardDisplayManagerTest.java
index 4beec574cd2a..826be2ba0d83 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardDisplayManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardDisplayManagerTest.java
@@ -54,11 +54,11 @@ import java.util.concurrent.Executor;
public class KeyguardDisplayManagerTest extends SysuiTestCase {
@Mock
- private NavigationBarController mNavigationBarController;
- @Mock
private KeyguardStatusViewComponent.Factory mKeyguardStatusViewComponentFactory;
+
@Mock
private DisplayManager mDisplayManager;
+
@Mock
private KeyguardDisplayManager.KeyguardPresentation mKeyguardPresentation;
@@ -76,8 +76,9 @@ public class KeyguardDisplayManagerTest extends SysuiTestCase {
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext.addMockSystemService(DisplayManager.class, mDisplayManager);
- mManager = spy(new KeyguardDisplayManager(mContext, () -> mNavigationBarController,
- mKeyguardStatusViewComponentFactory, mBackgroundExecutor));
+ mDependency.injectMockDependency(NavigationBarController.class);
+ mManager = spy(new KeyguardDisplayManager(mContext, mKeyguardStatusViewComponentFactory,
+ mBackgroundExecutor));
doReturn(mKeyguardPresentation).when(mManager).createPresentation(any());
mDefaultDisplay = new Display(DisplayManagerGlobal.getInstance(), Display.DEFAULT_DISPLAY,
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt
index 6d0c64088abc..c69ec1a254c3 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt
@@ -49,8 +49,6 @@ class KeyguardPatternViewControllerTest : SysuiTestCase() {
@Mock
private lateinit var mLatencyTracker: LatencyTracker
@Mock
- private lateinit var mEmergencyButtonController: EmergencyButtonController
- @Mock
private lateinit
var mKeyguardMessageAreaControllerFactory: KeyguardMessageAreaController.Factory
@Mock
@@ -74,8 +72,7 @@ class KeyguardPatternViewControllerTest : SysuiTestCase() {
.thenReturn(mKeyguardMessageAreaController)
mKeyguardPatternViewController = KeyguardPatternViewController(mKeyguardPatternView,
mKeyguardUpdateMonitor, mSecurityMode, mLockPatternUtils, mKeyguardSecurityCallback,
- mLatencyTracker, mEmergencyButtonController,
- mKeyguardMessageAreaControllerFactory)
+ mLatencyTracker, mKeyguardMessageAreaControllerFactory)
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinBasedInputViewControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinBasedInputViewControllerTest.java
index 8d1e1a4a4463..31cc7bb7c958 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinBasedInputViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinBasedInputViewControllerTest.java
@@ -67,8 +67,6 @@ public class KeyguardPinBasedInputViewControllerTest extends SysuiTestCase {
private LatencyTracker mLatencyTracker;
@Mock
private LiftToActivateListener mLiftToactivateListener;
- @Mock
- private EmergencyButtonController mEmergencyButtonController;
private FalsingCollector mFalsingCollector = new FalsingCollectorFake();
@Mock
private View mDeleteButton;
@@ -94,7 +92,7 @@ public class KeyguardPinBasedInputViewControllerTest extends SysuiTestCase {
mKeyguardPinViewController = new KeyguardPinBasedInputViewController(mPinBasedInputView,
mKeyguardUpdateMonitor, mSecurityMode, mLockPatternUtils, mKeyguardSecurityCallback,
mKeyguardMessageAreaControllerFactory, mLatencyTracker, mLiftToactivateListener,
- mEmergencyButtonController, mFalsingCollector) {
+ mFalsingCollector) {
@Override
public void onResume(int reason) {
super.onResume(reason);
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityViewFlipperControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityViewFlipperControllerTest.java
index 9296d3d5ec82..3b7f4b839853 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityViewFlipperControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityViewFlipperControllerTest.java
@@ -59,10 +59,6 @@ public class KeyguardSecurityViewFlipperControllerTest extends SysuiTestCase {
@Mock
private KeyguardInputViewController.Factory mKeyguardSecurityViewControllerFactory;
@Mock
- private EmergencyButtonController.Factory mEmergencyButtonControllerFactory;
- @Mock
- private EmergencyButtonController mEmergencyButtonController;
- @Mock
private KeyguardInputViewController mKeyguardInputViewController;
@Mock
private KeyguardInputView mInputView;
@@ -80,12 +76,9 @@ public class KeyguardSecurityViewFlipperControllerTest extends SysuiTestCase {
any(KeyguardSecurityCallback.class)))
.thenReturn(mKeyguardInputViewController);
when(mView.getWindowInsetsController()).thenReturn(mWindowInsetsController);
- when(mEmergencyButtonControllerFactory.create(any(EmergencyButton.class)))
- .thenReturn(mEmergencyButtonController);
mKeyguardSecurityViewFlipperController = new KeyguardSecurityViewFlipperController(mView,
- mLayoutInflater, mKeyguardSecurityViewControllerFactory,
- mEmergencyButtonControllerFactory);
+ mLayoutInflater, mKeyguardSecurityViewControllerFactory);
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeUiTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeUiTest.java
index 6d8c372a061b..d60772730dff 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeUiTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeUiTest.java
@@ -42,6 +42,7 @@ import androidx.test.runner.AndroidJUnit4;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.statusbar.phone.DozeParameters;
+import com.android.systemui.tuner.TunerService;
import com.android.systemui.util.wakelock.WakeLockFake;
import org.junit.After;
@@ -67,6 +68,8 @@ public class DozeUiTest extends SysuiTestCase {
private DozeHost mHost;
@Mock
private DozeLog mDozeLog;
+ @Mock
+ private TunerService mTunerService;
private WakeLockFake mWakeLock;
private Handler mHandler;
private HandlerThread mHandlerThread;
@@ -82,7 +85,7 @@ public class DozeUiTest extends SysuiTestCase {
mHandler = mHandlerThread.getThreadHandler();
mDozeUi = new DozeUi(mContext, mAlarmManager, mWakeLock, mHost, mHandler,
- mDozeParameters, mKeyguardUpdateMonitor, mDozeLog);
+ mDozeParameters, mKeyguardUpdateMonitor, mDozeLog, mTunerService);
mDozeUi.setDozeMachine(mMachine);
}
@@ -138,7 +141,7 @@ public class DozeUiTest extends SysuiTestCase {
reset(mHost);
when(mDozeParameters.getDisplayNeedsBlanking()).thenReturn(true);
mDozeUi = new DozeUi(mContext, mAlarmManager, mWakeLock, mHost, mHandler,
- mDozeParameters, mKeyguardUpdateMonitor, mDozeLog);
+ mDozeParameters, mKeyguardUpdateMonitor, mDozeLog, mTunerService);
mDozeUi.setDozeMachine(mMachine);
// Never animate if display doesn't support it.
diff --git a/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagReaderTest.java b/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagReaderTest.java
index c79037b761aa..223714cfda30 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagReaderTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagReaderTest.java
@@ -18,7 +18,6 @@ package com.android.systemui.flags;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
@@ -27,59 +26,44 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.res.Resources;
-import android.provider.DeviceConfig;
import androidx.annotation.BoolRes;
import androidx.test.filters.SmallTest;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
-import com.android.systemui.assist.DeviceConfigHelper;
import com.android.systemui.util.wrapper.BuildInfo;
import org.junit.Before;
import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.Executor;
-
@SmallTest
public class FeatureFlagReaderTest extends SysuiTestCase {
@Mock private Resources mResources;
@Mock private BuildInfo mBuildInfo;
- @Mock private DeviceConfigHelper mDeviceConfig;
- @Mock private Executor mBackgroundExecutor;
+ @Mock private SystemPropertiesHelper mSystemPropertiesHelper;
private FeatureFlagReader mReader;
- @Captor private ArgumentCaptor<DeviceConfig.OnPropertiesChangedListener> mListenerCaptor;
- private DeviceConfig.OnPropertiesChangedListener mPropChangeListener;
-
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- when(mDeviceConfig.getBoolean(anyString(), anyBoolean()))
+ when(mSystemPropertiesHelper.getBoolean(anyString(), anyBoolean()))
.thenAnswer(invocation -> invocation.getArgument(1));
defineFlag(FLAG_RESID_0, false);
defineFlag(FLAG_RESID_1, true);
initialize(true, true);
-
- verify(mDeviceConfig).addOnPropertiesChangedListener(any(), mListenerCaptor.capture());
- mPropChangeListener = mListenerCaptor.getValue();
}
private void initialize(boolean isDebuggable, boolean isOverrideable) {
when(mBuildInfo.isDebuggable()).thenReturn(isDebuggable);
when(mResources.getBoolean(R.bool.are_flags_overrideable)).thenReturn(isOverrideable);
- mReader = new FeatureFlagReader(mResources, mBuildInfo, mDeviceConfig, mBackgroundExecutor);
+ mReader = new FeatureFlagReader(mResources, mBuildInfo, mSystemPropertiesHelper);
}
@Test
@@ -136,24 +120,8 @@ public class FeatureFlagReaderTest extends SysuiTestCase {
// THEN the underlying resource and override are only queried once
verify(mResources, times(1)).getBoolean(FLAG_RESID_0);
- verify(mDeviceConfig, times(1)).getBoolean(fakeStorageKey(FLAG_RESID_0), false);
- }
-
- @Test
- public void testCachesAreClearedAfterPropsChange() {
- // GIVEN a flag whose value has already been queried
- assertFalse(mReader.isEnabled(FLAG_RESID_0));
-
- // WHEN the value of the flag changes
- overrideFlag(FLAG_RESID_0, true);
- Map<String, String> changedMap = new HashMap<>();
- changedMap.put(fakeStorageKey(FLAG_RESID_0), "true");
- DeviceConfig.Properties properties =
- new DeviceConfig.Properties("systemui", changedMap);
- mPropChangeListener.onPropertiesChanged(properties);
-
- // THEN the new value is provided
- assertTrue(mReader.isEnabled(FLAG_RESID_0));
+ verify(mSystemPropertiesHelper, times(1))
+ .getBoolean(fakeStorageKey(FLAG_RESID_0), false);
}
private void defineFlag(int resId, boolean value) {
@@ -162,12 +130,12 @@ public class FeatureFlagReaderTest extends SysuiTestCase {
}
private void overrideFlag(int resId, boolean value) {
- when(mDeviceConfig.getBoolean(eq(fakeStorageKey(resId)), anyBoolean()))
+ when(mSystemPropertiesHelper.getBoolean(eq(fakeStorageKey(resId)), anyBoolean()))
.thenReturn(value);
}
private String fakeStorageKey(@BoolRes int resId) {
- return "flag_testname_" + resId;
+ return "persist.systemui.flag_testname_" + resId;
}
private static final int FLAG_RESID_0 = 47;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/carrier/QSCarrierGroupControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/carrier/QSCarrierGroupControllerTest.java
index e855834dcad4..1ec1da44c0b5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/carrier/QSCarrierGroupControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/carrier/QSCarrierGroupControllerTest.java
@@ -33,7 +33,7 @@ import android.widget.TextView;
import androidx.test.filters.SmallTest;
-import com.android.keyguard.CarrierTextManager;
+import com.android.keyguard.CarrierTextController;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.statusbar.policy.NetworkController;
import com.android.systemui.utils.leaks.LeakCheckedTest;
@@ -54,7 +54,7 @@ public class QSCarrierGroupControllerTest extends LeakCheckedTest {
private QSCarrierGroupController mQSCarrierGroupController;
private NetworkController.SignalCallback mSignalCallback;
- private CarrierTextManager.CarrierTextCallback mCallback;
+ private CarrierTextController.CarrierTextCallback mCallback;
@Mock
private QSCarrierGroup mQSCarrierGroup;
@Mock
@@ -62,9 +62,9 @@ public class QSCarrierGroupControllerTest extends LeakCheckedTest {
@Mock
private NetworkController mNetworkController;
@Mock
- private CarrierTextManager.Builder mCarrierTextControllerBuilder;
+ private CarrierTextController.Builder mCarrierTextControllerBuilder;
@Mock
- private CarrierTextManager mCarrierTextManager;
+ private CarrierTextController mCarrierTextController;
private TestableLooper mTestableLooper;
@Before
@@ -83,11 +83,11 @@ public class QSCarrierGroupControllerTest extends LeakCheckedTest {
.thenReturn(mCarrierTextControllerBuilder);
when(mCarrierTextControllerBuilder.setShowMissingSim(anyBoolean()))
.thenReturn(mCarrierTextControllerBuilder);
- when(mCarrierTextControllerBuilder.build()).thenReturn(mCarrierTextManager);
+ when(mCarrierTextControllerBuilder.build()).thenReturn(mCarrierTextController);
doAnswer(invocation -> mCallback = invocation.getArgument(0))
- .when(mCarrierTextManager)
- .setListening(any(CarrierTextManager.CarrierTextCallback.class));
+ .when(mCarrierTextController)
+ .setListening(any(CarrierTextController.CarrierTextCallback.class));
when(mQSCarrierGroup.getNoSimTextView()).thenReturn(new TextView(mContext));
when(mQSCarrierGroup.getCarrier1View()).thenReturn(mock(QSCarrier.class));
@@ -113,8 +113,8 @@ public class QSCarrierGroupControllerTest extends LeakCheckedTest {
(Answer<Integer>) invocationOnMock -> invocationOnMock.getArgument(0));
// listOfCarriers length 1, subscriptionIds length 1, anySims false
- CarrierTextManager.CarrierTextCallbackInfo
- c1 = new CarrierTextManager.CarrierTextCallbackInfo(
+ CarrierTextController.CarrierTextCallbackInfo
+ c1 = new CarrierTextController.CarrierTextCallbackInfo(
"",
new CharSequence[]{""},
false,
@@ -122,8 +122,8 @@ public class QSCarrierGroupControllerTest extends LeakCheckedTest {
mCallback.updateCarrierInfo(c1);
// listOfCarriers length 1, subscriptionIds length 1, anySims true
- CarrierTextManager.CarrierTextCallbackInfo
- c2 = new CarrierTextManager.CarrierTextCallbackInfo(
+ CarrierTextController.CarrierTextCallbackInfo
+ c2 = new CarrierTextController.CarrierTextCallbackInfo(
"",
new CharSequence[]{""},
true,
@@ -131,8 +131,8 @@ public class QSCarrierGroupControllerTest extends LeakCheckedTest {
mCallback.updateCarrierInfo(c2);
// listOfCarriers length 2, subscriptionIds length 2, anySims false
- CarrierTextManager.CarrierTextCallbackInfo
- c3 = new CarrierTextManager.CarrierTextCallbackInfo(
+ CarrierTextController.CarrierTextCallbackInfo
+ c3 = new CarrierTextController.CarrierTextCallbackInfo(
"",
new CharSequence[]{"", ""},
false,
@@ -140,8 +140,8 @@ public class QSCarrierGroupControllerTest extends LeakCheckedTest {
mCallback.updateCarrierInfo(c3);
// listOfCarriers length 2, subscriptionIds length 2, anySims true
- CarrierTextManager.CarrierTextCallbackInfo
- c4 = new CarrierTextManager.CarrierTextCallbackInfo(
+ CarrierTextController.CarrierTextCallbackInfo
+ c4 = new CarrierTextController.CarrierTextCallbackInfo(
"",
new CharSequence[]{"", ""},
true,
@@ -159,8 +159,8 @@ public class QSCarrierGroupControllerTest extends LeakCheckedTest {
(Answer<Integer>) invocationOnMock -> invocationOnMock.getArgument(0));
// listOfCarriers length 2, subscriptionIds length 1, anySims false
- CarrierTextManager.CarrierTextCallbackInfo
- c1 = new CarrierTextManager.CarrierTextCallbackInfo(
+ CarrierTextController.CarrierTextCallbackInfo
+ c1 = new CarrierTextController.CarrierTextCallbackInfo(
"",
new CharSequence[]{"", ""},
false,
@@ -168,8 +168,8 @@ public class QSCarrierGroupControllerTest extends LeakCheckedTest {
mCallback.updateCarrierInfo(c1);
// listOfCarriers length 2, subscriptionIds length 1, anySims true
- CarrierTextManager.CarrierTextCallbackInfo
- c2 = new CarrierTextManager.CarrierTextCallbackInfo(
+ CarrierTextController.CarrierTextCallbackInfo
+ c2 = new CarrierTextController.CarrierTextCallbackInfo(
"",
new CharSequence[]{"", ""},
true,
@@ -177,8 +177,8 @@ public class QSCarrierGroupControllerTest extends LeakCheckedTest {
mCallback.updateCarrierInfo(c2);
// listOfCarriers length 1, subscriptionIds length 2, anySims false
- CarrierTextManager.CarrierTextCallbackInfo
- c3 = new CarrierTextManager.CarrierTextCallbackInfo(
+ CarrierTextController.CarrierTextCallbackInfo
+ c3 = new CarrierTextController.CarrierTextCallbackInfo(
"",
new CharSequence[]{""},
false,
@@ -186,8 +186,8 @@ public class QSCarrierGroupControllerTest extends LeakCheckedTest {
mCallback.updateCarrierInfo(c3);
// listOfCarriers length 1, subscriptionIds length 2, anySims true
- CarrierTextManager.CarrierTextCallbackInfo
- c4 = new CarrierTextManager.CarrierTextCallbackInfo(
+ CarrierTextController.CarrierTextCallbackInfo
+ c4 = new CarrierTextController.CarrierTextCallbackInfo(
"",
new CharSequence[]{""},
true,
@@ -203,8 +203,8 @@ public class QSCarrierGroupControllerTest extends LeakCheckedTest {
when(spiedCarrierGroupController.getSlotIndex(anyInt())).thenReturn(
SubscriptionManager.INVALID_SIM_SLOT_INDEX);
- CarrierTextManager.CarrierTextCallbackInfo
- c4 = new CarrierTextManager.CarrierTextCallbackInfo(
+ CarrierTextController.CarrierTextCallbackInfo
+ c4 = new CarrierTextController.CarrierTextCallbackInfo(
"",
new CharSequence[]{"", ""},
true,
@@ -223,8 +223,8 @@ public class QSCarrierGroupControllerTest extends LeakCheckedTest {
@Test
public void testNoEmptyVisibleView_airplaneMode() {
- CarrierTextManager.CarrierTextCallbackInfo
- info = new CarrierTextManager.CarrierTextCallbackInfo(
+ CarrierTextController.CarrierTextCallbackInfo
+ info = new CarrierTextController.CarrierTextCallbackInfo(
"",
new CharSequence[]{""},
true,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
index d69d2dbdd841..e788a1c0954b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
@@ -61,7 +61,6 @@ import com.android.keyguard.KeyguardStatusView;
import com.android.keyguard.KeyguardStatusViewController;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.dagger.KeyguardQsUserSwitchComponent;
-import com.android.keyguard.dagger.KeyguardStatusBarViewComponent;
import com.android.keyguard.dagger.KeyguardStatusViewComponent;
import com.android.keyguard.dagger.KeyguardUserSwitcherComponent;
import com.android.systemui.R;
@@ -207,16 +206,10 @@ public class NotificationPanelViewTest extends SysuiTestCase {
@Mock
private KeyguardStatusViewComponent mKeyguardStatusViewComponent;
@Mock
- private KeyguardStatusBarViewComponent.Factory mKeyguardStatusBarViewComponentFactory;
- @Mock
- private KeyguardStatusBarViewComponent mKeyguardStatusBarViewComponent;
- @Mock
private KeyguardClockSwitchController mKeyguardClockSwitchController;
@Mock
private KeyguardStatusViewController mKeyguardStatusViewController;
@Mock
- private KeyguardStatusBarViewController mKeyguardStatusBarViewController;
- @Mock
private NotificationStackScrollLayoutController mNotificationStackScrollLayoutController;
@Mock
private AuthController mAuthController;
@@ -304,10 +297,6 @@ public class NotificationPanelViewTest extends SysuiTestCase {
new ViewGroup.LayoutParams(600, 400));
when(mNotificationStackScrollLayoutController.getLayoutParams()).thenReturn(
new ViewGroup.LayoutParams(600, 400));
- when(mKeyguardStatusBarViewComponentFactory.build(any()))
- .thenReturn(mKeyguardStatusBarViewComponent);
- when(mKeyguardStatusBarViewComponent.getKeyguardStatusBarViewController())
- .thenReturn(mKeyguardStatusBarViewController);
mNotificationPanelViewController = new NotificationPanelViewController(mView,
mResources,
@@ -326,7 +315,6 @@ public class NotificationPanelViewTest extends SysuiTestCase {
mKeyguardStatusViewComponentFactory,
mKeyguardQsUserSwitchComponentFactory,
mKeyguardUserSwitcherComponentFactory,
- mKeyguardStatusBarViewComponentFactory,
mQSDetailDisplayer,
mGroupManager,
mNotificationAreaController,
diff --git a/packages/SystemUI/tools/lint/baseline.xml b/packages/SystemUI/tools/lint/baseline.xml
index 3e494032b8e2..9a2e3207a6f4 100644
--- a/packages/SystemUI/tools/lint/baseline.xml
+++ b/packages/SystemUI/tools/lint/baseline.xml
@@ -1262,17 +1262,6 @@
<issue
id="MergeRootFrame"
message="This `&lt;FrameLayout>` can be replaced with a `&lt;merge>` tag"
- errorLine1="&lt;FrameLayout"
- errorLine2="^">
- <location
- file="res/layout/pip_menu_activity.xml"
- line="16"
- column="1"/>
- </issue>
-
- <issue
- id="MergeRootFrame"
- message="This `&lt;FrameLayout>` can be replaced with a `&lt;merge>` tag"
errorLine1="&lt;FrameLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;"
errorLine2="^">
<location
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java
index 22efd3718d7a..eb30fdeddd90 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java
@@ -118,6 +118,9 @@ class AccessibilityUserState {
private int mNonInteractiveUiTimeout = 0;
private int mInteractiveUiTimeout = 0;
private int mLastSentClientState = -1;
+
+ /** {@code true} if the device config supports magnification area. */
+ private final boolean mSupportMagnificationArea;
// The magnification mode of default display.
private int mMagnificationMode = ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN;
// The magnification capabilities used to know magnification mode could be switched.
@@ -138,6 +141,10 @@ class AccessibilityUserState {
private int mSoftKeyboardShowMode = SHOW_MODE_AUTO;
boolean isValidMagnificationModeLocked() {
+ if (!mSupportMagnificationArea
+ && mMagnificationMode == Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW) {
+ return false;
+ }
return (mMagnificationCapabilities & mMagnificationMode) != 0;
}
@@ -156,6 +163,8 @@ class AccessibilityUserState {
R.color.accessibility_focus_highlight_color);
mFocusStrokeWidth = mFocusStrokeWidthDefaultValue;
mFocusColor = mFocusColorDefaultValue;
+ mSupportMagnificationArea = mContext.getResources().getBoolean(
+ R.bool.config_magnification_area);
}
boolean isHandlingAccessibilityEventsLocked() {
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 0ce26739b51c..5cb9d8ff3f31 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -70,6 +70,7 @@ import android.content.pm.IDataLoaderStatusListener;
import android.content.pm.IPackageInstallObserver2;
import android.content.pm.IPackageInstallerSession;
import android.content.pm.IPackageInstallerSessionFileSystemConnector;
+import android.content.pm.IPackageLoadingProgressCallback;
import android.content.pm.InstallationFile;
import android.content.pm.InstallationFileParcel;
import android.content.pm.PackageInfo;
@@ -321,6 +322,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
private float mProgress = 0;
@GuardedBy("mLock")
private float mReportedProgress = -1;
+ @GuardedBy("mLock")
+ private float mIncrementalProgress = 0;
/** State of the session. */
@GuardedBy("mLock")
@@ -3770,7 +3773,15 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
mIncrementalFileStorages = IncrementalFileStorages.initialize(mContext, stageDir,
inheritedDir, params, statusListener, healthCheckParams, healthListener,
- addedFiles, perUidReadTimeouts);
+ addedFiles, perUidReadTimeouts,
+ new IPackageLoadingProgressCallback.Stub() {
+ @Override
+ public void onPackageLoadingProgressChanged(float progress) {
+ synchronized (mLock) {
+ mIncrementalProgress = progress;
+ }
+ }
+ });
return false;
} catch (IOException e) {
throw new PackageManagerException(INSTALL_FAILED_MEDIA_UNAVAILABLE, e.getMessage(),
diff --git a/services/core/java/com/android/server/speech/RemoteSpeechRecognitionService.java b/services/core/java/com/android/server/speech/RemoteSpeechRecognitionService.java
index 96248c3711e3..0974537e2584 100644
--- a/services/core/java/com/android/server/speech/RemoteSpeechRecognitionService.java
+++ b/services/core/java/com/android/server/speech/RemoteSpeechRecognitionService.java
@@ -18,22 +18,65 @@ package com.android.server.speech;
import static com.android.internal.infra.AbstractRemoteService.PERMANENT_BOUND_TIMEOUT_MS;
+import android.annotation.Nullable;
+import android.app.AppOpsManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.os.Binder;
+import android.os.Bundle;
import android.os.RemoteException;
import android.speech.IRecognitionListener;
import android.speech.IRecognitionService;
import android.speech.RecognitionService;
+import android.speech.SpeechRecognizer;
+import android.util.Log;
import android.util.Slog;
+import com.android.internal.annotations.GuardedBy;
import com.android.internal.infra.ServiceConnector;
final class RemoteSpeechRecognitionService extends ServiceConnector.Impl<IRecognitionService> {
private static final String TAG = RemoteSpeechRecognitionService.class.getSimpleName();
- private static final boolean DEBUG = true;
+ private static final boolean DEBUG = false;
- RemoteSpeechRecognitionService(Context context, ComponentName serviceName, int userId) {
+ private static final String APP_OP_MESSAGE = "Recording audio for speech recognition";
+ private static final String RECORD_AUDIO_APP_OP =
+ AppOpsManager.permissionToOp(android.Manifest.permission.RECORD_AUDIO);
+
+ private final Object mLock = new Object();
+
+ private boolean mConnected = false;
+
+ @Nullable
+ private IRecognitionListener mListener;
+
+ @Nullable
+ @GuardedBy("mLock")
+ private String mPackageName;
+
+ @Nullable
+ @GuardedBy("mLock")
+ private String mFeatureId;
+
+ @Nullable
+ @GuardedBy("mLock")
+ private DelegatingListener mDelegatingListener;
+
+ // Makes sure we can block startListening() if session is still in progress.
+ @GuardedBy("mLock")
+ private boolean mSessionInProgress = false;
+
+ // Makes sure we call startProxyOp / finishProxyOp at right times and only once per session.
+ @GuardedBy("mLock")
+ private boolean mRecordingInProgress = false;
+
+ private final int mCallingUid;
+ private final AppOpsManager mAppOpsManager;
+ private final ComponentName mComponentName;
+
+ RemoteSpeechRecognitionService(
+ Context context, ComponentName serviceName, int userId, int callingUid) {
super(context,
new Intent(RecognitionService.SERVICE_INTERFACE).setComponent(serviceName),
Context.BIND_AUTO_CREATE
@@ -43,46 +86,197 @@ final class RemoteSpeechRecognitionService extends ServiceConnector.Impl<IRecogn
userId,
IRecognitionService.Stub::asInterface);
+ mCallingUid = callingUid;
+ mAppOpsManager = mContext.getSystemService(AppOpsManager.class);
+ mComponentName = serviceName;
+
if (DEBUG) {
Slog.i(TAG, "Bound to recognition service at: " + serviceName.flattenToString());
}
}
+ ComponentName getServiceComponentName() {
+ return mComponentName;
+ }
+
void startListening(Intent recognizerIntent, IRecognitionListener listener, String packageName,
- String featureId) throws RemoteException {
+ String featureId) {
if (DEBUG) {
- Slog.i(TAG, "#startListening for package: " + packageName + ", feature=" + featureId);
+ Slog.i(TAG, String.format("#startListening for package: %s, feature=%s, callingUid=%d",
+ packageName, featureId, mCallingUid));
+ }
+
+ if (listener == null) {
+ Log.w(TAG, "#startListening called with no preceding #setListening - ignoring");
+ return;
+ }
+
+ if (!mConnected) {
+ tryRespondWithError(listener, SpeechRecognizer.ERROR_SERVER_DISCONNECTED);
+ return;
+ }
+
+ synchronized (mLock) {
+ if (mSessionInProgress) {
+ Slog.i(TAG, "#startListening called while listening is in progress.");
+ tryRespondWithError(listener, SpeechRecognizer.ERROR_RECOGNIZER_BUSY);
+ return;
+ }
+
+ if (startProxyOp(packageName, featureId) != AppOpsManager.MODE_ALLOWED) {
+ tryRespondWithError(listener, SpeechRecognizer.ERROR_INSUFFICIENT_PERMISSIONS);
+ return;
+ }
+ mSessionInProgress = true;
+ mRecordingInProgress = true;
+
+ mListener = listener;
+ mDelegatingListener = new DelegatingListener(listener, () -> {
+ // To be invoked in terminal calls of the callback: results() or error()
+ if (DEBUG) {
+ Slog.i(TAG, "Recognition session complete");
+ }
+
+ synchronized (mLock) {
+ resetStateLocked();
+ }
+ });
+ mPackageName = packageName;
+ mFeatureId = featureId;
+
+ run(service ->
+ service.startListening(
+ recognizerIntent,
+ mDelegatingListener,
+ packageName,
+ featureId,
+ mCallingUid));
}
- run(service -> service.startListening(recognizerIntent, listener, packageName, featureId));
}
- void stopListening(IRecognitionListener listener, String packageName, String featureId)
- throws RemoteException {
+ void stopListening(
+ IRecognitionListener listener, String packageName, String featureId) {
if (DEBUG) {
Slog.i(TAG, "#stopListening for package: " + packageName + ", feature=" + featureId);
}
- run(service -> service.stopListening(listener, packageName, featureId));
+
+ if (!mConnected) {
+ tryRespondWithError(listener, SpeechRecognizer.ERROR_SERVER_DISCONNECTED);
+ return;
+ }
+
+ synchronized (mLock) {
+ if (mListener == null) {
+ Log.w(TAG, "#stopListening called with no preceding #startListening - ignoring");
+ tryRespondWithError(listener, SpeechRecognizer.ERROR_CLIENT);
+ return;
+ }
+
+ if (mListener.asBinder() != listener.asBinder()) {
+ Log.w(TAG, "#stopListening called with an unexpected listener");
+ tryRespondWithError(listener, SpeechRecognizer.ERROR_CLIENT);
+ return;
+ }
+
+ if (!mRecordingInProgress) {
+ Slog.i(TAG, "#stopListening called while listening isn't in progress, ignoring.");
+ return;
+ }
+ mRecordingInProgress = false;
+
+ finishProxyOp(packageName, featureId);
+
+ run(service -> service.stopListening(mDelegatingListener, packageName, featureId));
+ }
}
- void cancel(IRecognitionListener listener, String packageName, String featureId)
- throws RemoteException {
+ void cancel(
+ IRecognitionListener listener,
+ String packageName,
+ String featureId,
+ boolean isShutdown) {
if (DEBUG) {
Slog.i(TAG, "#cancel for package: " + packageName + ", feature=" + featureId);
}
- run(service -> service.cancel(listener, packageName, featureId));
+
+ if (!mConnected) {
+ tryRespondWithError(listener, SpeechRecognizer.ERROR_SERVER_DISCONNECTED);
+ }
+
+ synchronized (mLock) {
+ if (mListener == null) {
+ if (DEBUG) {
+ Log.w(TAG, "#cancel called with no preceding #startListening - ignoring");
+ }
+ return;
+ }
+
+ if (mListener.asBinder() != listener.asBinder()) {
+ Log.w(TAG, "#cancel called with an unexpected listener");
+ tryRespondWithError(listener, SpeechRecognizer.ERROR_CLIENT);
+ return;
+ }
+
+ // Temporary reference to allow for resetting the hard link mDelegatingListener to null.
+ IRecognitionListener delegatingListener = mDelegatingListener;
+
+ run(service -> service.cancel(delegatingListener, packageName, featureId, isShutdown));
+
+ if (mRecordingInProgress) {
+ finishProxyOp(packageName, featureId);
+ }
+ mRecordingInProgress = false;
+ mSessionInProgress = false;
+
+ mDelegatingListener = null;
+ mListener = null;
+
+ // Schedule to unbind after cancel is delivered.
+ if (isShutdown) {
+ run(service -> unbind());
+ }
+ }
+ }
+
+ void shutdown() {
+ synchronized (mLock) {
+ if (this.mListener == null) {
+ if (DEBUG) {
+ Slog.i(TAG, "Package died, but session wasn't initialized. "
+ + "Not invoking #cancel");
+ }
+ return;
+ }
+ }
+
+ cancel(mListener, mPackageName, mFeatureId, true /* isShutdown */);
}
@Override // from ServiceConnector.Impl
protected void onServiceConnectionStatusChanged(
IRecognitionService service, boolean connected) {
- if (!DEBUG) {
- return;
+ mConnected = connected;
+
+ if (DEBUG) {
+ if (connected) {
+ Slog.i(TAG, "Connected to speech recognition service");
+ } else {
+ Slog.w(TAG, "Disconnected from speech recognition service");
+ }
}
- if (connected) {
- Slog.i(TAG, "Connected to ASR service");
- } else {
- Slog.w(TAG, "Disconnected from ASR service");
+ synchronized (mLock) {
+ if (!connected) {
+ if (mListener == null) {
+ Slog.i(TAG, "Connection to speech recognition service lost, but no "
+ + "#startListening has been invoked yet.");
+ return;
+ }
+
+ tryRespondWithError(mListener, SpeechRecognizer.ERROR_SERVER_DISCONNECTED);
+
+ resetStateLocked();
+ }
}
}
@@ -90,4 +284,119 @@ final class RemoteSpeechRecognitionService extends ServiceConnector.Impl<IRecogn
protected long getAutoDisconnectTimeoutMs() {
return PERMANENT_BOUND_TIMEOUT_MS;
}
+
+ private void resetStateLocked() {
+ if (mRecordingInProgress && mPackageName != null && mFeatureId != null) {
+ finishProxyOp(mPackageName, mFeatureId);
+ }
+
+ mListener = null;
+ mDelegatingListener = null;
+ mSessionInProgress = false;
+ mRecordingInProgress = false;
+ }
+
+ private int startProxyOp(String packageName, String featureId) {
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ return mAppOpsManager.startProxyOp(
+ RECORD_AUDIO_APP_OP,
+ mCallingUid,
+ packageName,
+ featureId,
+ APP_OP_MESSAGE);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ private void finishProxyOp(String packageName, String featureId) {
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ mAppOpsManager.finishProxyOp(
+ RECORD_AUDIO_APP_OP, mCallingUid, packageName, featureId);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ private static void tryRespondWithError(IRecognitionListener listener, int errorCode) {
+ if (DEBUG) {
+ Slog.i(TAG, "Responding with error " + errorCode);
+ }
+
+ try {
+ if (listener != null) {
+ listener.onError(errorCode);
+ }
+ } catch (RemoteException e) {
+ Slog.w(TAG,
+ String.format("Failed to respond with an error %d to the client", errorCode),
+ e);
+ }
+ }
+
+ private static class DelegatingListener extends IRecognitionListener.Stub {
+
+ private final IRecognitionListener mRemoteListener;
+ private final Runnable mOnSessionComplete;
+
+ DelegatingListener(IRecognitionListener listener, Runnable onSessionComplete) {
+ mRemoteListener = listener;
+ mOnSessionComplete = onSessionComplete;
+ }
+
+ @Override
+ public void onReadyForSpeech(Bundle params) throws RemoteException {
+ mRemoteListener.onReadyForSpeech(params);
+ }
+
+ @Override
+ public void onBeginningOfSpeech() throws RemoteException {
+ mRemoteListener.onBeginningOfSpeech();
+ }
+
+ @Override
+ public void onRmsChanged(float rmsdB) throws RemoteException {
+ mRemoteListener.onRmsChanged(rmsdB);
+ }
+
+ @Override
+ public void onBufferReceived(byte[] buffer) throws RemoteException {
+ mRemoteListener.onBufferReceived(buffer);
+ }
+
+ @Override
+ public void onEndOfSpeech() throws RemoteException {
+ mRemoteListener.onEndOfSpeech();
+ }
+
+ @Override
+ public void onError(int error) throws RemoteException {
+ if (DEBUG) {
+ Slog.i(TAG, String.format("Error %d during recognition session", error));
+ }
+ mOnSessionComplete.run();
+ mRemoteListener.onError(error);
+ }
+
+ @Override
+ public void onResults(Bundle results) throws RemoteException {
+ if (DEBUG) {
+ Slog.i(TAG, "#onResults invoked for a recognition session");
+ }
+ mOnSessionComplete.run();
+ mRemoteListener.onResults(results);
+ }
+
+ @Override
+ public void onPartialResults(Bundle results) throws RemoteException {
+ mRemoteListener.onPartialResults(results);
+ }
+
+ @Override
+ public void onEvent(int eventType, Bundle params) throws RemoteException {
+ mRemoteListener.onEvent(eventType, params);
+ }
+ }
}
diff --git a/services/core/java/com/android/server/speech/SpeechRecognitionManagerService.java b/services/core/java/com/android/server/speech/SpeechRecognitionManagerService.java
index 592ba9e616b8..dbe73546d748 100644
--- a/services/core/java/com/android/server/speech/SpeechRecognitionManagerService.java
+++ b/services/core/java/com/android/server/speech/SpeechRecognitionManagerService.java
@@ -18,7 +18,9 @@ package com.android.server.speech;
import android.annotation.NonNull;
import android.annotation.UserIdInt;
+import android.content.ComponentName;
import android.content.Context;
+import android.os.IBinder;
import android.os.UserHandle;
import android.speech.IRecognitionServiceManager;
import android.speech.IRecognitionServiceManagerCallback;
@@ -42,6 +44,7 @@ public final class SpeechRecognitionManagerService extends
public SpeechRecognitionManagerService(@NonNull Context context) {
super(context,
+ // TODO(b/176578753): think if we want to favor the particular service here.
new FrameworkResourcesServiceNameResolver(
context,
R.string.config_defaultOnDeviceSpeechRecognitionService),
@@ -63,11 +66,15 @@ public final class SpeechRecognitionManagerService extends
final class SpeechRecognitionManagerServiceStub extends IRecognitionServiceManager.Stub {
@Override
- public void createSession(IRecognitionServiceManagerCallback callback) {
+ public void createSession(
+ ComponentName componentName,
+ IBinder clientToken,
+ boolean onDevice,
+ IRecognitionServiceManagerCallback callback) {
int userId = UserHandle.getCallingUserId();
synchronized (mLock) {
SpeechRecognitionManagerServiceImpl service = getServiceForUserLocked(userId);
- service.createSessionLocked(callback);
+ service.createSessionLocked(componentName, clientToken, onDevice, callback);
}
}
}
diff --git a/services/core/java/com/android/server/speech/SpeechRecognitionManagerServiceImpl.java b/services/core/java/com/android/server/speech/SpeechRecognitionManagerServiceImpl.java
index bcaf174b1d92..2656a3d32555 100644
--- a/services/core/java/com/android/server/speech/SpeechRecognitionManagerServiceImpl.java
+++ b/services/core/java/com/android/server/speech/SpeechRecognitionManagerServiceImpl.java
@@ -24,30 +24,44 @@ import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ServiceInfo;
+import android.os.Binder;
+import android.os.IBinder;
import android.os.RemoteException;
import android.speech.IRecognitionListener;
import android.speech.IRecognitionService;
import android.speech.IRecognitionServiceManagerCallback;
+import android.speech.SpeechRecognizer;
import android.util.Slog;
import com.android.internal.annotations.GuardedBy;
import com.android.server.infra.AbstractPerUserSystemService;
+import com.google.android.collect.Sets;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+
final class SpeechRecognitionManagerServiceImpl extends
AbstractPerUserSystemService<SpeechRecognitionManagerServiceImpl,
SpeechRecognitionManagerService> {
-
private static final String TAG = SpeechRecognitionManagerServiceImpl.class.getSimpleName();
+ private static final int MAX_CONCURRENT_CONNECTIONS_BY_CLIENT = 10;
+
+ private final Object mLock = new Object();
+
+ @NonNull
@GuardedBy("mLock")
- @Nullable
- private RemoteSpeechRecognitionService mRemoteService;
+ private final Map<Integer, Set<RemoteSpeechRecognitionService>> mRemoteServicesByUid =
+ new HashMap<>();
SpeechRecognitionManagerServiceImpl(
@NonNull SpeechRecognitionManagerService master,
@NonNull Object lock, @UserIdInt int userId, boolean disabled) {
super(master, lock, userId);
- updateRemoteServiceLocked();
}
@GuardedBy("mLock")
@@ -67,92 +81,196 @@ final class SpeechRecognitionManagerServiceImpl extends
@Override // from PerUserSystemService
protected boolean updateLocked(boolean disabled) {
final boolean enabledChanged = super.updateLocked(disabled);
- updateRemoteServiceLocked();
return enabledChanged;
}
- /**
- * Updates the reference to the remote service.
- */
- @GuardedBy("mLock")
- private void updateRemoteServiceLocked() {
- if (mRemoteService != null) {
- if (mMaster.debug) {
- Slog.d(TAG, "updateRemoteService(): destroying old remote service");
- }
- mRemoteService.unbind();
- mRemoteService = null;
+ void createSessionLocked(
+ ComponentName componentName,
+ IBinder clientToken,
+ boolean onDevice,
+ IRecognitionServiceManagerCallback callback) {
+ if (mMaster.debug) {
+ Slog.i(TAG, String.format("#createSessionLocked, component=%s, onDevice=%s",
+ componentName, onDevice));
+ }
+
+ ComponentName serviceComponent = componentName;
+ if (onDevice) {
+ serviceComponent = getOnDeviceComponentNameLocked();
}
- }
- void createSessionLocked(IRecognitionServiceManagerCallback callback) {
- // TODO(b/176578753): check clients have record audio permission.
- // TODO(b/176578753): verify caller package is the one supplied
+ if (serviceComponent == null) {
+ tryRespondWithError(callback, SpeechRecognizer.ERROR_CLIENT);
+ return;
+ }
- RemoteSpeechRecognitionService service = ensureRemoteServiceLocked();
+ final int creatorCallingUid = Binder.getCallingUid();
+ Set<String> creatorPackageNames =
+ Sets.newArraySet(
+ getContext().getPackageManager().getPackagesForUid(creatorCallingUid));
+
+ RemoteSpeechRecognitionService service = createService(creatorCallingUid, serviceComponent);
if (service == null) {
- tryRespondWithError(callback);
+ tryRespondWithError(callback, SpeechRecognizer.ERROR_TOO_MANY_REQUESTS);
return;
}
+ IBinder.DeathRecipient deathRecipient =
+ () -> handleClientDeath(creatorCallingUid, service, true /* invoke #cancel */);
+
+ try {
+ clientToken.linkToDeath(deathRecipient, 0);
+ } catch (RemoteException e) {
+ // RemoteException == binder already died, schedule disconnect anyway.
+ handleClientDeath(creatorCallingUid, service, true /* invoke #cancel */);
+ }
+
service.connect().thenAccept(binderService -> {
if (binderService != null) {
try {
callback.onSuccess(new IRecognitionService.Stub() {
@Override
- public void startListening(Intent recognizerIntent,
+ public void startListening(
+ Intent recognizerIntent,
IRecognitionListener listener,
- String packageName, String featureId) throws RemoteException {
+ String packageName,
+ String featureId,
+ int callingUid) throws RemoteException {
+ verifyCallerIdentity(
+ creatorCallingUid, packageName, creatorPackageNames, listener);
+ if (callingUid != creatorCallingUid) {
+ listener.onError(SpeechRecognizer.ERROR_INSUFFICIENT_PERMISSIONS);
+ return;
+ }
+
service.startListening(
recognizerIntent, listener, packageName, featureId);
}
@Override
- public void stopListening(IRecognitionListener listener,
+ public void stopListening(
+ IRecognitionListener listener,
String packageName,
String featureId) throws RemoteException {
+ verifyCallerIdentity(
+ creatorCallingUid, packageName, creatorPackageNames, listener);
+
service.stopListening(listener, packageName, featureId);
}
@Override
- public void cancel(IRecognitionListener listener,
+ public void cancel(
+ IRecognitionListener listener,
String packageName,
- String featureId) throws RemoteException {
- service.cancel(listener, packageName, featureId);
+ String featureId,
+ boolean isShutdown) throws RemoteException {
+ verifyCallerIdentity(
+ creatorCallingUid, packageName, creatorPackageNames, listener);
+
+ service.cancel(listener, packageName, featureId, isShutdown);
+
+ if (isShutdown) {
+ handleClientDeath(
+ creatorCallingUid,
+ service,
+ false /* invoke #cancel */);
+ clientToken.unlinkToDeath(deathRecipient, 0);
+ }
}
});
} catch (RemoteException e) {
Slog.e(TAG, "Error creating a speech recognition session", e);
- tryRespondWithError(callback);
+ tryRespondWithError(callback, SpeechRecognizer.ERROR_CLIENT);
}
} else {
- tryRespondWithError(callback);
+ tryRespondWithError(callback, SpeechRecognizer.ERROR_CLIENT);
}
});
}
+ private void verifyCallerIdentity(
+ int creatorCallingUid,
+ String packageName,
+ Set<String> creatorPackageNames,
+ IRecognitionListener listener) throws RemoteException {
+ if (creatorCallingUid != Binder.getCallingUid()
+ || !creatorPackageNames.contains(packageName)) {
+ listener.onError(SpeechRecognizer.ERROR_INSUFFICIENT_PERMISSIONS);
+ }
+ }
+
+ private void handleClientDeath(
+ int callingUid,
+ RemoteSpeechRecognitionService service, boolean invokeCancel) {
+ if (invokeCancel) {
+ service.shutdown();
+ }
+ removeService(callingUid, service);
+ }
+
@GuardedBy("mLock")
@Nullable
- private RemoteSpeechRecognitionService ensureRemoteServiceLocked() {
- if (mRemoteService == null) {
- final String serviceName = getComponentNameLocked();
- if (serviceName == null) {
- if (mMaster.verbose) {
- Slog.v(TAG, "ensureRemoteServiceLocked(): no service component name.");
- }
+ private ComponentName getOnDeviceComponentNameLocked() {
+ final String serviceName = getComponentNameLocked();
+ if (serviceName == null) {
+ if (mMaster.verbose) {
+ Slog.v(TAG, "ensureRemoteServiceLocked(): no service component name.");
+ }
+ return null;
+ }
+ return ComponentName.unflattenFromString(serviceName);
+ }
+
+ private RemoteSpeechRecognitionService createService(
+ int callingUid, ComponentName serviceComponent) {
+ synchronized (mLock) {
+ Set<RemoteSpeechRecognitionService> servicesForClient =
+ mRemoteServicesByUid.get(callingUid);
+
+ if (servicesForClient != null
+ && servicesForClient.size() >= MAX_CONCURRENT_CONNECTIONS_BY_CLIENT) {
return null;
}
- final ComponentName serviceComponent = ComponentName.unflattenFromString(serviceName);
- mRemoteService =
- new RemoteSpeechRecognitionService(getContext(), serviceComponent, mUserId);
+
+ if (servicesForClient != null) {
+ Optional<RemoteSpeechRecognitionService> existingService =
+ servicesForClient
+ .stream()
+ .filter(service ->
+ service.getServiceComponentName().equals(serviceComponent))
+ .findFirst();
+ if (existingService.isPresent()) {
+ return existingService.get();
+ }
+ }
+
+ RemoteSpeechRecognitionService service =
+ new RemoteSpeechRecognitionService(
+ getContext(), serviceComponent, getUserId(), callingUid);
+
+ Set<RemoteSpeechRecognitionService> valuesByCaller =
+ mRemoteServicesByUid.computeIfAbsent(callingUid, key -> new HashSet<>());
+ valuesByCaller.add(service);
+
+ return service;
+ }
+ }
+
+ private void removeService(int callingUid, RemoteSpeechRecognitionService service) {
+ synchronized (mLock) {
+ Set<RemoteSpeechRecognitionService> valuesByCaller =
+ mRemoteServicesByUid.get(callingUid);
+ if (valuesByCaller != null) {
+ valuesByCaller.remove(service);
+ }
}
- return mRemoteService;
}
- private static void tryRespondWithError(IRecognitionServiceManagerCallback callback) {
+ private static void tryRespondWithError(IRecognitionServiceManagerCallback callback,
+ int errorCode) {
try {
- callback.onError();
+ callback.onError(errorCode);
} catch (RemoteException e) {
Slog.w(TAG, "Failed to respond with error");
}
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 589a8c31a07b..75a7660c0ac1 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -864,7 +864,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
mTaskChangeNotificationController =
new TaskChangeNotificationController(mGlobalLock, mTaskSupervisor, mH);
- mLockTaskController = new LockTaskController(mContext, mTaskSupervisor, mH);
+ mLockTaskController = new LockTaskController(mContext, mTaskSupervisor, mH,
+ mTaskChangeNotificationController);
mActivityStartController = new ActivityStartController(this);
setRecentTasks(new RecentTasks(this, mTaskSupervisor));
mVrController = new VrController(mGlobalLock);
diff --git a/services/core/java/com/android/server/wm/ScreenshotHashController.java b/services/core/java/com/android/server/wm/DisplayHashController.java
index 03f4e2891d19..7e16c22ee15e 100644
--- a/services/core/java/com/android/server/wm/ScreenshotHashController.java
+++ b/services/core/java/com/android/server/wm/DisplayHashController.java
@@ -16,9 +16,8 @@
package com.android.server.wm;
-import static android.service.screenshot.ScreenshotHasherService.EXTRA_SCREENSHOT_HASH;
-import static android.service.screenshot.ScreenshotHasherService.EXTRA_VERIFICATION_STATUS;
-import static android.service.screenshot.ScreenshotHasherService.SERVICE_META_DATA_KEY_AVAILABLE_ALGORITHMS;
+import static android.service.displayhash.DisplayHasherService.EXTRA_VERIFIED_DISPLAY_HASH;
+import static android.service.displayhash.DisplayHasherService.SERVICE_META_DATA_KEY_AVAILABLE_ALGORITHMS;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
@@ -46,11 +45,12 @@ import android.os.Message;
import android.os.RemoteCallback;
import android.os.RemoteException;
import android.os.UserHandle;
-import android.service.screenshot.IScreenshotHasherService;
-import android.service.screenshot.ScreenshotHash;
-import android.service.screenshot.ScreenshotHasherService;
+import android.service.displayhash.DisplayHasherService;
+import android.service.displayhash.IDisplayHasherService;
import android.util.Slog;
import android.view.MagnificationSpec;
+import android.view.displayhash.DisplayHash;
+import android.view.displayhash.VerifiedDisplayHash;
import com.android.internal.annotations.GuardedBy;
@@ -61,29 +61,29 @@ import java.util.concurrent.TimeUnit;
import java.util.function.BiConsumer;
/**
- * Handles requests into {@link android.service.screenshot.ScreenshotHasherService}
+ * Handles requests into {@link android.service.displayhash.DisplayHasherService}
*
* Do not hold the {@link WindowManagerService#mGlobalLock} when calling methods since they are
* blocking calls into another service.
*/
-public class ScreenshotHashController {
- private static final String TAG = TAG_WITH_CLASS_NAME ? "ScreenshotHashController" : TAG_WM;
+public class DisplayHashController {
+ private static final String TAG = TAG_WITH_CLASS_NAME ? "DisplayHashController" : TAG_WM;
private static final boolean DEBUG = false;
private final Object mServiceConnectionLock = new Object();
@GuardedBy("mServiceConnectionLock")
- private ScreenshotHasherServiceConnection mServiceConnection;
+ private DisplayHasherServiceConnection mServiceConnection;
private final Context mContext;
/**
- * Lock used for the cached {@link #mHashingAlgorithms} array
+ * Lock used for the cached {@link #mHashAlgorithms} array
*/
- private final Object mHashingAlgorithmsLock = new Object();
+ private final Object mHashAlgorithmsLock = new Object();
@GuardedBy("mHashingAlgorithmsLock")
- private String[] mHashingAlgorithms;
+ private String[] mHashAlgorithms;
private final Handler mHandler;
@@ -94,24 +94,24 @@ public class ScreenshotHashController {
private final RectF mTmpRectF = new RectF();
private interface Command {
- void run(IScreenshotHasherService service) throws RemoteException;
+ void run(IDisplayHasherService service) throws RemoteException;
}
- ScreenshotHashController(Context context) {
+ DisplayHashController(Context context) {
mContext = context;
mHandler = new Handler(Looper.getMainLooper());
mSalt = UUID.randomUUID().toString().getBytes();
}
- String[] getSupportedHashingAlgorithms() {
+ String[] getSupportedHashAlgorithms() {
// We have a separate lock for the hashing algorithm array since it doesn't need to make
// the request through the service connection. Instead, we have a lock to ensure we can
// properly cache the hashing algorithms array so we don't need to call into the
// ExtServices process for each request.
- synchronized (mHashingAlgorithmsLock) {
+ synchronized (mHashAlgorithmsLock) {
// Already have cached values
- if (mHashingAlgorithms != null) {
- return mHashingAlgorithms;
+ if (mHashAlgorithms != null) {
+ return mHashAlgorithms;
}
final ServiceInfo serviceInfo = getServiceInfo();
@@ -128,55 +128,48 @@ public class ScreenshotHashController {
final int resourceId = serviceInfo.metaData.getInt(
SERVICE_META_DATA_KEY_AVAILABLE_ALGORITHMS);
- mHashingAlgorithms = res.getStringArray(resourceId);
+ mHashAlgorithms = res.getStringArray(resourceId);
- return mHashingAlgorithms;
+ return mHashAlgorithms;
}
}
- boolean verifyScreenshotHash(ScreenshotHash screenshotHash) {
+ @Nullable
+ VerifiedDisplayHash verifyDisplayHash(DisplayHash displayHash) {
final SyncCommand syncCommand = new SyncCommand();
Bundle results = syncCommand.run((service, remoteCallback) -> {
try {
- service.verifyScreenshotHash(mSalt, screenshotHash, remoteCallback);
+ service.verifyDisplayHash(mSalt, displayHash, remoteCallback);
} catch (RemoteException e) {
- Slog.e(TAG, "Failed to invoke verifyScreenshotHash command");
+ Slog.e(TAG, "Failed to invoke verifyDisplayHash command");
}
});
- return results.getBoolean(EXTRA_VERIFICATION_STATUS);
+ return results.getParcelable(EXTRA_VERIFIED_DISPLAY_HASH);
}
- ScreenshotHash generateScreenshotHash(HardwareBuffer screenshot, Rect bounds,
- String hashAlgorithm) {
- final SyncCommand syncCommand = new SyncCommand();
- Bundle results = syncCommand.run((service, remoteCallback) -> {
- try {
- service.generateScreenshotHash(mSalt, screenshot, bounds, hashAlgorithm,
- remoteCallback);
- } catch (RemoteException e) {
- Slog.e(TAG, "Failed to invoke generateScreenshotHash command", e);
- }
- });
-
- return results.getParcelable(EXTRA_SCREENSHOT_HASH);
+ void generateDisplayHash(HardwareBuffer buffer, Rect bounds,
+ String hashAlgorithm, RemoteCallback callback) {
+ connectAndRun(
+ service -> service.generateDisplayHash(mSalt, buffer, bounds, hashAlgorithm,
+ callback));
}
/**
- * Calculate the bounds to take the screenshot when generating the ScreenshotHash. This
- * takes into account window transform, magnification, and display bounds.
+ * Calculate the bounds to generate the hash for. This takes into account window transform,
+ * magnification, and display bounds.
*
* Call while holding {@link WindowManagerService#mGlobalLock}
*
- * @param win Window that the ScreenshotHash is generated for.
- * @param boundsInWindow The bounds passed in about where in the window to take the screenshot.
- * @param outBounds The result of the calculated bounds
+ * @param win Window that the DisplayHash is generated for.
+ * @param boundsInWindow The bounds in the window where to generate the hash.
+ * @param outBounds The result of the calculated bounds
*/
- void calculateScreenshotHashBoundsLocked(WindowState win, Rect boundsInWindow,
+ void calculateDisplayHashBoundsLocked(WindowState win, Rect boundsInWindow,
Rect outBounds) {
if (DEBUG) {
Slog.d(TAG,
- "calculateScreenshotHashBoundsLocked: boundsInWindow=" + boundsInWindow);
+ "calculateDisplayHashBoundsLocked: boundsInWindow=" + boundsInWindow);
}
outBounds.set(boundsInWindow);
@@ -195,7 +188,7 @@ public class ScreenshotHashController {
if (DEBUG) {
Slog.d(TAG,
- "calculateScreenshotHashBoundsLocked: boundsIntersectWindow=" + outBounds);
+ "calculateDisplayHashBoundsLocked: boundsIntersectWindow=" + outBounds);
}
if (outBounds.isEmpty()) {
@@ -210,7 +203,7 @@ public class ScreenshotHashController {
outBounds.set((int) mTmpRectF.left, (int) mTmpRectF.top, (int) mTmpRectF.right,
(int) mTmpRectF.bottom);
if (DEBUG) {
- Slog.d(TAG, "calculateScreenshotHashBoundsLocked: boundsInDisplay=" + outBounds);
+ Slog.d(TAG, "calculateDisplayHashBoundsLocked: boundsInDisplay=" + outBounds);
}
// Apply the magnification spec values to the bounds since the content could be magnified
@@ -221,7 +214,7 @@ public class ScreenshotHashController {
}
if (DEBUG) {
- Slog.d(TAG, "calculateScreenshotHashBoundsLocked: boundsWithMagnification="
+ Slog.d(TAG, "calculateDisplayHashBoundsLocked: boundsWithMagnification="
+ outBounds);
}
@@ -229,12 +222,12 @@ public class ScreenshotHashController {
return;
}
- // Intersect with the display bounds since it shouldn't take a screenshot of content
- // outside the display since it's not visible to the user.
+ // Intersect with the display bounds since content outside the display are not visible to
+ // the user.
final Rect displayBounds = displayContent.getBounds();
outBounds.intersectUnchecked(displayBounds);
if (DEBUG) {
- Slog.d(TAG, "calculateScreenshotHashBoundsLocked: finalBounds=" + outBounds);
+ Slog.d(TAG, "calculateDisplayHashBoundsLocked: finalBounds=" + outBounds);
}
}
@@ -248,7 +241,7 @@ public class ScreenshotHashController {
if (DEBUG) Slog.v(TAG, "creating connection");
// Create the connection
- mServiceConnection = new ScreenshotHasherServiceConnection();
+ mServiceConnection = new DisplayHasherServiceConnection();
final ComponentName component = getServiceComponentName();
if (DEBUG) Slog.v(TAG, "binding to: " + component);
@@ -279,7 +272,7 @@ public class ScreenshotHashController {
return null;
}
- final Intent intent = new Intent(ScreenshotHasherService.SERVICE_INTERFACE);
+ final Intent intent = new Intent(DisplayHasherService.SERVICE_INTERFACE);
intent.setPackage(packageName);
final ResolveInfo resolveInfo = mContext.getPackageManager().resolveService(intent,
PackageManager.GET_SERVICES | PackageManager.GET_META_DATA);
@@ -296,10 +289,10 @@ public class ScreenshotHashController {
if (serviceInfo == null) return null;
final ComponentName name = new ComponentName(serviceInfo.packageName, serviceInfo.name);
- if (!Manifest.permission.BIND_SCREENSHOT_HASHER_SERVICE
+ if (!Manifest.permission.BIND_DISPLAY_HASHER_SERVICE
.equals(serviceInfo.permission)) {
Slog.w(TAG, name.flattenToShortString() + " requires permission "
- + Manifest.permission.BIND_SCREENSHOT_HASHER_SERVICE);
+ + Manifest.permission.BIND_DISPLAY_HASHER_SERVICE);
return null;
}
@@ -312,7 +305,7 @@ public class ScreenshotHashController {
private Bundle mResult;
private final CountDownLatch mCountDownLatch = new CountDownLatch(1);
- public Bundle run(BiConsumer<IScreenshotHasherService, RemoteCallback> func) {
+ public Bundle run(BiConsumer<IDisplayHasherService, RemoteCallback> func) {
connectAndRun(service -> {
RemoteCallback callback = new RemoteCallback(result -> {
mResult = result;
@@ -331,9 +324,9 @@ public class ScreenshotHashController {
}
}
- private class ScreenshotHasherServiceConnection implements ServiceConnection {
+ private class DisplayHasherServiceConnection implements ServiceConnection {
@GuardedBy("mServiceConnectionLock")
- private IScreenshotHasherService mRemoteService;
+ private IDisplayHasherService mRemoteService;
@GuardedBy("mServiceConnectionLock")
private ArrayList<Command> mQueuedCommands;
@@ -342,7 +335,7 @@ public class ScreenshotHashController {
public void onServiceConnected(ComponentName name, IBinder service) {
if (DEBUG) Slog.v(TAG, "onServiceConnected(): " + name);
synchronized (mServiceConnectionLock) {
- mRemoteService = IScreenshotHasherService.Stub.asInterface(service);
+ mRemoteService = IDisplayHasherService.Stub.asInterface(service);
if (mQueuedCommands != null) {
final int size = mQueuedCommands.size();
if (DEBUG) Slog.d(TAG, "running " + size + " queued commands");
diff --git a/services/core/java/com/android/server/wm/LockTaskController.java b/services/core/java/com/android/server/wm/LockTaskController.java
index 4b3a43432fc5..e18516d7bc3a 100644
--- a/services/core/java/com/android/server/wm/LockTaskController.java
+++ b/services/core/java/com/android/server/wm/LockTaskController.java
@@ -141,6 +141,7 @@ public class LockTaskController {
private final IBinder mToken = new LockTaskToken();
private final ActivityTaskSupervisor mSupervisor;
private final Context mContext;
+ private final TaskChangeNotificationController mTaskChangeNotificationController;
// The following system services cannot be final, because they do not exist when this class
// is instantiated during device boot
@@ -204,10 +205,11 @@ public class LockTaskController {
private int mPendingDisableFromDismiss = UserHandle.USER_NULL;
LockTaskController(Context context, ActivityTaskSupervisor supervisor,
- Handler handler) {
+ Handler handler, TaskChangeNotificationController taskChangeNotificationController) {
mContext = context;
mSupervisor = supervisor;
mHandler = handler;
+ mTaskChangeNotificationController = taskChangeNotificationController;
}
/**
@@ -532,6 +534,7 @@ public class LockTaskController {
// thread, which makes it guarded by ATMS#mGlobalLock as ATMS#getLockTaskModeState.
final int oldLockTaskModeState = mLockTaskModeState;
mLockTaskModeState = LOCK_TASK_MODE_NONE;
+ mTaskChangeNotificationController.notifyLockTaskModeChanged(mLockTaskModeState);
// When lock task ends, we enable the status bars.
try {
setStatusBarState(mLockTaskModeState, userId);
@@ -661,6 +664,7 @@ public class LockTaskController {
}
mWindowManager.onLockTaskStateChanged(lockTaskModeState);
mLockTaskModeState = lockTaskModeState;
+ mTaskChangeNotificationController.notifyLockTaskModeChanged(mLockTaskModeState);
setStatusBarState(lockTaskModeState, userId);
setKeyguardState(lockTaskModeState, userId);
if (getDevicePolicyManager() != null) {
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index 8b186796db8d..b82a30847c8d 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -54,10 +54,10 @@ import android.os.Bundle;
import android.os.IBinder;
import android.os.Parcel;
import android.os.Process;
+import android.os.RemoteCallback;
import android.os.RemoteException;
import android.os.Trace;
import android.os.UserHandle;
-import android.service.screenshot.ScreenshotHash;
import android.text.TextUtils;
import android.util.ArraySet;
import android.util.MergedConfiguration;
@@ -850,11 +850,11 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient {
}
@Override
- public ScreenshotHash generateScreenshotHash(IWindow window, Rect boundsInWindow,
- String hashAlgorithm) {
+ public void generateDisplayHash(IWindow window, Rect boundsInWindow, String hashAlgorithm,
+ RemoteCallback callback) {
final long origId = Binder.clearCallingIdentity();
try {
- return mService.generateScreenshotHash(this, window, boundsInWindow, hashAlgorithm);
+ mService.generateDisplayHash(this, window, boundsInWindow, hashAlgorithm, callback);
} finally {
Binder.restoreCallingIdentity(origId);
}
diff --git a/services/core/java/com/android/server/wm/TaskChangeNotificationController.java b/services/core/java/com/android/server/wm/TaskChangeNotificationController.java
index 622fe05b6170..9b7257057836 100644
--- a/services/core/java/com/android/server/wm/TaskChangeNotificationController.java
+++ b/services/core/java/com/android/server/wm/TaskChangeNotificationController.java
@@ -59,6 +59,7 @@ class TaskChangeNotificationController {
private static final int NOTIFY_TASK_REQUESTED_ORIENTATION_CHANGED_MSG = 25;
private static final int NOTIFY_ACTIVITY_ROTATED_MSG = 26;
private static final int NOTIFY_TASK_MOVED_TO_BACK_LISTENERS_MSG = 27;
+ private static final int NOTIFY_LOCK_TASK_MODE_CHANGED_MSG = 28;
// Delay in notifying task stack change listeners (in millis)
private static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
@@ -177,6 +178,10 @@ class TaskChangeNotificationController {
l.onTaskMovedToBack((RunningTaskInfo) m.obj);
};
+ private final TaskStackConsumer mNotifyLockTaskModeChanged = (l, m) -> {
+ l.onLockTaskModeChanged(m.arg1);
+ };
+
@FunctionalInterface
public interface TaskStackConsumer {
void accept(ITaskStackListener t, Message m) throws RemoteException;
@@ -268,6 +273,9 @@ class TaskChangeNotificationController {
case NOTIFY_TASK_MOVED_TO_BACK_LISTENERS_MSG:
forAllRemoteListeners(mNotifyTaskMovedToBack, msg);
break;
+ case NOTIFY_LOCK_TASK_MODE_CHANGED_MSG:
+ forAllRemoteListeners(mNotifyLockTaskModeChanged, msg);
+ break;
}
if (msg.obj instanceof SomeArgs) {
((SomeArgs) msg.obj).recycle();
@@ -550,4 +558,11 @@ class TaskChangeNotificationController {
forAllLocalListeners(mNotifyTaskMovedToBack, msg);
msg.sendToTarget();
}
+
+ void notifyLockTaskModeChanged(int lockTaskModeState) {
+ final Message msg = mHandler.obtainMessage(NOTIFY_LOCK_TASK_MODE_CHANGED_MSG,
+ lockTaskModeState, 0 /* unused */);
+ forAllLocalListeners(mNotifyLockTaskModeChanged, msg);
+ msg.sendToTarget();
+ }
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 5dc5ab767b2e..39b749ef54cb 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -83,6 +83,10 @@ import static android.view.WindowManagerGlobal.ADD_OKAY;
import static android.view.WindowManagerGlobal.RELAYOUT_RES_BLAST_SYNC;
import static android.view.WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_INVALID;
+import static android.view.displayhash.DisplayHashResultCallback.DISPLAY_HASH_ERROR_MISSING_WINDOW;
+import static android.view.displayhash.DisplayHashResultCallback.DISPLAY_HASH_ERROR_NOT_VISIBLE_ON_SCREEN;
+import static android.view.displayhash.DisplayHashResultCallback.DISPLAY_HASH_ERROR_UNKNOWN;
+import static android.view.displayhash.DisplayHashResultCallback.EXTRA_DISPLAY_HASH_ERROR_CODE;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ADD_REMOVE;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_BOOT;
@@ -187,6 +191,7 @@ import android.os.PowerManager;
import android.os.PowerManager.ServiceType;
import android.os.PowerManagerInternal;
import android.os.PowerSaveState;
+import android.os.RemoteCallback;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.ServiceManager;
@@ -199,7 +204,6 @@ import android.os.Trace;
import android.os.UserHandle;
import android.os.WorkSource;
import android.provider.Settings;
-import android.service.screenshot.ScreenshotHash;
import android.service.vr.IVrManager;
import android.service.vr.IVrStateCallbacks;
import android.sysprop.SurfaceFlingerProperties;
@@ -261,6 +265,8 @@ import android.view.WindowManager.LayoutParams;
import android.view.WindowManager.RemoveContentMode;
import android.view.WindowManagerGlobal;
import android.view.WindowManagerPolicyConstants.PointerEventListener;
+import android.view.displayhash.DisplayHash;
+import android.view.displayhash.VerifiedDisplayHash;
import android.window.ClientWindowFrames;
import android.window.TaskSnapshot;
@@ -768,7 +774,8 @@ public class WindowManagerService extends IWindowManager.Stub
final EmbeddedWindowController mEmbeddedWindowController;
final AnrController mAnrController;
- private final ScreenshotHashController mScreenshotHashController;
+ private final DisplayHashController mDisplayHashController;
+
@VisibleForTesting
final WindowContextListenerController mWindowContextListenerController =
new WindowContextListenerController();
@@ -1419,7 +1426,7 @@ public class WindowManagerService extends IWindowManager.Stub
mDisplayAreaPolicyProvider = DisplayAreaPolicy.Provider.fromResources(
mContext.getResources());
- mScreenshotHashController = new ScreenshotHashController(mContext);
+ mDisplayHashController = new DisplayHashController(mContext);
setGlobalShadowSettings();
mAnrController = new AnrController(this);
mStartingSurfaceController = new StartingSurfaceController(this);
@@ -8599,39 +8606,42 @@ public class WindowManagerService extends IWindowManager.Stub
}
@Override
- public String[] getSupportedScreenshotHashingAlgorithms() {
- return mScreenshotHashController.getSupportedHashingAlgorithms();
+ public String[] getSupportedDisplayHashAlgorithms() {
+ return mDisplayHashController.getSupportedHashAlgorithms();
}
@Override
- public boolean verifyScreenshotHash(ScreenshotHash screenshotHash) {
- return mScreenshotHashController.verifyScreenshotHash(screenshotHash);
+ public VerifiedDisplayHash verifyDisplayHash(DisplayHash displayHash) {
+ return mDisplayHashController.verifyDisplayHash(displayHash);
}
- ScreenshotHash generateScreenshotHash(Session session, IWindow window,
- Rect boundsInWindow, String hashAlgorithm) {
+ void generateDisplayHash(Session session, IWindow window, Rect boundsInWindow,
+ String hashAlgorithm, RemoteCallback callback) {
final SurfaceControl displaySurfaceControl;
final Rect boundsInDisplay = new Rect(boundsInWindow);
synchronized (mGlobalLock) {
final WindowState win = windowForClientLocked(session, window, false);
if (win == null) {
- Slog.w(TAG, "Failed to generate ScreenshotHash. Invalid window");
- return null;
+ Slog.w(TAG, "Failed to generate DisplayHash. Invalid window");
+ sendDisplayHashError(callback, DISPLAY_HASH_ERROR_MISSING_WINDOW);
+ return;
}
DisplayContent displayContent = win.getDisplayContent();
if (displayContent == null) {
- Slog.w(TAG, "Failed to generate ScreenshotHash. Window is not on a display");
- return null;
+ Slog.w(TAG, "Failed to generate DisplayHash. Window is not on a display");
+ sendDisplayHashError(callback, DISPLAY_HASH_ERROR_NOT_VISIBLE_ON_SCREEN);
+ return;
}
displaySurfaceControl = displayContent.getSurfaceControl();
- mScreenshotHashController.calculateScreenshotHashBoundsLocked(win,
- boundsInWindow, boundsInDisplay);
+ mDisplayHashController.calculateDisplayHashBoundsLocked(win, boundsInWindow,
+ boundsInDisplay);
if (boundsInDisplay.isEmpty()) {
- Slog.w(TAG, "Failed to generate ScreenshotHash. Bounds are not on screen");
- return null;
+ Slog.w(TAG, "Failed to generate DisplayHash. Bounds are not on screen");
+ sendDisplayHashError(callback, DISPLAY_HASH_ERROR_NOT_VISIBLE_ON_SCREEN);
+ return;
}
}
@@ -8650,11 +8660,18 @@ public class WindowManagerService extends IWindowManager.Stub
SurfaceControl.captureLayers(args);
if (screenshotHardwareBuffer == null
|| screenshotHardwareBuffer.getHardwareBuffer() == null) {
- Slog.w(TAG, "Failed to generate ScreenshotHash. Failed to take screenshot");
- return null;
+ Slog.w(TAG, "Failed to generate DisplayHash. Couldn't capture content");
+ sendDisplayHashError(callback, DISPLAY_HASH_ERROR_UNKNOWN);
+ return;
}
- return mScreenshotHashController.generateScreenshotHash(
- screenshotHardwareBuffer.getHardwareBuffer(), boundsInWindow, hashAlgorithm);
+ mDisplayHashController.generateDisplayHash(screenshotHardwareBuffer.getHardwareBuffer(),
+ boundsInWindow, hashAlgorithm, callback);
+ }
+
+ private void sendDisplayHashError(RemoteCallback callback, int errorCode) {
+ Bundle bundle = new Bundle();
+ bundle.putInt(EXTRA_DISPLAY_HASH_ERROR_CODE, errorCode);
+ callback.sendResult(bundle);
}
}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 1cf4ce163640..dd599c9cfb60 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -10092,7 +10092,6 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
final int userId = user.id;
- // TODO(b/177547285): add CTS test
if (mInjector.userManagerIsHeadlessSystemUserMode()) {
ComponentName admin = mOwners.getDeviceOwnerComponent();
Slog.i(LOG_TAG, "Automatically setting profile owner (" + admin + ") on new user "
@@ -12911,8 +12910,10 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
if (mOwners.hasProfileOwner(deviceOwnerUserId)) {
return CODE_USER_HAS_PROFILE_OWNER;
}
+
+ boolean isHeadlessSystemUserMode = mInjector.userManagerIsHeadlessSystemUserMode();
// System user is always running in headless system user mode.
- if (!mInjector.userManagerIsHeadlessSystemUserMode()
+ if (!isHeadlessSystemUserMode
&& !mUserManager.isUserRunning(new UserHandle(deviceOwnerUserId))) {
return CODE_USER_NOT_RUNNING;
}
@@ -12920,7 +12921,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
return CODE_HAS_PAIRED;
}
- if (mInjector.userManagerIsHeadlessSystemUserMode()) {
+ if (isHeadlessSystemUserMode) {
if (deviceOwnerUserId != UserHandle.USER_SYSTEM) {
Slog.e(LOG_TAG, "In headless system user mode, "
+ "device owner can only be set on headless system user.");
@@ -12932,9 +12933,13 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
// If shell command runs after user setup completed check device status. Otherwise, OK.
if (mIsWatch || hasUserSetupCompleted(UserHandle.USER_SYSTEM)) {
// In non-headless system user mode, DO can be setup only if
- // there's no non-system user
- if (!mInjector.userManagerIsHeadlessSystemUserMode()
- && mUserManager.getUserCount() > 1) {
+ // there's no non-system user.
+ // In headless system user mode, DO can be setup only if there are
+ // two users: the headless system user and the foreground user.
+ // If there could be multiple foreground users, this constraint should be modified.
+
+ int maxNumberOfExistingUsers = isHeadlessSystemUserMode ? 2 : 1;
+ if (mUserManager.getUserCount() > maxNumberOfExistingUsers) {
return CODE_NONSYSTEM_USER_EXISTS;
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java
index 8099eda9a0af..775276bd03f6 100644
--- a/services/tests/mockingservicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java
@@ -63,7 +63,6 @@ import android.util.DataUnit;
import com.android.server.LocalServices;
import com.android.server.job.JobSchedulerService;
import com.android.server.job.JobSchedulerService.Constants;
-import com.android.server.job.JobServiceContext;
import com.android.server.net.NetworkPolicyManagerInternal;
import org.junit.Before;
@@ -144,8 +143,7 @@ public class ConnectivityControllerTest {
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY);
final ConnectivityController controller = new ConnectivityController(mService);
- when(mService.getMaxJobExecutionTimeMs(any()))
- .thenReturn(JobServiceContext.DEFAULT_EXECUTING_TIMESLICE_MILLIS);
+ when(mService.getMaxJobExecutionTimeMs(any())).thenReturn(10 * 60_000L);
// Slow network is too slow
assertFalse(controller.isSatisfied(createJobStatus(job), net,
diff --git a/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java
index c4c9173536ad..b72121f096ba 100644
--- a/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java
@@ -82,8 +82,6 @@ import com.android.internal.util.ArrayUtils;
import com.android.server.LocalServices;
import com.android.server.PowerAllowlistInternal;
import com.android.server.job.JobSchedulerService;
-import com.android.server.job.JobSchedulerService.Constants;
-import com.android.server.job.JobServiceContext;
import com.android.server.job.JobStore;
import com.android.server.job.controllers.QuotaController.ExecutionStats;
import com.android.server.job.controllers.QuotaController.QcConstants;
@@ -123,6 +121,7 @@ public class QuotaControllerTest {
private BroadcastReceiver mChargingReceiver;
private QuotaController mQuotaController;
private QuotaController.QcConstants mQcConstants;
+ private JobSchedulerService.Constants mConstants = new JobSchedulerService.Constants();
private int mSourceUid;
private PowerAllowlistInternal.TempAllowlistChangeListener mTempAllowlistListener;
private IUidObserver mUidObserver;
@@ -158,7 +157,7 @@ public class QuotaControllerTest {
// Called in StateController constructor.
when(mJobSchedulerService.getTestableContext()).thenReturn(mContext);
when(mJobSchedulerService.getLock()).thenReturn(mJobSchedulerService);
- when(mJobSchedulerService.getConstants()).thenReturn(mock(Constants.class));
+ when(mJobSchedulerService.getConstants()).thenReturn(mConstants);
// Called in QuotaController constructor.
IActivityManager activityManager = ActivityManager.getService();
spyOn(activityManager);
@@ -1282,23 +1281,23 @@ public class QuotaControllerTest {
}
@Test
- public void testGetMaxJobExecutionTimeLocked() {
+ public void testGetMaxJobExecutionTimeLocked_Regular() {
mQuotaController.saveTimingSession(0, SOURCE_PACKAGE,
createTimingSession(sElapsedRealtimeClock.millis() - (6 * MINUTE_IN_MILLIS),
3 * MINUTE_IN_MILLIS, 5), false);
JobStatus job = createJobStatus("testGetMaxJobExecutionTimeLocked", 0);
- job.setStandbyBucket(RARE_INDEX);
+ setStandbyBucket(RARE_INDEX, job);
setCharging();
synchronized (mQuotaController.mLock) {
- assertEquals(JobServiceContext.DEFAULT_EXECUTING_TIMESLICE_MILLIS,
+ assertEquals(JobSchedulerService.Constants.DEFAULT_RUNTIME_FREE_QUOTA_MAX_LIMIT_MS,
mQuotaController.getMaxJobExecutionTimeMsLocked((job)));
}
setDischarging();
setProcessState(ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
synchronized (mQuotaController.mLock) {
- assertEquals(JobServiceContext.DEFAULT_EXECUTING_TIMESLICE_MILLIS,
+ assertEquals(JobSchedulerService.Constants.DEFAULT_RUNTIME_FREE_QUOTA_MAX_LIMIT_MS,
mQuotaController.getMaxJobExecutionTimeMsLocked((job)));
}
@@ -1310,7 +1309,7 @@ public class QuotaControllerTest {
}
setProcessState(ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND);
synchronized (mQuotaController.mLock) {
- assertEquals(JobServiceContext.DEFAULT_EXECUTING_TIMESLICE_MILLIS,
+ assertEquals(JobSchedulerService.Constants.DEFAULT_RUNTIME_FREE_QUOTA_MAX_LIMIT_MS,
mQuotaController.getMaxJobExecutionTimeMsLocked((job)));
mQuotaController.maybeStopTrackingJobLocked(job, null, false);
}
@@ -1322,6 +1321,81 @@ public class QuotaControllerTest {
}
}
+ @Test
+ public void testGetMaxJobExecutionTimeLocked_EJ() {
+ final long timeUsedMs = 3 * MINUTE_IN_MILLIS;
+ mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+ createTimingSession(sElapsedRealtimeClock.millis() - (6 * MINUTE_IN_MILLIS),
+ timeUsedMs, 5), true);
+ JobStatus job = createExpeditedJobStatus("testGetMaxJobExecutionTimeLocked_EJ", 0);
+ setStandbyBucket(RARE_INDEX, job);
+ mQuotaController.maybeStartTrackingJobLocked(job, null);
+
+ setCharging();
+ synchronized (mQuotaController.mLock) {
+ assertEquals(JobSchedulerService.Constants.DEFAULT_RUNTIME_FREE_QUOTA_MAX_LIMIT_MS,
+ mQuotaController.getMaxJobExecutionTimeMsLocked(job));
+ }
+
+ setDischarging();
+ setProcessState(ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
+ synchronized (mQuotaController.mLock) {
+ assertEquals(mQcConstants.EJ_LIMIT_WORKING_MS / 2,
+ mQuotaController.getMaxJobExecutionTimeMsLocked(job));
+ }
+
+ // Top-started job
+ setProcessState(ActivityManager.PROCESS_STATE_TOP);
+ synchronized (mQuotaController.mLock) {
+ mQuotaController.prepareForExecutionLocked(job);
+ }
+ setProcessState(ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND);
+ synchronized (mQuotaController.mLock) {
+ assertEquals(mQcConstants.EJ_LIMIT_ACTIVE_MS / 2,
+ mQuotaController.getMaxJobExecutionTimeMsLocked(job));
+ mQuotaController.maybeStopTrackingJobLocked(job, null, false);
+ }
+
+ setProcessState(ActivityManager.PROCESS_STATE_RECEIVER);
+ synchronized (mQuotaController.mLock) {
+ assertEquals(mQcConstants.EJ_LIMIT_RARE_MS - timeUsedMs,
+ mQuotaController.getMaxJobExecutionTimeMsLocked(job));
+ }
+
+ // Test used quota rolling out of window.
+ synchronized (mQuotaController.mLock) {
+ mQuotaController.clearAppStatsLocked(SOURCE_USER_ID, SOURCE_PACKAGE);
+ }
+ mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+ createTimingSession(sElapsedRealtimeClock.millis() - mQcConstants.EJ_WINDOW_SIZE_MS,
+ timeUsedMs, 5), true);
+
+ setProcessState(ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
+ synchronized (mQuotaController.mLock) {
+ assertEquals(mQcConstants.EJ_LIMIT_WORKING_MS / 2,
+ mQuotaController.getMaxJobExecutionTimeMsLocked(job));
+ }
+
+ // Top-started job
+ setProcessState(ActivityManager.PROCESS_STATE_TOP);
+ synchronized (mQuotaController.mLock) {
+ mQuotaController.maybeStartTrackingJobLocked(job, null);
+ mQuotaController.prepareForExecutionLocked(job);
+ }
+ setProcessState(ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND);
+ synchronized (mQuotaController.mLock) {
+ assertEquals(mQcConstants.EJ_LIMIT_ACTIVE_MS / 2,
+ mQuotaController.getMaxJobExecutionTimeMsLocked(job));
+ mQuotaController.maybeStopTrackingJobLocked(job, null, false);
+ }
+
+ setProcessState(ActivityManager.PROCESS_STATE_RECEIVER);
+ synchronized (mQuotaController.mLock) {
+ assertEquals(mQcConstants.EJ_LIMIT_RARE_MS,
+ mQuotaController.getMaxJobExecutionTimeMsLocked(job));
+ }
+ }
+
/**
* Test getTimeUntilQuotaConsumedLocked when the determination is based within the bucket
* window.
@@ -2508,7 +2582,7 @@ public class QuotaControllerTest {
assertEquals(15 * MINUTE_IN_MILLIS, mQuotaController.getEJLimitsMs()[WORKING_INDEX]);
assertEquals(10 * MINUTE_IN_MILLIS, mQuotaController.getEJLimitsMs()[FREQUENT_INDEX]);
assertEquals(10 * MINUTE_IN_MILLIS, mQuotaController.getEJLimitsMs()[RARE_INDEX]);
- assertEquals(0, mQuotaController.getEJLimitsMs()[RESTRICTED_INDEX]);
+ assertEquals(5 * MINUTE_IN_MILLIS, mQuotaController.getEJLimitsMs()[RESTRICTED_INDEX]);
assertEquals(0, mQuotaController.getEjLimitSpecialAdditionMs());
assertEquals(HOUR_IN_MILLIS, mQuotaController.getEJLimitWindowSizeMs());
assertEquals(1, mQuotaController.getEJTopAppTimeChunkSizeMs());
diff --git a/services/tests/wmtests/src/com/android/server/wm/LockTaskControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/LockTaskControllerTest.java
index f935bfcd9068..d663b649fbba 100644
--- a/services/tests/wmtests/src/com/android/server/wm/LockTaskControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/LockTaskControllerTest.java
@@ -122,6 +122,7 @@ public class LockTaskControllerTest {
@Mock private StatusBarManagerInternal mStatusBarManagerInternal;
@Mock private TelecomManager mTelecomManager;
@Mock private RecentTasks mRecentTasks;
+ @Mock private TaskChangeNotificationController mTaskChangeNotificationController;
private LockTaskController mLockTaskController;
private Context mContext;
@@ -145,7 +146,7 @@ public class LockTaskControllerTest {
mSupervisor.mRootWindowContainer = mRootWindowContainer;
mLockTaskController = new LockTaskController(mContext, mSupervisor,
- new ImmediatelyExecuteHandler());
+ new ImmediatelyExecuteHandler(), mTaskChangeNotificationController);
mLockTaskController.setWindowManager(mWindowManager);
mLockTaskController.mStatusBarService = mStatusBarService;
mLockTaskController.mDevicePolicyManager = mDevicePolicyManager;
diff --git a/tests/FlickerTests/OWNERS b/tests/FlickerTests/OWNERS
index f35a318acbf7..b5561010e7f9 100644
--- a/tests/FlickerTests/OWNERS
+++ b/tests/FlickerTests/OWNERS
@@ -1,2 +1,3 @@
+# Bug component: 909476
include /services/core/java/com/android/server/wm/OWNERS
natanieljr@google.com \ No newline at end of file